<?php
define('IN_WEB', true);
/**
 * 登录接口
 * 89c1942a
 */
/**
 * 停服流程 => 登录返回-999 =>后台发送指令踢出在线用户 => 前端每次尝试登录 => 登录成功就正常，登录失败就判断是否在停服时间内，弹出提示
 */
//echo json_encode(array('uid' => -999 ,'ret' => -999, 'msg' => '停服'));
//exit(0);//停服,玩家不能登录


class LoginNew {
    public $getParams = array();
    public $param = array();
    public $arr_poker = array();
    public $siteuid = 0;
    public $uid = 0;
    public $sid = 0;
    public $userinfo = array();
    public $account = array();
    public $isNewUser = false;
    public $startTime = 0;
    public $secret = 'superant';
    public $signVaild = true;
    public $macAddress = "";
    public $fbToken = "";
    public $macType = 1;
    public $isAppleAuth = false;
    public $isFirst = false;
    public $randNum=0;
    public $mobile_date_src=0;
    /**
     * 初始化
     */
    public function __construct($getParams=[]) {
        $this->startTime = intval(microtime(TRUE) * 1000);
        $this->randNum = mt_rand(1,100000);
        $this->getParams = $getParams;
    }


    public function start() {
        if(empty($this->getParams)){
            return ["code"=>0,"uid"=>-1,'line'=>__LINE__];
        }
        if(strpos($this->getParams['from_host'],"vivo") !== false||(!empty($this->getParams['plat'])&&$this->getParams['plat']=='vivo')){
            return array("code"=>0,"uid"=>-999,'ret'=>-999,'data'=>[
                'stime' => time() - 5,
                'etime' => time() + 3*24*60*60,
                'type'  => 1,
                'title' => "Tips",
                'content' => "This version is no longer available, please search for Crazy Coin from Google Play to download the latest version!",
            ]);
        }
//        $this->writeloginLog(0);
        //if($this->getParams['from_ip']&&oo::commonOprRedis('common')->get(okeys::ipStatus())){//ip区域限行
        //    $info =  oo::ipAlg()->memorySearch($this->getParams['from_ip']);
        //    $addressInfo = explode('|', $info['region']);
        //    if($addressInfo[2]=='加利福尼亚'){
        //        oo::logs()->debug3($this->getParams,'notpasslogin.log');
        //        return array("code"=>0,"uid"=>-999,'ret'=>-999,'data'=>["content"=>"I'm sorry, service has been suspended","type"=>1,"stime"=>time(),"etime"=>time()+86400*3]);
        //    }
        //}
        $this->_before();
        $res = $this->_verifyParams();
        if($res['code']!=1){
            return $res;
        }

        //记录所有api请求记录,未响应的也记录
        oo::commonOprModel('statistics')->apiRequestLog('login', 'new');

        //登录频率,防止重复插入问题
        if(!funs::concurrentLock($this->macAddress,'insert_new', 1)){
            usleep(200000); //延迟200毫秒登录
        }

        if (!empty($this->getParams['signed_request'])) { // fb登录
            $this->param['lid'] && $this->param['lid'] = 1;
            $res1 = $this->_fbLoginNew();
            if($res1['code']!=1){
                return $res1;
            }
        }else { // 游客登录
            $this->param['lid'] && $this->param['lid'] = 2;
            $res2 = $this->_vistorLogin();
            if($res2['code']!=1){
                return $res2;
            }
        }
        isset($this->account['uid']) && $this->uid = (int)$this->account['uid'];

        //更新玩家设备和语言信息
        $updefinedArr = [
            'lid'  => isset($this->param['lid']) ? $this->param['lid'] : 2,
            'sid'  => isset($this->param['sid']) ? $this->param['sid'] : 1,
            'lang' => isset($this->param['lang']) ? $this->param['lang'] : 'en',
        ];
        //更新玩家lid,sid,lang等信息
        oo::commonOprModel('member')->setUserDefinedInfo($this->uid, $updefinedArr);
        //系统公告
        $notice = oo::commonOprModel('notice')->getNowAnnouncement($this->uid);
        if(!empty($notice)&&$notice['type']==1){//停服公告
            return array("code"=>0,"uid"=>-999,'ret'=>-999,'data'=>$notice);
        }
        //强更
        $updateCfg = oo::commonOprRedis('common')->exists(okeys::updateVersionCfg($this->sid))?json_decode(oo::commonOprRedis('common')->get(okeys::updateVersionCfg($this->sid)),true):[];
        if(oo::compareVersion($this->param['version'],'1.7.7')&&!empty($updateCfg)&&isset($updateCfg['curVersion'])){
            if(!oo::compareVersion($this->param['version'],$updateCfg['curVersion'])&&$updateCfg['isForce']==1){
                return array("code"=>-666,'ret'=>-666,'data'=>$updateCfg);
            }
        }

        $this->param['mtkey'] = oo::commonOprModel('member')->createMtkey($this->siteuid);/* 生成mtkey */
        $this->param['sex'] = $this->userinfo['gender'] ?? 'f';/* 用户性别 */
        $this->param['country'] = $this->getParams['country'] ?? ''; //用户国家地区
        $this->param['countryId'] = $this->getParams['countryId'] ?? 0;//用户国家ID
        $this->param['notificationStatus'] = isset($this->getParams['notificationStatus'])?intval($this->getParams['notificationStatus']):-1;//是否开启推送通知

        if ($this->isNewUser) { // 新用户
            $res3 = $this->_reg();
            if($res3['code']!=1){
                return $res3;
            }
            $this->_regTodo();
            if($this->param['isRobot']){
                oo::commonOprRedis('common')->delete(okeys::GetRobotUserList());
            }
        } else {
            $res3 = $this->_loginTodo();
            if($res3['code']!=1){
                return $res3;
            }
        }

        $this->_after();
        $this->arr_poker['isNewUser'] = (int)$this->isNewUser; //是否新玩家
        $this->arr_poker['slotConfig'] = oo::commonOprModel('slot')->getSlotImgConfig($this->uid);
        $openOlineVersion = oo::commonOprRedis('common')->get(okeys::openOlineVersion())?? '1.7.7';
        //ios vip 兑换码 开关
        if(oo::compareVersion($this->param['version'], $openOlineVersion)){
            $this->arr_poker['openOline'] = 0;
        }else{
            $this->arr_poker['openOline'] = oo::commonOprRedis('common')->get(okeys::openOline())??0;
        }

        //客户端ios相关参数
        if(oo::compareVersion($this->param['version'], '1.8.1')){
            $this->arr_poker['isOpenMaple'] = (int)oo::commonOprRedis('common')->get(okeys::isOpenMaple());
        }

        //abtest开关
        if(oo::compareVersion($this->param['version'], '1.8.6')){
            $this->arr_poker['abClose'] = (int)oo::commonOprRedis('common')->get(okeys::abSwitch());
        }

        if(!empty($notice)){
            $this->arr_poker['announcement'] =$notice;//系统公告
        }
        //新版更新公告
        if(oo::compareVersion($this->param['version'], '1.11.0')){
            $notice = oo::commonOprModel('notice')->getNowAnnouncementNew($this->uid);
            if(!empty($notice)){
                $this->arr_poker['upnotice'] = $notice;//系统公告
            }
        }
        $this->writeloginLog(1);
        $this->_slowlog();
        if(!isset($this->arr_poker['code'])){
            $this->arr_poker['code'] = errorCode::SUCCESS;
        }
        $this->arr_poker['petShopOpenLv'] = oo::commonOprModel('readconfig')->getCon('Game','petShopOpenLv') ?? 4;
        return $this->arr_poker;
    }

