<?php
defined( 'IN_WEB') or die( 'Include Error!');
class ModelMember {
    public $secretkey = '#$^&*+_)is!@~/good=<>[]';

    private $_attr = ["money"=>1,"spins"=>2,"shield"=>3,"star"=>4,"diamond"=>5];

    /**
     * 获取玩家资源属性
     */
    public function getAttr() {
        return $this->_attr;
    }

    /**
     * Notes:初始化一些用户信息
     * User: wsc
     * Time: 2020/4/22 14:13
     * @param $uid
     */
    public function initSomeInfo($uid){
        //清空默认攻击列表
        $dLKey = okeys::defaultAttactList($uid);
        oo::commonOprRedis('Userinfo')->delete($dLKey);
    }

    /**
     * api请求更换websocket每次更新玩家sid、lid、lang
     * @param array $arr
     * @return bool
     */
    public function setUserDefinedInfo($uid, array $arr = []) {
        oo::commonOprRedis('Userinfo')->hMset(okeys::userDefinedInfo($uid), $arr);
//        $ttl = oo::commonOprRedis('Userinfo')->ttl(okeys::userDefinedInfo($uid));//保护时间
//        if($ttl == -1){
            oo::commonOprRedis('user')->expire(okeys::userDefinedInfo($uid), oo::redisRandomExpire(24*3600));
//        }
    }
    //====================用户基本信息相关======================
    /**
     * 获取用户基础信息
     * @param int $uid
     * @param mixed $array 需要获取用户信息的字段
     * @param bool $flag true表示需要更新最后登录时间和用户VIP标志位，还有用户的昵称、性别、国家等信息
     * @param string $info 用户的FB信息
     * @return mixed
     */
    public function getUserInfo( $uid, $array = NULL, $flag = false, $info = NULL){
        if (!$uid = oo::functions()->uint( $uid)) {
            return 0;
        }
        //从新缓存中读取
        $userInfo = oo::commonOprRedis('userinfo')->hGetAll(okeys::t_userinfoNew($uid));
        if(empty($userInfo)){
            $userInfo = oo::commonOprDb('userinfo')->getOne("SELECT * FROM ".otable::userinfo($uid)." WHERE uid='{$uid}'", MYSQLI_ASSOC);
            if(empty($userInfo)){
                return 0;
            }
            if(empty($userInfo['isFb'])){ //非fb,重新查一次t_account表
                $infoArr = self::getAccount($userInfo['siteuid']);
                (!empty($infoArr) && $infoArr['uid'] == $uid) ? $userInfo['isFb'] = 1 : $userInfo['isFb'] = 0;
            }
            if (isset($userInfo['nick'])){
                $nickJson = json_encode($userInfo['nick']);
                empty($nickJson) && $userInfo['nick'] = oo::functions()->phutil_utf8ize( $userInfo['nick']);
                $userInfo['nick'] = oo::functions()->escapeNick($userInfo['nick']);
            }
            //设置进入新缓存
            oo::commonOprRedis('userinfo')->hMset(okeys::t_userinfoNew($uid), $userInfo);
            oo::commonOprRedis('userinfo')->expire(okeys::t_userinfoNew($uid), oo::redisRandomExpire(7*24*60*60));
        }
        //如果vip过期了,且avatar头像还在,清理头像框
        if(!empty($userInfo['avatar']) && $userInfo['vip_expire'] < time()){
            $userInfo['avatar'] = 0;
            $userInfo['avatarBox'] = json_encode([]);
        }
        if ($flag && !empty($userInfo['status'])){
            if(!$userInfo['isFb']){
                if(isset($info['ssiteuid'])){
                    $userInfo['siteuid'] = $info['ssiteuid'];
                }
                $infoArr = self::getAccount($userInfo['siteuid']);
                if(!empty($infoArr) && $infoArr['uid'] == $uid){
                    $userInfo['isFb'] = 1;
                    //防止缓存过期,更新全量数据
                    oo::commonOprRedis('userinfo')->hMset(okeys::t_userinfoNew($uid), $userInfo);
                }
            }
            if(isset($info['snick']) && empty($info['snick'])){
                $updateInfo['snick'] = $uid;
            }
            foreach($info as $k=>$v){
                if($k[0] == 's'){
                    $updateInfo[substr($k,1)] = oo::functions()->escape($v);
                }else{
                    $updateInfo[$k] = $v;
                }
            }
            self::updateUserInfo($uid,$updateInfo);
        }
        if(!empty($array)){
            foreach ($userInfo as $key=>$row){
                if(!in_array($key,$array)){
                    unset($userInfo[$key]);
                }
            }
        }
        return $userInfo;
    }
    /**
     * 批量返回用户基本信息
     * @param array $mainkey 需要批量拉取的主键
     * @param array $userinfo 返回用户信息数组，引用方式
     * @return mixed <0,失败; =0,没有记录; >1,有记录
     */
    public function getUserInfoMulti( $mainkey, &$userinfo ){
        if(empty($mainkey['keylist'])) {
            return 0;
        }
        $mainkey['keylist'] = array_unique($mainkey['keylist']);
        foreach ($mainkey['keylist'] as $uid) {
            $tmp = oo::commonOprRedis('userinfo')->hGetAll(okeys::t_userinfoNew($uid));
            if(!empty($tmp)){
                $userinfo[] = $tmp;
            }
        }
        if(empty($userinfo)){
            return 0;
        }
        return 1;
    }
    /**
     * 插入用户基本信息
     * @param  userinfo  用户信息数组
     * @param  uid       插入用户信息后返回的uid
     * @return <0,失败; =0,成功
     */
    public function setUserInfo( $userinfo, $uid )
    {
        $siteuid = isset( $userinfo['siteuid'] ) ? intval( $userinfo['siteuid'] ) : 0;
        if ( empty( $siteuid ) )
        {
            return -1;
        }
        $array = array(
            'isiteuid'      => $siteuid,
            'snick'         => isset( $userinfo['nick'] ) ? addslashes(htmlspecialchars( $userinfo['nick']) ) : $uid,
            'ssex'          => isset( $userinfo['sex'] )  ? htmlspecialchars( $userinfo['sex'] ) : '',
            'semail'        => isset( $userinfo['email'] ) ? htmlspecialchars( $userinfo['email'] ) : '',
            'ss_picture'    => isset( $userinfo['s_picture'] ) ? htmlspecialchars( $userinfo['s_picture'] ) : '',
            'sm_picture'    => isset( $userinfo['m_picture'] ) ? htmlspecialchars( $userinfo['m_picture'] ) : '',
            'sb_picture'    => isset( $userinfo['b_picture'] ) ? htmlspecialchars( $userinfo['b_picture'] ) : '',
            'istatus'       => 1,
            'icreatetime'   => time(),
            'ilasttime'     => time(),
            'slocale'       => isset( $userinfo['locale'] ) ? $userinfo['locale'] : '',
            'slocationid'   => isset( $userinfo['locationid'] ) ? $userinfo['locationid'] : '',
            'slocationname' => isset( $userinfo['locationname'] ) ? $userinfo['locationname'] : '',
            'shometownid'   => isset( $userinfo['hometownid'] ) ? $userinfo['hometownid'] : '',
            'shometownname' => isset( $userinfo['hometownname'] ) ? $userinfo['hometownname'] : '',
            'iinviteuid'    => 0,
            'isound'        => 70,
            'iinvite'       => 0,
            'ilogin_plat'   => isset( $userinfo['plat'])   ?  $userinfo['plat'] : 0,
            'iversion'      => isset( $userinfo['version'])?  $userinfo['version'] : '1.0.0',
            'itoken'        => isset( $userinfo['mac'])    ?  $userinfo['mac'] : '1.0.0',
            'imac'          => isset( $userinfo['token'])  ?  $userinfo['token'] : '1.0.0',
        );

        $ikey = '';
        $ivalue = '';
        foreach($array as $k=>$v){
            $ikey = $ikey.substr($k,1).',';
            if($k[0] == 's'){
                $v = oo::functions()->escape($v);
            }
            $ivalue = $ivalue."'".$v."',";

        }
        $ikey = trim($ikey,',');
        $ivalue = trim($ivalue,',');
        $sql = "INSERT INTO ".otable::userinfo($uid)." (uid,{$ikey}) VALUE('{$uid}',{$ivalue})";
        $res = oo::commonOprDb('userinfo')->query($sql);

        if($res === true){
            $ret = 0;
        }else{
            $ret = -1;
        }
        return $ret;
    }
    /**
     * 插入用户基本信息(1.10更新: 用户缓存从string类型替换成hash)
     * @param int $uid       插入用户信息后返回的uid
     * @param array $array  需要更新的用户信息数组
     * @return int -1失败, 1成功
     */
    public function updateUserInfo( $uid, $array = NULL ){
        if(empty($array)) {
            return 0;
        }
        $userInfo  = self::getUserInfo($uid);
        if(empty($userInfo)){
            return 0;
        }
        ///15天未登录的玩家,好友召回业务添加///
        if(empty($userInfo['lasttime']) || $userInfo['lasttime'] + 24 * 15 * 3600 < time()){
            oo::commonOprModel('friend')->dealCallBackFriend($uid);
        }
        ///超过7天未登录的玩家,facebook、adjust邀请也算邀请成功///
        if(empty($userInfo['lasttime']) || $userInfo['lasttime'] + 24 * 7 * 3600 < time()){
            oo::commonOprRedis('User')->setex(okeys::AdjustBackInviteStatus($uid),3,3*24*60*60);
        }
        foreach($array as $k=>$v){
            $userInfo[$k] = $v;
        }
        //全量字段更新
        oo::commonOprRedis('userinfo')->hMset(okeys::t_userinfoNew($uid), $userInfo);
        oo::commonOprRedis('userinfo')->expire(okeys::t_userinfoNew($uid), oo::redisRandomExpire(7*24*60*60));
        $updateSql = '';
        $nick      = "";
        foreach($array as $k=>$v){
            $updateSql .= $k.'='."'{$v}',";
            if($k == "nick"){
                $nick = $v;
            }
        }
        $updateSql = trim($updateSql, ',');
        $sql = "UPDATE ".otable::userinfo($uid)." SET {$updateSql} WHERE uid={$uid} LIMIT 1";
        $res = oo::commonOprDb('userinfo')->query($sql);

        if(!empty($nick)){
            oo::commonOprModel('ta')->setEventData($uid,'user_set',["nick_name"=>$nick]);
        }

        return $res === true ? 1 : -1;
    }
    /**
     * 更新FB siteuid和uid
     * @param $siteUid
     * @param $uid
     * @param $newUid
     * @return bool
     * Created by: Owen
     * Created on: 2020/5/22 19:57
     */
    public function updateAccount($siteUid, $uid ,$newUid){
        if (!$siteUid || !$uid || !$newUid) {
            return false;
        }
        $tb  = otable::taccount($siteUid);
        $sql = "UPDATE {$tb} SET uid={$newUid} WHERE uid={$uid} AND siteuid='{$siteUid}'";
        oo::commonOprRedis('user')->delete(okeys::account($siteUid));
//        oo::commonOprCache('account')->delete(okeys::account($siteUid));
        return oo::commonOprDb('account')->query($sql);
    }
    /**
     * 插入siteuid和uid
     * @param unknown $siteuid 平台uid，例如facebook、新浪平台的用户id
     * @param unknown $uid 游戏uid
     * @return unknown <0,失败; =0,成功
     */
    public function setAccount( $siteuid, $uid ) {
        if (!$siteuid || !$uid) {
            return -1;
        }
        $siteuid = (int)$siteuid;
        $uid = (int)$uid;
        $now = time();
        $tb = otable::taccount($siteuid);
        $query = "insert ignore into {$tb} (siteuid,uid,createtime) values ('{$siteuid}','{$uid}','{$now}')";
        $ret = oo::commonOprDb('account')->query($query);
        if ($ret) {
//            oo::commonOprCache('account')->set(okeys::account($siteuid), array('uid'=>$uid,'createtime'=>$now));
            oo::commonOprRedis('user')->hMset(okeys::account($siteuid), array('uid'=>$uid,'createtime'=>$now));
            //更新玩家信息
            $this->updateUserInfo($uid, ['isFb' => 1]);
            return 0;
        } else {
            oo::logs()->debug3(['siteuid' => $siteuid, 'uid' => $uid],'duplicate_account');
            return -2;
        }
    }
    /**
     * 根据siteuid返回uid
     * @param string $siteuid 平台uid，例如facebook、新浪平台的用户id
     * @return mixed|number
     */
    public function getAccount($siteuid){
        $siteuid = (int)$siteuid;
        if (!$siteuid) return 0;
//        $cache = oo::commonOprCache('account')->get(okeys::account($siteuid));
        $cache =oo::commonOprRedis('user')->hGetAll(okeys::account($siteuid));
        if ($cache && isset($cache['uid'])) {
            return $cache;
        }
        $tb = otable::taccount($siteuid);
        $query = "select siteuid, uid, createtime from {$tb} where siteuid='{$siteuid}' limit 1";
        $row = oo::commonOprDb('account')->getOne($query, MYSQLI_ASSOC);
        if ($row) {
            $account = array('uid'=>(int)$row['uid'],'createtime'=>(int)$row['createtime']);
//            oo::commonOprCache('account')->set(okeys::account($siteuid), $account, 7*86400);
            oo::commonOprRedis('user')->hMset(okeys::account($siteuid), $account);
            oo::commonOprRedis('user')->expire(okeys::account($siteuid),oo::redisRandomExpire(7*86400));
            return $account;
        } else {
            return 0;
        }
    }
    /**
     * 根据siteuid批量返回uid
     * @param unknown $mainkey 平台uid，例如facebook、新浪平台的用户id
     * @param unknown $need
     * @param unknown $account 返回数组，引用方式
     * @return unknown|number <0,失败; =0,没有记录; >1,有记录
     */
    public function getAccountMulti( $mainkey, $need, &$account )
    {
        if (!$mainkey || $mainkey['keyname']!='siteuid' || !$mainkey['keylist'] || !is_array($mainkey['keylist'])) {
            return -1;
        }
        $account = array();
        foreach ($mainkey['keylist'] as $siteuid) {
            $key = okeys::account($siteuid);
            $cache = oo::commonOprRedis('user')->hGetAll($key);
            $row = isset($cache) ? $cache : $this->getAccount($siteuid);
            if (!$row) continue;
            $account[] = array(
                'siteuid' => $siteuid,
                'uid' => (int)$row['uid'],
                'createtime' => (int)$row['createtime'],
            );
        }
        if (count($account) == 0) {
            return 0;
        }
        return 1;
    }
    public function getAccountMulti2( $mainkey, $need, &$account )
    {
//        if (!$mainkey || $mainkey['keyname']!='siteuid' || !$mainkey['keylist'] || !is_array($mainkey['keylist'])) {
//            return -1;
//        }
//        $keys = array();
//        foreach ($mainkey['keylist'] as $siteuid) {
//            $keys[] = okeys::account($siteuid);
//        }
//        $cache = oo::commonOprCache('account')->getMulti($keys);
//        $account = array();
//        foreach ($mainkey['keylist'] as $siteuid) {
//            $key = okeys::account($siteuid);
//            $row = isset($cache[$key]) ? $cache[$key] : $this->getAccount($siteuid);
//            if (!$row) continue;
//            $account[] = array(
//                'siteuid' => $siteuid,
//                'uid' => (int)$row['uid'],
//                'createtime' => (int)$row['createtime'],
//            );
//        }
//        if (count($account) == 0) {
//            return 0;
//        }
//        return 1;
    }
    /**
     * 插入用户信息
     * @param  uid       游戏uid
     * @return <0,失败; =0,没有记录; >1,有记录
     */
    public function createMtkey( $siteuid )
    {
        return md5($siteuid.$this->secretkey.date('YW'));
    }
    /**
     * 获取用户MTKEY
     * @param unknown $mtkey
     * @return boolean|array <mixed/false, mixed>
     */
    public function getUserInfoByMtkey($mtkey){
        if ($mtkey == '') {
            return false;
        }
        $res = oo::commonOprRedis('usercache')->hGetAll(okeys::php_mtkey($mtkey));
        return $res;
    }
    /**
     * 通过MTKEY保存用户基础信息
     * @param array $userinfo
     * @return boolean|Ambigous <true/false, boolean>
     */
    public function setUserInfoByMtkey($userinfo){
        if (empty($userinfo)) {
            return false;
        }
        $srvMtkey = $this->createMtkey($userinfo['id']);
        $expire = oo::redisRandomExpire(3 * 86400);
        $res = oo::commonOprRedis('usercache')->hMset(okeys::php_mtkey($srvMtkey),$userinfo);
        oo::commonOprRedis('usercache')->expire(okeys::php_mtkey($srvMtkey),$expire);
        return $res;
    }

