<?php

/**
 * AccountLogic.php
 * 文件描述
 * Created On 2022/1/18
 * @author yuanb yuanbo0x@gmail.com
 */

namespace Game\Logic;

use Framework\Log\LogMark;
use Framework\MVC\ModelManager;
use Framework\Lib\Utils;
use Framework\Logic\OnLineLogic;
use Framework\Model\CommonModel;
use Framework\Model\PacketCacheModel;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateClothing;
use Game\Constant\ConstTemplate\TemplateConst;
use Game\Constant\DBTableDefine;
use Game\Constant\EventTypeDefine;
use Game\Constant\GameConstantDefine;
use Game\Constant\ModelTypeDefine;
use Game\Config\GameConfig;
use Game\Constant\TemplateDefine;
use Game\Data\AccountData;
use Game\Data\MoneyData;
use Game\Data\ProficiencyData;
use Game\Data\RoleExtData;
use Game\GameLive;
use Game\Method\Activity\PushActivityLimitTimeTask;
use Game\Method\Task\GetTaskOnLogin;
use Game\Model\AccountModel;
use Framework\Logic\TemplateHelp;
use Game\Model\NoticeModel;
use Game\Model\PaiweiLevelModel;
use Game\Model\PVE\PveModel;
use Game\Model\SyncModel;
use Game\Model\Task\Manager\WeekTaskManager;
use Game\Operation\EventLog\EventLog_Manager;
use Game\Operation\EventLog\EventLogType;
use Game\Operation\EventLog\LoginLog;
use Game\Operation\EventLog\LogoutLog;
use Game\Operation\PlatformManager;
use Game\Protobuf\ClothData;
use Game\Logic\Activity\WelfareLogic;
use Game\Logic\Activity\LimitActivityLogic;

trait AccountLogic
{
    use TemplateHelp;
    use NoticeLogic;
    use OnLineLogic;
    use EventConditionLogic;
    use EventLogic;
    use RankLogic;
    use WelfareLogic;
    use LimitActivityLogic;
    use GetTaskOnLogin;
    use PushActivityLimitTimeTask;

    public function searchPlayerIdByAccount($account): int
    {
        /**
         * @var CommonModel $common
         */
        $common = ModelManager::getInstance()->getModel(ModelTypeDefine::COMMON);
        $val = $common->search(CommonModel::TYPE_PLAY_ACCOUNT_PLAYER, $account);
        if ($val == "") {
            return 0;
        }
        $arr = explode('*', $val);
        if (count($arr) > 1) {
            return 0;
        }
        return $val;
    }

    public function searchPlayerIdByNickName($account): int
    {
        /**
         * @var CommonModel $common
         */
        $common = ModelManager::getInstance()->getModel(ModelTypeDefine::COMMON);
        $val = $common->search(CommonModel::TYPE_PLAY_NAME_PLAYER, $account);
        if ($val == "") {
            return 0;
        }
        $arr = explode('*', $val);
        if (count($arr) > 1) {
            return 0;
        }
        return $val;
    }

    public function searchPlayerIdByRoleID($roleID): int
    {
        /**
         * @var CommonModel $common
         */
        $common = ModelManager::getInstance()->getModel(ModelTypeDefine::COMMON);
        $val = $common->search(CommonModel::TYPE_PLAY_ROLEID_PLAYER, $roleID);
        if ($val == "") {
            return 0;
        }
        $arr = explode('*', $val);
        if (count($arr) > 1) {
            return 0;
        }
        return $val;
    }

    public function searchPlayerIdByDevice($device): int
    {
        /**
         * @var CommonModel $common
         */
        $common = ModelManager::getInstance()->getModel(ModelTypeDefine::COMMON);
        $val = $common->search(CommonModel::TYPE_PLAY_DEVICE_ID, $device);
        if ($val == "") {
            return 0;
        }
        $arr = explode('*', $val);
        if (count($arr) > 1) {
            return 0;
        }
        return $val;
    }

    public function saveLoginSessoin($playerId, $sessionId) {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $accountModel->saveLoginSession($playerId, $sessionId);
    }

    public function login($playerId, $isRegister, $clientData)
    {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);