    /**
     * Notes:FB登录
     * User: wsc
     * Time: 2020/5/19 14:24
     */
    protected function _fbLoginNew(){
        $this->param['loginSrc'] = 'fb';
        $this->param['accessToken'] = $this->fbToken = $accessToken = htmlspecialchars($this->getParams['signed_request']);
        $url = 'https://graph.facebook.com/me?access_token='.$accessToken.'&fields=id,name,email,first_name,gender,locale,location,birthday,hometown,picture.height(200).width(200)';
        $userinfo = !empty($accessToken)?oo::commonOprModel('member')->getFbInfoByToken($accessToken) : [];
        if(empty($userinfo)){
            $userinfo = json_decode(funs::sendCurlPastThird($url),true);
        }
        if ($userinfo['error'] || empty($userinfo) || !is_array($userinfo) || empty($userinfo['id'])){
            $error = ['code'=>0,'uid'=>errorCode::FB_TOKEN_ERROR,'line'=>__LINE__,'accessToken'=>$accessToken,'msg'=>isset($userinfo['error'])?$userinfo['error']['message']:'','clientMtkey'=>$this->param['clientMtkey'],'sid'=>$this->param['sid']];
            $this->errLog($error);
            return $error;
        }
        !empty($userinfo) && oo::commonOprModel('member')->setFbInfoByToken($accessToken,$userinfo);
        $this->userinfo = $userinfo;
        $this->siteuid  = $userinfo['id'];
        oo::commonOprRedis('user')->delete(okeys::account($this->siteuid));
        $account = oo::commonOprModel('member')->getAccount($this->siteuid);
        if($account){
            $this->account = $account;
            oo::commonOprModel('statistics')->loginPlayer($account['uid'], 1, $this->mobile_date_src, $this->param['sid']);//记录在线
            return ['code'=>1];
        }

        $appleAuthUid = 0;
        /** 苹果同步 */
        if($this->param['device'] == 'ios' && !empty($this->getParams['appleUserId']) && !empty($this->getParams['appleIdentityToken'])) {
            $ret = oo::commonOprModel('ios')->appleJwtVerify($this->getParams['appleIdentityToken']);
            if (!$ret['status'] || ($ret['data']['aud'] != "com.newsky.crazycoin" || $ret['data']['sub'] != $this->getParams['appleUserId'])) {
                $msg = ['code'=>0,'uid' => -1, 'line' => __LINE__, 'msg' => $ret['error']];
                $this->errLog($msg);
                return $msg;
            }
            $appleAuthUserInfo = oo::commonOprDb('userinfo')->getOne(sprintf("SELECT * FROM %s WHERE openudid='%s'", otable::openudid(), $this->getParams['appleUserId']), MYSQLI_ASSOC);
            if(!empty($appleAuthUserInfo)){
                $appleAuthUid  = $appleAuthUserInfo['uid'];
            }
        }
        $synchronizeUid = 0;
        if($appleAuthUid){
            if(0 != oo::commonOprModel('member')->setAccount($this->siteuid, $appleAuthUid)){
                $msg = ['code'=>-2,'uid' => -1, 'line' => __LINE__, 'msg' => "set fb account error"];
                $this->errLog($msg);
                return $msg;
            }
            oo::commonOprModel('user')->setTransformLog(['sid'=> $this->sid, 'uid'=> $appleAuthUid, 'transformType'=> 3, 'visitorUid'=> $this->getParams['appleUserId'], 'visitorMac'=> $this->getParams['appleIdentityToken'], 'fbUid'=> 0, 'fbSiteUid'=> $this->siteuid, 'fbToken'=> $this->fbToken, 'time'=>time()]);
            $this->account = [
                'siteuid' => $this->siteuid,
                'uid'     => $appleAuthUid,
                'createtime' => $appleAuthUserInfo['createtime'],
            ];
            oo::commonOprModel('statistics')->loginPlayer($appleAuthUid, 1, $this->mobile_date_src, $this->param['sid']);//记录在线
            oo::commonOprRedis('common')->setex(okeys::FbBindReward($appleAuthUid),1,7*24*60*60);
            $updateInfo = ['ssiteuid'=>$this->siteuid,'slocale'=>$this->getParams['from_ip']];
            !empty($userinfo['name']) && $updateInfo['snick'] = $userinfo['name'];
            oo::commonOprModel('member')->getUserInfo($appleAuthUid, NULL, TRUE,$updateInfo);
            $synchronizeUid = $appleAuthUid;
        }else{
            /** 游客同步 */
            $sql = ($this->macType == 1)? sprintf("SELECT * FROM %s WHERE macid='%s'", otable::mobile(), $this->macAddress) : sprintf("SELECT * FROM %s WHERE openudid='%s'", otable::openudid(), $this->macAddress);
            $ret = oo::commonOprDb('userinfo')->getOne($sql,MYSQLI_ASSOC);
            if(!empty($ret)){
                $curVisitorUid  = $ret['uid'];
                $setAccountBool = oo::commonOprModel('member')->setAccount($this->siteuid, $curVisitorUid);
                if($setAccountBool == 0){
                    $sql = $this->macType == 1 ? sprintf("DELETE FROM %s WHERE uid='%d' AND macid='%s' LIMIT 1", otable::mobile(), $curVisitorUid , $this->macAddress) : sprintf("DELETE FROM %s WHERE uid='%d' AND openudid='%s' LIMIT 1", otable::openudid(), $curVisitorUid , $this->macAddress);
                    oo::commonOprDb('common')->query($sql);
                    oo::commonOprModel('user')->setTransformLog(['sid'=> $this->sid, 'uid'=> 0, 'transformType'=> 2, 'visitorUid'=> $curVisitorUid, 'visitorMac'=> $this->macAddress, 'fbUid'=> 0, 'fbSiteUid'=> $this->siteuid, 'fbToken'=> $this->fbToken, 'time'=>time()]);
                    $this->account = [
                        'siteuid' => $this->siteuid,
                        'uid'     => $curVisitorUid,
                        'createtime' => $ret['createtime'],
                    ];
                    oo::commonOprModel('statistics')->loginPlayer($curVisitorUid, 1, $this->mobile_date_src, $this->param['sid']);//记录在线
                    oo::commonOprRedis('common')->setex(okeys::FbBindReward($curVisitorUid),1,7*24*60*60);
                    $updateInfo = ['ssiteuid'=>$this->siteuid,'slocale'=>$this->getParams['from_ip']];
                    !empty($userinfo['name']) && $updateInfo['snick'] = $userinfo['name'];
                    oo::commonOprModel('member')->getUserInfo($curVisitorUid, NULL, TRUE,$updateInfo);
                    $synchronizeUid = $curVisitorUid;
                }
            }else{
                $this->isNewUser = true;
            }
        }
        /**
         * 被邀请者绑定FB给予邀请者奖励
         */
        $synchronizeUid && oo::commonOprModel('ta')->setEventData($this->uid,'user_setOnce',["account_bind_time"=>time()]);
        $synchronizeUid && oo::commonOprModel('invite')->recordInviteBindFb($synchronizeUid);
        return ['code'=>1];
    }

    /**
     * 游客登录
     */
    protected function _vistorLogin() {
        $this->param['loginSrc'] = 'visitor';
        $visitorId = $this->param['mac'];
        if ($this->param['device'] === 'ios') {
            if(isset($this->getParams['appleUserId']) && !empty($this->getParams['appleUserId'])){
                $ret = $loginInfo = oo::commonOprModel('user')->iosLoginByAppleUserId($visitorId,$this->getParams['appleUserId'],$this->getParams['appleIdentityToken']);
                if(!empty($loginInfo['err'])){
                    return $loginInfo['err'];
                }
                $this->isAppleAuth = true;
                $visitorId = $this->param['openudid'] = $this->getParams['appleUserId'];
            }else{
                //苹果游客mobile_request传_superant空值处理
                if(empty($visitorId) && !funs::checkIosDeviceId($this->getParams['deviceId'])){
                    return ['code'=>0,'uid'=>-1,'line'=>__LINE__, 'msg' => 'invalid mac or device'];
                }elseif(empty($visitorId)){
                    $visitorId = $this->getParams['deviceId'];
                }
                $ret =  oo::commonOprModel('user')->iosLoginByMac($visitorId);
                $this->param['openudid'] = $visitorId;
                $visitorId = intval(sprintf('%u', crc32($visitorId)));
            }
        }else{
            $ret = oo::commonOprModel('user')->androidLoginByMac($visitorId,$this->getParams['deviceId']);
        }
        if (!empty($ret)) {
            $account['uid'] = intval($ret['uid']);
            $this->account = $account;
            !$this->param['isRobot'] && oo::commonOprModel('statistics')->loginPlayer($account['uid'], 2, $this->mobile_date_src, $this->param['sid']);//记录在线
        }else{
            $this->isNewUser = true;
        }
        $this->siteuid = $visitorId;
        return ['code'=>1];
    }