    /**
     * 获取fb 信息
     * @param unknown $mtkey
     * @return boolean|array <mixed/false, mixed>
     */
    public function getFbInfoByToken($token){
        $res = oo::commonOprRedis('usercache')->get(okeys::FbInfoByToken($token)) ?? "";
        return json_decode($res,true);
    }

    /**
     * 设置fb 信息
     * @param unknown $mtkey
     * @return boolean|array <mixed/false, mixed>
     */
    public function setFbInfoByToken($token,$info){
        return oo::commonOprRedis('usercache')->setex(okeys::FbInfoByToken($token),json_encode($info),30*60);
    }


    /**
     * Notes:获取用户基本信息封装
     * User: wsc
     * Time: 2020/4/2 14:36
     * @param $uid
     * @return array
     */
    public function getUserBasic($uid){
        $data = [];
        $temp_array = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $temp_info = oo::commonOprModel('member')->getUserInfo($uid);
        $data['uid'] = intval($uid);
        $data['star'] = $temp_array['star'];
        $data['coins'] = intval($temp_array['money']);
        $data['money'] = intval($temp_array['money']);
        $data['levelId'] = intval($temp_array['levelId']);
        $data['spins'] = intval($temp_array['spins']);
        $data['shield'] = intval($temp_array['shield']);
        $data['diamond'] = intval($temp_array['diamond']);
        $data['siteuid'] = $temp_info['siteuid'];
        $data['nick'] = $temp_info['nick'];
        $data['sex'] = $temp_info['sex'];
        $data['s_picture'] = $temp_info['s_picture'];
        $data['signature'] = $temp_info['signature'];
        $data['u_flag'] = intval($temp_info['u_flag']);
        $data['vip'] = $temp_info['vip'];//是否是vip
        $data['vipLv'] = $temp_info['vipLv'];//vip等级
        $data['vipExpire'] = $temp_info['vip_expire'];//vip过期时间
        $data['vipPoint'] = $temp_info['vipPoint'];//vip积分
        $data['avatar'] = intval($temp_info['avatar']);
        $data['isFb'] = intval($temp_info['isFb']);//
        $data['login_plat'] =intval($temp_info['login_plat']);//平台：1安卓，2ios
        $data['version'] = $temp_info['version'];
        return $data;
    }
    //===================================================
    /**
     * Notes:获取用户的资产信息 【金币money、体力spins、盾牌shield、星星数star、等级levelId】
     * User: wsc
     * Time: 2020/6/8 19:38
     * @param $uid
     * @param string $from
     * @return mixed
     */
    public function getUserAssetsInfo($uid,$from=""){
        if(!$uid){
            return [];
        }
        $data = oo::commonOprModel('attr')->get($uid);
        $data['levelId'] = $this->getUserLevelId($uid);
        return $data;
    }
    /**
     * Notes:设置用户属性
     * User: wsc
     * Time: 2020/6/9 14:21
     * @param $uid
     * @param $arr --["money"=>1,"spins"=>1,"shield"=>1,"star"=>1]中任意或组合
     * @param $rid  config/common/config.reason.php
     * @param $t  --符号 + -
     * @param $reason --原因
     * @return bool
     */
    public function optProperty($uid, $arr,$t,$rid,$reason = ""){
        $arr = array_filter($arr);
        if (!$uid || !is_array($arr) || empty($arr) || empty($t)) {
            return false;
        }

        if(!empty($arr['shield']) && $t == '+'){ //累加盾牌添加上限验证
            $maxShield = oo::commonOprModel('member')->getUserLevelUpLimit($uid,'shield');
            $curShield = oo::commonOprModel('attr')->get($uid, 'shield');
            $addShield = max(0,$maxShield - $curShield);
            $addSpins  = intval($arr['shield'] - $addShield);
            $arr['shield'] = min($addShield,$arr['shield']);
            if($addSpins > 0){
                $arr['spins'] = empty($arr['spins']) ? $addSpins : $arr['spins'] + $addSpins;
            }
            if(empty($arr['shield'])){
                unset($arr['shield']);
            }
        }
        foreach ($arr as $k=>$v){
            if(in_array($k,array_keys($this->_attr))){
               $fun =  $t=="+"?"add":"del";
               $resCount = oo::commonOprModel('attr')->$fun($uid,$k,$v,$rid,$reason);//写入缓存，及流水，统计
            }
            if($k == 'spins' && $t == '-' && $v > 0){
                $this->userSpinConsume($uid, $v); //玩家当天体力消耗值
            }
        }
        $res = $resCount<0?false:($resCount==0?true:$resCount);
        return $res;
    }

    /**
     * 玩家当天体力消耗记录,保留4天,排行榜分房使用
     * @param int $uid
     * @param int $consumeNum 单次消耗体力数量
     */
    public function userSpinConsume($uid, $consumeNum = 0) {
        //消耗体力累计
        $consumeKey = okeys::userspinconsume($uid, date('Ymd'));
        $incrRet = oo::commonOprRedis('usercache')->incrBy($consumeKey, $consumeNum);
        if($incrRet <= $consumeNum){ //保留过去4天数据
            oo::commonOprRedis('usercache')->expire($consumeKey, 5 * 24 * 3600);
        }
    }

    /**
     * 同意发货
     * @param $uid
     * @param $propsId  int 奖品Id common/props.php
     * @param $num  int 道具数量
     * @param $rid int 来源
     * @param $ext string|int 附加说明
     * @param array $value array|string|int 附加道具信息 例如卡片信息数组
     * @param mixed $source 源数据
     * @return mixed
     * Created by: Owen
     * Created on: 2020/12/14 14:40
     */
    public function sendReward($uid,$propsId,$num,$rid,$ext,$value=[],&$source = []){
        $res = null;
        $isActProp =false;//是否是道具活动
        switch (intval($propsId)){
            case 13://随机金卡
                if(!empty($value[0])&&isset($value[0]['id'])&&!empty($value[0]['id'])){
                    $cid = $value[0]['id'];
                    oo::commonOprRedis('activity')->sRemove(okeys::userCacheShowCardList($uid),$cid);//已展示的金卡中去掉
                    oo::commonOprModel('card')->getCardByType($uid,7,0,[$cid]);
                    $res = $value;
                }else{
                    $cardData = oo::commonOprModel('card')->getRandomCard($uid);
                    if(!empty($cardData)){
                        oo::commonOprModel('card')->getCardByType($uid,7,0,[$cardData['id']]);
                        $res = [$cardData];
                    }
                }
                break;
            case 14://金币
                $res =oo::commonOprModel('member')->optProperty($uid,['money'=>$num],'+',$rid,$ext);
                break;
            case 15://体力
                $res = oo::commonOprModel('member')->optProperty($uid,['spins'=>$num],'+',$rid,$ext);
                break;
            case 16://盾牌
                $res = oo::commonOprModel('member')->optProperty($uid,['shield'=>$num],'+',$rid,$ext);
                break;
            case 17://卡片
                oo::commonOprModel('card')->getCardByType($uid,7,0,[$num]);
                $res = $num;
                break;
            case 18://小丑卡
                oo::commonOprModel('statistics')->jokerCardSta($propsId,1,$uid,$ext,$rid);//小丑卡统计
                $res = $source['value'] = oo::commonOprModel('card')->setJokerCard($uid);
                break;
            case 19:case 20:case 21:case 29:case 30://宝箱类
            $res = $source['value'] = oo::commonOprModel('props')->rewardChest($uid,$propsId,$ext,$rid,intval($source['value']['skin']));
            break;
            case 22://钻石
                $res =oo::commonOprModel('member')->optProperty($uid,['diamond'=>$num],'+',$rid,$ext);
                break;
            case 23://头像框
                $res = oo::commonOprModel('user')->rewardAvatarBox($uid,$num);
                break;
            case 24://vip积分

                break;
            case 38://通行证经验
                $res = $source['value'] = oo::commonOprModel('activitynew')->addTrafficPermitNumByProps($uid,$num,$rid,$ext);
                break;
            default :
                $actProp = oo::commonOprModel('activitynew')->specialActTypeList;
                $propArr = funs::array_column_ext($actProp,'propsId',-1);
                if(in_array($propsId,$propArr)){//道具型活动
                    $isActProp =true;
                    $propArr = array_flip($propArr);
                    $setAid = 0;
                    if($propsId == 41 && !empty($value['skin'])){
                        //四选一活动
                        $setAid = $value['skin'];
                    }else if($propsId == 41 && empty($value['skin']) && !empty($source['value']['skin'])){
                        $setAid = $source['value']['skin'];
                    }
                    $res = oo::commonOprModel('activitynew')->openSpecialAct($uid,$propArr[$propsId],$num * 60,$setAid);
                }else{
                    $ret = oo::commonOprModel('props')->addUserProps($uid,$propsId,$num,0,$rid,$ext);
                    if($ret==['code'=>1]){
                        $res =$num;
                    }
                }
                break;
        }
        if($isActProp&&$res){//道具活动加流水
            oo::commonOprModel('currency')->log($uid,$propsId,"+",$num,$num,$rid,$ext);
        }
        return $res;
    }
    //=========================用户统计=============================
    /**
     * Notes:各类变化汇总统计，money,spins变化来源分类合计统计  （wsc-6.10-废弃）
     * User: wsc
     * Time: 2020/6/6 16:48
     * @param $t
     * @param $key
     * @param $num
     * @param string $reason
     */
    public function PropertyStatistics($t,$key,$num,$reason = ""){
        if($t == "+"){
            $okey = okeys::PropertyAdd($key);
        }else if($t == "-"){
            $okey = okeys::PropertyLow($key);
        }
        oo::commonOprRedis('statistics')->incrBy($okey,intval($num));
        if($key == 'money' && $reason != ""){
            if($t == "+"){
                foreach (self::moneyAddType() as $keys=>$row){
                    if(strpos($reason,$row) !== false){
                        oo::commonOprRedis('statistics')->incrBy("Statistics:{$key}{$t}{$keys}",$num);
                    }
                }
            }else if($t == "-"){
                foreach (self::moneyLowType() as $keys=>$row){
                    if(strpos($reason,$row) !== false){
                        oo::commonOprRedis('statistics')->incrBy("Statistics:{$key}{$t}{$keys}",$num);
                    }
                }
            }
        }else if($key == 'spins' && $reason != ""){
            if($t == "+"){
                foreach (self::sipnAddType() as $keys=>$row){
                    if(strpos($reason,$row) !== false){
                        oo::commonOprRedis('statistics')->incrBy("Statistics:{$key}{$t}{$keys}",$num);
                    }
                }
            }else if($t == "-"){
                foreach (self::sipnLowType() as $keys=>$row){
                    if(strpos($reason,$row) !== false){
                        oo::commonOprRedis('statistics')->incrBy("Statistics:{$key}{$t}{$keys}",$num);
                    }
                }
            }
        }
    }

    public function getUserBasicsStatistics($uid){
        $key =  okeys::userBasicsStatistics($uid);
        $res =oo::commonOprRedis('userinfo')->hGetAll($key);
        if(empty($res)){
            $tb  = otable::statistics();
            $sql = "SELECT * FROM {$tb} WHERE uid={$uid} LIMIT 1";
            $data = oo::commonOprDb('common')->getOne($sql,1);
            if(!empty($data)){
//                oo::logs()->debug3($data,'recover_user_statistics.log');//写恢复日志
                unset($data['uid']);
                unset($data['id']);
            }else{
                $sql2 = " INSERT INTO {$tb} (uid) VALUES ({$uid}) ";
                oo::commonOprDb('common')->query($sql2,1);
                $data = ['money'=>0,'damage'=>0,'destroy'=>0,'coinbya'=>0,'stealnum'=>0,'allstealnum'=>0,'stealcoin'=>0,'defense'=>0,'damaged'=>0,'destroyed'=>0,'stealed'=>0,'loginTime'=>0];
            }
            oo::commonOprRedis('userinfo')->hMset($key,$data);
            oo::commonOprRedis('userinfo')->expire($key,oo::redisRandomExpire(86400*7));
        }
        return $res;
    }
    public function saveUserBasicsStatistics($uid,$type,$num){
        $key =  okeys::userBasicsStatistics($uid);
        $ret = oo::commonOprRedis('userinfo')->hIncrBy($key,$type,$num);
        /** 数据落地标识 */
        oo::commonOprRedis('Usercache')->zAdd(okeys::Landing("STATISTICS", $uid),time(),$uid);
        return $ret;
    }
    /**
     * Notes:获取个人统计
     * User: wsc
     * Time: 2020/6/9 14:30
     * @param $uid
     * @param string $type
     * @return array
     */
//    public function getStatistics($uid,$type=""){
//        $key =  okeys::userBasicsStatistics($uid);
//        $res =oo::commonOprRedis('userinfo')->hGetAll($key);
//        $fieldArr = ['money','damage','destroy','coinbya','stealnum','allstealnum','stealcoin','defense','damaged','destroyed','stealed','loginTime'];
//        if(empty($res)||count($res)<count($fieldArr)){//缓存数据不全或无缓存时，先恢复数据
//            oo::commonOprModel('recoverdata')->recoverUserBasicsStatistics($uid);
//            $res =oo::commonOprRedis('userinfo')->hGetAll($key);
//        }
//        return $res;
//    }
    /**
     * 保存个人统计
     * @param $uid
     * @param $type
     * @param $num
     * @return bool
     * Created by: Owen
     * Created on: 2020/4/10 16:09
     */
    public function saveStatistics($uid,$type,$num){
        return true;//过度返回,之后删除整个方法
        $ret =false;
        //$this->getStatistics($uid,$type);//恢复可能没有的数据
        $key =  okeys::userBasicsStatistics($uid);
        $ret = oo::commonOprRedis('userinfo')->hIncrBy($key,$type,$num);
        /** 数据落地标识 */
        oo::commonOprRedis('Usercache')->zAdd(okeys::Landing("STATISTICS", $uid),time(),$uid);
        return $ret;
    }
    /**
     * 保存个人统计 -- 数组
     * @param $uid
     * @param $data
     * @return bool
     * Created by: Owen
     * Created on: 2020/4/10 15:28
     */
//    public function saveStatisticsByArray($uid,$data){
//        $ret = false;
//        if(!empty($data)){
//            foreach ($data as $k=>$v){
//                $ret = self::saveStatistics($uid,$k,$v);
//            }
//        }
//        return $ret;
//    }