        // 存储客户端数据
        $data = [
            AccountData::DB_CLIENT_DATA => $clientData,
        ];
        $accountModel->saveAccount($data);

        $this->clearMessage();
        $this->updateTimeById($playerId, Utils::getServerTimestamp());
        $this->upRoleStatus(GameConstantDefine::PLAYER_STATUS_ONLINE, $playerId);

        // 登录初始信息处理
        $accountModel->search($this->playerId, $data);

        if(!$isRegister && $data[AccountData::DB_STEP] >= GameConstantDefine::STEP_COMPLETE) {
            $this->initLoginPlayerData();
        }

        if (!$isRegister) {
            //记录打点日志
            GameLive::getInstance()->InitProtagonistPlayerId($playerId);

            $log = EventLog_Manager::getInstance()->getEventLog(EventLogType::Login);
            if (is_null($log)) {
                return;
            }
            /**
             * @var LoginLog $log
             */
            $log->first = LoginLog::NOT_FIRST_LOGIN;
            $log->diamond = $accountInfo[MoneyData::DIAMOND] ?? 0;
            $log->ticket = $accountInfo[MoneyData::TICKETS] ?? 0;
            $log->gold = $accountInfo[MoneyData::GOLD] ?? 0;
            $log->clubCoin = $accountInfo[MoneyData::CLUB] ?? 0;
            $log->seasonCoin = $accountInfo[MoneyData::SEASON] ?? 0;
            $log->warTokenCoin = $accountInfo[MoneyData::ZL] ?? 0;
            $log->markLog();
        }
    }

    // 登录滞后检测
    public function loginCheckMsg($playerId, bool $isRegister) {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);

        if($isRegister) {
            // 注册检测福利活动
            $this->registerCheckActivity();
        }
        // 触发任务
        $this->triggerEvent(EventTypeDefine::EVENT_TYPE_TASK_LOGIN_DAY, []);
        // 非注册
        if(!$isRegister) {
            //更新登录天数,在修改登录时间前更新
            $this->updatePlayerLoginDate($accountModel, $playerId);

            $timeOut = $this->getTerm(
                TemplateDefine::TYPE_CONST,
              TemplateConst::Const_Rank_Player_Time_Out_Max,
                TemplateConst::ConstNum);
            $minTime = Utils::getServerTimestamp() - $timeOut  * 24 * 60 * 60;

            // 登录时间超过排行榜配置 则重新更新排行榜
            $accountInfo = $this->searchPlayerInfo($playerId);
            if((Utils::getServerTimestamp() - $accountInfo[AccountData::DB_LOGIN_TIME]) >= $minTime) {
                $this->loginTimeOutUpdateRank();
            }
            //检查同步模块和跨天
            /**
             * @var SyncModel $syncModel
             */
            $syncModel = ModelManager::getInstance()->getModel(ModelTypeDefine::SYNC);
            $lastSyncTime = $syncModel->getLastSyncTime();
            $this->crossDayReset($lastSyncTime);
            $syncModel->syncSysModel();
            $syncModel->updateLastSyncTime();
            $syncModel->savePlayerModelIndex();

            //通知亲密好友上线
            $this->syncFriendIntimacyLoginNotice($playerId, $accountInfo);
            //同步日常任务,战令任务,熟练度任务
            $this->sendTaskListOnLoginCheckMsg($playerId);
        }

        // 推送限时活动开启任务
        $this->PushAcitvityRedInfo($playerId);

        //更新登录时间
        $accountModel->login($playerId);
    }

    //更新自己或者他人角色的状态
    //注意 不包含离线状态!!!
    public function upRoleStatus(int $status, int $playerId): bool
    {
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $update = [RoleExtData::DB_Status => $status];
        if (!$account->saveAccountDataByPlayerId($playerId, $update)) {
            return false;
        }

        //增加心跳通知所有好友我的当前状态
        $this->syncFriendStatusToAll($status, $playerId);
        return true;
    }

    //设置玩家离线
    public function setPlayerOffline(int $playerId, int $offlineTime)
    {
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        //更新状态和离线时间
        $update = array(
            RoleExtData::DB_Status => GameConstantDefine::PLAYER_STATUS_OFFLINE,
            AccountData::DB_LOGOUT_TIME => $offlineTime
        );
        if (!$account->saveAccountDataByPlayerId($playerId, $update)){
            return;
        }
        //增加心跳通知所有好友我的当前状态
        $this->syncFriendStatusToAll(GameConstantDefine::PLAYER_STATUS_OFFLINE, $playerId);

        //记录打点日志
        GameLive::getInstance()->InitProtagonistPlayerId($playerId);
        $log = EventLog_Manager::getInstance()->getEventLog(EventLogType::Logout);
        if (!is_null($log)) {
            EventLog_Manager::getInstance()->cliInitAccount();
            $account->searchAccount($accountInfo);
            /**
             * @var LogoutLog $log
             */
            $log->diamond = $accountInfo[MoneyData::DIAMOND] ?? 0;
            $log->ticket = $accountInfo[MoneyData::TICKETS] ?? 0;
            $log->gold = $accountInfo[MoneyData::GOLD] ?? 0;
            $log->clubCoin = $accountInfo[MoneyData::CLUB] ?? 0;
            $log->seasonCoin = $accountInfo[MoneyData::SEASON] ?? 0;
            $log->warTokenCoin = $accountInfo[MoneyData::ZL] ?? 0;
            $log->online_time = (string)($offlineTime - $accountInfo[AccountData::DB_LOGIN_TIME]);
            $log->markLog();
            //更新用户属性
            /**
             * @var PveModel $pveModel
             */
            $pveModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PVE);
            $attr = array(
                EventLogType::LOG_KEY_PLAYER_PROFICIENCY_LV => $accountInfo[ProficiencyData::PROFICIENCY_LV] ?? 1,
                EventLogType::LOG_KEY_CAREER_LEVEL_ID => $pveModel->getMaxLevelId(),
            );
            EventLog_Manager::getInstance()->updateUserAttr($attr);
            PlatformManager::getInstance()->close();
        }
    }

    public function getAccountAttribute($attr)
    {
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        return $account->getAccountAttr($attr);
    }

    public function register($account, $playerId, $type, $password, $deviceID, $clientData)
    {
        /**
         * @var CommonModel $common
         */
        $common = ModelManager::getInstance()->getModel(ModelTypeDefine::COMMON);
        if (!$common->startAdd(CommonModel::TYPE_PLAY_ACCOUNT_PLAYER, $account, $playerId)) {
            return ;
        }

        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $accountModel->register($playerId, $account, $type, $password, $clientData);

        if($type == AccountData::PLAYER_GUEST) {
            if(!empty($deviceID)) {
                $common->finishAdd(CommonModel::TYPE_PLAY_DEVICE_ID, $deviceID, $playerId);
            }
        }

        $common->finishAdd(CommonModel::TYPE_PLAY_ACCOUNT_PLAYER, $account, $playerId);
        ModelManager::getInstance()->setPlayerId($playerId);
        // 发送邮件 告知保存账号密码
        if($type == AccountData::PLAYER_GUEST) {
            // 发送保存账号密码邮件
            $mailID = $this->getTerm(TemplateDefine::TYPE_CONST,
                TemplateConst::Const_Guest_Account_MailID, TemplateConst::ConstNum);
            $replaceString = $this->replaceMailContent($mailID, array(
                GameConstantDefine::MAIL_KEY_ACCOUNT => $account,
                GameConstantDefine::MAIL_KEY_PASSWORD => $this->message->getPassword(),
            ));
            $this->createPlayerMail($mailID, Utils::getServerTimestamp(), array(), 0, $this->playerId,
                0, "", $replaceString);
        }

        //记录打点日志
        GameLive::getInstance()->InitProtagonistPlayerId($playerId);
        $log = EventLog_Manager::getInstance()->getEventLog(EventLogType::Login);
        if (!is_null($log)) {
            $clientDataArr = json_decode($clientData, true);
            /**
             * @var LoginLog $log
             */
            $log->first = LoginLog::FIRST_LOGIN;
            $log->diamond = $accountInfo[MoneyData::DIAMOND] ?? 0;
            $log->ticket = $accountInfo[MoneyData::TICKETS] ?? 0;
            $log->gold = $accountInfo[MoneyData::GOLD] ?? 0;
            $log->clubCoin = $accountInfo[MoneyData::CLUB] ?? 0;
            $log->seasonCoin = $accountInfo[MoneyData::SEASON] ?? 0;
            $log->warTokenCoin = $accountInfo[MoneyData::ZL] ?? 0;
            $log->mac = $clientDataArr['#mac'] ?? 0;
            $log->imsi = $clientDataArr['#imsi'] ?? 0;
            $log->markLog();
            //更新玩家数据
            $attr = array(
                EventLogType::LOG_KEY_ROLE_FIRST_LOGIN_TIME => Utils::getServerDate(),
                EventLogType::LOG_KEY_ROLE_REGISTER_TIME => Utils::getServerDate(),
            );
            EventLog_Manager::getInstance()->register($attr);
        }
    }

    public function makePlayerId(): int
    {
        $index = $this->getUidIndex();
        return Utils::makeObjectID(GameConfig::getInstance()->SERVER_ID(), DBTableDefine::TABLE_ACCOUNT, $index);
    }

    public function makeSessionId(): string
    {
        return  uniqid("", true);
    }

    public function searchPlayerInfo($playerId): ?array
    {
        ModelManager::getInstance()->setPlayerId($playerId);
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $playerInfo = array();
        if ($accountModel->search($playerId, $playerInfo)) {
            return $playerInfo;
        }
        return null;
    }

    // 保存服饰
    public function saveDress($sex, $cloth):bool
    {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        return $accountModel->saveDress($sex, $cloth);
    }

    /**
     * 登录后处理 初始信息检测
     */
    private function initLoginPlayerData()
    {
        $modelList = Utils::arrMerge(
            ModelTypeDefine::MODEL_MAP1,
            ModelTypeDefine::MODEL_MAP2,
            ModelTypeDefine::MODEL_MAP3);
        foreach ($modelList as $modelType => $value) {
            $model = ModelManager::getInstance()->getModel($modelType);
            if (!is_null($model) && method_exists($model, "onLoginExec")) {
                $model->onLoginExec();
            }
        }
    }

    //删除缓存消息
    private function clearMessage()
    {
        /**
         * @var PacketCacheModel $packetCache
         */
        $packetCache = ModelManager::getInstance()->getModel(ModelTypeDefine::PACKET_CACHE);
        $packetCache->clearPacket();
        /**
         * @var NoticeModel $notice
         */
        $notice = ModelManager::getInstance()->getModel(ModelTypeDefine::NOTICE);
        $notice->clearNotice();
    }

    //获取Account属性
    public function getAccountProperty(int $playerId, string $key, string $default = null): ?string
    {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $playerInfo = array();
        if ($accountModel->search($playerId, $playerInfo)) {
            return $playerInfo[$key] ?? $default;
        }
        return null;
    }

    /**
     * 获取Account多个属性
     * @param int $playerId
     * @param array $keys [account包含的key]
     * @return array [key=>value(默认为string)key不存在为null]
     */
    public function getAccountPropertyArr(int $playerId, array $keys): array
    {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $playerInfo = array();
        $ret = array();
        if ($accountModel->search($playerId, $playerInfo)) {
            foreach ($keys as $key) {
                $ret[$key] = $playerInfo[$key] ?? null;
            }
        }
        return $ret;
    }

    //记录消息缓存
    public function savePacketCache(int $index, string $packet)
    {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $accountModel->savePacketCache( $index, $packet);
    }

    // 记录玩家当前房间id
    public function savePlayerRoomID(int $roomID, $playerID = 0) {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $accountModel->savePlayerRoomID($roomID, $playerID);
    }

    // 记录玩家当前自定义房间id
    public function savePlayerRoomCustomizeID(int $roomID, $playerID = 0) {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $accountModel->savePlayerRoomCustomizeID($roomID, $playerID);
    }

    public function savePlayerLicenceNum(int $num, $playerID = 0) {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $accountModel->savePlayerLicenceNum($num, $playerID);
    }

    public function savePlayerLicenceDate(string $date, $playerID = 0) {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $accountModel->savePlayerLicenceDate($date, $playerID);
    }

    public function savePlayerClubExitDate(int $date, $playerID = 0) {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $accountModel->saveClubExitDate($date, $playerID);
    }

    //更新记录登录时间次数
    private function updatePlayerLoginDate(AccountModel $accountModel, int $playerId)
    {
        if ($accountModel->search($playerId, $playerInfo)) {
            $day = abs(Utils::getGapDay((int)$playerInfo[AccountData::DB_LOGIN_TIME]));
            if ((int)$playerInfo[AccountData::DB_LOGIN_TIME] == 0 || $day <= 0) {
                // 新用户
                return;
            }
            if ($day == 1) {
                // 连续登录
                $loginNum = isset($playerInfo[AccountData::DB_LOGIN_NUM]) ?
                    (int)$playerInfo[AccountData::DB_LOGIN_NUM] + 1 :
                    2;
                $loginContinuousNum = isset($playerInfo[AccountData::DB_LOGIN_CONTINUOUS_NUM]) ?
                    (int)$playerInfo[AccountData::DB_LOGIN_CONTINUOUS_NUM] + 1 :
                    2;
                $accountModel->updatePlayerLoginDay($loginNum, $loginContinuousNum);
            } elseif ($day > 1) {
                // 非连续登录
                $loginNum = isset($playerInfo[AccountData::DB_LOGIN_NUM]) ?
                    (int)$playerInfo[AccountData::DB_LOGIN_NUM] + 1 :
                    2;
                $loginContinuousNum = 1;
                $accountModel->updatePlayerLoginDay($loginNum, $loginContinuousNum);
            }
            // 当日首次登录
            //更新离线天数和赛季登录积分
            /**
             * @var PaiweiLevelModel $levelModel
             */
            $levelModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PAIWEI_LEVEL);
            $levelModel->updateGapDay($day);
        }
    }

    /**
     * 创建默认车辆
     * @param $carId
     * @return int 返回carUid
     */
    public function createSystemCar($carId, int $itemID = 0)
    {

        if (!$this->systemGainCar($carId, 1, 0))
        {
            return false;
        }

        $carData = $this->searchCarDataByCarID($carId);
        if (is_null($carData) || empty($carData->uid))
        {
            return false;
        }
        return $carData->uid;
    }

    public function getStep(): int
    {
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $step = $account->getAccountAttr(AccountData::DB_STEP);
        if ($step === false){
            return 0;
        }
        return $step;
    }

    public function getModelID(): int
    {
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $step = $account->getAccountAttr(AccountData::DB_ROLE_MODEL_ID);
        if ($step === false){
            return 0;
        }
        return $step;
    }

    //更新车辆的总性能分
    public function saveCarsPerformance($scores): bool
    {
        return (ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT))->updateCarsPerformanceScore($scores);
    }

    public function getClothProtoData(int $playerId): array
    {
        $accountProperty = $this->getAccountPropertyArr($playerId,
            [
                AccountData::DB_GENDER,
                AccountData::DB_CLOTH_FEMALE,
                AccountData::DB_CLOTH_MALE
            ]);
        $gender = (int)$accountProperty[AccountData::DB_GENDER];
        if($gender == AccountData::FEMALE) {
            $cloth = json_decode($accountProperty[AccountData::DB_CLOTH_FEMALE], true);
        } else {
            $cloth = json_decode($accountProperty[AccountData::DB_CLOTH_MALE], true);
        }
        $clothRes = new ClothData();
        foreach($cloth as $item) {
            if(empty($item)) {
                continue;
            }
            $cfg = $this->getTitle(TemplateDefine::TYPE_CLOTHING, $item);
            switch($cfg[TemplateClothing::Part]) {
                case 1:  $clothRes->setHairId($item); break;
                case 2:  $clothRes->setFaceId($item); break;
                case 3:  $clothRes->setUpClothId($item); break;
                case 4:  $clothRes->setDownClothId($item); break;
                case 5:  $clothRes->setShoesId($item); break;
            }
        }
        return array($gender, $clothRes);
    }

    public function saveAccountModel($step,  $modelID)
    {
        if ($step != GameConstantDefine::roleSelectModel)
        {
            return false;
        }
        /**
         * @var CommonModel $common
         */
        $common = ModelManager::getInstance()->getModel(ModelTypeDefine::COMMON);
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        if (!$account->roleRegister($modelID, $step, $data)){
            return false;
        }
        $common->finishAdd(CommonModel::TYPE_PLAY_ROLEID_PLAYER, $data[AccountData::DB_RoleId], $this->playerId);
        EventLog_Manager::getInstance()->updateUserAttr(array(EventLogType::LOG_KEY_ROLE_ID => $data[AccountData::DB_RoleId]));
        return true;
    }

    public function saveAccountName($step, $name)
    {
        if ($step != GameConstantDefine::roleInputName)
        {
            return false;
        }
        /**
         * @var CommonModel $common
         */
        $common = ModelManager::getInstance()->getModel(ModelTypeDefine::COMMON);
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $data = [
            AccountData::DB_STEP => $step,
            AccountData::DB_NICK_NAME => $name,
        ];
        if (!$account->saveAccount($data)){
            return false;
        }
        $common->finishAdd(CommonModel::TYPE_PLAY_NAME_PLAYER, $name, $this->playerId);
        return true;
    }

    public function saveAccountData($data)
    {
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        if (!$account->saveAccount($data)){
            return false;
        }
        return true;
    }

    //检查昵称长度
    public function checkNicknameLen(string $nickName): int
    {
        $maxLength = $this->getTerm(TemplateDefine::TYPE_CONST, TemplateConst::Const_Nick_Name_Max_Length, TemplateConst::ConstNum);
        $minLength = $this->getTerm(TemplateDefine::TYPE_CONST, TemplateConst::Const_Nick_Name_Min_Length, TemplateConst::ConstNum);
        //检查昵称长度
        $nameLen = $this->getNickNameLength($nickName, $charLen);
        if ($nameLen < $minLength) {
            return ClientErrorCode::NICKNAME_LEN_LESS;
        }
        if ($nameLen > $maxLength) {
            return ClientErrorCode::NICKNAME_LEN_OVER;
        }
        return ClientErrorCode::CLIENT_SUCCESS;
    }

    # 检测角色名字,如果昵称重复,在此昵称后加随机字符
    public function checkRoleName(string &$nickName): string
    {
        $loop = 100;
        $status = true;
        $maxLength = $this->getTerm(TemplateDefine::TYPE_CONST, TemplateConst::Const_Nick_Name_Max_Length, TemplateConst::ConstNum);
        do {
            if ($loop <= 0){
                return $status;
            }
            $nameLen = $this->getNickNameLength($nickName, $charLen);
            /**
             * @var CommonModel $common
             */
            $common = ModelManager::getInstance()->getModel(ModelTypeDefine::COMMON);
            $val = $common->search(CommonModel::TYPE_PLAY_NAME_PLAYER, $nickName);
            if ($val == "") {
                return $status;
            }
            $arr = explode($val, "*");
            if (count($arr) > 1) {
                return $status;
            }
            if ($maxLength > $nameLen) {
                $nickName .= Utils::RandomChar(random_int(1, $maxLength - $nameLen));
            } else {
                $nickName .= Utils::RandomChar(1);
            }
            $status = false;
            $loop--;
        }while(true);
    }
    private function getNickNameLength($nickName, &$charLen): int
    {
        // todo 汉字按2个字符计数, 重新计算 nickName的长度, 不能使用strlen计算了   字节数-字符数 就是 汉字多出的字节数量
        $charLen = iconv_strlen($nickName, "utf-8");
        $byteLen = strlen($nickName);
        $len = $byteLen - $charLen;
        if ($len == 0){
            return $byteLen;
        }
        return $byteLen - $len/2;
    }

    public function getRoleStatus(int $playerId = null)
    {
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        if (!is_null($playerId)){
            $account->setPlayerId($playerId);
        }
        return $account->getAccountAttr(RoleExtData::DB_Status);
    }

    /**
     * 更新最近比赛的好友列表
     * @param array|string $matchPlayers
     * @return bool
     */
    public function upRoleExtLatelyMatchFriend($matchPlayers): bool
    {
        if (is_array($matchPlayers)){
            $matchPlayers = json_encode($matchPlayers);
        }
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        if (!$account->updateRoleExt([RoleExtData::DB_LATELY_MATCH_FRIEND => $matchPlayers])){
            return false;
        }
        return true;
    }
}