    /**
     * 注册逻辑
     */
    protected function _reg() {
        $sql = sprintf("INSERT INTO %s SET create_time=%d,plat=%d", otable::userid(), time(), $this->mobile_date_src);
        $query = oo::commonOprDb('userinfo')->query($sql);
        if (empty($query)) {
            $errArr['code'] = 0;
            $errArr['uid'] = -1;
            $errArr['siteuid'] = $this->siteuid;
            $errArr['line'] = __LINE__;
            $ret =  $errArr;
            $errArr['sql'] = $sql;
            $errArr['key'] = 'initUidFail';
            $errArr['sid'] = $this->param['sid'];
            $this->errLog($errArr);
            return $ret;
        }
        $uid = oo::commonOprDb('userinfo')->insertID();
        if ($this->param['loginSrc'] == 'fb') {
            $this->arr_poker = array(
                'siteuid'       => $this->siteuid,
                'nick'          => isset($this->userinfo['name']) ? $this->userinfo['name'] : $uid,
                'sex'           => $this->param['sex'],
                'email'         => isset($this->userinfo['email']) ? $this->userinfo['email'] : '',
                's_picture'     => 'https://graph.facebook.com/'.$this->siteuid.'/picture',
                'm_picture'     => 'https://graph.facebook.com/'.$this->siteuid.'/picture?type=normal',
                'b_picture'     => 'https://graph.facebook.com/'.$this->siteuid.'/picture?type=large',
                'status'        => 1,
                'locale'        => isset($this->userinfo['locale']) ? $this->userinfo['locale'] : '',
                'locationid'    => isset($this->userinfo['location']['id']) ? $this->userinfo['location']['id'] : '',
                'locationname'  => isset($this->userinfo['location']['name']) ? $this->userinfo['location']['name'] : '',
                'hometownid'    => isset($this->userinfo['hometown']['id']) ? $this->userinfo['hometown']['id'] : '',
                'hometownname'  => isset($this->userinfo['hometown']['name']) ? $this->userinfo['hometown']['name'] : '',
                'u_flage'           => 1,
                'signature'    => '',
                'plat'          => $this->mobile_date_src,
            );

            $ret = oo::commonOprModel('member')->setAccount($this->siteuid, $uid);
            if ($ret != 0) {
                $err = ['siteuid' => $this->siteuid, 'uid' => $uid, 'ret' => $ret, 'key' => 'setAccountFail', 'sid' => $this->param['sid']];
                $this->errLog($err);
            }
            $statisticsType = 1;
        }else {
            if ($this->param['device'] === 'ios') {
                $sql = sprintf("INSERT INTO %s (openudid,uid,createtime) VALUES('%s',%d,%d)", otable::openudid(), $this->param['openudid'], $uid, time());
                if($this->isAppleAuth){
                    $sql = sprintf("INSERT INTO %s (openudid,uid,createtime) VALUES('%s',%d,%d)", otable::openudid(), $this->getParams['appleUserId'], $uid, time());
                }
            } else {
                $sql = sprintf("INSERT INTO %s (macid,uid,createtime) VALUES('%s',%d,%d)", otable::mobile(), $this->siteuid, $uid, time());
                if (!$this->signVaild) {
                    return array('code'=>0, 'ret' => -100, 'msg' => 'sign error!');
                }
            }
            $query = oo::commonOprDb('userinfo')->query($sql);
            if (empty($query)) {
                $err = array('uid' => $uid, 'siteuid' => $this->siteuid, 'line' => __LINE__, 'sql' => $sql, 'key' => 'initQUIDFail', 'sid' => $this->param['sid'],);
                $this->errLog($err);
                return ['code'=>0,'uid'=>-1,'line'=>__LINE__];
            }
            $postDeviceName = empty($this->getParams['deviceName']) ? oo::getLang('VISITOR_NICK').$uid : $this->getParams['deviceName'];//IOS大量名称是iphone和ipad
            $postDeviceName = in_array(strtolower($postDeviceName), array('iphone', 'ipad')) ? $postDeviceName.$uid : $postDeviceName;
            $this->arr_poker = array(
                'siteuid'       => $this->siteuid,
                'nick'          => $postDeviceName,
                'sex'           => $this->param['sex'],
                'email'         => '2',
                's_picture'     => 1,
                'u_flag'        => 1,
                'signature'     => '',
                'status'        => 1,
                'plat'          => $this->mobile_date_src,
            );
            $statisticsType = 2;
        }
        //插入server需要的用户表  初始用户
        $ghtable = otable::gh_gameserver($uid);
        $csSpins = intval(oo::commonOprModel('readconfig')->getCon('basic','initialSpins')); //初始体力值
        $baseStar = intval(oo::commonOprModel('readconfig')->getCon('basic','initialStar')); //初始星星
        $baseMoney = intval(oo::commonOprModel('readconfig')->getCon('basic','repairMoney')); //初始金幣;
        $baseLevel = intval(oo::commonOprModel('readconfig')->getCon('basic','initialLevel'));
        $insertSrv = " INSERT INTO {$ghtable} (mid, appid, star,levelId,money,spins,shield) VALUES ({$uid}, 1, {$baseStar}, {$baseLevel},{$baseMoney},{$csSpins},0) ";
        oo::commonOprDb('ghgames')->query($insertSrv);

//        $time = time();
//        $lvtb = otable::userlevel();
//        $lvSrv = "INSERT INTO {$lvtb} (uid,levelId,total,createtime,logintime,attackProtectionTime,attackedNum) VALUES ({$uid}, {$baseLevel},0,{$time},{$time},0,0)";
//        oo::commonOprDb('userlevel')->query($lvSrv);

        oo::commonOprModel('member')->setUserNewLevel($uid,1);
        $this->arr_poker['version'] = $this->param['version'];
        $this->arr_poker['locale']  = $this->getParams['from_ip'];
        $this->arr_poker['mac']     = $this->getParams['mobile_request'];
        $this->arr_poker['token']   = $this->getParams['signed_request'];
        $this->arr_poker['lasttime']= time();
        oo::commonOprModel('ipaddress')->intoIpList($uid,$this->arr_poker['locale']);
        $ret = oo::commonOprModel('member')->setUserInfo($this->arr_poker, $uid);
        if ($ret != 0) {
            $err = array('uid' => $uid, 'siteuid' => $this->siteuid, 'line' => __LINE__, 'result' => $ret, 'key' => 'setUserInfoFail', 'sid' => $this->param['sid'],);
            $this->errLog($err);
            return ['code'=>0,'uid'=>-1,'line'=>__LINE__];
        }
        oo::commonOprModel('statistics')->newPlayer($uid, $statisticsType, $this->mobile_date_src, $this->param['sid']);//新注册玩家统计
        oo::commonOprModel('friend')->setUserFriends($uid, array('sisapper'=>'', 'snotapper'=>'', 'spoker'=>'', 'iupdatetime'=>0));
        $this->arr_poker['money'] 			 = $baseMoney; //初始金幣;
        $this->arr_poker['uid'] 		     = $uid;
        $this->arr_poker['u_flag'] 			 = 1;
        $this->arr_poker['shield'] 			 = 0;
        $this->arr_poker['mtkey'] 			 = $this->param['mtkey'];
        $this->arr_poker['firstin'] 		 = 1;
        $this->arr_poker['spins'] 		     = $csSpins;
        $this->arr_poker['coins'] 		     =  $baseMoney; //初始金幣; //初始金币
        $this->arr_poker['star'] 		     = $baseStar;
        $this->arr_poker['levelId'] 		 = $baseLevel;
        $this->arr_poker['restoreSpinsTime'] = oo::commonOprModel('readconfig')->getCon('basic','restoreTime'); //体力恢复时间
        $this->arr_poker['miningInfo'] 		 = oo::commonOprModel('mining')->getInfo($uid);
        /********大转盘剩余秒数**************/
        $this->arr_poker['tpCountdown'] = 0;
        $this->arr_poker['tpStatus'] = 1;
        /********end**************/
        //获取当前用户岛建筑信息
        $mylevelElement                     = oo::commonOprModel('member')->getUserLevel($uid);
        $mylevelElements                    = $mylevelElement['element'];
        $this->arr_poker['element'] 		= $mylevelElements;
        //总消息数  - 未读
        $this->arr_poker['totalMessage']    = 0;
        $this->arr_poker['spinsCountdown']  = oo::commonOprModel('user')->refreshSpins($uid,0);
        $this->arr_poker['spinNextTime'] = max(intval($this->arr_poker['spinsCountdown']),0)+time();
        $this->arr_poker['spinsRecover']    = oo::commonOprModel('readconfig')->getCon('basic','restoreSpins'); //初始体力恢复
        $this->arr_poker['dailyFirstin'] 	= 1;
        $this->arr_poker['inviteuid'] =0;
        $this->uid = $uid;
        return ['code'=>1];
    }

    /**
     * 注册时要触发的逻辑
     */
    protected function _regTodo() {
        // 新手保护
        oo::commonOprRedis('common')->setex(okeys::newcomerProtection($this->uid),1,3*24*60*60);
        // 插入新手引导步数
        if($this->param['loginSrc'] == 'fb'){
            $tb = otable::gh_gameserver($this->uid);
            $sql = "SELECT beginGuide FROM {$tb} WHERE mid={$this->uid} LIMIT 1";
            $ret = oo::commonOprDb('ghgames')->getOne($sql,1);
            if($ret['beginGuide'] == 0){
                $vistorId = $this->param['mac'];
                if ($this->param['device'] === 'ios') {
                    $sql = sprintf("SELECT * FROM %s WHERE openudid='%s'", otable::openudid(), $vistorId);
                } else {
                    $sql = sprintf("SELECT * FROM %s WHERE macid=%d", otable::mobile(), $vistorId);
                }
                $vistor = oo::commonOprDb('userinfo')->getOne($sql,1);
                if(empty($vistor)){
                    oo::commonOprRedis('common')->hSet(okeys::beginGuide(),$this->uid,0);
                }else{
                    $tb = otable::gh_gameserver($vistor['uid']);
                    $sql = "SELECT beginGuide FROM {$tb} WHERE mid={$vistor['uid']} LIMIT 1";
                    $ret = oo::commonOprDb('ghgames')->getOne($sql,1);
                    if($ret['beginGuide'] == 18){
                        // 给予引导奖励
                        oo::commonOprModel('member')->optProperty($this->uid, ['money' => 951000], '+',101, 'FB跳过新手引导');
                        oo::commonOprModel('member')->optProperty($this->uid, ['shield'=>1], '+',101, 'FB跳过新手引导');
                        $AssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($this->uid);
                        $this->arr_poker['coins']  = $AssetsInfo['money'];
                        $this->arr_poker['shield'] = $AssetsInfo['shield'];
                        $this->arr_poker['money']  = $AssetsInfo['money'];
                        oo::commonOprRedis('common')->hSet(okeys::beginGuide(),$this->uid,18);
                    }else{
                        oo::commonOprRedis('common')->hSet(okeys::beginGuide(),$this->uid,0);
                    }
                }
            }
        }else{
            oo::commonOprRedis('common')->hSet(okeys::beginGuide(),$this->uid,0);
        }

        $tb = otable::statistics($this->uid);
        $sql = " INSERT INTO {$tb} (uid) VALUES ({$this->uid}) ";
        oo::commonOprDb('common')->query($sql,1);
        /**
         * 注册人数
         */
        oo::commonOprRedis('common')->sAdd(okeys::getRegCount($this->sid),$this->uid);

        /**
         * 注册确定版本 -- 新用户不能领更新礼包
         */
        $tb  = otable::versionGitfLog($this->uid);
        $time = time();
        oo::commonOprDb('common')->query("INSERT INTO {$tb}(id, uid, version, time, reward) VALUES( NULL,{$this->uid},'{$this->arr_poker['version']}','{$time}','{}')");

        /**
         * adjust 邀请检测设置
         */
        oo::commonOprRedis('User')->setex(okeys::AdjustInviteStatus($this->uid),10,3*24*60*60);
        //数数事件-用户注册
        oo::commonOprModel('ta')->setEventData($this->uid,'user_create',[]);

        //注册就分群 数数 CMS处理
        //oo::commonOprModel('member')->regSSgroup($this->uid);
    }