    /**
     * 判断是否为游客
     * @param unknown $uid
     * @return number 1游客 0FB
     */
    public function isVistor( $uid ) {
        $userInfo = $this->getUserInfo($uid);
        if ($userInfo == 0) {
            return 1;
        }

        $siteUid = $userInfo['siteuid'];
        $account = $this->getAccount($siteUid);
        if ( $account <= 0 ) {
            return 1;
        }
        return 0;
    }
    /**
     * Notes:个人老虎机相关配置
     * User: wsc
     * Time: 2020/6/9 14:31
     * @param $uid
     * @return array
     */
    public function getUserConfig($uid){
        $memberAssets  = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $trun_arr = oo::commonOprModel('slot')->getSlotTurnConfig($memberAssets['levelId']);
        $turnplateConfig = array_column($trun_arr, 'prize');

        $spins_arr = oo::commonOprModel('slot')->getSpinsTurnConfig(1);
        $turnspinsConfig = array_column($spins_arr, 'prize');

        $confs = oo::commonOprModel('level')->getLevelConf($memberAssets['levelId']);
        $coin_arr = json_decode($confs['coinConfig'],true);

        return [
            'turnplateConfig'=>$turnplateConfig,
            'turnspinsConfig'=>$turnspinsConfig,
            'buildConfig'=>$coin_arr,
            'slotConfig'=>oo::commonOprModel('slot')->getSlotImgConfig($uid),
        ];
    }
    /**
     * 首冲
     * @param $uid
     * @param $gid
     * @return mixed
     * Created by: Owen
     * Created on: 2019/7/10 17:42
     * Description:
     */
    public function getUserFirstPayStatus($uid,$gid = 601){
        $cacheKey = okeys::firstPay($uid,$gid);
        $cache    = oo::commonOprRedis('User')->get($cacheKey);
        if($cache !== false){
            return $cache;
        }
        $tb = otable::payment($uid);
        $sql = "SELECT * FROM {$tb} WHERE uid={$uid} AND status=2 AND gid= {$gid}";
        $ret =  oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
        if(empty($ret)){
            oo::commonOprRedis('User')->setex($cacheKey,0,oo::redisRandomExpire(3*24*60*60));
            return 0;
        }else{
            oo::commonOprRedis('User')->setex($cacheKey,1,oo::redisRandomExpire(3*24*60*60));
            return 1;
        }
    }

    /**
     * 新首充礼包状态
     * @param $uid
     * @return array|bool
     * Created by: Owen
     * Created on: 2020/8/18 15:29
     */
    public function getUserFirstPayStatus2($uid){
        $minLevelId = oo::commonOprModel('readconfig')->getSysCon('FirstPay','minLevelId') ?? 2;
        $maxLevelId = oo::commonOprModel('readconfig')->getSysCon('FirstPay','maxLevelId') ?? 4;
        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $userLevelId = $userAssetsInfo['levelId'];
        if($userLevelId >= $maxLevelId || $userLevelId < $minLevelId){
            return false;
        }
        if(oo::commonOprRedis('User')->delete(okeys::FirstPayLevelLock($uid))){
            return false;
        }
        if(self::getUserFirstPayStatus($uid,602)){
            return false;
        }
        return [
            'gid'        => 602,
            'maxLevelId' => $maxLevelId,
        ];
    }

    /**
     * 保护时间
     * @param $uid
     * @param $time
     * Created by: Owen
     * Created on: 2020/1/2 15:34
     */
    public function setUserStealProtect($uid,$time,$isSteal=false){
        if($isSteal){
            oo::commonOprModel('steal')->setBeStealNum($uid);
        }
        oo::commonOprModel('steal')->setProteTime($uid,$time);
    }

    /**
     * 体力限制
     * @param $uid
     * @return int
     * Created by: owen
     * Created on: 2020/2/6 18:20
     */
    public function getSpinsUpLimit($uid){
        $totalPayNum = oo::commonOprModel('payment')->getUserDayPayNum($uid);
        if($totalPayNum<0.99){
            return 500;
        }else if($totalPayNum<=1.99){
            return 1000;
        }else if($totalPayNum<=19.99){
            return 2000;
        }else if($totalPayNum<=99){
            return 5000;
        }else if($totalPayNum>100){
            return 10000;
        }
    }
    //====================签到相关========================
    /**
     * 签到奖励
     * @param $uid
     * @return string
     * Created by: Owen
     * Created on: 2020/4/24 16:51
     */
    public function getSignInReward($uid){
        $signInToday = oo::commonOprRedis('User')->get(okeys::SignInToday($uid));
        if($signInToday){
            return oo::response(-1,[],'今日已签到');
        }
        $signInTimes = oo::commonOprRedis('User')->get(okeys::SignInTimes($uid));
        $id = $signInTimes + 1;
        $config = oo::commonOprModel('config')->getSignInConfig($id);
        $monthly = oo::commonOprModel('payment')->getSpinMonthly($uid,1001);
        $monthly = empty($monthly)?0:$monthly['num'];
        $monthlyPro = oo::commonOprModel('payment')->getSpinMonthly($uid,1002);
        $monthlyPro = empty($monthlyPro)?0:$monthlyPro['num'];
        $bet = max(1,$monthly,$monthlyPro);

        $version = oo::commonOprModel('user')->getUserVersion($uid);
        //1.8.5vip特权取消额外签到倍率,改为vip订阅的特权
        if(!oo::compareVersion($version,"1.8.5")){
            if(oo::commonOprModel('newvip')->checkVip($uid)) {
                $config = oo::commonOprModel('newvip')->getUserVipLv($uid, true,false,155);
                $bet = max(intval($config['signInBet']), $bet);
            }
        }else{
            $subVip = oo::commonOprModel('newvip')->checkSubVip($uid);
            if($subVip && !empty($subVip['vipSignBet'])){
                $bet = max(intval($subVip['vipSignBet']), $bet);
            }
        }

        if($config['type'] == 1){
            $reward = [
                'money' => $config['num']*$bet
            ];
            oo::commonOprModel('member')->optProperty($uid,$reward,'+',15,'签到奖励');
        }else if($config['type'] == 2){
            $reward = [
                'spins' => $config['num']*$bet
            ];
            oo::commonOprModel('member')->optProperty($uid,$reward,'+',15,'签到奖励');
        }else if($config['type'] == 3){
            oo::commonOprModel('props')->addUserProps($uid,$config['num'],1*$bet,0,15);
            $reward['card'] = [];
        }
        oo::commonOprRedis('User')->setex(okeys::SignInToday($uid),1,oo::todayDeadline());
        $expireTime = $id >= 7 ?  oo::todayDeadline() : oo::todayDeadline() + 86400;
        oo::commonOprRedis('User')->setex(okeys::SignInTimes($uid),$id,$expireTime);

        //召回活动任务
//        oo::commonOprModel('callback')->doCallbackTask($uid, 4, $id);

        //签到率统计
        oo::commonOprModel('statistics')->signInSta($uid,'all');
        if($monthly){
            oo::commonOprModel('statistics')->signInSta($uid,'1001');
        }
        if($monthlyPro){
            oo::commonOprModel('statistics')->signInSta($uid,'1002');
        }
        return oo::response(1,$reward);
    }

    /**
     * 新版签到奖励
     * @param $uid
     * @return string
     * Created by: Owen
     * Created on: 2020/4/24 17:16
     */
    public function getSignInReward2($uid){
        $signInToday = oo::commonOprRedis('User')->get(okeys::SignInToday($uid));
        if($signInToday){
            return oo::response(-1,[],'今日已签到');
        }
        $signInTimes = oo::commonOprRedis('User')->get(okeys::SignInTimes($uid));
        $id = $signInTimes + 1;

        $version = oo::commonOprModel('user')->getUserVersion($uid);
        if(oo::compareVersion($version,"1.7.7")){
            $config = oo::commonOprModel('config')->signInConfByUserGroup($uid,$id);
        }else{
            $config = oo::commonOprModel('config')->getSignInConfig($id,true,$this->getSignInSectionId($uid));
        }

        $monthly = oo::commonOprModel('payment')->getSpinMonthly($uid,1001);
        $monthly = empty($monthly)?0:$monthly['num'];
        $monthlyPro = oo::commonOprModel('payment')->getSpinMonthly($uid,1002);
        $monthlyPro = empty($monthlyPro)?0:$monthlyPro['num'];
        $bet = max(1,$monthly,$monthlyPro);
        //1.8.5vip特权取消额外签到倍率,改为vip订阅的特权
        if(!oo::compareVersion($version,"1.8.5")){
            if(oo::commonOprModel('newvip')->checkVip($uid)) {
                $vipConfig = oo::commonOprModel('newvip')->getUserVipLv($uid,true,false,155);
                $bet = max($bet,$vipConfig['signInBet']);
            }
        }else{
            $subVip = oo::commonOprModel('newvip')->checkSubVip($uid);
            if($subVip && !empty($subVip['vipSignBet'])){
                $bet = max(intval($subVip['vipSignBet']), $bet);
            }
        }
        $reward  = [];
        $coins   = intval(oo::commonOprModel('goods')->getGoodCoins($uid,$config['coins']['coins']));
        $coinBet = round($config['coins']['bet'],2);
        $coins   = intval($coins * $coinBet);
        if($coins){
            $reward['money'] = intval($coins * $bet);
        }
        if($config['spins']){
            $reward['spins'] = intval($config['spins'] * $bet);
        }
        if(!empty($reward)){
            oo::commonOprModel('member')->optProperty($uid,$reward,'+',15,'签到奖励:'.$id);
        }
        if($config['props']){
           foreach ($config['props'] as $row){
               oo::commonOprModel('props')->addUserProps($uid,$row['propsId'],$row['num'] * $bet,0,15);
           }
        }
        self::updateUserSignInProgress($uid,['signInDay'=>1],false);
        oo::commonOprRedis('User')->setex(okeys::SignInToday($uid),1,oo::todayDeadline());
        $expireTime = $id >= 7 ?  oo::todayDeadline() : oo::todayDeadline() + 86400;
        oo::commonOprRedis('User')->setex(okeys::SignInTimes($uid),$id,$expireTime);

        if(oo::compareVersion($version,"1.7.7")){
            oo::commonOprRedis('User')->expire(okeys::SignInUserGroupId($uid),$expireTime); // 分组签到的配置与签到周期绑定一致的结束时间
        }
        //召回活动-签到任务
        if(oo::compareVersion($version,"1.8.4")){
            oo::commonOprModel('callback')->doTask($uid, 4, 1);
        }

        //签到率统计
        oo::commonOprModel('statistics')->signInSta($uid,'all');
        if($monthly){
            oo::commonOprModel('statistics')->signInSta($uid,'1001');
        }
        if($monthlyPro){
            oo::commonOprModel('statistics')->signInSta($uid,'1002');
        }
        //数数事件-完成签到
        $curUserSignInProgress=self::getUserSignInProgress($uid);
        oo::commonOprModel('ta')->setEventData($uid,'sign',["sign_total_days"=>$curUserSignInProgress['signInDay'],"sign_continuity_days"=>$id]);
        return oo::response(1,$reward);
    }

    /**
     * 获取用户签到进度
     * @param $uid
     * @return array|mixed
     * Created by: Owen
     * Created on: 2020/4/24 14:55
     */
    public function getUserSignInProgress($uid){
        $cacheKey = okeys::UserSignInProgress($uid);
        $cache    = oo::commonOprRedis('common')->get($cacheKey);
        if($cache){
            return self::signInProgressRefresh(json_decode($cache,true));
        }
        $tb = otable::UserSignInProgress();
        $ret= oo::commonOprDb('common')->getOne("SELECT * FROM {$tb} WHERE uid={$uid} LIMIT 1",MYSQLI_ASSOC);
        if(empty($ret)){
            $ret = [
                'uid'       => $uid,
                'rewardDay' => [],
                'signInDay' => 0,
            ];
            oo::commonOprRedis('common')->setex($cacheKey,json_encode($ret,JSON_NUMERIC_CHECK),oo::redisRandomExpire(7*24*60*60));
            oo::commonOprDb('common')->query("INSERT INTO {$tb} (uid) VALUE ({$uid})");
            return self::signInProgressRefresh($ret);
        }
        $ret['rewardDay'] = json_decode($ret['rewardDay'],true);
        oo::commonOprRedis('common')->setex($cacheKey,json_encode($ret,JSON_NUMERIC_CHECK),oo::redisRandomExpire(7*24*60*60));
        return self::signInProgressRefresh($ret);
    }

    /**
     * 更新签到进度数据
     * @param $uid
     * @param $updateInfo
     * @param bool $set
     * @return bool
     * Created by: Owen
     * Created on: 2020/4/24 15:07
     */
    public function updateUserSignInProgress($uid,$updateInfo,$set = false){
        $curUserSignInProgress = self::getUserSignInProgress($uid);
        foreach ($updateInfo as $key=>$row){
            if($set){
                $curUserSignInProgress[$key] = $row;
            }else{
                $curUserSignInProgress[$key] +=$row;
            }
        }
        $cacheKey = okeys::UserSignInProgress($uid);
        oo::commonOprRedis('common')->setex($cacheKey,json_encode($curUserSignInProgress,JSON_NUMERIC_CHECK),oo::redisRandomExpire(7*24*60*60));
        $tb = otable::UserSignInProgress();
        $rewardDay = addslashes(json_encode($curUserSignInProgress['rewardDay']));
        $signInDay = $curUserSignInProgress['signInDay'];
        return oo::commonOprDb('common')->query("UPDATE {$tb} SET `rewardDay` = '{$rewardDay}' ,`signInDay`={$signInDay} WHERE `uid` = {$uid}");
    }

    /**
     * 刷新
     * @param $info
     * @return mixed
     * Created by: Owen
     * Created on: 2020/4/27 15:49
     */
    public function signInProgressRefresh($info){
        if($info['signInDay'] >= 30){
            if(!oo::commonOprRedis('common')->get(okeys::SignInProgressRefresh($info['uid']))){
                //新版签到等级区间 获取用户所在区间
                $section_id = $this->getSignInSectionId($info['uid']);
                $version = oo::commonOprModel('user')->getUserVersion($info['uid']);
                if(oo::compareVersion($version,'1.7.0')){
                    $config = oo::commonOprModel('config')->getSignInProgressConfig(0,$section_id,2);
                }else{
                    $config = oo::commonOprModel('config')->getSignInProgressConfig(0,$section_id);
                }
                $progressCount = count($config);
                if($progressCount <= count($info['rewardDay'])){
                    $curUserSignInProgress = [
                        'uid'       => $info['uid'],
                        'rewardDay' => [],
                        'signInDay' => 0,
                    ];
                    $cacheKey = okeys::UserSignInProgress($info['uid']);
                    oo::commonOprRedis('common')->setex($cacheKey,json_encode($curUserSignInProgress,JSON_NUMERIC_CHECK),oo::redisRandomExpire(7*24*60*60));
                    $tb = otable::UserSignInProgress();
                    $rewardDay = addslashes(json_encode($curUserSignInProgress['rewardDay']));
                    $signInDay = $curUserSignInProgress['signInDay'];
                    oo::commonOprDb('common')->query("UPDATE {$tb} SET `rewardDay` = '{$rewardDay}' ,`signInDay`={$signInDay} WHERE `uid` = {$curUserSignInProgress['uid']}");
                    $info['rewardDay'] =  [];
                    $info['signInDay'] =  0;
                }
            }
        }
        return $info;
    }