    /**
     * 登录时要触发的逻辑
     */
    protected function _loginTodo() {
        $this->arr_poker = array();
        $updateInfo = array();
        $updateInfo['lasttime']     = time();
        $updateInfo['slocale'] = $this->getParams['from_ip'];
        if ($this->param['loginSrc'] == 'fb') {
            !empty($this->userinfo['name']) && $updateInfo['snick'] = $this->userinfo['name'];
            !empty($this->userinfo['gender']) && $updateInfo['ssex'] = $this->userinfo['gender'];
            !empty($this->userinfo['email']) && $updateInfo['semail'] = $this->userinfo['email'];
            if (isset($this->userinfo['locale']) && $this->userinfo['locale']) {
                $updateInfo['slocale'] = $this->userinfo['locale'];
                !empty($this->userinfo['location']['id']) && $updateInfo['slocationid'] = $this->userinfo['location']['id'];
                !empty($this->userinfo['location']['name']) && $updateInfo['slocationname'] = $this->userinfo['location']['name'];
            }
            if (isset($this->userinfo['hometown']) && $this->userinfo['hometown']) {
                !empty($this->userinfo['hometown']['id']) && $updateInfo['shometownid'] = $this->userinfo['hometown']['id'];
                !empty($this->userinfo['hometown']['name']) && $updateInfo['shometownname'] = $this->userinfo['hometown']['name'];
            }
            $fbpicture =  'https://graph.facebook.com/'.$this->siteuid.'/picture?t='.$_SERVER['REQUEST_TIME'];
            $updateInfo['ss_picture'] = $fbpicture;
            $updateInfo['sm_picture'] = $fbpicture;
            $updateInfo['sb_picture'] = $fbpicture;
            $updateInfo['smac']       = $this->getParams['mobile_request'];
            $updateInfo['stoken']     = $this->getParams['signed_request'];
            $arr_userinfo = oo::commonOprModel('member')->getUserInfo($this->uid, null, TRUE, $updateInfo);
            oo::commonOprRedis('common')->setex(okeys::FbAccountSynListTime($this->uid),$arr_userinfo['lasttime'],1*24*60*60);
            !is_array($arr_userinfo) && $arr_userinfo = array();
            /* fb用户在头像后面加时间戳 */
            $arr_userinfo['s_picture'] = $fbpicture;
            $this->arr_poker['s_picture'] = $fbpicture;
        }  else {
            $updateInfo['smac'] = $this->getParams['mobile_request'];
            $arr_userinfo = oo::commonOprModel('member')->getUserInfo($this->uid, NULL, TRUE,$updateInfo);
        }

        if (!$arr_userinfo) {
            $err = array('uid' => $this->uid, 'siteuid' => $this->siteuid, 'line' => __LINE__, 'result' => $arr_userinfo, 'key' => 'getUserInfoFail', 'sid' => $this->param['sid']);
            $this->errLog($err);
            $arr_userinfo = array();
        }
        $this->arr_poker['inviteuid'] = $arr_userinfo['inviteuid'];
        $updata = [];
        if($arr_userinfo['version'] != $this->param['version']){
            $updata['version']=$this->param['version'];
        }
        if($arr_userinfo['login_plat'] != $this->mobile_date_src){
            $updata['login_plat']=$this->mobile_date_src;
        }
        oo::commonOprModel('member')->updateUserInfo($this->uid, $updata);

        if($arr_userinfo['status'] != 1){
            if(IS_DEBUF){ //测试服不删号
                oo::commonOprModel('member')->updateUserInfo($this->uid, ['status' => 1]);
                $this->arr_poker['status'] = 1;
            } else {
                $ip = $this->getParams['from_ip'];
                oo::logs()->debug3(["ts"=>date("Y-m-d H:i:s"),"uinfo"=>$arr_userinfo,'upinfo'=>$updateInfo,'ip'=>$ip],'loginerr.log');
                return ['code'=>0,'uid'=>-100,'line'=>__LINE__,'msg'=>"The game is starting","ruid"=>$this->uid];
    //          exit(0);
            }
        }

        $arr_userinfo['countryId'] = empty($arr_userinfo['hometownid']) ? 101 :  $arr_userinfo['hometownid'];
        //用户资产
        $arr_userproperty  = oo::commonOprModel('member')->getUserAssetsInfo($this->uid);
        if (!$arr_userproperty) {
            $err = array('uid' => $this->uid, 'siteuid' => $this->siteuid, 'line' => __LINE__, 'result' => $arr_userproperty, 'key' => 'getUserPropertyFail', 'sid' => $this->param['sid']);
            $this->errLog($err);
        }

        $arr_userproperty['money']  = max($arr_userproperty['money'],0);
        $arr_userproperty['spins']  = max($arr_userproperty['spins'],0);
        $arr_userproperty['shield'] = max($arr_userproperty['shield'],0);

        /**先暂时屏蔽这些参数*/
        $hide = ['locale', 'locationid', 'locationname', 'hometownid', 'hometownname', 'user_gift', 'inviteuid', 'sound', 'cardFace', 'cardBack', 'sound'];
        foreach ($hide as $row){
            unset($arr_userinfo[$row]);
        }

        self::checkSpins($this->uid,$arr_userinfo['lasttime']);
        $returnLastTimes = oo::commonOprModel('user')->refreshSpins($this->uid,0);
        $afterRefreshSpins = oo::commonOprModel('member')->getUserAssetsInfo($this->uid);
        $arr_userproperty['spins'] = $afterRefreshSpins['spins'];

        $this->arr_poker['spinsCountdown']= $returnLastTimes;
        $dts =0;
//        $dts = max(0,oo::commonOprRedis('common')->ttl(okeys::SpeedUpSpins($this->uid)));
//        if($returnLastTimes<$dts){
//            $dts = $returnLastTimes/2;
//        }
        $this->arr_poker['spinNextTime'] = max(intval($this->arr_poker['spinsCountdown']),0)+time()-$dts;
        $this->arr_poker = array_merge($this->arr_poker, $arr_userinfo, $arr_userproperty);
        $this->arr_poker['location'] = isset($updateInfo['slocationname']) ? $updateInfo['slocationname'] : '';

        //获取当前用户岛建筑信息
        $mylevelElement = oo::commonOprModel('member')->getUserLevel($this->uid);
        $mylevelElements = $mylevelElement['element'];

        /********大转盘剩余秒数**************/
        $bigwheel_key = okeys::bigwheel($this->uid);

        $ttl = oo::commonOprRedis('common')->ttl($bigwheel_key);
        $this->arr_poker['tpCountdown'] = intval($ttl) > 0 ? intval($ttl) : 0;

        //设置大转盘幸运值
        $n = intval((time()-$arr_userinfo['lasttime'])/(12*3600));
        if($n>0){
            $hn =intval(oo::commonOprRedis('common')->get(okeys::bigwheelLuckNum($this->uid)));
            $sunNum = $n+$hn;
            if($sunNum>7){
                $sunNum=7;
            }
            oo::commonOprRedis('common')->setex(okeys::bigwheelLuckNum($this->uid),$sunNum,86400*4);
        }


        $payWheel = oo::commonOprRedis('common')->hGetAll(okeys::bigwheelPay($this->uid));
        if(!empty($payWheel)){
            $this->arr_poker['tpStatus'] = 4;
        }else{
            $bigwheel = oo::commonOprRedis('common')->get(okeys::bigwheel($this->uid));
            if(empty($bigwheel)){
                $this->arr_poker['tpStatus'] = 1;
            }else{
                $data = explode('#',$bigwheel);
                if(count($data) == 3 || count($data) == 5){
                    $this->arr_poker['tpStatus'] = 2;
                }else{
                    $this->arr_poker['tpStatus'] = 3;
                }
            }
        }
        /********end**************/
        if(!oo::compareVersion($this->param['version'],"1.8.4")){
            //记录登录奖励
            $message = oo::commonOprModel('message')->getTotalNum($this->uid);
            $applyNum = oo::commonOprModel('message')->getFriApplyNum($this->uid);
            $this->arr_poker['totalMessage'] = (int)($message+$applyNum);
        }else{
            //邮件消息
            $message = oo::commonOprModel('message')->getSysMailMsgByUid($this->uid, $this->sid, $arr_userinfo['lasttime']);
            $this->arr_poker['totalMessage']  = $message['newNum'];
        }

        //新版本礼包商品按rfm分组来显示
        if(oo::compareVersion($this->param['version'], "1.8.5")){
            $this->arr_poker['rfmGroup'] = oo::commonOprModel('config')->getUserGroupIdByCid($this->uid, 2);
        }
        //新版本礼包商品按数数分组来显示
        if(oo::compareVersion($this->param['version'], "1.13.0")){
            $this->arr_poker['ssGroup'] = oo::commonOprModel('config')->getUserGroupIdByCid($this->uid, 5);
        }

        $this->arr_poker['spinsRecover']  = oo::commonOprModel('member')->getUserLevelUpLimit($this->uid,'recovery');
        $this->arr_poker['element'] = $mylevelElements;
        $this->arr_poker['mtkey']   = $this->param['mtkey'];
        $this->arr_poker['miningInfo'] = [];
        $this->arr_poker['restoreSpinsTime'] = intval(oo::commonOprModel('readconfig')->getCon('basic','restoreTime')); //体力恢复时间
        return ['code'=>1];
    }

    /**
     * header输出
     */
    public function _header() {
        header('Access-Control-Allow-Origin:*');
        header("Access-Control-Allow-Method:*");
        header("Access-Control-Allow-Headers:Content-Type");
        if($this->getParams['param']){
            header('Content-type: image/png');
        }else{
            header('Content-type: text/plain');
        }
    }

    /**
     * 登录前操作
     */
    protected function _before() {
//        $this->_header();
        $this->param['device']     = isset($this->getParams['device'])    ? $this->getParams['device']    : ''; // ios|android
        $this->param['payChannel'] = isset($this->getParams['pay'])       ? $this->getParams['pay']       : '';
        $this->param['osVersion']  = isset($this->getParams['osVersion']) ? $this->getParams['osVersion'] : '';
        $this->param['version']    = isset($this->getParams['version'])   ? $this->getParams['version']   : '';
        $this->param['sign']       = isset($this->getParams['sign'])      ? $this->getParams['sign']      : '';
        $this->param['sid']        = isset($this->getParams['sid'])       ? $this->getParams['sid']       : 1;
        $this->param['isRobot']    = isset($this->getParams['isRobot'])   ? true                          : false;
        $this->param['lang']       = isset($this->getParams['lang'])      ? $this->getParams['lang']       : 'en';
        if ($this->param['device'] == 'ios') {
            $this->mobile_date_src = MOBILE_DATA_SRC_IOS;
        } else {
            $this->mobile_date_src = MOBILE_DATA_SRC_ANDROID;
        }

        if (isset($this->getParams['lid']) && ($this->getParams['lid'] != '')) {
            $this->param['lid'] = $this->getParams['lid'];
        }

        $this->param['macAddr']     = isset($this->getParams['macAddr']) ? htmlspecialchars($this->getParams['macAddr']) : '';
        $this->param['clientMtkey'] = isset($this->getParams['mtkey'])   ? htmlspecialchars($this->getParams['mtkey'])   : '';
        $this->sid = (int)$this->param['sid'];
    }

    /**
     * 验证参数
     */
    protected function _verifyParams() {
        /* 上报登陆包json解析错误的数据 */
        if (isset($this->getParams['report']) && $this->getParams['report'] === 'true') {
            $errType = isset($this->getParams['cli_err_type']) ? $this->getParams['cli_err_type'] : 'unknown';
            $errData = isset($this->getParams['cli_receive_pack']) ? $this->getParams['cli_receive_pack'] : '';
            $this->errLog(array('type'=>$errType, 'data'=>$errData));
            return ['code'=>0,'uid'=>-1,'line'=>__LINE__];
        }

        /* 统计机器码 */
        if (empty($this->getParams['mobile_request'])) {
            $this->errLog(['uid'=>-1,'line'=>__LINE__]);
            return ['code'=>0,'uid'=>-1,'line'=>__LINE__];
        }

        $code = base64_decode($this->getParams['mobile_request']);
        if (empty($code)) {
            $this->errLog(['uid'=>-1,'line'=>__LINE__]);
            return ['code'=>0,'uid'=>-1,'line'=>__LINE__];
        }

        $arr = explode('_', $code);
        if (count($arr) !== 2) {
            $this->errLog(['uid'=>-1,'line'=>__LINE__,'request'=>$arr]);
            return ['code'=>0,'uid'=>-1,'line'=>__LINE__,'request'=>$arr];
        }

        if ($this->secret !== $arr[1]) {
            $this->errLog(['uid'=>-1,'line'=>__LINE__,'request'=>$arr]);
            return ['code'=>0,'uid'=>-1,'line'=>__LINE__,'request'=>$arr];
        }

        $this->sid     = $this->param['sid'];
        $this->macType = $this->param['device'] == 'ios' ? 2 : 1;
        if(empty($this->getParams['signed_request']) && isset($this->getParams['emptyMacTag']) && !empty($this->getParams['emptyMacTag'])){
            $superKey  = $this->getParams['emptyMacTag'];
        }
        $mac = oo::commonOprModel("user")->getSiteIdByMac($this->macType,$arr[0],$superKey);
        if($mac === 0 && empty($superKey)){
            $this->errLog(['uid'=>-1,'line'=>__LINE__,'request'=>$arr]);
            return ['code'=>0,'uid'=>-1,'line'=>__LINE__,'request'=>$arr];
        }
        $this->macAddress   = $mac;
        $this->param['arr'] = $arr;
        $this->param['mac'] = $mac;
        return ['code'=>1];
    }