    /**
     * 领取签到阶段奖励
     * @param $uid
     * @param $progress
     * @return string
     * Created by: Owen
     * Created on: 2020/4/24 15:26
     */
    public function getSignInProgressReward($uid,$progress){
        $curUserSignInProgress = self::getUserSignInProgress($uid);
        if(in_array($progress,$curUserSignInProgress['rewardDay'])){
            return oo::response(-2,[],'奖励已领取');
        }
        if($progress > $curUserSignInProgress['signInDay']){
            return oo::response(-3,[],'进度未达标');
        }

        $version = oo::commonOprModel('user')->getUserVersion($uid);
        if(oo::compareVersion($version,'1.7.0')){
            $config = oo::commonOprModel('config')->getSignInProgressConfig($progress,$this->getSignInSectionId($uid),2);
        }else{
            $config = oo::commonOprModel('config')->getSignInProgressConfig($progress,$this->getSignInSectionId($uid));
        }

        if(empty($config)){
            return oo::response(-4,[],'奖励配置异常');
        }
        $curUserSignInProgress['rewardDay'][] = $progress;
        $newProgress = array_unique($curUserSignInProgress['rewardDay']);
        $ret = self::updateUserSignInProgress($uid,['rewardDay'=>$newProgress],true);
        if($ret){
            if(count($newProgress) == $config['count']){
                oo::commonOprRedis('common')->setex(okeys::SignInProgressRefresh($uid),1,oo::todayDeadline());
            }
            $coins = oo::commonOprModel('goods')->getGoodCoins($uid,$config['coins']['coins']);
            $coins = intval($coins * $config['coins']['bet']);
            $spins = intval($config['spins']);
            $props = $config['props'];
            oo::commonOprModel('member')->optProperty($uid,['money'=>$coins,'spins'=>$spins],'+',16,'领取签到进度奖励:'.$curUserSignInProgress['signInDay']);
            foreach ($props as $key=>&$row){
                $this->sendReward($uid,$row['propsId'],$row['num'],16,'领取签到进度奖励:'.$curUserSignInProgress['signInDay'],[],$row);
            }
            $props[] = ['propsId'=>14,"num"=>$coins,"value"=>$coins];
            $props[] = ['propsId'=>15,"num"=>$spins,"value"=>$spins];
            return oo::response(1,$props);
        }
        return oo::response(-4,[],'system error');
    }
	
	/**
     * 获取用户所在签到等级配置区间
     * @param $uid
     * @return int
     * Created by: Hss
     * Created on: 2020/5/25 11:11
     */
    public function getSignInSectionId($uid){
    	$userLevel = $this->getUserLevel($uid);
		$levelId = $userLevel['levelId'];
		$config = oo::commonOprModel('config')->signinSection();
		$section_id = 1;
		foreach($config as $k => $v){
			if($levelId >= $v['start_level'] && $levelId < $v['end_level']){
				$section_id = $v['section_id'];
			}
		}
		return $section_id;
    }

    //=================================================

    /**
     * Notes:新手引导
     * User: wsc
     * Time: 2020/6/9 14:35
     * @param $param
     * @return false|string
     */
    public function endGuide($param){
        $dump = oo::functions()->escape($param['dump']);
        $uid = oo::functions()->uint($param['uid']);
        $sid = oo::functions()->uint($param['sid']);
        if($dump == "SUPERANT"){
            $data['code'] = 1;
            oo::commonOprRedis('common')->hDel(okeys::beginGuide(),$uid);
            $tb = otable::gh_gameserver($uid);
            $sql = "UPDATE {$tb} SET beginGuide = 19 WHERE mid = {$uid} LIMIT 1";
            oo::commonOprDb('ghgames')->query($sql);
            /**
             * 结束新手引导人数
             */
            oo::commonOprRedis('common')->sAdd(okeys::getGuideCount($sid),$uid);
            return json_encode($data,JSON_NUMERIC_CHECK);
        }
        $stage = oo::commonOprRedis('common')->hGet(okeys::beginGuide(),$uid);
        $data = ['code'=>-1];
        if($stage !== false && $stage!=18){
            return json_encode($data,JSON_NUMERIC_CHECK);
        }
        // 判断当前玩家的类型
        $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
        //查询是否属于FB
        $infoArr = oo::commonOprModel('member')->getAccount($userInfo['siteuid']);
        if (!empty($infoArr) && $infoArr['uid'] == $uid) {
            $spinType = 'fbLoginSpin';
            $coinType = 'fbLoginCoin';
        } else {
            $spinType = 'guestLoginSpin';
            $coinType = 'guestLoginCoin';
        }
        $spins = oo::commonOprModel('readconfig')->getCon('BeginnerReward',$spinType);
        $coins = oo::commonOprModel('readconfig')->getCon('BeginnerReward',$coinType);

        $tb = otable::gh_gameserver($uid);
        $sql = "SELECT * FROM {$tb} WHERE mid = {$uid} LIMIT 1";
        $ret = oo::commonOprDb('ghgames')->getOne($sql,MYSQLI_ASSOC);
        $userAssets = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        if(empty($ret)){
            return json_encode($data,JSON_NUMERIC_CHECK);
        }else if($ret['beginGuide'] == 19){
            $data['data']['spins'] = $userAssets['spins'];
            $data['data']['coins'] = $userAssets['money'];
            $data['code'] = 1;
            return json_encode($data,JSON_NUMERIC_CHECK);
        }

        oo::commonOprModel('member')->optProperty($uid,['spins'=>$spins],'+',101,"结束新手引导");
        oo::commonOprModel('member')->optProperty($uid,['money'=>$coins],'+',101,"结束新手引导");
        $userAssets['spins'] += $spins; //不取redis,直接更新内存数据
        $userAssets['money'] += $coins; //不取redis,直接更新内存数据
        $data['code'] = 1;
        $data['data']['spins'] = $userAssets['spins'];
        $data['data']['coins'] = $userAssets['money'];
        if($userAssets['shield'] == 0){
            oo::commonOprModel('member')->optProperty($uid,['shield'=>1],'+',101,"结束新手引导");
        }

        if($userAssets['star'] == 0){
            oo::commonOprModel('member')->optProperty($uid,['star'=>1],'+',101,"结束新手引导");
        }

        $userLevel = oo::commonOprModel('member')->getUserLevel($uid);
        $element   = $userLevel['element'];
        if($element[0]['level'] == 0){
            $element[0]['level'] = 1;
            oo::commonOprModel('member')->setUserLevel($uid,$userLevel['levelId'],$element);
        }

        oo::commonOprRedis('common')->hDel(okeys::beginGuide(),$uid);
        $tb = otable::gh_gameserver($uid);
        $sql = "UPDATE {$tb} SET beginGuide = 19 WHERE mid = {$uid} LIMIT 1";
        oo::commonOprDb('ghgames')->query($sql);
        /**
         * 结束新手引导人数
         */
        oo::commonOprRedis('common')->sAdd(okeys::getGuideCount($sid),$uid);

        return json_encode($data,JSON_NUMERIC_CHECK);
    }

    /**
     * Notes:新新手引导
     * User: wsc
     * Time: 2020/6/9 14:35
     * @param $uid
     * @param $build
     * @param $dump
     * @return string
     */
    public function endGuide2($uid,$build, $dump){
        if($dump == "SUPERANT"){
            oo::commonOprRedis('common')->hDel(okeys::beginGuide(),$uid);
            $tb = otable::gh_gameserver($uid);
            $sql = "UPDATE {$tb} SET beginGuide = 19 WHERE mid = {$uid} LIMIT 1";
            oo::commonOprDb('ghgames')->query($sql);
            /**
             * 结束新手引导人数
             */
            $userPlat = oo::commonOprModel('user')->getUserLoginPlat($uid);
            oo::commonOprRedis('common')->sAdd(okeys::getGuideCount($userPlat),$uid);
            return oo::response(1);
        }

        $tb = otable::gh_gameserver($uid);
        $ret = oo::commonOprDb('ghgames')->getOne("SELECT * FROM {$tb} WHERE mid = {$uid} LIMIT 1",MYSQLI_ASSOC);
        if(empty($ret)){
            return oo::response(-2);
        }else if($ret['beginGuide'] == 19){
            $userAssets = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $data['spins'] = $userAssets['spins'];
            $data['coins'] = $userAssets['money'];
            $data = 1;
            return oo::response(1,$data);
        }else{
            $ret = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        }
        /**
         * 同步数据
         */
        $config  = oo::commonOprModel('config')->getBeginGuideConfig(true);

        oo::commonOprModel('member')->optProperty($uid,['spins'=>$ret['spins']],'-',101,"同步新手引导");
        oo::commonOprModel('member')->optProperty($uid,['money'=>$config['coins']],'+',101,"同步新手引导");

        $build     = json_decode($build,true);
        $userLevel = oo::commonOprModel('member')->getUserLevel($uid);
        $element   = $userLevel['element'];
        $elementConfig = json_decode(oo::commonOprModel('level')->getCoinConfig($userLevel['levelId']),true);
        $spendCoin = 0;
        $start     = 0;
        foreach ($build as $row){
            $start = $start + $row['level'];
            $buildId = $row['id'] - 1;
            $buildCoins = $elementConfig[$buildId];
            for ($i=0;$i<$row['level'];$i++){
                if($i == 1){
                    $start--;
                    continue;
                }
                $spendCoin += $buildCoins[$i];
            }
            $element[$buildId]['level']    = $row['level'];
            $element[$buildId]['maxLevel'] = min($row['level'],5);
        }

        $userAssets = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        if($spendCoin != 0 && $spendCoin <= $userAssets['money']){
            oo::commonOprModel('member')->optProperty($uid,['money'=>$spendCoin],'-',101,"同步新手引导");
            oo::commonOprModel('member')->setUserLevel($uid,$userLevel['levelId'],$element);
            oo::commonOprModel('member')->optProperty($uid,['star'=>min($start,10)],'+',101,"同步新手引导");
        }

        $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
        if(empty($userInfo['inviteuid'])){
            $inviteUid = oo::commonOprModel('member')->actionAdjustInvite($uid);
            if($inviteUid > 0){
                $userInfo['inviteuid'] = $inviteUid;
            }
        }
        //邀请活动完成模式2
        if($userInfo['inviteuid']){
            $fromid = $userInfo['inviteuid'];
            if($userInfo['isFb']&&$fromid){
                $aid =  oo::commonOprModel('activitynew')->activityLock($fromid,'time_limit_invite');
//                oo::logs()->commlog(['uid'=>$uid,'fid'=>$fromid,'aid'=>$aid],'time_limit_invite');
                if($aid){
                    oo::commonOprModel('activitynew')->setInviteLog($aid,$fromid,$uid,0);
                    oo::commonOprModel('activitynew')->tryFinishIntivityAct($aid,$fromid,$uid,2);
                }
            }
        }

        if ($userInfo['isFb'] == 1) {
            $spinType = 'fbLoginSpin';
            $coinType = 'fbLoginCoin';
        } else {
            $spinType = 'guestLoginSpin';
            $coinType = 'guestLoginCoin';
        }
        $spins = oo::commonOprModel('readconfig')->getCon('BeginnerReward',$spinType);
        $coins = oo::commonOprModel('readconfig')->getCon('BeginnerReward',$coinType);
        $isReward = oo::commonOprModel('readconfig')->getCon('Game',"isGuestReward") ?? 1;
        if($userInfo['isFb'] == 1 || $isReward){
            oo::commonOprModel('member')->optProperty($uid,['spins'=>$spins],'+',101,"结束新手引导");
            oo::commonOprModel('member')->optProperty($uid,['money'=>$coins],'+',101,"结束新手引导");
        }
        $userAssets = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $data['spins'] = $userAssets['spins'];
        $data['coins'] = $userAssets['money'];

        if($userAssets['shield'] == 0){
            oo::commonOprModel('member')->optProperty($uid,['shield'=>1],'+',101,"结束新手引导");
        }

        oo::commonOprRedis('common')->hDel(okeys::beginGuide(),$uid);
        $tb = otable::gh_gameserver($uid);
        oo::commonOprDb('ghgames')->query("UPDATE {$tb} SET beginGuide = 19 WHERE mid = {$uid} LIMIT 1");
        $userPlat = oo::commonOprModel('user')->getUserLoginPlat($uid);
        /**
         * 结束新手引导人数
         */
        oo::commonOprRedis('common')->sAdd(okeys::getGuideCount($userPlat),$uid);
        return oo::response(1,$data);
    }



    //===============流水，日志，统计相关配置=============
  	public function moneyAddType(){
        return [
        	'stealAttack'   =>'偷打活动',
        	'rankActivity'  =>'排行榜活动',
        	'festival'      =>'节日礼包',
        	'holidayCollect'=>'节日收集',
        	'goldEgg'       =>'金蛋进度',
        	'Architect'     =>'建筑大师',
            'server'        =>'后台修改',
            'slot'          =>'摇奖奖励',
            'friendGift'    =>'好友赠送',
            'mining'        =>'矿岛收益',
            'shop'          =>'商城购买',
            'card'          =>'卡组收集满',
            'cardProgress'  =>'卡组进度',
            'wheel'         =>'大转盘',
            'chat'          =>'聊天礼物',
            'firstPay'      =>'首冲获取',
            'specialOffer'  =>'限时特惠',
            'GiftPackage'   =>'优惠礼包',
            'attackShield'  =>'摧毁盾牌',
            'attack'        =>'摧毁建筑',
            'attackStatus'  =>'损毁建筑',
            'task'          =>'每日任务',
            'ach'           =>'领取成就',
            'level'         =>'通过关卡',
            'balloon'       =>'气球奖励',
            'ad'            =>'广告获得',
            'newplayer'     =>'新手引导',
            'exchange'      =>'兑换码',
//            'betSteal'      =>'倍率偷取',
            'recall'        =>'回归',
            'invite'        =>'邀请奖励',
          	'speaker'       =>'购买喇叭',
          	'signIn'        =>'签到奖励',
            'share'         =>'分享奖励',
          	'sysCom'        =>'系统补偿',
          	'versionGift'   =>'更新礼包',
            'robot'         =>'机器人补发',
            'recallCoin'    =>'贈送召回',
            'luckyDraw'     =>'夺宝抽奖',
//            'petGain'       =>'宠物加成',
            'JackPot'       =>'JackPot',
            'MiningGame'    =>'矿工游戏',
            'VipWeek'       =>'VIP每周奖励',
            'signProgress'  =>'签到进度',
            "systemPay"     =>"系统补发",
            "fbBind"     =>"fb绑定",
        ];
    }
    public function moneyLowType(){
        return [
            'uplevel'   =>'升级建筑',
            'relevel'   =>'修复建筑',
            'upminig'   =>'升级矿工',
            'bugChest'  =>'购买宝箱',
            'miningGame'=>'矿工小游戏',
        ];
    }
    public function sipnAddType(){
        return [
        	'stealAttack' =>'偷打活动',
        	'rankActivity'  =>'排行榜活动',
        	'festival'    =>'节日礼包',
        	'holidayCollect'=>'节日收集',
        	'goldEgg'     =>'金蛋进度',
        	'Architect'   =>'建筑大师',
            'time'        =>'自动恢复',
            'server'      =>'后台修改',
            'slot'        =>'摇奖奖励',
            'friendGift'  =>'好友赠送',
            'shop'        =>'商城购买',
            'newplayer'   =>'新手引导',
            'slotShield'  =>'盾牌转能量',
            'invite'      =>'邀请奖励',
            'wheel'       =>'大转盘',
            'chat'        =>'聊天礼物',
            'recall'      =>'回归',
            'card'        =>'卡组收集满',
            'cardProgress'=>'卡组进度',
            'exchange'    =>'兑换码',
            'task'        =>'每日任务',
            'taskProgress'=>'每日任务进度',
            'ach'         =>'领取成就',
            'level'       =>'通过关卡',
            'balloon'     =>'气球奖励',
            'ad'          =>'广告获得',
            'firstPay'    =>'首冲获取',
            'specialOffer'=>'限时特惠',
            'GiftPackage' =>'优惠礼包',
          	'signIn'      =>'签到奖励',
            'share'       =>'分享奖励',
          	'sysCom'      =>'系统补偿',
          	'versionGift' =>'更新礼包',
          	'monthly'     =>'体力月卡',
            'luckyDraw'   =>'夺宝抽奖',
            'MiningGame'  =>'矿工游戏',
            'VipWeek'     =>'VIP每周奖励',
            'signProgress'=>'签到进度',
            "fbBind"     =>"fb绑定",
        ];
    }
    public function sipnLowType(){
        return [
            'slot'   =>'摇奖扣除能量',
        ];
    }

    /**
     * 获取玩家等级id,简化部分接口获取多余的信息
     * @param int $uid
     * @return int
     */
    public function getUserLevelId($uid) {
        $key = okeys::UserBuildLevel($uid);
        $levelId = oo::commonOprRedis('common')->hGet($key, 'levelId');
        if(!empty($levelId)){
            return $levelId;
        }
        $info = $this->getUserLevel($uid);
        return empty($info['levelId']) ? 1 : $info['levelId'];
    }

    //=========================用户等级相关========================
    /**
     * 获取玩家当前岛的建筑情况
     * @param $uid
     * @return array|bool
     * Created by: Owen
     * Created on: 2020/6/9 15:11
     */
    public function getUserLevel($uid) {
        if (empty($uid)) {
            return false;
        }
        $key = okeys::UserBuildLevel($uid);
        $cache = oo::commonOprRedis('common')->hGetAll($key);
        if(!$cache['levelId']){
            $tb = otable::userlevel($uid);
            $sql0 = "SELECT max(levelId) as levelId FROM {$tb} WHERE uid={$uid}";
            $lv = oo::commonOprDb('userlevel')->getOne($sql0,1);
            if(empty($lv)||!isset($lv['levelId'])){
                $this->setUserNewLevel($uid,1);
                $lv['levelId'] =1;
            }
            $sql = "SELECT * FROM {$tb} WHERE levelId={$lv['levelId']} AND uid={$uid} limit 1";
            $cache = oo::commonOprDb('userlevel')->getOne($sql,1);
            oo::commonOprRedis('common')->delete($key);
            if(!empty($cache)&&is_array($cache)){
                $temp = [
                    'levelId'   => $cache['levelId'],
                    'element'   => $cache['element'],
                    'is_reward' => $cache['is_reward'],
                ];
                oo::commonOprRedis('common')->hMset($key,$temp);
                oo::commonOprRedis('common')->expire($key,oo::redisRandomExpire(86400));
            }
        }
        $cache = !empty($cache)?funs::getArrayFromOne($cache):[];
        return $cache;
    }
    /**
     * Notes:获取用户orig信息
     * User: wsc
     * Time: 2020/3/30 19:54
     * @param $uid
     * @param bool $db
     * @return array
     */
    public function getUserLevel_orig($uid,$db=false){
        $cache = [];
        $key   = okeys::userLevelOrig($uid);
        if(!$db){
            $cache = oo::commonOprRedis('common')->hGetAll($key);
        }
        if(empty($cache)){
            $tb  = otable::userlevel();
            $sql = "SELECT * FROM {$tb} WHERE uid={$uid} LIMIT 1";
            $cache = oo::commonOprDb('userlevel')->getOne($sql,1);
            if(!empty($cache)){
                oo::commonOprRedis('common')->hMset($key,$cache);
                $time = timeFuns::today()[1];
                oo::commonOprRedis('common')->expireAt($key,oo::redisRandomExpire($time));
            }
        }
        return $cache;
    }
    /**
     * 更新用户orig信息
     * @param $uid
     * @param array $updateInfo
     * @return  mixed
     * Created by: Owen
     * Created on: 2020/6/5 15:28
     */
    public function setUserLevel_orig($uid,$updateInfo = []){
        self::getUserLevel_orig($uid); // 初始化
        $tb  = otable::userlevel();
        $cacheKey = okeys::userLevelOrig($uid);
        $sql = "";
        foreach ($updateInfo as $key=>$row){
            if($row['add']){
                $sql.= "`{$key}`+='{$row['data']}',";
                oo::commonOprRedis('user')->hIncrBy($cacheKey,$key,$row['data']);
            }else{
                $sql.= "`{$key}`='{$row['data']}',";
                oo::commonOprRedis('user')->hSet($cacheKey,$key,$row['data']);
            }
        }
        if(empty($sql)){
            return false;
        }
        $sql = trim($sql,",");
        $sql = "UPDATE {$tb} SET {$sql} WHERE uid={$uid}";
        oo::commonOprDb('ghgames')->query($sql,false);
    }
    /**
     * Notes:获取用户当前最小可建建筑的钱及位置
     * User: wsc
     * Time: 2020/4/17 16:38
     * @param $uid
     * @return array|int
     */
    public function getThisConstMinMoney($uid){
        if(!$uid){
            return 0;
        }
        $minArr = [];
        $levelInfo = $this->getUserLevel($uid);
        $levelCfg = oo::commonOprModel('level')->getLevelConf($levelInfo['levelId']);
        $levelCfg = funs::getArrayFromOne($levelCfg);
        foreach ($levelInfo['element'] as $k=>$v){
            if($v['level']==5){
                continue;
            }
            $minArr[$k] = $levelCfg['coinConfig'][$k][$v['level']];
        }
        $min['money'] = min($minArr);
        $min['place_k'] = array_search($min['money'],$minArr)+1;
        $min['place_v'] = array_search($min['money'],$levelCfg['coinConfig'][$min['place_k']])+1;
        return $min;
    }
    /**
     * 设置新等级
     * @param $uid
     * @param $level
     * @return int
     * Created by: Owen
     * Created on: 2019/8/13 14:57
     * Description:
     */
    public function setUserNewLevel($uid,$level) {
        $str_level = '[{\"id\":1,\"level\":0,\"maxLevel\":0,\"status\":0},{\"id\":2,\"level\":0,\"maxLevel\":0,\"status\":0},{\"id\":3,\"level\":0,\"maxLevel\":0,\"status\":0},{\"id\":4,\"level\":0,\"maxLevel\":0,\"status\":0},{\"id\":5,\"level\":0,\"maxLevel\":0,\"status\":0}]';
        if($level == 1){
            $tb = otable::userlevel($uid);
            $time = time();
            oo::commonOprDb('common')->query("INSERT INTO {$tb} (`uid`,`levelId`,`element`,`createTime`) VALUES ({$uid},{$level}, '$str_level','{$time}')");
            return true;
        }
        $info  = $this->getUserAssetsInfo($uid);
        oo::commonOprModel('steal')->outAllQueue($uid,$level-1);
        oo::commonOprModel('steal')->toJoinQueue($uid,$level,$info['money']);
        self::updateUserLevel($uid,[
            'levelId'  => $level,
            'element'  => json_decode(stripslashes($str_level),true),
            'is_reward'=> 0,
        ]);
//        oo::commonOprRedis('common')->hIncrBy(okeys::todayDataRank('level'),$uid,1);
        if($level == 2){
            oo::commonOprRedis('common')->delete(okeys::newcomerSpinNum($uid));
        }
        return true;
    }
    /**
     * 更新建筑用户信息
     * @param $uid
     * @param array $updateInfo
     * @return false
     * Created by: Owen
     * Created on: 2020/6/8 11:08
     */
    public function updateUserLevel($uid,$updateInfo = []){
        if(empty($updateInfo)){
            return false;
        }
        $taUpdateInfo = [];
        if(!empty($updateInfo['element'])){
            $total = array_sum(array_column($updateInfo['element'],'level'));
            $updateInfo['element'] = json_encode($updateInfo['element']);
            oo::commonOprRedis('common')->setex(okeys::UserBuildTotal($uid),$total,oo::redisRandomExpire(86400*10));
            self::updateUserLevelTotal($uid,$total);
            $taUpdateInfo["current_building_level"] = $total;
        }
        if(!empty($updateInfo['levelId'])){
            $taUpdateInfo["current_level"] = $updateInfo['levelId'];
        }
        /**
         * ta 公共属性
         */
        if(!empty($taUpdateInfo)){
            oo::commonOprModel('ta')->setCommonEventProperty($uid,'common',$taUpdateInfo);
        }
        $updateInfo['isLanding'] = 1;
        $key = okeys::UserBuildLevel($uid);
        oo::commonOprRedis('common')->hMset($key,$updateInfo);
        oo::commonOprRedis('common')->expire($key,oo::redisRandomExpire(86400));
        return oo::commonOprRedis('common')->zAdd(okeys::Landing("BUILDING", $uid),time(),$uid) !== false;
    }
    /**
     * 更新建筑总等级
     * @param $uid
     * @param $updateInfo
     * @return mixed
     * Created by: Owen
     * Created on: 2019/11/5 12:25
     */
    public function updateLevelTotal($uid,$updateInfo = []){
        if(empty($updateInfo)){
            return false;
        }
        if(isset($updateInfo['total'])){
            oo::commonOprRedis('common')->setex(okeys::UserBuildTotal($uid),$updateInfo['total']['data'],oo::redisRandomExpire(86400*10));
            self::updateUserLevelTotal($uid,$updateInfo['total']['data']);
        }
    }
    /**
     * 更新建筑数据 -- 兼容版本
     * @param $uid
     * @param $level
     * @param $userElement
     * @return mixed
     * Created by: Owen
     * Created on: 2019/8/13 14:59
     * Description:
     */
    public function setUserLevel($uid,$level,$userElement){
        return self::updateUserLevel($uid,[
            'levelId'  => $level,
            'element'  => $userElement,
        ]);
    }

    /** --------------------------打逻辑重构--------------------------- */
    //====================打相关============================
    /**
     * Notes:获取当前默认敌人信息
     * User: owen
     * Time: 2020/3/31 20:05
     * @param $uid
     * @return mixed
     */
    public function getEnemyData($uid){
        $toUid = $this->getEnemyListByType($uid,1);
        if(empty($toUid)||$toUid==false){
            return false;
        }
        $info  = $this->checkBuildDamaged($toUid);
        if($info){
            return [
                'toUid'  => $toUid,
                'levelId'=> $info['levelId'],
                'element'=> $info['element']
            ];
        }else{
            $this->delFromAttackProtectList($toUid);
        }
        return false;
    }

    /**
     * 获取攻击列表
     * @param $uid
     * @param int $first 1=>老虎机，2=>攻击列表
     * @return mixed
     * Created by: Owen
     * Created on: 2020/6/22 16:27
     */
    public function getEnemyListByType($uid,$first=1){
        $cacheKey = okeys::DefaultEnemy($uid);
        $cache    = oo::commonOprRedis('User')->get($cacheKey);
        if(!$cache){
            $firstOne = self::getFriendEnemyList($uid);
            if(!empty($firstOne)){
                $firstOne = $firstOne[0];
                // 攻击好友之后当天不能再被攻击
                if(oo::commonOprModel('friend')->isFriend($uid,$firstOne)){
                    oo::commonOprRedis('User')->sAdd(okeys::TodayFriendAttackLog($uid),$firstOne);
                    oo::commonOprRedis('User')->expire(okeys::TodayFriendAttackLog($uid),oo::todayDeadline());
                }
                self::outputAttackList($firstOne);
            }else{
                $firstOne = self::getFromAttackWaitList($uid);
            }
            $firstOne && oo::commonOprRedis('User')->setex($cacheKey,$firstOne,5*60);
        }else{
            $firstOne = $cache;
        }
        if($first == 1){
            return $firstOne;
        }
        $actionList = [$firstOne];
//        $actionList[] = self::getFromAttackWaitList($uid,$actionList); // 20210104 默认攻击对象减为1个
        $enemy = self::getMyEnemyList($uid);
        foreach ($enemy as $uid){
            if(!in_array($uid,$actionList) && self::isFromAttackWaitList($uid)){
                $actionList[] = $uid;
                if(count($actionList) >= 10){
                    break;
                }
            }
        }
        return $actionList;
    }