    /**
     * 登录后操作
     */
    protected function _after() {
        $uid = $this->uid;
        /*********************** 用户信息相关 ***********************/
        $this->arr_poker['device'] = $this->param['device'];
        /* 平台代号 */
        $this->arr_poker['dataSrc'] = $this->mobile_date_src;
        /* 用户uid */
        $this->arr_poker['uid'] = intval($this->uid);
        /* 昵称utf-8检测 */
        if (empty($this->arr_poker['nick']) || $this->arr_poker['uid'] == $this->arr_poker['nick']) {
            $this->arr_poker['nick'] = '';
        }
        $nickJson = json_encode($this->arr_poker['nick']);
        if (empty($nickJson)) {
            $this->arr_poker['nick'] = oo::functions()->phutil_utf8ize($this->arr_poker['nick']);
        }

        $this->arr_poker['siteuid'] = (string)$this->siteuid;
        ///api/gateway.php短连接替换长连接开关
        $this->arr_poker['apiwebsocket'] = 0;

        /**
         * 新手引导
         */
        $beginGuide = oo::commonOprRedis('common')->hGet(okeys::beginGuide(),$this->uid);
        if($beginGuide !== false){
            $this->arr_poker['beginGuide'] = intval($beginGuide);
        }
        $ad = oo::commonOprRedis('common')->hGetAll(okeys::Adreward($this->uid));
        if(!empty($ad) && $ad['time'] == date('Y-m-d')){
            $adSpins = count(json_decode($ad['spins']??"",true));
            $adCoins = count(json_decode($ad['coins']??"",true));
            $this->arr_poker['adNum'] = ['spins'=>$adSpins,'coins'=>$adCoins];
        }else{
            $this->arr_poker['adNum'] = ['spins'=>0,'coins'=>0];
        }

        /**
         * 用户推送设置
         */
        $UserSettingLock = oo::commonOprModel('member')->getUserSettingLock($uid);
        if(!empty($UserSettingLock)){
            in_array('ALL',$UserSettingLock) ? $temp['ALL']= 1 : $temp['ALL']= 0;
            in_array('stealAndAttack',$UserSettingLock) ? $temp['stealAndAttack']= 1 : $temp['stealAndAttack']= 0;
            $this->arr_poker['userSetting'] = $temp;
        }else{
            $this->arr_poker['userSetting'] = ['ALL'=>0,'stealAndAttack'=>0];
        }

        /**
         * 用户Token
         */
        if(funs::concurrentLock($this->uid,'login_token',60*30)){
            $token = (string)$this->arr_poker['siteuid'].time()."SUPERANT".$this->uid;
            $token = sha1(md5($token));
            oo::commonOprRedis('common')->setex(okeys::UserToken($this->uid),$token,3*24*60*60);
        }else{
            $token = oo::commonOprRedis('common')->get(okeys::UserToken($this->uid));
        }
        if(empty($token)){ //如果cache中未取到token,重新生成一份新的token
            usleep(100000); //延迟100毫秒
            $token = (string)$this->arr_poker['siteuid'].time()."SUPERANT".$this->uid;
            $token = sha1(md5($token));
            oo::commonOprRedis('common')->setex(okeys::UserToken($this->uid),$token,3*24*60*60);
        }
        $this->arr_poker['saToken'] = $token;

        $version = oo::commonOprModel('user')->getUserVersion($uid);
        /**
         * 登录成就
         */
        $time = oo::commonOprRedis('common')->hGet(okeys::LoginUser(),$this->uid);
        if(empty($time)){//今天第一次登陆
            $this->isFirst = true;
            /**
             * 连续性登陆
             */
            if(oo::commonOprRedis('user')->get(okeys::ContinuityLoginDays($this->uid))){
                oo::commonOprModel('Statistics')->addUserStatistics($this->uid,['continuityLoginDays'=>1]);
            }else{
                oo::commonOprModel('Statistics')->setUserStatistics($this->uid,['continuityLoginDays'=>1]);
            }
            oo::commonOprRedis('user')->setex(okeys::ContinuityLoginDays($this->uid),1,24*60*60);

            /**
             * 登陆天数
             */
            oo::commonOprModel('member')->addUserDynamicsData($this->uid,['activeDay'=>1]);
            $activeDay = oo::commonOprModel('member')->getUserDynamicsData($uid)['activeDay'];
            oo::commonOprModel('Statistics')->setUserStatistics($this->uid,['loginDays'=>$activeDay]);

            oo::commonOprRedis('common')->hSet(okeys::LoginUser(),$this->uid,1);
            oo::commonOprRedis('User')->rPush(okeys::UserGroupAction(2),$this->uid);
            oo::commonOprModel('member')->setUserStealProtect($this->uid,300);//每天首次登陆保护五分钟
        }

        /**
         * 用户获得奖励
         */
        $this->arr_poker['dialogList'] = [];
        /**
         * 新版首充
         */
        $firstPay2     = oo::commonOprModel('member')->getUserFirstPayStatus2($uid);
        if($firstPay2){
            $this->arr_poker['dialogList'][] = [
                'dialogId'=>15,
                'data'    =>$firstPay2
            ];
        }

        /**
         * 首冲
         */
        $activity1 = oo::commonOprModel('activity')->activityLock($uid,1,true);
        $firstPay     = oo::commonOprModel('member')->getUserFirstPayStatus($uid);
        $this->arr_poker['firstPayStatus'] = $firstPay;
        $this->arr_poker['firstPayLevel']  = $activity1['openLv'];
        /**
         * 首冲弹框
         */
        if($firstPay == 0 && oo::commonOprModel('switch')->bullet(1001)){
            $this->arr_poker['dialogList'][] = [
                'type'    =>2,
                'id'      =>1,
                'dialogId'=>4,
            ];
        }

        if(oo::commonOprModel('activity')->activityLock($this->uid,5,true)){
            $this->arr_poker['promotion'] = [
                ['curTimes'=>intval(oo::commonOprRedis('common')->get(okeys::promotion($uid))),'maxTimes'=>max(1,intval(oo::commonOprModel('goods')->getGoodsInfoByGid(701)['gMax'])),'gid'=>701],
                ['curTimes'=>intval(oo::commonOprRedis('common')->get(okeys::promotion($uid,702))),'maxTimes'=>max(1,intval(oo::commonOprModel('goods')->getGoodsInfoByGid(702)['gMax'])),'gid'=>702],
                ['curTimes'=>intval(oo::commonOprRedis('common')->get(okeys::promotion($uid,703))),'maxTimes'=>max(1,intval(oo::commonOprModel('goods')->getGoodsInfoByGid(703)['gMax'])),'gid'=>703],
            ];
            $this->arr_poker['dialogList'][] = [
                'type'=>2,
                'id'=>2,
                'dialogId'=>5,
            ];
        }

        $this->arr_poker['ChatSocket']   = CHAR_SERVER_URL;
        $this->arr_poker['ServerSocket'] = WORKER_SERVER_URL;
        $writeList = oo::commonOprRedis('common')->sMembers(okeys::writeList());
        if(!empty($writeList)&&in_array($this->arr_poker['uid'],$writeList)&&!IS_DEBUF){
            $this->arr_poker['ServerSocket'] = 'ws://47.253.40.215:8282';
        }

        $elementSaleId = oo::commonOprRedis('common')->get(okeys::elementSaleId($this->uid));
        $this->arr_poker['saleBuildId'] = ($elementSaleId==false)?0:$elementSaleId;

        oo::commonOprRedis('common')->incr(okeys::getLoginCount());
        oo::commonOprRedis('common')->delete(okeys::LevelList($this->uid));

        $this->arr_poker['ChatRemain']   = max(1 - intval(oo::commonOprRedis('common')->hGet(okeys::chatMaxNum(),$this->uid)),0);

        $data   = [];
        //回归
        oo::commonOprModel('callback')->callBackLog($uid,$this->arr_poker['lasttime'],$this->param['version']);//回归记录
        $reward = oo::commonOprModel('config')->recallConfig(true);
        foreach ($reward as $row){
            if($this->arr_poker['lasttime'] + $row['day']*24*60*60 <= time()){
                $data[] = $row;
            }
        }
        if(!empty($data)){
            $this->arr_poker['dialogList'][] = [
                'type'    =>1,
                'id'      =>2,
                'dialogId'=>1,
                'data'    =>[
                    'list'=>$data
                ]
            ];
            oo::commonOprRedis('common')->setex(okeys::recall($this->uid),json_encode($data),7*86400);
        }

        /**
         * fb分享轉盤
         */
        $this->arr_poker['tpShareTimes'] = intval(oo::commonOprRedis('common')->hGet(okeys::fbTurnCount(),$this->uid));

        /**
         * VIP
         */
        $this->arr_poker['vipInfo'] = oo::commonOprModel('newvip')->getVipInfo($this->uid);

        /**
         * 限时特惠
         */
        $this->arr_poker['specialOffer'] = oo::commonOprRedis('common')->hGet(okeys::specialOffer(),$this->uid);

        /**
         * 头像框
         */
        $this->arr_poker['avatarBox'] = empty($this->arr_poker['avatarBox'])?[]:json_decode($this->arr_poker['avatarBox']);

        /**
         * 常规礼包
         */
        $downLevel   = oo::commonOprModel('readconfig')->getCon('Game','MainPackMinLv') ?? 3;
        if($this->arr_poker['levelId'] >=$downLevel) {
            $this->arr_poker['dialogList'][] = [
                'type' => 2,
                'id' => 3,
                'dialogId' => 6
            ];
        }

        $this->arr_poker['dialogList'][] = [
            'type'=>4,
            'id'  =>1,
            'dialogId'=>12
        ];

        $maxLevelInfo = oo::commonOprModel('level')->getMaxLevelStatus($uid);
        $this->arr_poker['curMaxLevelInfo'] = [
            "level"    => $maxLevelInfo['curMaxLevel'],
            "isReward" => max(0,$maxLevelInfo['isReward']),
        ];

        oo::commonOprModel('member')->initSomeInfo($uid);
        self::unsetData($this->uid);

        $this->arr_poker['accountSync2'] = oo::commonOprModel('user')->checkAccountSynchronize($this->macType,$this->macAddress,$this->fbToken,$uid,$this->getParams['deviceId']); // 账号绑定


        $this->arr_poker['tpInfo'] = [
            'feeTimes'  => oo::commonOprModel('slot')->getTurnTableFeeTimes($uid),
            'nextTime'  => $this->arr_poker['tpCountdown'] + time(),
            'countdown' => $this->arr_poker['tpCountdown'],
            'status'    => $this->arr_poker['tpStatus'],
            'shareTimes'=> $this->arr_poker['tpShareTimes'],
        ];
        /**
         * FB 绑定奖励
         */
        $fbBindReward = oo::commonOprRedis('common')->get(okeys::FbBindReward($uid));
        $fbBindReward && $this->arr_poker['fbBindReward'] = 1;

        /**
         * 排行榜活动结束奖励
         */
        $rankReward =oo::commonOprModel('activitynew')->getUserCheckRankReward($uid);
        if($rankReward){
            $actinfo = oo::commonOprModel('activitynew')->getActivity($rankReward['aid']);
            $rankReward['activityName'] = $actinfo['imgName'];
            $rankReward['rankData'] = oo::commonOprModel('activitynew')->getRankData($uid,$rankReward['aid']);
            $rankReward['rankReward'] = array_values(oo::commonOprModel('activitynew')->getRankEndRewardConf($rankReward['aid'],$uid));
            $this->arr_poker['dialogList'][] = [
                'dialogId'=>14,
                "data"=>$rankReward
            ];
        }

        /**
         * 锦标赛无进度活动结束奖励
         */
        $rankReward =oo::commonOprModel('activitynew')->getUserCheckRankReward($uid,0,"rank2");
        if($rankReward){
            $actinfo = oo::commonOprModel('activitynew')->getActivity($rankReward['aid']);
            $rankReward['activityName'] = $actinfo['imgName'];
            $rankReward['rankData'] = oo::commonOprModel('activitynew')->getRankData($uid,$rankReward['aid']);
            $rankReward['rankReward'] = array_values(oo::commonOprModel('activitynew')->getRankEndRewardConf($rankReward['aid'],$uid));
            $this->arr_poker['dialogList'][] = [
                'dialogId'=>16,
                "data"=>$rankReward
            ];
        }


        $this->arr_poker['packRefreshTime']   = strtotime('23:59:59') - 60*60;
        $this->arr_poker['serverRefreshTime'] = strtotime('23:59:59') + 60;
        $this->arr_poker['userInviteUrl']     = oo::commonOprModel('invite')->getUserInviteUrl($this->uid);
        $this->arr_poker['userInviteRecord']  = [];
        $this->arr_poker['coins'] = $this->arr_poker['money'];
        $this->arr_poker['serverTime'] = time();
        //vivo平台返回签名
        if($this->param['device'] !== 'ios' && !empty($this->getParams['plat']) && $this->getParams['plat'] == 'vivo'){
            $merchantInfo = oo::commonOprModel('paymentvivo')->getApayInfo();
            $this->arr_poker['vivoMchInfo'] = base64_encode(json_encode($merchantInfo));
            if($this->arr_poker['channel'] != 1){
                oo::commonOprModel('member')->getUserInfo($this->uid, NULL, TRUE,['schannel'=>1]);
            }
        }else if($this->arr_poker['channel'] == 1){
            oo::commonOprModel('member')->getUserInfo($this->uid, NULL, TRUE,['schannel'=>0]);
        }

        if(defined('API_SERVER_URL')){
            $this->arr_poker['api_url'] = API_SERVER_URL;
        }
        if(oo::compareVersion($this->param['version'],'1.7.5')){
            //是否有新召回的好友
            $this->arr_poker['hasNewCallback'] = oo::commonOprModel('friend')->hasNewCallback($this->uid);

            //签到数据合并到登录接口
            $isreward = intval(oo::commonOprRedis('User')->get(okeys::SignInToday($this->uid)));
            $spinMonthly = oo::commonOprModel('payment')->getSpinMonthly($this->uid,1001);
            $spinMonthly = empty($spinMonthly)?0:$spinMonthly['endTime'];
            $spinMonthlyPro = oo::commonOprModel('payment')->getSpinMonthly($this->uid, 1002);
            $spinMonthlyPro = empty($spinMonthlyPro)?0:$spinMonthlyPro['endTime'];
            $progress  = oo::commonOprModel('member')->getUserSignInProgress($this->uid,true);
            $activityName = oo::commonOprModel('readconfig')->getSysCon("Game","signInDir")??'summer';
            if(!oo::compareVersion($this->param['version'],'1.9.1')){
                $activityName = "easterSignIn";
            }
            $this->arr_poker['signIn'] = [
                'activityName'=>$activityName,
                'days'       => intval(oo::commonOprRedis('User')->get(okeys::SignInTimes($this->uid))) + 1 - $isreward,
                'isreward'   => $isreward,
                'spinMonthly'=> [$spinMonthly,$spinMonthlyPro],
                'progress'   => [
                    'rewardDay' => $progress['rewardDay'],
                    'signInDay' => $progress['signInDay'],
                ],
            ];

            //广告数据合并到登录接口
            $agConfig = oo::commonOprModel('Advertisement')->getAggregateConfig2($this->uid);
            $config['adPro']   = 100;
            $config['adTotal'] = array_sum(array_column($agConfig,"max"));
            $this->arr_poker['polymerization'] = [
                'config'      => $agConfig,
                'probability' => $config['adPro'],
                'total'       => $config['adTotal'],
            ];

            //玩家云端数据合并到登录接口
            $cloudRet = oo::commonOprRedis('common')->hGetAll(okeys::UserCache($this->uid));
            foreach ($cloudRet as $key=>$crow){
                if(!$crow){
                    $cloudRet[$key] = null;
                }else{
                    $cloudRet[$key] = json_decode($crow);
                }
            }

            $userDynamicsData = oo::commonOprModel('member')->getUserDynamicsData($this->uid);
            if(!is_array($userDynamicsData['userCache'])){
                $userDynamicsData = json_decode($userDynamicsData['userCache'],true)??[];
            }
            foreach ($userDynamicsData as $key=>$crow){
                !$crow ? $cloudRet[$key] = null : $cloudRet[$key] = $crow;
            }
            $this->arr_poker['user_cloud'] = $cloudRet;
            //气泡数据
            $this->arr_poker['bubble'] = oo::commonOprModel('level')->getBubble($this->uid);

            //是否有领取礼物
            $this->arr_poker['can_receive'] = oo::commonOprModel('friend')->hasNewGiftReceive($this->uid) ? 1 : 0;

            //宠物数据
            $freeFeedStatus = oo::commonOprRedis('common')->ttl(okeys::FreeFeedPet($this->uid));
            $userPet = oo::commonOprModel('pet')->getUserPet($this->uid);
            $this->arr_poker['pet_list'] = [
                'freeFeedStatus' => time() + max($freeFeedStatus,0),
                'list'           => empty($userPet) ? [] : json_decode(json_encode($userPet, JSON_NUMERIC_CHECK), true),
            ];
            $this->arr_poker['two_gold_prob'] = 65;
            $this->arr_poker['stealWaringCfg'] = oo::commonOprModel('config')->getStealWaringCfg($this->uid);
        }
        /**
         * 推金币状态
         */
        $this->arr_poker['isGuideCoinDozer'] = oo::commonOprModel('member')->isPushCoinsUser($this->uid);
        /**
         * 用户支付信息
         */
        $this->arr_poker['payInfo'] = [
            'payTotalTimes' => intval(oo::commonOprModel('payment')->getUserPayTimes($this->uid)),
        ];
        /**
         * vip 续订次数
         */
        $this->arr_poker['vipRenewTimes'] = intval(oo::commonOprRedis('User')->get(okeys::VipRenewTimes($this->uid)));
        /**
         * 当天登录时长
         */
        $this->arr_poker['todayLoginTime'] = intval(oo::commonOprRedis('User')->hGet(okeys::LoginTime($this->uid),$this->uid));
        $signInConf = array_values(oo::commonOprModel('config')->signInConfByUserGroup($this->uid,0,true));
        $signInConfIds = array_map(function ($v){return $v['id'];}, $signInConf);
        array_multisort($signInConfIds, SORT_ASC, $signInConf);
        $this->arr_poker['signInConf'] = [
            'daily'    => $signInConf,
            'progress' => array_values(oo::commonOprModel('config')->userSignInProgressConf($this->uid))
        ];

        if(oo::compareVersion($version,'1.7.8')){
            $this->arr_poker['cardInfo']    = oo::commonOprModel('card')->info($this->uid,false);
            $this->arr_poker['propsInfo']   = ['props'=>oo::commonOprModel('props')->getUserProps($this->uid), 'state'=>[]];

            //处理背包钻石
            if(!empty($this->arr_poker['propsInfo']['props'])){
                $props = array_column($this->arr_poker['propsInfo']['props'], 'count', 'id');
                if(isset($props[22]) && $props[22] > 0){ //钻石背包余量处理
                    oo::commonOprModel('props')->decUserProps($this->uid, 22, $props[22]);
                    oo::commonOprRedis('user')->hIncrBy(okeys::userAttr($this->uid), 'diamond', $props[22]);
                    $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
                    $this->arr_poker['diamond'] = isset($userInfo['diamond']) ? $userInfo['diamond'] : 0;
                    $this->arr_poker['propsInfo']   = ['props'=>oo::commonOprModel('props')->getUserProps($this->uid), 'state'=>[]];
                }
            }

            $this->arr_poker['messageInfo'] = oo::commonOprModel('message')->getMessageList($this->uid)['data'];
        }

        ////钻石全部转化成公告领体力
        //if(!empty($this->arr_poker['diamond']) && $this->arr_poker['diamond'] <= 1000){
        //    $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($this->uid);
        //    if(!empty($userInfo['diamond']) && $userInfo['diamond'] > 0 && $userInfo['diamond'] <= 1000){
        //        oo::commonOprModel('message')->diamondToSysMail($this->uid, $userInfo['diamond']);
        //        $message = oo::commonOprModel('message')->getSysMailMsgByUid($this->uid, $this->sid, $this->arr_poker['lasttime']);
        //        $this->arr_poker['totalMessage'] = $message['newNum'];
        //        oo::commonOprModel('attr')->del($this->uid, 'diamond', intval($userInfo['diamond']), '12', '钻石转体力邮件');
        //        oo::commonOprRedis('userinfo')->hdel(okeys::userAttr($this->uid), 'diamond');
        //        $gmtb = otable::gh_gameserver($this->uid);
        //        oo::commonOprDb('userinfo')->query("UPDATE {$gmtb} SET diamond = 0 WHERE mid={$this->uid}");
        //        unset($this->arr_poker['diamond']);
        //    }
        //}

        //inst/twitter粉丝页
        if(oo::compareVersion($version, '1.8.0')){
            $this->arr_poker['showRecommend'] = oo::commonOprModel('config')->fansConfig($this->uid);
        }

        //更新firebase token
        if(!empty($this->getParams['fcmToken']) && strlen((string)$this->getParams['fcmToken']) < 300){
            oo::commonOprModel('user')->recordPushToken([
                'uid'   => $this->uid,
                'token' => $this->getParams['fcmToken'],
                'sid'   => $this->sid,
            ]);
        }

        $this->arr_poker['signature']   = $this->arr_poker['signature'] ?? "";

        /**
         * 控制Ab test
         */
        $this->arr_poker['ABTest']      = [
            'diamond' => oo::commonOprModel('switch')->abTestDiamond($this->uid),
        ];

        /**
         * 记录上次登录时间
         */
        oo::commonOprRedis('User')->setex(okeys::LastLoginTime($this->uid),$this->arr_poker['lasttime'],24*60*60);

        //inst/twitter粉丝页
        if(oo::compareVersion($version, '1.10')){
            $this->arr_poker['shareInfo'] = oo::commonOprModel('config')->getUserCountry($this->getParams['from_ip']);
        }else{
            $this->arr_poker['shareImgInfo'] = oo::commonOprModel('config')->getShareImgInfo($this->getParams['from_ip']);
        }
        /**
         * 总消耗体力
         */
        if(time() - $this->arr_poker['createtime'] <= 7*24*60*60){
            $newUserSpins = intval(oo::commonOprRedis('User')->get(okeys::NewUserSpins($this->uid)));
            $this->arr_poker['newUserSpins'] = $newUserSpins;
            oo::commonOprRedis('User')->setex(okeys::NewUserSpins($this->uid),$newUserSpins,7*24*60*60);
        }

        self::statistics();
        self::setStatus($uid);
        self::loginMonitor($uid);
    }
    //统计相关
    public function statistics(){
        //统计是否开启推送
        $os = $this->param['notificationStatus'];
        if($os>=0){
            oo::commonOprRedis('statistics')->hSet(okeys::openPushUserLog($os),$this->uid,$os);
        }
        oo::commonOprRedis('statistics')->hIncrBy(okeys::LoginCount(),$this->uid,1);
        /**
         * ta 公共属性
         */

        oo::commonOprModel('ta')->setCommonEventProperty($this->uid,'common',["current_play_time"=>time()]);
        $data = ["current_level"=>intval($this->arr_poker['levelId']),"last_login_time"=>time(),"user_source"=>0,"user_login_type"=>$this->param['lid'] == 1 ? 1 : 0,"app_version"=>(string)$this->getParams['version'],'friend_num'=>count(oo::commonOprModel('friend')->getUserAllFriend($this->uid))];

        if($this->isNewUser){
            $data2["register_time"] = time();
        }else{
            $data['register_time'] = $this->arr_poker['createtime'];
        }
        $addressInfo = oo::commonOprModel('ipaddress')->getUserCountry($this->uid);
        if(empty($addressInfo['country_code'])){
            $addressInfo = oo::commonOprModel('ipaddress')->getAddressByIp($this->uid,$this->getParams['from_ip'],1);
            if(isset($addressInfo['country_code'])&&!empty($addressInfo['country_code'])){
                $data2['country'] = $addressInfo['country_code'];
            }
        }else{
            $data2['country'] =$addressInfo['country_code'];
        }
        $data2['os'] = $this->sid==2?"ios":"android";
        $data2['first_pay_time'] = oo::commonOprModel('payment')->getUserFirstPayTS($this->uid);
        if(intval($data2['first_pay_time'])<2){
            unset($data2['first_pay_time']);
        }
        oo::commonOprModel('ta')->setEventData($this->uid,'user_setOnce',$data2);
        
        //数数事件用户信息-用户邀请人
        $data['invited_user'] = $this->arr_poker['inviteuid'];//首次注册无法知道inviteuid,所以每次登陆设置该属性
        oo::commonOprModel('ta')->setEventData($this->uid,'user_set',$data);
    }
    public function setStatus($uid){
        oo::commonOprRedis('Usercache')->zAdd(okeys::EmailRecall(3),time(),$uid);  // 邮件召回
        oo::commonOprRedis('User')->delete([okeys::SlotSet($uid),okeys::SlotList($uid)]);
//        oo::commonOprModel('member')->reLoginAddIntoProtectList($uid);
        if(!$this->isNewUser){ //检测7天以上未玩登录家adjust邀请
            $inviteCode = !empty($this->getParams['inviteCode']) ? (int)base64_decode($this->getParams['inviteCode']) : 0;
            oo::commonOprModel('member')->actionCallbackAdjustInvite($uid, $inviteCode);
            oo::commonOprModel('member')->actionAdjustInvite($uid);//检测邀请
        }
        oo::commonOprModel('user')->setUserDeviceId($this->sid,$uid,$this->getParams['deviceId'],$this->param['lid']);

    }