    /**
     * Notes:验证list是否满足条件
     * User: wsc
     * Time: 2020/4/1 10:28
     * @param $list
     * @return array 返回满足条件的 [uid1,uid2,uid3...]
     */
    public function verifyIsPass($uid,$type,$list){
        $cfg = oo::cfg('stealattack')['attack'];
        if(!empty($list)&&is_array($list)){
            foreach ($list as $k=>$v){
                if($v==$uid){
                    unset($list[$k]);
                }
                $ttl = oo::commonOprRedis('Userinfo')->ttl(okeys::AttackLock($v));//保护时间
                $auid = oo::commonOprRedis('Userinfo')->get(okeys::beAttactLock($v));
                $levelInfo = $this->getUserLevel_orig($v);
                $res1 = $levelInfo['attackedNum']>=$cfg['maxLimit']?true:false;//次数
                $res2 = $levelInfo['total']>0?false:true;//是否有建筑
                $res3 = !empty($auid)?($auid==$uid?false:true):false;//是否有被锁定
                $res4 = $levelInfo['levelId']<=$cfg['minLv']?true:false;//是否满足等级条件
                if($ttl>0||$res1||$res2||$res3||$res4){//排除被保护的,排除被打大于maxLimit次的
                    unset($list[$k]);
                    if($type==3){
                        $dLKey = okeys::defaultAttactList($uid);
                        oo::commonOprRedis('Userinfo')->hDel($dLKey,$v);
                    }
                }
            }
        }
        return $list;
    }
    /**
     * Notes:获取默认估计列表uidList
     * User: wsc
     * Time: 2020/4/26 12:23
     * @param $uid
     * @return array
     */
//    public function getDefaultAttactList($uid){
//        $cfg = oo::cfg('stealattack')['attack'];
//        $list = [];
//        $inStr ='';
//        $order = '';
//        $enemyList = oo::commonOprRedis('common')->hGetAll(okeys::EnemyID($uid));//历史仇人列表
//        $friends = oo::commonOprModel('friend')->getUserAllFriend($uid);//好友列表
//        $w = " 1=1 ";
//        if(!empty($friends)){
//            $inStr .= implode(',',$friends);
//        }
//        if(!empty($enemyList)){
//            $enemylist = array_keys($enemyList);
//            $inStr .= implode(',',$enemylist);
//        }
//        if(!empty($inStr)){
//            $w .= " AND uid IN ({$inStr}) ";
//            $order .= " FIELD(`uid`,{$inStr}), ";
//        }
//        $w .= " AND levelId>{$cfg['minLv']}";
//        $w .= " AND attackedNum<{$cfg['maxLimit']}";
//        $w .= " AND total>0 ";
//        $w .=" AND total<25";
//        $order .= " total DESC,levelId DESC, logintime DESC ";
//        $tb = otable::userlevel();
//        $sql = "SELECT uid,attackedNum,logintime,total FROM {$tb} WHERE  {$w}  ORDER BY $order LIMIT 50";
//        $data = oo::commonOprDb('userlevel')->getAll($sql,1);
//        $list = array_column($data,'uid');
//
//        $randList =  $this->getRandEnemyListFromDB($uid);//随机用户
//        $ruidList =!empty($randList)?array_column($randList,'uid'):[];
//        $list =  array_unique(array_merge($list,$ruidList));
//        return $list;
//    }
    /**
     * Notes:获取我的仇人满足条件的列表
     * User: wsc
     * Time: 2020/4/1 10:20
     * @param $uid
     * @return array [uid1,uid2,uid3...]
     */
    public function getMyEnemyList($uid){
        return array_keys(array_reverse(oo::commonOprRedis('common')->hGetAll(okeys::EnemyID($uid)),true));
    }
    /**
     * Notes:获取满足条件的好友
     * User: wsc
     * Time: 2020/4/1 10:16
     * @param $uid
     * @param $num
     * @return array [uid1,uid2,uid3...]
     */
    public function getFriendEnemyList($uid , $num = 1){
        $list = [];
        $enemy = self::getMyEnemyList($uid);
        $friends = oo::commonOprModel('friend')->getUserAllFriend($uid);
        $enemyFriends = array_intersect($enemy,$friends);
        $actions= [];
        $todayAttackLog = oo::commonOprRedis('User')->sMembers(okeys::TodayFriendAttackLog($uid));
        foreach ($enemyFriends as $row){
            if(in_array($row,$todayAttackLog)){
                continue;
            }
            $actions[] = $row;
        }
        foreach ($enemy as $row){
            if(in_array($row,$todayAttackLog)){
                continue;
            }
            !in_array($row,$actions) && $actions[] = $row;
        }
        foreach ($friends as $row){
            if(in_array($row,$todayAttackLog)){
                continue;
            }
            !in_array($row,$actions) && $actions[] = $row;
        }
        $i = 0;
        foreach ($actions as $row){
            if(self::isFromAttackWaitList($row)){
                $list[] = $row;
                $i++;
                if($num == $i){
                    break;
                }
            }
        }
        return $list;
    }
    /**
     * Notes:从DB中随机被打玩家缓存
     * User: wsc
     * Time: 2020/3/31 9:53
     * @param $uid
     * @param bool $db
     * @return array [uid1,uid2,uid3...]
     */
//    public function getRandEnemyListFromDB($uid,$db=false){
//        $cfg = oo::cfg('stealattack')['attack'];
//        $list = $cache = [];
//        $eListkey = okeys::EnemyListCache($uid);
//        if(!$db){
//            $cache =   oo::commonOprRedis('common')->hGetAll($eListkey);
//            $list = funs::getArrFromJsonArr($cache);
////            $list = $this->verifyIsPass($list);
//        }
//        if(empty($cache)){
//            $tb = otable::userlevel();
//            $stime =0;
////            if(!IS_DEBUF){//获取近期活跃
////                  $stime = time()-86400*5;
////            }
//            $w = "";
//            $w .= " levelId>{$cfg['minLv']} ";
//            $w .=" AND attackedNum<{$cfg['maxLimit']}";
//            $w .=" AND total>0";
//            $w .= " AND logintime>{$stime} ";
//            $sql = "SELECT uid,attackedNum,logintime,total FROM {$tb} WHERE  {$w}   ORDER BY RAND() LIMIT 50";
//            $ulist = oo::commonOprDb('userlevel')->getAll($sql,MYSQLI_ASSOC);
//            oo::commonOprRedis('common')->delete($eListkey);
//            if(!empty($ulist)){
//                array_multisort(array_column($ulist,'total'),SORT_DESC,$ulist);
//                foreach ($ulist as $k=>$v){
//                    $cache[$v['uid']] = json_encode($v,true);
//                }
//                oo::commonOprRedis('common')->hMset($eListkey,$cache);
//                oo::commonOprRedis('common')->expire($eListkey,600);
//                $list = array_column($ulist,null,'uid');
//            }
//        }
//        !empty($list)?array_multisort(array_column($list,'total'),SORT_DESC,array_column($list,'logintime'),SORT_DESC,$list):$list=[];
//
//        return $list;
//    }
    /**
     * 获取用户岛建筑总值
     * @param $uid
     * @return int
     * Created by: Owen
     * Created on: 2020/6/20 17:49
     */
    public function getUserCurLevelTotal($uid){
        $cacheKey = okeys::UserBuildTotal($uid);
        $total = oo::commonOprRedis('User')->get($cacheKey);
        if($total === false){
            $userLevelData = self::getUserLevel($uid);
            $element = $userLevelData['element'];
            $total   = 0;
            foreach ($element as $row){
                $total += max($row['level'],0);
            }
            oo::commonOprRedis('User')->setex($cacheKey,$total,oo::redisRandomExpire(86400*10));
        }
        return (int)$total;
    }

    /**
     * 更新用户岛建筑总值(20210728-wsc-弃用)
     * @param $uid
     * @param $total
     * Created by: Owen
     * Created on: 2020/6/20 17:48
     */
    public function updateUserLevelTotal($uid,$total){
        return true;
        $total = max(0,$total);
        if($total){
            if(!self::getFromAttackProtectList($uid)){
                self::addToAttackWaitList($uid);
            }
        }else{
            self::delFromAttackWaitList($uid,true);
        }
    }

    /**
     * 获取用户每日被攻击次数
     * @param $uid
     * @return int
     * Created by: Owen
     * Created on: 2020/6/20 16:30
     */
    public function getUserDailyAttackedNum($uid){
        return intval(oo::commonOprRedis('User')->hGet(okeys::UserDailyAttackedNum(),$uid));
    }

    /**
     * 增加用户每日被攻击次数
     * @param $uid
     * @param $num
     * @return int
     * Created by: Owen
     * Created on: 2020/6/20 16:30
     */
    public function addUserDailyAttackedNum($uid,$num = 1){
        return oo::commonOprRedis('User')->hIncrBy(okeys::UserDailyAttackedNum(),$uid,$num);
    }

    /**
     * 获取用户被攻击次数
     * @param $uid
     * @return int
     * Created by: Owen
     * Created on: 2021/2/20 17:26
     */
    public function getUserAttackedNum($uid){
        return intval(oo::commonOprRedis('User')->get(okeys::UserAttackedNum($uid)));
    }

    /**
     * 增加用户被攻击次数
     * @param $uid
     * @param int $num
     * @return bool
     * Created by: Owen
     * Created on: 2021/2/20 17:24
     */
    public function addUserAttackedNum($uid,$num = 1){
        $curNum = oo::commonOprRedis('User')->incrBy(okeys::UserAttackedNum($uid),$num);
        if($curNum == $num){
            oo::commonOprRedis('User')->expire(okeys::UserAttackedNum($uid),720*60);
        }else if($curNum > 5){
            $ttl = oo::commonOprRedis('User')->ttl(okeys::UserAttackedNum($uid));
            if($ttl <= 0){
                oo::commonOprRedis('User')->expire(okeys::UserAttackedNum($uid),720*60);
            }
        }
        return $curNum;
    }

    /**
     * 判断是否在保护期中
     * @param $uid
     * @return int
     * Created by: Owen
     * Created on: 2020/6/20 17:47
     */
    public function getFromAttackProtectList($uid){
        return oo::commonOprRedis('common')->zScore(okeys::AttackProtectList(),$uid);
    }

    /**
     * 加入保护期 -- 超过5次保护到今天结束
     * @param $uid
     * @param $from // 来源 1=>攻击，2=>支付，3=>好友攻击
     * @param $time
     * @return mixed
     * Created by: Owen
     * Created on: 2020/6/20 16:44
     */
    public function addToAttackProtectList($uid,$from,$time = 0){
        $cfg = oo::cfg('stealattack')['attack']['proteCfg'];
        if($from != 1 && $from != 2 && $from != 3){
            return false;
        }
        if($from == 1){
            $curAttackedNum = $this->getUserAttackedNum($uid);
            $limit = $cfg['changeProteTimeLimit']?$cfg['changeProteTimeLimit']:5;
            if($curAttackedNum >= $limit){
                $time = $cfg['changeNotFriendProteTime']?$cfg['changeNotFriendProteTime']:720 * 60;
                oo::commonOprRedis('User')->delete(okeys::UserAttackedNum($uid));
            }else{
                $time = $cfg['notFriendProteTime']?$cfg['notFriendProteTime']:60 * 60;
            }
        }
        $curTime = intval(self::getFromAttackProtectList($uid));
        self::delFromAttackWaitList($uid);
        $userInfo = oo::commonOprModel('member')->getUserInfo($uid);//玩家基本信息
        $longTimes = $cfg['longNoOnlineTime']?$cfg['longNoOnlineTime']:2880 * 60;
        if(time() - $userInfo['lasttime'] > $longTimes){//超过两天不在线
            $time = $cfg['longNoOnlineProteTime']?$cfg['longNoOnlineProteTime']:7*24*60*60;
        }
        $setTime = max($curTime,time() + $time);
        self::addAttackProtectList($uid,$setTime);
        oo::commonOprRedis('common')->setex(okeys::AttackLock($uid),1,$setTime - time());
    }

    /**
     * 加入保护期 -- 超过5次保护到今天结束
     * @param $uid
     * @param $from // 来源 1=>攻击，2=>支付
     * @param $time
     * @return mixed
     * Created by: Owen
     * Created on: 2020/6/20 16:44
     */
//    public function addFromAttackProtectList_backup($uid,$from,$time = 0){
//        if($from != 1 && $from != 2){
//            return false;
//        }
//        if($from == 1){
//            $cfg = oo::cfg('stealattack')['attack'];
//            $curDailyAttackedNum = self::getUserDailyAttackedNum($uid);
//            if($curDailyAttackedNum >= $cfg['maxLimit']){
//                $time = oo::todayDeadline();
//            }else{
//                $cacheKey  = okeys::UserDailyAttackedTime();
//                $totalTime = intval(oo::commonOprRedis('User')->hGet($cacheKey,$uid));
//                $totalTime = min($totalTime,300);
//                if($totalTime >= 300){
//                    $time  = 18000;
//                }else{
//                    $userAssetsInfo   = oo::commonOprModel('member')->getUserAssetsInfo($uid);
//                    if($userAssetsInfo['shield'] > 0){
//                        oo::commonOprRedis('User')->hIncrBy($cacheKey,$uid,3);
//                        $time = min($totalTime + 3,300) * 60;
//                    }else{
//                        $needTime = [1=>5,2=>5,3=>5,4=>10,5=>60];
//                        $total = self::getUserCurLevelTotal($uid);
//                        if($total > 20){
//                            $lv = 1;
//                        }else if($total>=16){
//                            $lv = 2;
//                        }else if($total>=11){
//                            $lv = 3;
//                        }else if($total>=5){
//                            $lv = 4;
//                        }else{
//                            $lv = 5;
//                        }
//                        $needTime = min($totalTime + $needTime[$lv],300);
//                        oo::commonOprRedis('User')->hSet($cacheKey,$uid,$needTime);
//                        $time = $needTime * 60;
//                    }
//                }
//            }
//        }
//        $curTime = intval(self::getFromAttackProtectList($uid));
//        self::delFromAttackWaitList($uid);
//        $setTime = max($curTime,time() + $time);
//        self::addAttackProtectList($uid,$setTime);
//        oo::commonOprRedis('common')->setex(okeys::AttackLock($uid),1,$setTime - time());
//    }

    /**
     * 加入保护队列
     * @param $uid
     * @param $time
     * @return bool
     * Created by: Owen
     * Created on: 2020/9/22 19:38
     */
    public function addAttackProtectList($uid,$time,$max = true){
        if($max){
            $time = max(intval(oo::commonOprRedis('common')->zScore(okeys::AttackProtectList(),$uid)),$time);
        }
        return oo::commonOprRedis('common')->zAdd(okeys::AttackProtectList(),$time,$uid);
    }

    /**
     * 删除保护期中用户
     * @param $uid
     * @return bool
     * Created by: Owen
     * Created on: 2020/6/20 16:07
     */
    public function delFromAttackProtectList($uid){
        return oo::commonOprRedis('User')->zDelete(okeys::AttackProtectList(),$uid);
    }

    /**
     * 是否保护期中用户
     * @param $uid
     * @return bool
     * Created by: Owen
     * Created on: 2020/6/20 16:07
     */
    public function isFromAttackProtectList($uid){
        return oo::commonOprRedis('User')->zScore(okeys::AttackProtectList(),$uid);
    }

    /**
     * 获取随机攻击对象
     * @param $uid
     * @param $noUid
     * @return int
     * Created by: Owen
     * Created on: 2020/6/20 17:47
     */
    public function getFromAttackWaitList($uid,$noUid = []){
        $noUid[] = $uid;
        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $actionLevel    = oo::getActionLevel('attack',$userAssetsInfo['levelId']);
        $curMaxLevel    = oo::commonOprModel('config')->getCurMaxLevel();
        $actionMaxLevel = $actionLevel['max'];
        $trueMax        = min($curMaxLevel,$actionMaxLevel);
        $rand = rand(0,100);
        if($rand < 40){
            $max = $trueMax;
        }else if($rand < 85){
            $max = max(ceil($actionMaxLevel - $userAssetsInfo['levelId']/2),4);
        }else{
            $max = max($userAssetsInfo['levelId'] - 5,4);
        }
        $randUid = self::popFromAttackWaitList($max,$actionLevel['min'],$noUid);
        if($max != $trueMax && !$randUid){
            $randUid = self::popFromAttackWaitList($trueMax,$actionLevel['min'],$noUid);
        }
        return $randUid;
    }

    public function popFromAttackWaitList($max,$min = 3,$noUid = []){
        $fromPro = rand(0,100);
        for($i=$max;$i >= $min;$i--){
            if($fromPro < 90){
                $randUid = self::getFromAttackShieldList($i,$noUid);
                if($randUid && !in_array($randUid,$noUid)){
                    return $randUid;
                }
            }
            $size = oo::commonOprRedis('common')->sSize(okeys::AttackWaitList($i));
            for($s=0;$s<$size;$s++){
                $randUid = oo::commonOprRedis('common')->sPop(okeys::AttackWaitList($i));
                self::outputAttackList($randUid,$i);
                if($randUid && !in_array($randUid,$noUid)){
                    return $randUid;
                }
            }
        }
        return false;
    }

    /**
     * 判断是否在待攻击中
     * @param $uid
     * @return int
     * Created by: Owen
     * Created on: 2020/6/20 17:47
     */
    public function isFromAttackWaitList($uid){
        $cfg = oo::cfg('stealattack')['attack'];
        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        return $userAssetsInfo['levelId'] > $cfg['minLv'] && oo::commonOprRedis('common')->sContains(okeys::AttackWaitList($userAssetsInfo['levelId']),$uid);
    }

    /**
     * 加入待攻击列表
     * @param $uid
     * @return bool
     * Created by: Owen
     * Created on: 2020/6/20 16:16
     */
    public function addToAttackWaitList($uid){
        $total = self::getUserCurLevelTotal($uid);
        if($total > 0){
            if(self::checkBuildDamaged($uid)){
                $cfg = oo::cfg('stealattack')['attack'];
                $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
                return $userAssetsInfo['levelId'] > $cfg['minLv'] && oo::commonOprRedis('User')->sAdd(okeys::AttackWaitList($userAssetsInfo['levelId']),$uid);
            }
        }
        return false;
    }

    /**
     * 删除待攻击列表
     * @param $uid
     * @param $check
     * @return bool
     * Created by: Owen
     * Created on: 2020/6/20 16:08
     */
    public function delFromAttackWaitList($uid,$check = false){
        if($check){
            $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $bool = oo::commonOprRedis('User')->sRemove(okeys::AttackWaitList($userAssetsInfo['levelId']),$uid);
            !$bool && self::checkDelFromAttackWaitList($uid);
            self::delFromAttackShieldList($userAssetsInfo['levelId'],$uid);
        }else{
            $bool = self::outputAttackList($uid);
        }
        return $bool;
    }