    public function checkSpins($uid,$lasttime){
        $key     = okeys::userRestoreTime($uid);
        $restore = oo::commonOprRedis('common')->get($key);
        if(!$restore){
            $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $levelId  = max($userInfo['levelId'],1);
            $maxSpins = oo::commonOprModel('member')->getLevelUpLimit($levelId,'spins') ?? 50;
            if($userInfo['spins'] < $maxSpins){
                oo::commonOprRedis('common')->set($key,$lasttime."*0");;
            }
        }
    }

    public function unsetData($uid){
        oo::commonOprRedis('common')->delete(okeys::countdownLock($uid,"SLOT"));
        unset($this->arr_poker['vip']);
        unset($this->arr_poker['vipLv']);
        unset($this->arr_poker['vip_expire']);
        unset($this->arr_poker['token']);
        unset($this->arr_poker['mac']);
    }

    public function getMacId($macAddr) {
        $macAddr = trim($macAddr);
        if(strlen($macAddr) > 30){
            return 0;
        }
        $match = array();
        if (!preg_match("/^[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f]/i", $macAddr, $match)) {
            return 0;
        }
        $str = strtr($macAddr, array(':' => ''));
        $hexadecimal = '0x'.$str;
        $macid = base_convert($hexadecimal, 16, 10);
        return $macid;
    }