    /**
     * 加入攻击锁定状态
     * @param $uid
     * @return  mixed
     * Created by: Owen
     * Created on: 2020/6/30 16:08
     */
    public function addToAttackLockList($uid){
        $ret = oo::commonOprRedis('common')->zAdd(okeys::AttackLockList(),time() + 3*60 ,$uid);
        return $ret !== false ? true : false;
    }

    /**
     * 删除攻击锁定
     * @param $uid
     * @return bool
     * Created by: Owen
     * Created on: 2020/6/30 17:55
     */
    public function delFromAttackLockList($uid){
        return oo::commonOprRedis('User')->zDelete(okeys::AttackLockList(),$uid);
    }

    /**
     * 将结束保护期的用户刷入待攻击列表(20210728-wsc-弃用)
     * Created by: Owen
     * Created on: 2020/6/20 17:13
     */
    public function refreshIntoAttackWaitList(){
        return false;
        $ret = oo::commonOprRedis('common')->zRangeByScore(okeys::AttackProtectList(),0,time(),['withscores'=>true]);
        foreach ($ret as $uid=>$row){
            self::addToAttackWaitList($uid) && self::checkAttackShieldByUid($uid);
            self::delFromAttackProtectList($uid);
        }
    }

    /**
     * 检测建筑
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2020/6/30 21:23
     */
    public function checkElementTotal($uid){
        $list = self::getEnemyListByType($uid,2);
        $trueList = [];
        foreach ($list as $row){
            $userLevelInfo = self::getUserLevel($row);
            $element = (array)$userLevelInfo['element'];
            $total   = 0;
            foreach ($element as $e){
                $total = $total + max($e['level'],0);
            }
            if($total > 0){
                $trueList[] = $row;
            }else{
                self::updateUserLevelTotal($row,0);
            }
        }
        $count = count($trueList);
        //如果仇人列表只有1个且为自己好友时,也添加一个随机对象
        if($count < 1||($count == 1 && oo::commonOprModel('friend')->isFriend($uid, $trueList[0]))){
            $trueList[] = self::getFromAttackWaitList($uid, [$trueList[0]]);
        }
        return $trueList;
    }

    /**
     * 检测出队
     * @param $uid
     * @return bool
     * Created by: Owen
     * Created on: 2020/7/1 15:50
     */
    public function checkDelFromAttackWaitList($uid){
        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $maxWorldLevel  = intval(oo::commonOprModel('readconfig')->getCon('basic','curMaxLevel'))??60;//当前世界最大等级
        $level = min($maxWorldLevel,$userAssetsInfo['levelId'] + 5);
        for ($i=4;$i<$level;$i++){
            $bool = oo::commonOprRedis('User')->sRemove(okeys::AttackWaitList($i),$uid);
            if($bool){
                return true;
            }
        }
        return true;
    }

    /**
     * 从可被攻击盾牌池子获取可被攻击对象
     * @@param $noUid
     * @return mixed
     * Created by: Owen
     * Created on: 2020/8/21 16:33
     */
    public function getFromAttackShieldList($lv,$noUid = []){
        $cacheKey = okeys::AttackShieldList($lv);
        $zSize    = oo::commonOprRedis('User')->zSize($cacheKey);
        for($i=0;$i<$zSize;$i++){
            $ret = oo::commonOprRedis('User')->zRevRange($cacheKey,$i,$i,true);
            $randUid = array_keys($ret)[0];
            if(!in_array($randUid,$noUid)){
                self::outputAttackList($randUid,$lv);
                return $randUid;
            }
        }
        return false;
    }

    /**
     * 攻击出队
     * @param $uid
     * @param $lv
     * @return bool
     * Created by: Owen
     * Created on: 2020/9/27 16:31
     */
    public function outputAttackList($uid,$lv = 0){
        if($lv == 0){
            $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $lv = $userAssetsInfo['levelId'];
        }
        oo::commonOprRedis('User')->zDelete(okeys::AttackShieldList($lv),$uid);
        oo::commonOprRedis('User')->sRemove(okeys::AttackWaitList($lv),$uid);
        return self::addAttackProtectList($uid,time() + 15);
    }

    /**
     * 监测用户盾牌攻击池子
     * @param $uid
     * @param $checkInProtectPool
     * @return mixed
     * Created by: Owen
     * Created on: 2020/8/21 16:48
     */
    public function checkAttackShieldByUid($uid,$checkInProtectPool = false){
        if($checkInProtectPool){
            if(self::isFromAttackProtectList($uid)){
                return false;
            }
        }
        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        if($userAssetsInfo['levelId'] > 3){
            if($userAssetsInfo['shield'] > 0){
                $total  = self::getUserCurLevelTotal($uid);
                $total && self::addAttackShieldList($userAssetsInfo['levelId'],$uid,$userAssetsInfo['shield']);
            }else{
                self::delFromAttackShieldList($userAssetsInfo['levelId'],$uid);
            }
        }
    }

    /**
     * 加入可被攻击盾牌池子
     * @param $lv
     * @param $uid
     * @param $num
     * Created by: Owen
     * Created on: 2020/8/21 16:39
     */
    public function addAttackShieldList($lv,$uid,$num){
        $cacheKey = okeys::AttackShieldList($lv);
        oo::commonOprRedis('User')->zAdd($cacheKey,$num,$uid);
    }

    /**
     * 移出可被攻击盾牌池子
     * @param $lv
     * @param $uid
     * @return bool
     * Created by: Owen
     * Created on: 2020/8/21 16:38
     */
    public function delFromAttackShieldList($lv,$uid){
        $cacheKey = okeys::AttackShieldList($lv);
        $bool     = oo::commonOprRedis('User')->zDelete($cacheKey,$uid);
        if(!$bool){
            for($i=$lv;$i>=4;$i--){
                $tBool = oo::commonOprRedis('User')->zDelete($cacheKey,$uid);
                if($tBool){
                    return true;
                }
            }
        }
        return $bool;
    }

    /**
     * 建筑检测--1级破损不进行攻击
     * @param $uid
     * @return bool
     * Created by: Owen
     * Created on: 2020/9/21 15:04
     */
    public function checkBuildDamaged($uid){
        $userLevelData = self::getUserLevel($uid);
        $levelId  = $userLevelData['levelId'];
        $maxLevel = intval(oo::commonOprModel('readconfig')->getCon('basic',"curMaxLevel"));
        $element = $userLevelData['element'];
        if($levelId == $maxLevel){
            if(array_sum(array_column($element,'level')) == 25){
                return false;
            }
        }
        if(empty($element)){ //没有岛,不进行攻击
            oo::logs()->debug3(['uid' => $uid, 'userLevelData' => $userLevelData],'checkbuilddmg_err');//写日志
            return false;
        }
        foreach ($element as $row){
            if($row['level'] > 1 || ($row['level'] == 1 && $row['status'] == 0)){
                return $userLevelData;
            }
        }
        return false;
    }

    /**
     * 若玩家被打后，已经超过2880分钟不在线，会拥有永久被打保护时间，玩家上线后，永久被打保护时间会变为30分钟被打保护时间
     * @param $uid
     * Created by: Owen
     * Created on: 2021/2/20 18:35
     */
    public function reLoginAddIntoProtectList($uid){
        $protectTime = intval($this->getFromAttackProtectList($uid));
        if($protectTime - time() > 24 * 60 * 60){
            if($this->checkBuildDamaged($uid)){
                $this->addAttackProtectList($uid,time() + 30 * 60,false);
            }
        }
    }
    /** --------------------------打逻辑重构--------------------------- */

    /**
     * 获取用户动态数据
     * @param $uid
     * @return array|false|mixed
     * Created by: Owen
     * Created on: 2020/7/23 14:37
     */
    public function getUserDynamicsData($uid){
        $cacheKey = okeys::UserDynamicsData($uid);
        $cache    = oo::commonOprRedis('User')->get($cacheKey);
        if(empty($cache)){
            $tb   = otable::UserDynamicsData();
            $cache= oo::commonOprDb('userinfo')->getOne("SELECT * FROM {$tb} WHERE uid={$uid} LIMIT 1",MYSQLI_ASSOC);
            if(!empty($cache['userCache'])){
                $cache['userCache'] = (array)json_decode($cache['userCache'], true);
            }
            if(empty($cache)){ //创建一条表记录
//                oo::commonOprDb('userinfo')->query("INSERT INTO {$tb} (`uid`,`userCache`) VALUES ({$uid},'[]')");
                $cache = oo::commonOprDb('userinfo')->getOne("SELECT * FROM {$tb} WHERE uid={$uid} LIMIT 1",MYSQLI_ASSOC);
            }
            //有无数据都要写入缓存
            oo::commonOprRedis('User')->setex($cacheKey,json_encode($cache),oo::redisRandomExpire(7*24*60*60));
        }else{
            $cache = json_decode($cache,true);
            if(empty($cache['userCache'])){
                $cache['userCache'] = [];
            }
            if(!is_array($cache['userCache'])){
                $cache['userCache'] = (array)json_decode($cache['userCache'], true);
            }
        }
        return $cache;
    }

    /**
     * 更新用户动态数据
     * @param $uid
     * @param $updateInfo
     * @return mixed
     * Created by: Owen
     * Created on: 2020/7/23 14:38
     */
    public function updateUserDynamicsData($uid,$updateInfo){
        if(empty($updateInfo)){
            return false;
        }
        $userDynamicsData = self::getUserDynamicsData($uid);
        foreach ($updateInfo as $key=>$row){
            $userDynamicsData[$key] = $row;
        }
        return self::setUserDynamicsData($uid,$userDynamicsData);
    }

    /**
     * 追加用户动态数据
     * @param $uid
     * @param $updateInfo
     * @return bool
     * Created by: Owen
     * Created on: 2020/7/23 14:43
     */
    public function addUserDynamicsData($uid,$updateInfo){
        if(empty($updateInfo)){
            return false;
        }
        $userDynamicsData = self::getUserDynamicsData($uid);
        foreach ($updateInfo as $key=>$row){
            $userDynamicsData[$key] += $row;
        }
        return self::setUserDynamicsData($uid,$userDynamicsData);
    }

    /**
     * 设定用户动态数据
     * @param $uid
     * @param $dynamicsData
     * @return bool
     * Created by: Owen
     * Created on: 2020/7/23 14:54
     */
    public function setUserDynamicsData($uid,$dynamicsData){
        $dynamicsData['isLanding'] = 1;
        $cacheKey = okeys::UserDynamicsData($uid);
        if(isset($dynamicsData['userCache']) && !is_array($dynamicsData['userCache'])){
            $dynamicsData['userCache'] = (array)json_decode($dynamicsData['userCache'], true);
        }
        oo::commonOprRedis('User')->setex($cacheKey,json_encode($dynamicsData, 32),oo::redisRandomExpire(7*24*60*60));
//        $ret = oo::commonOprRedis('Usercache')->zAdd(okeys::Landing("DYNAMICS", $uid),time(),$uid);
//        if($ret !== false){
//            return true;
//        }
        return false;
    }
    /**
     * 领取短链奖励
     * @param $uid
     * @param $id
     * @return string
     * Created by: Owen
     * Created on: 2020/8/5 11:32
     */
    public function getShareLinkReward($uid,$id){
        $config = oo::commonOprModel('config')->getShareLinkConfig($id);
        if(isset($config['expireTime']) && $config['expireTime'] < time()){
            return oo::response(errorCode::SHARELINK_TIME_EXPIRED,[],'奖励已过期');
        }
        if(isset($config['userLimit']) && !empty($config['userLimit']) && strpos($config['userLimit'],"{$uid}") === false){
            return oo::response(errorCode::SHARELINK_USER_LIMIT,[],'不在指定用户里');
        }

        if(in_array($config['action'],[1,4])){
            if(oo::commonOprRedis('User')->hGet(okeys::ShareLinkReward($id),$uid)){
                return oo::response(-2,[],'奖励已领取');
            }
        }
        $curNum = oo::commonOprRedis('User')->hLen(okeys::ShareLinkReward($id));
        if($curNum >= $config['num']){
            return oo::response(-3,[],'奖励已超量');
        }
        if($config['action'] == 1){
            $reward = $config['data'];
            foreach ($reward['props'] as $row){
                if($row['propsId'] == 14) {
                    $row['num'] = oo::commonOprModel('goods')->getGoodCoins($uid, oo::commonOprModel('config')->gidToCoins($row['gid'])) * $row['bet'];
                }
                self::sendReward($uid,$row['propsId'],$row['num'],4001,"点击链接:{$id}");
            }
            oo::commonOprRedis('User')->hSet(okeys::ShareLinkReward($id),$uid,1);
            //oo::commonOprRedis('User')->expire(okeys::ShareLinkReward($id),86400*3);
            return oo::response(1,$reward['props']);
        }else if($config['action'] == 4){
            if($config['data']['activityId'] == 102){
                $this->sendReward($uid,27,intval($config['data']['time']),4001,'链接发放');
            }else if($config['data']['activityId'] == 103){
                $this->sendReward($uid,25,intval($config['data']['time']),4001,'链接发放');
            }
            oo::commonOprRedis('User')->hSet(okeys::ShareLinkReward($id),$uid,1);
        }

        return oo::response(1);
    }

    /**
     * 获取用户firstName
     * @param $nick
     * @return mixed
     * Created by: Owen
     * Created on: 2020/8/17 19:55
     */
    public function getUserFirstName($nick){
        $nick = explode(' ',$nick);
        return $nick[0];
    }



    /**
     * 获取上限限配置
     * @param $levelId
     * @param $from
     * @return int|mixed
     * Created by: Owen
     * Created on: 2020/8/20 18:43
     */
    public function getLevelUpLimit($levelId,$from){
        $config = oo::commonOprModel('config')->getUpLimitConfig($from);
        $minNum = 0;
        foreach ($config as $c){
            if($levelId <= $c['levelId']){
                return $c['upLimit'];
            }else{
                $minNum = $c['upLimit'];
            }
        }
        return $minNum;
    }

    /**
     * 获取用户最大值
     * @param $uid
     * @param $from
     * @return mixed
     * Created by: Owen
     * Created on: 2020/8/21 10:39
     */
    public function getUserLevelUpLimit($uid,$from){
        $userAssetsInfo = self::getUserAssetsInfo($uid);
        $levelId        = $userAssetsInfo['levelId'];
        if($from == 'shield'){
            $levelMaxShield = self::getLevelUpLimit($levelId,$from);
            $vipShield = 3;
            if(oo::commonOprModel('newvip')->checkNewVip($uid)) {
                $config    = oo::commonOprModel('newvip')->getUserVipLv($uid,true,false,155);
                $vipShield += intval($config['shieldGroove']);
            }
            return max($vipShield,$levelMaxShield,3);
        }else if($from == 'recovery'){
            $levelSpins = self::getLevelUpLimit($levelId,'recovery'); // 恢复多少
            $checkVip = oo::commonOprModel('newvip')->checkNewVip($uid);
            $setSpins = oo::commonOprModel('readconfig')->getCon('basic','restoreSpins');; // 恢复多少
            if($checkVip){
                $config = oo::commonOprModel('newvip')->getUserVipLv($uid,true,false,155);
                $setSpins += intval($config['spinsRestore']);
            }
            return max($levelSpins,$setSpins,5);
        }
    }

    /**
     * 用户推送开关
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2020/8/28 19:43
     */
    public function getUserSettingLock($uid){
        $userDynamicsData = self::getUserDynamicsData($uid);
        return explode(',',$userDynamicsData['pushLock']);
    }

    /**
     * 发送下一次攻击对象等级
     * @param $uid
     * Created by: Owen
     * Created on: 2020/9/12 18:56
     */
    public function sendNextAttackObject($uid){
        $toUid = self::getEnemyListByType($uid,1);
        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($toUid);
        oo::commonOprModel('Workerman')->push($uid,ocmd::$send['Slot_AttackObject'],['levelId'=>$userAssetsInfo['levelId']]);
    }

    /**
     * 是否是推金币进来的用户
     * @param $uid
     * @return false|int
     * Created by: Owen
     * Created on: 2020/11/25 14:50
     */
    public function isPushCoinsUser($uid){
        return 0;
        $cacheKey = okeys::isPushCoinsUser($uid);
        $cache    = oo::commonOprRedis('User')->get($cacheKey);
        if($cache === false){
            $isPush = 0;
            $tb  = otable::AdJustSta($uid);
            $ret = oo::commonOprDb('common')->getOne("SELECT * FROM {$tb} WHERE uid={$uid} LIMIT 1",MYSQLI_ASSOC);
            $tb  = otable::AdJustData();
            if(!empty($ret['android']) || !empty($ret['ios'])) {
                $agps = trim($ret['android'], '"');
                if(!empty($agps)){$where = "gps_adid='{$agps}'";}
                $igps = trim($ret['ios'], '"');
                if(!empty($igps)){$where = "idfa='{$igps}'";}
                $ret = oo::commonOprDb('common')->getOne("SELECT * FROM {$tb} WHERE {$where} LIMIT 1", MYSQLI_ASSOC);
                if(!empty($ret) && strpos($ret['campaign_name'],'PUSH') !== false){
                    $isPush = 1;
                }
            }
            oo::commonOprRedis('User')->setex($cacheKey,$isPush,oo::redisRandomExpire(3*24*60*60));
        }else{
            $isPush = $cache;
        }
        return intval($isPush);
    }

    /**
     * 获取adjust渠道名称(google, facebook, ironsource, ironsource)
     * @param string $network
     * @return string
     */
    public function getAdjustChannel($network = '') {
        if(strpos($network, 'Facebook') !== false) {
            return "facebook";
        }
        if(strpos($network, 'Google') !== false) {
            return "google";
        }
        if(strpos($network, 'unity') !== false) {
            return "unity";
        }
        if(strpos($network, 'ironSource') !== false) {
            return "ironsource";
        }
        return "";
    }

    /**
     * 获取adjust(creative_name,adgroup_name,campaign_name)等对应的id
     */
    public function getAdjustId($name = '') {
        if(substr($name, -1) != ')' || strpos($name, '(') == false){
            return '';
        }
        return substr($name, (int)strrpos($name, '(')+1, -2);
    }

    /**
     * 检测adjust 邀请
     * @param $uid
     * @return bool
     * Created by: Owen
     * Created on: 2021/3/11 18:31
     */
    public function actionAdjustInvite($uid){
        $cacheKey = okeys::AdjustInviteStatus($uid);
        $status   = oo::commonOprRedis('User')->get($cacheKey);
        if($status){
            $deviceID = $this->getAdjustDeviceIDByUid($uid);
            if(!empty($deviceID)){
                $ret    = $this->getDataFromAdjust($deviceID);
                $taData = [];
                if(!empty($ret)){
                    if(strpos($ret['campaign_name'],'UAC2.0') !== false){
                        $group = 'UAC2.0';
                    }else if(strpos($ret['campaign_name'],'UAC2.5') !== false){
                        $group = 'UAC2.5';
                    }else if(strpos($ret['campaign_name'],'AEO') !== false){
                        $group = 'AEO';
                    }else if(strpos($ret['campaign_name'],'VO') !== false){
                        $group = 'VO';
                    }else if(strpos($ret['campaign_name'],'Recall') !== false){
                        $group = 'Recall';
                    }
                    $taData = [
                        //Google
                        "network_name"  => $ret['network_name'],
                        "campaign_name" => $ret['campaign_name'],
                        "adgroup_name"  => $ret['adgroup_name'],
                        "creative_name" => $ret['creative_name'],
                        "network_id"    => $this->getAdjustChannel($ret['network_name']),
                        "campaign_id"   => $this->getAdjustId($ret['campaign_name']),
                        "adgroup_id"    => $this->getAdjustId($ret['adgroup_name']),
                        "creative_id"   => $this->getAdjustId($ret['creative_name']),
                    ];
                    !empty($group) && $taData["user_source"] = 2;
                }
                $labelUid = intval(base64_decode($ret['label']));
                if($labelUid > 0 || (IS_DEBUF && $labelUid != 0)){
                    oo::commonOprModel('invite')->inviteSuccess(abs($labelUid),$uid,3);
                    $this->updateInviteeAdjustData($deviceID,$ret);
                    $taData["user_source"] = 1;
                }
                !empty($taData) && oo::commonOprModel('ta')->setEventData($uid,'user_set',$taData);
                oo::commonOprRedis('User')->delete($cacheKey);
                return $labelUid;
            }
            $newStatus = $status - 1;
            if($newStatus > 0){
                oo::commonOprRedis('User')->setex($cacheKey,$newStatus,3*24*60*60);
            }else{
                oo::commonOprRedis('User')->delete($cacheKey);
            }
        }
    }

    /**
     * 检测adjust离开7天以上(再归因深链)或客户端上报玩家邀请
     * @param int $uid
     * @param int $fid
     */
    public function actionCallbackAdjustInvite($uid, $fid = 0){
        $cacheKey = okeys::AdjustBackInviteStatus($uid);
        $status   = oo::commonOprRedis('User')->get($cacheKey);
        if(empty($status)){
            return false;
        }
        if(!empty($fid)){ //客户端直接上报
            if($uid == $fid){
                return false;
            }
            $info = oo::commonOprModel('member')->getUserInfo($fid);
            if(empty($info)){
                return false;
            }
            oo::commonOprModel('invite')->inviteSuccess(abs($fid),$uid,3);
            oo::commonOprRedis('User')->delete($cacheKey);
            return true;
        }
        $deviceID = $this->getAdjustDeviceIDByUid($uid);
        if(!empty($deviceID)){
            $ret = $this->adjustDataFromCallbacks($deviceID);
            $labelUid = intval(base64_decode($ret['label']));
            if($labelUid > 0 || (IS_DEBUF && $labelUid != 0)){
                oo::commonOprModel('invite')->inviteSuccess(abs($labelUid),$uid,3);
                $this->updateInviteAdjustCalback($deviceID,$ret);
            }
            oo::commonOprRedis('User')->delete($cacheKey);
            return $labelUid;
        }
        $newStatus = $status - 1;
        if($newStatus > 0){
            oo::commonOprRedis('User')->setex($cacheKey,$newStatus,3*24*60*60);
        }else{
            oo::commonOprRedis('User')->delete($cacheKey);
        }
        return false;
    }

    /**
     * 更新邀请label
     * @param $deviceID
     * @param $ret
     * Created by: Owen
     * Created on: 2021/3/25 16:18
     */
    public function updateInviteeAdjustData($deviceID,$ret){
        $labelUid = intval(base64_decode($ret['label']));
        $labelUid = -abs($labelUid);
        $newLabel = base64_encode($labelUid);
        $tb  = otable::AdJustData();
        oo::commonOprDb('common')->query("UPDATE {$tb} SET label='{$newLabel}' WHERE created_at='{$ret['created_at']}' AND (gps_adid='{$deviceID}' OR idfa='{$deviceID}') ORDER BY created_at LIMIT 1");
        oo::commonOprRedis('User')->delete(okeys::AdjustData($deviceID));
    }

    /**
     * 更新7天回归邀请label(再归因深链)
     * @param $deviceID
     * @param $ret
     * Created by: Owen
     * Created on: 2021/3/25 16:18
     */
    public function updateInviteAdjustCalback($deviceID,$ret){
        $labelUid = intval(base64_decode($ret['label']));
        $labelUid = -abs($labelUid);
        $newLabel = base64_encode($labelUid);
        $tb  = otable::AdjustBackData();
        oo::commonOprDb('common')->query("UPDATE {$tb} SET label='{$newLabel}' WHERE created_at='{$ret['created_at']}' AND (gps_adid='{$deviceID}' OR idfa='{$deviceID}') ORDER BY created_at LIMIT 1");
        oo::commonOprRedis('User')->delete(okeys::AdjustBackData($deviceID));
    }

    /**
     * adjust 数据
     * @param $deviceID
     * @return array|mixed
     * Created by: Owen
     * Created on: 2021/3/11 18:12
     */
    public function getDataFromAdjust($deviceID){
        $cacheKey = okeys::AdjustData($deviceID);
        $cache    = oo::commonOprRedis('User')->get($cacheKey);
        if(empty($cache)){
            $tb  = otable::AdJustData();
            $data = oo::commonOprDb('common')->getOne("SELECT * FROM {$tb} WHERE gps_adid='{$deviceID}' OR idfa='{$deviceID}' ORDER BY created_at LIMIT 1", MYSQLI_ASSOC);
            oo::commonOprRedis('User')->setex($cacheKey,json_encode($data),oo::redisRandomExpire(3*24*60*60));
        }else{
            $data = json_decode($cache,true);
        }
        return $data;
    }

    /**
     * adjust7天回归数据
     * @param string $deviceID
     * @return array
     */
    public function adjustDataFromCallbacks($deviceID) {
        $cacheKey = okeys::AdjustBackData($deviceID);
        $cache    = oo::commonOprRedis('User')->get($cacheKey);
        if(empty($cache)){
            $tb  = otable::AdjustBackData();
            $data = oo::commonOprDb('common')->getOne("SELECT * FROM {$tb} WHERE gps_adid='{$deviceID}' OR idfa='{$deviceID}' ORDER BY created_at LIMIT 1", MYSQLI_ASSOC);
            oo::commonOprRedis('User')->setex($cacheKey,json_encode($data),oo::redisRandomExpire(3*24*60*60));
        }else{
            $data = json_decode($cache,true);
        }
        return $data;
    }

    /**
     * adjust 设备ID
     * @param $uid
     * @return false|string
     * Created by: Owen
     * Created on: 2021/3/11 18:07
     */
    public function getAdjustDeviceIDByUid($uid){
        $cacheKey = okeys::AdjustDeviceID($uid);
        $cache    = oo::commonOprRedis('User')->get($cacheKey);
        if(empty($cache)){
            $tb   = otable::AdJustSta($uid);
            $ret  = oo::commonOprDb('common')->getOne("SELECT * FROM {$tb} WHERE uid={$uid} LIMIT 1",MYSQLI_ASSOC);
            if(!empty($ret)){
                $actionID = "";
                $agps = trim($ret['android'], '"');
                if(!empty($agps)){
                    $actionID = $agps;
                }
                $igps = trim($ret['ios'], '"');
                if(!empty($igps)){
                    $actionID = $igps;
                }
                oo::commonOprRedis('User')->setex($cacheKey,$actionID,oo::redisRandomExpire(24*60*60));
                return $actionID;
            }
            $actionID = 0;
        }else{
            $actionID = $cache;
        }
        return $actionID;
    }

    /**
     * 奖励列表
     * @param $uid
     * @param string $from
     * @return array
     * Created by: Owen
     * Created on: 2020/12/2 19:24
     */
    public function getUserGiftList($uid,$from = ''){
        $tb = otable::UserGiftList();
        $expire = time();
        $where  = "WHERE uid={$uid} AND expired_at>='{$expire}' AND rewarded_at=0";
        if($from){
            $where .= " AND from={$from}";
        }
        $ret = oo::commonOprDb('userinfo')->getAll("SELECT * FROM {$tb} {$where}",MYSQLI_ASSOC);
        $output = [];
        foreach ($ret as $row) {
            $reward = json_decode($row['reward'],true);
            foreach ($reward['props'] as &$p){
                $pConf = oo::commonOprModel('props')->getChestData($uid,$p['propsId']);
                if($pConf){
                    $p['value'] = $pConf;
                }
            }
            $output[] = [
                'id'    => $row['id'],
                'uid'   => $row['uid'],
                'from'  => $row['from'],
                'reward'=> $reward
            ];
        }
        return $output;
    }

    /**
     * 领取奖励
     * @param $uid
     * @param $id
     * @return string
     * Created by: Owen
     * Created on: 2020/12/2 19:40
     */
    public function rewardUserGift($uid,$id){
        $tb = otable::UserGiftList();
        $ret = oo::commonOprDb('userinfo')->getOne("SELECT * FROM {$tb} WHERE id={$id}",MYSQLI_ASSOC);
        if(empty($ret)){
            return oo::response(errorCode::GIFT_EMPTY_ERROR);
        }
        if($ret['uid'] != $uid){
            return oo::response(errorCode::GIFT_UID_ERROR);
        }
        if($ret['rewarded_at']){
            return oo::response(errorCode::GIFT_REWARD_ERROR);
        }
        $reward = json_decode($ret['reward'],true);
        $reward = $reward['props'];
        foreach ($reward as $k=>&$row){
            $this->sendReward($uid,$row['propsId'],$row['num'],452,"用户礼包:".$id,[],$row);
        }
        $time = time();
        oo::commonOprDb('userinfo')->query("UPDATE {$tb} SET `rewarded_at`='{$time}' WHERE id={$id} LIMIT 1");
        return oo::response(errorCode::SUCCESS,$reward);
    }

    /**
     * 用户注册版本
     * @param $uid
     * @return false
     * Created by: Owen
     * Created on: 2021/2/25 17:40
     */
    public function getUserRegVersion($uid){
        $cacheKey = okeys::UserRegVersion($uid);
        $cache    = oo::commonOprRedis('User')->get($cacheKey);
        if($cache){
           return $cache;
        }
        $tb  = otable::versionGitfLog($uid);
        $ret = oo::commonOprDb('common')->getOne("SELECT * FROM {$tb} WHERE uid ='{$uid}' ORDER BY id LIMIT 1",MYSQLI_ASSOC);
        $version = $ret['version'] ?? "1.8.0";
        oo::commonOprRedis('User')->setex($cacheKey,$version,7*24*60*60);
        return $version;
    }

    /**
     * 获取玩家语言
     * @param int $uid
     * @return string
     */
    public function getUserLang($uid) {
        $lang = oo::getDefinedLang($uid);
        if(!empty($lang)){
            return strtoupper($lang);
        }
        $tb  = otable::xg_push($uid);
        $sql = "SELECT lang FROM {$tb} WHERE uid = {$uid}";
        $info = oo::commonOprDb('common')->getOne($sql, 1);
        $lang = empty($info['lang']) ? 'EN' : $info['lang'];
        return strtoupper($lang);
    }
    /**
     * Notes:注册分群 数数
     * User: hss
     * Time: 2021/09/16 10:55
     * @param $uid
     * @return boolean
     */
    public function regSSgroup($uid = 0){
        if(empty($uid)){
            return false;
        }
        //190 lastnumber1 id尾号为1
        //191 lastnumber0 id尾号为0
        //192 lastnumber89 id尾号8&9
        //193 lastnumber67 id尾号6&7
        //194 lastnumber45 id尾号4&5
        //195 lastnumber23 id尾号2&3
        //196 lastnumber01 id尾号0&1
        $end = $uid % 10;
        $groupId = [];
        switch ($end){
            case 0:
                $groupId = [191,196];
                break;
            case 1:
                $groupId = [190,196];
                break;
            case 2:
            case 3:
                $groupId = [195];
                break;
            case 4:
            case 5:
                $groupId = [194];
                break;
            case 6:
            case 7:
                $groupId = [193];
                break;
            case 8:
            case 9:
                $groupId = [192];
                break;
        }
        if($groupId){
            $groupStr = implode(",",$groupId);
            return oo::commonOprModel('member')->updateUserDynamicsData($uid,["groupId3"=>$groupStr]);
        }
    }
}