    /**
     * 接口消耗时间
     */
    protected function _slowlog() {
//        $endTime = intval(microtime(TRUE) * 1000);
//        $runTime = $endTime - $this->startTime;
//        $runTime >= 500 && oo::logs()->debug3(['date' => date('Y-m-d H:i:s'),'startTime'=>$this->startTime,'endTime'=>$endTime,'runTime'=> $runTime,'isNewUser'=>$this->isNewUser,'uid'=>$this->uid,'loginSrc'=> $this->param['loginSrc']], 'loginRuntimeDetail.log');
    }

    /**
     * 登录监控
     * Created by: Owen
     * Created on: 2020/4/24 19:47
     */
    public function loginMonitor($uid=''){
        $ts = timeFuns::todaySecond();
        $curKey = intval($ts/5);
        oo::commonOprRedis('common')->hIncrBy(okeys::LoginMonitor($this->sid),$curKey,1);
        oo::commonOprRedis('statistics')->hIncrBy(okeys::loginCountLog(),$ts,1);
    }

    /**
     * Curl
     * Created by: Owen
     * Created on: 2020/5/19 16:01
     */
    public function curl($url){
        //初始化
        $curl = curl_init();
        //设置 url email,first_name,gender,locale,location,birthday,hometown,token_for_business
        curl_setopt($curl, CURLOPT_URL, $url);
        //设置头文件的信息作为数据流输出
        curl_setopt($curl, CURLOPT_HEADER, false);
        //设置获取的信息以文件流的形式返回，而不是直接输出。
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        //执行命令
        $data = curl_exec($curl);
        //关闭URL请求
        curl_close($curl);
        //显示获得的数据
        $userInfo = json_decode($data,true);
        if ($userInfo['error'] || empty($userInfo) || !is_array($userInfo)){
            $error = ['uid'=>-1,'line'=>__LINE__,'url'=>$url,'msg'=>$userInfo['error']['message']];
            $this->errLog($error);
            return $error;
        }
        return $userInfo;
    }

    /**
     * 错误日记
     * @param $logMsg
     * @param string $file
     * @return bool|int
     * Created by: Owen
     * Created on: 2020/5/19 16:11
     */
    public function errLog($logMsg, $file = 'mobileError') {
        $array = debug_backtrace();
        $path = [];
        foreach ($array as $row) {
            $path[] = $row['file'] . ':' . $row['line'] . '行,调用方法:' . $row['function'];
        }
        $logMsg['path'] = $path;
        oo::logs()->debug5($logMsg, $file.'.log',"loginError/".date('Ymd').'/');
        return $logMsg;
    }

    /**
     * Notes:写登录记录
     * User: wsc
     * Time: 2020/12/23 19:20
     * @param $status
     */
    public function writeloginLog($status){
        $ts = intval(microtime(TRUE) * 1000);
        $uid = $this->uid?$this->uid:0;
        $ips = explode('.',SERVER_INT_IP);
//        $data =json_encode([$this->startTime.'_'.$this->randNum.'_'.$ips[3],$uid,$this->param['version'],$status,$ts]);
        $data = [$uid,$this->param['sid'],$this->arr_poker['levelId'],$this->param['version'],$this->getParams['from_ip'],$this->getParams['deviceId'],$this->getParams['deviceInfos'],time(),$this->param['arr'][0]];
        oo::commonOprRedis('statistics')->rPush(okeys::apiLogs('loginNew'),json_encode($data));

        //系统预置个人数据
        $deviceInfos  = $this->getParams['deviceInfos']?explode('|',$this->getParams['deviceInfos']):[];
        if($this->param['sid']==1){
            $os = 'android';
            $os_version = $deviceInfos[3]?$deviceInfos[3]:'0';
        }else if($this->param['sid']==2){
            $os = 'ios';
            $os_version = $deviceInfos[2]?$deviceInfos[2]:'0';
        }else{
            $os ='unknow';
            $os_version='0';
        }
        $info=[
            "distinctId"  =>$this->getParams['distinctId'],
            "os"         =>$os,
            "os_version" =>$os_version,
            "app_version"=>$this->param['version'],
        ];
        oo::commonOprModel('ta')->setSysEventProperty($uid,$info);
        //数数事件-用户登录
        oo::commonOprModel('ta')->setEventData($uid,'user_login',["login_type"=>$this->param['lid'],'device_id'=>$this->getParams['deviceId']]);
    }

}
