<?php
require_once __DIR__ . '/../vendor/autoload.php';
/**
 *	用户等级
 */
class ModelLevel{

    /**
     * 返回玩家岛元素信息
     */
    public function getLandData($uid){
        if( empty($uid) ){
            $data = array('code' => -1, 'desc' => '参数错误');
            return $data;
        }
        $data = oo::commonOprModel('member')->getUserBasic($uid);
        $dataInfo = oo::commonOprModel('member')->getUserLevel($uid);
        $data['element'] = $dataInfo['element'];
        $data['canUpLevel'] =true;
        foreach ($dataInfo['element'] as $v){
            if($v["level"]!=5||$v["status"]==1){
                $data['canUpLevel']=false;
                break;
            }
        }
//        if(oo::commonOprModel('config')->getCurMaxLevel()==$dataInfo["levelId"]){
//            $data['canUpLevel']=false;
//        }
        return $data;
    }

    public function getLandDatas($uid){

        if( empty($uid) ){
            $data = array('code' => -1, 'desc' => '参数错误');
            return $data;
        }

        $dataInfo = oo::commonOprModel('member')->getUserLevel($uid);
        $dataInfo['test'] = $uid;
        $info_user = oo::commonOprModel('member')->getUserInfo($uid);
        //获取用户资产信息
        $MyUserInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $dataInfo['nick'] = $info_user['nick'];
      	$dataInfo['vip'] = $info_user['vip'];
      	$dataInfo['vipLv'] = $info_user['vipLv'];
      	$dataInfo['vipExpire'] = $info_user['vip_expire'];
      	$dataInfo['avatar'] = intval($info_user['avatar']);
        $dataInfo['uid'] = (int)$info_user['uid'];
        $dataInfo['sex'] = $info_user['sex'];
        $dataInfo['signature'] = $info_user['signature'];
        $dataInfo['u_flag'] = $info_user['u_flag'];
        $dataInfo['s_picture'] = $info_user['s_picture'];
        $dataInfo['coins'] = (int)$MyUserInfo['money'];

        return $dataInfo;
    }

    /**
     * 攻击岛
     * @param $uid  用户id $sid 被攻击的用户 $attId 攻击的建筑id  $bet 倍数 默认为1
     * @param $toUid
     * @param $attId
     * @param int $bet
     * @return array 0攻击失败 被盾牌挡了 1攻击成功-打回原形 2 攻击成功-摧毁状态
     * Created by: Owen
     * Created on: 2020/5/16 16:59
     */
    public function AttackOperation($uid,$toUid,$attId,$bet = 1){
        if( empty($uid)   || empty($toUid) || empty($attId) || $uid == $toUid){
            $data = array('code' => -1, 'desc' => '参数错误');
            return $data;
        }
        $bet = oo::commonOprRedis('usercache')->get(okeys::curUserBet($uid))??1;
        $toUid2 =oo::commonOprRedis('common')->get(okeys::slotLock($uid));
        oo::commonOprRedis('common')->delete(okeys::slotLock($uid));
        //获取用户资产信息
        $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($toUid);
        //获取用户资产信息
        $MyUserInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        //获取当前用户的金币
        $userCoin = intval($MyUserInfo['money']);
        //获取被攻击的岛的数据 在判断一下
        $dataInfo = oo::commonOprModel('member')->getUserLevel($toUid);
        //格式化建筑数据
        $userElement = $dataInfo['element'];
        $MyUserLevel = intval($MyUserInfo['levelId']);
        //岛必须要有建筑 也就是说建筑等级必须大于1
        $total_level = 0;
        //获取当前建筑信息
        $LevelInfo = &$userElement[$attId-1];
        if($toUid2!=$toUid){
            oo::logs()->debug3(["ts"=>date('Y-m-d H:i:s'),"uid"=>$uid,"toUid"=>$toUid,"lockUid"=>$toUid2],'attackerr.log');
        }
        if(intval(oo::commonOprRedis('usercache')->get(okeys::slotTypeLimit(4,$uid)))<=0){
            oo::logs()->debug3(["ts"=>date('Y-m-d H:i:s'),"uid"=>$uid,"toUid"=>$toUid,"lockUid"=>$toUid2,"err"=>"没有转直接打"],'attackerr.log');
            return ['code' => -1, 'msg' => 'Please stop doing it wrong','data'=>[]];
        }
        oo::commonOprRedis('usercache')->set(okeys::slotTypeLimit(4,$uid),0);

        if(empty($LevelInfo)){
            return ['code' => -1, 'msg' => '參數錯誤','data'=>[]];
        }

        foreach ($userElement as $k=>$v){
            $total_level += intval($v['level']);
        }

        $dataAbnormal = false;

        if($LevelInfo['level'] <= 0 || $total_level <= 0 ){//建筑数不足
            $dataAbnormal = true;
        }
        $lockUid = oo::commonOprRedis('common')->get(okeys::beAttactLock($toUid));
        if($lockUid!=$uid){//临界状态突破了锁,或变更打对象
            $dataAbnormal = true;
        }

        oo::commonOprRedis('common')->delete(okeys::beAttactLock($toUid));//删除锁
        /**
         * 删除默认攻击对象
         */
        $eUid = oo::commonOprRedis('User')->get(okeys::DefaultEnemy($uid));
        oo::commonOprRedis('User')->delete(okeys::DefaultEnemy($uid));


        $dLKey = okeys::defaultAttactList($uid);
        $dlist = array_flip(oo::commonOprRedis('Userinfo')->hGetAll($dLKey));
        $oldtToUid = array_shift($dlist);//系统默认推送的玩家
        if($oldtToUid!=$toUid){//选中了非系统推送的玩家时
            oo::commonOprRedis('common')->hDel($dLKey,$oldtToUid);
        }
        oo::commonOprRedis('common')->hDel($dLKey,$toUid);//默认攻击列表去除选出的元素

        $eListkey = okeys::EnemyListCache($uid);
        if(!empty(oo::commonOprRedis('common')->hGet($eListkey,$toUid))){
            oo::commonOprRedis('common')->hDel($eListkey,$toUid);//随机列表中清除选出元素
        }

        if(!$dataAbnormal){
            $lockFlag = oo::commonOprRedis('common')->get(okeys::AttackLock($toUid));//保护时间内
            if(intval($lockFlag)){
                $dataAbnormal = true;
            }
        }

        if(!$dataAbnormal){
            $maxLevelInfo = self::getMaxLevelStatus($toUid);//最大等级保护
            if($maxLevelInfo['isReward'] != -1){
                $dataAbnormal = true;
            }
        }

        $version = oo::commonOprModel('user')->getUserVersion($uid);
        $userPetSkill   = false;
        $toUserPetSkill = false;
        $actionBet = funs::bet($bet);

        $attackAwardCfg = oo::commonOprModel("config")->getAttackCoinConfig($MyUserInfo['levelId']);
        $dd =0;

        //打金币结算调整:(1+会员加成+打宠物加成)*bet倍数*(金币大爆炸加成+1)*金币打基础值
        //公式转换成下面几项累加:
        //bet倍数*金币打基础值+
        //vip会员加成*bet倍数*金币打基础值+
        //打宠物加成*bet倍数*金币打基础值+
        //金币大爆炸加成:(1+会员加成+打宠物加成)*bet倍数*金币大爆炸加成*金币打基础值

        //宠物加成倍率
        $petAddRate = oo::commonOprModel('pet')->usePetSkill($uid,3,1); //按照1倍倍率参数带入
        //vip加成倍率 
        $vipRate = oo::commonOprModel('newvip')->vipRewardConf($uid,'attackCoinsPro');
        //金币大爆炸加成倍率
        $blastRate = oo::commonOprModel('activitynew')->getCoinBlastBetByType($uid,'attack');

        if($dataAbnormal){//打在假盾上
            if($lockUid!=$uid&&$toUid2!=$toUid){//$touid绑定的人不是uid,且touid绑定的人不是uid
                oo::logs()->debug3(["ts"=>date('H:i:s'),"info"=>"{$uid}-{$lockUid}-{$toUid}-{$eUid}"],'attackErr.log');
            }
            $baseNumber = (int)$attackAwardCfg['shield'];
            $coins = $baseNumber * $actionBet;
            oo::commonOprModel('statistics')->attackStealSta('attack',$baseNumber,$coins,$uid);//打偷统计
//            oo::commonOprModel('member')->saveStatistics($uid,'coinbya',$coins);
            $userCoin = $coins + $userCoin;
            oo::commonOprModel('member')->optProperty($uid,array('money'=>$coins),'+',3,'摧毁盾牌获得的金币奖励:'.$toUid);
            $data = array('code' => 1, 'msg' => '被盾牌挡住了本次攻击');
            $data['data'] = ['dataFlag'=>true,'type'=>0,'getCoins'=>$coins,'lastCoins'=>$userCoin,'shield'=>0,'lastshield'=>max(intval($userInfo['shield'])-1,0)];
            $res1 = oo::commonOprRedis('usercache')->get(okeys::PetSkill($uid, 3));
            if($res1){
                $userPetSkill = true;
            }
            $res2 = oo::commonOprRedis('usercache')->get(okeys::PetSkill($toUid, 2));
            if($res2){
                $toUserPetSkill = true;
            }
            $data['data']['userPetSkill']   = $userPetSkill?1:0;
            $data['data']['toUserPetSkill'] = $toUserPetSkill?1:0;
            oo::commonOprRedis('usercache')->delete(okeys::PetSkill($uid, 3));
            oo::commonOprRedis('usercache')->delete(okeys::PetSkill($toUid, 2));
            self::addAchiTask($uid,$toUid,2,true);
            $dd =1;$ts = 2;
        }else{
            $res1 = oo::commonOprRedis('usercache')->get(okeys::PetSkill($uid, 3));
            if($res1){
                $userPetSkill = true;
            }
            $res2 = oo::commonOprRedis('usercache')->get(okeys::PetSkill($toUid, 2));
            if($res2){
                $toUserPetSkill = true;
            }
            oo::commonOprRedis('usercache')->delete(okeys::PetSkill($uid, 3));
            oo::commonOprRedis('usercache')->delete(okeys::PetSkill($toUid, 2));
            if($userPetSkill && intval($userInfo['shield']) >=1){
                oo::commonOprModel('member')->optProperty($toUid,array('shield'=>1),'-',8,'防御宠物攻击扣除盾牌:'.$uid);
                $userInfo['shield'] = $userInfo['shield'] - 1;
                $uidInfo = oo::commonOprModel('member')->getUserInfo($uid);
                $nick = $uidInfo['nick'];
                $s_picture = $uidInfo['s_picture'];
                oo::commonOprModel('message')->addPetMessage($toUid,$uid,$nick,$s_picture,9);
                oo::commonOprModel('Workerman')->push($toUid,ocmd::$send['defensePetSkill'],[
                    'uid'=>$uid,
                    'nick'=>$uidInfo['nick'],
                    'vip'=>$uidInfo['vip'],
                    'vipLv'=>$uidInfo['vipLv'],
                    'vipExpire'=>$uidInfo['vip_expire'],
                    'avatar'=>intval($uidInfo['avatar']),
                    'u_flag'=>$uidInfo['u_flag'],
                    'url'=>$uidInfo['s_picture']
                ]);
            }

            if($userPetSkill == false && $toUserPetSkill == true){
                self::addAchiTask($uid,$toUid,2,true);
                $baseNumber = (int)$attackAwardCfg['shield'];
                $coins = $baseNumber * $actionBet;
                oo::commonOprModel('statistics')->attackStealSta('attack',$baseNumber,$coins,$uid);//打偷统计
//                oo::commonOprModel('member')->saveStatistics($uid,'coinbya',$coins);
                $userCoin = $coins + $userCoin;
                oo::commonOprModel('member')->optProperty($uid,array('money'=>$coins),'+',3,'摧毁盾牌获得的金币奖励:'.$toUid);
                $data = array('code' => 1, 'msg' => '被盾牌挡住了本次攻击');
                $data['data'] = ['dataFlag'=>true,'type'=>0,'getCoins'=>$coins,'lastCoins'=>$userCoin,'shield'=>0,'lastshield'=>max(intval($userInfo['shield'])-1,0)];
                $dd =1;$ts = 2;
                $petGetExp =0;
                if($toUserPetSkill){//防御宠物 加经验
                    $petGetExp =  oo::commonOprModel('pet')->addUserPetExpBy($toUid,2,"defenseAddExp",1,122,'防御宠物触发');
                }
                self::sendMessageTo($uid,$toUid,2,$attId,0,$petGetExp);
            }else{
                if(intval($userInfo['shield']) >=1){
                    oo::commonOprModel('member')->optProperty($toUid,array('shield'=>1),'-',6,'防御攻击扣除盾牌:'.$uid);
//                    oo::commonOprModel('member')->saveStatistics($toUid,'defense',1);
                    self::sendMessageTo($uid,$toUid,2,$attId);
                    self::addAchiTask($uid,$toUid,2);
                    $baseNumber = (int)$attackAwardCfg['shield'];
                    $coins = $baseNumber * $actionBet;
                    oo::commonOprModel('statistics')->attackStealSta('attack',$baseNumber,$coins,$uid);//打偷统计
//                    oo::commonOprModel('member')->saveStatistics($uid,'coinbya',$coins);
                    $userCoin = $coins + $userCoin;
                    oo::commonOprModel('member')->optProperty($uid,array('money'=>$coins),'+',3,'摧毁盾牌获得的金币奖励:'.$toUid);
                    $data = array('code' => 1, 'msg' => '被盾牌挡住了本次攻击');
                    $data['data'] = ['dataFlag'=>true,'type'=>0,'getCoins'=>$coins,'lastCoins'=>$userCoin,'shield'=>0,'lastshield'=>max(intval($userInfo['shield'])-1,0)];
                    $dd =1;$ts = 2;
                }
                else{
                    //建筑损毁 已经破坏后 打回原形
                    if($LevelInfo['status'] == 1){
                        $LevelInfo['level'] = max($LevelInfo['level'] - 1,0);//摧毁状态
                        $star = 1;
                        if($LevelInfo['level'] == 0){
                            $LevelInfo['status'] = 0;
                            $star = 0;
                        }
                        $addReason = '';//摧毁率（岛被打光）
                        if($total_level <= 1){
                            $addReason = '(岛被打光)';
                        }
                        $baseNumber = (int)$attackAwardCfg['no_shield'];
                        $coins = $baseNumber * $actionBet;
                        $rets = oo::commonOprModel('member')->optProperty($uid,array('money'=>$coins),'+',2,'摧毁建筑获得的金币奖励'.$addReason.':'.$toUid);
                        oo::commonOprModel('statistics')->attackStealSta('attack',$baseNumber,$coins,$uid);//打偷统计
//                        oo::commonOprModel('member')->saveStatistics($uid,'coinbya',$coins);
                        $userCoin = $coins + $userCoin;
                        $sqlRet = oo::commonOprModel('member')->setUserLevel($toUid,$dataInfo['levelId'],$userElement);
                        if($sqlRet){
                            oo::commonOprModel('member')->optProperty($toUid,array('star'=>$star),'-',6,'建筑被摧毁损失星星:'.$uid);
                            self::sendMessageTo($uid,$toUid,4,$attId);
                            self::addAchiTask($uid,$toUid,4);
                            $data = array('code' => 1, 'msg' => '摧毁建筑');
                            $data['data'] = ['type'=>1,'levelinfo'=>$LevelInfo,'getCoins'=>$coins,'lastCoins'=>$userCoin];
                            $dd =1;$ts = 1;
                        }
                    }else{
                        //摧毁建筑
                        $LevelInfo['status'] = 1;
                        $baseNumber = (int)$attackAwardCfg['no_shield'];
                        $coins = $baseNumber * $actionBet;
                        oo::commonOprModel('statistics')->attackStealSta('attack',$baseNumber,$coins,$uid);//打偷统计
//                        oo::commonOprModel('member')->saveStatistics($uid,'coinbya',$coins);
                        $userCoin = $coins + $userCoin;
                        $rets = oo::commonOprModel('member')->optProperty($uid,array('money'=>$coins),'+',2,'损毁建筑获得的金币奖励:'.$toUid);
                        $sqlRet = oo::commonOprModel('member')->setUserLevel($toUid,$dataInfo['levelId'],$userElement);
                        if($sqlRet){
                            $res =  oo::commonOprModel('member')->optProperty($toUid,array('star'=>1),'-',6,'建筑被损毁损失星星:'.$uid);
                            self::sendMessageTo($uid,$toUid,3,$attId);
                            self::addAchiTask($uid,$toUid,3);
                            $data = array('code' => 1, 'msg' => '损毁建筑');
                            $data['data'] = ['type'=>2,'levelinfo'=>$LevelInfo,'getCoins'=>$coins,'lastCoins'=>$userCoin];
                            $dd =1;$ts = 1;
                        }
                    }
                }
            }
        }

        //宠物参与统计
        $petId = 2;
        $flag = (int)oo::commonOprRedis('statistics')->get(okeys::participationPetKey($uid, $petId));
        oo::commonOprModel('currency')->participation($uid, 'attack', $flag);

        oo::commonOprRedis('User')->setex(okeys::LastAttackCoinsNum($uid),$coins,2*60*60);

        if($dd==1){
            if(oo::compareVersion($version,'1.7.1')){
                $data['data']['trafficPermit'] = oo::commonOprModel('activitynew')->getUserActData($uid,'traffic_permit');
            }
            $symbol =false;
            $retData =oo::commonOprModel('activitynew')->setRateByDo($uid,'attack',$ts,intval($actionBet));
            if(oo::compareVersion($version,'1.7.7')){
                if(oo::commonOprModel('activitynew')->activityLock($uid,'super_collect')){
                    $symbol = oo::commonOprModel('activitynew')->getUserActData($uid,'super_collect');
                }
            }
            $data['data']['symbol'] =$symbol;
            $data['data']['stealAttack'] =  oo::commonOprModel('activitynew')->getUserActData($uid,'attack');
            $data['data']['AcRankData'] =  oo::commonOprModel('activitynew')->getUserActData($uid,'rank');
            $data['data']['AcRankNoProData'] =  oo::commonOprModel('activitynew')->getUserActData($uid,'rank2');

            $data['data']['userPetSkill']   = $userPetSkill?1:0;
            $data['data']['toUserPetSkill'] = $toUserPetSkill?1:0;

            //打宠物加成
            $userPetSkill    = false;
            //$userPetSkillNum = intval( oo::commonOprModel('pet')->usePetSkill($uid,3,$baseNumber)) * $actionBet;
            $userPetSkillNum = intval($baseNumber*$actionBet*$petAddRate);
            if($userPetSkillNum > 0){
                $userPetSkill = true;
                oo::commonOprModel('member')->optProperty($uid,array('money'=>$userPetSkillNum),'+',2,'攻击宠物技能获得金币');
                $data['data']['petCoins'] = $userPetSkillNum;
            }
            if($userPetSkill){//打宠物
                $data['data']['petGetExp']= oo::commonOprModel('pet')->addUserPetExpBy($uid,3,$ts == 1?"attackAddExp":"defenseAddExp",$bet,122,"打宠物触发");
            }
            /**
             * 通行证任务4
             */
            oo::commonOprModel('activitynew')->addTrafficPermitNum($uid,4,$actionBet);

            //通行证任务6
            $userPetSkill && oo::commonOprModel('activitynew')->addTrafficPermitNum($uid,6,$actionBet);

            //VIP 加成
            //$data['data']['vipCoins']= $vipCoins = (intval($data['data']['petCoins']) + $coins) * $attackCoinsPro;
            $data['data']['vipCoins'] = intval($vipRate * $baseNumber * $actionBet);
            if($data['data']['vipCoins'] > 0){
                oo::commonOprModel('member')->optProperty($uid,['money'=>$data['data']['vipCoins']],'+',353,"VIP加成：攻击 {$toUid}");
            }

            //金币爆炸活动加成
            //$bet2 = oo::commonOprModel('activitynew')->getCoinBlastBetByType($uid,'attack');
            //$data['data']['coin_blast_Coins'] = $coins*$bet2;
            $data['data']['coin_blast_Coins'] = intval((1+$vipRate+$petAddRate)*$actionBet*$baseNumber*$blastRate);
            if($data['data']['coin_blast_Coins']>0){
                oo::commonOprModel('member')->optProperty($uid,array('money'=>$data['data']['coin_blast_Coins']),'+',219,"攻击 {$toUid}");
            }

            $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            //获取当前用户的金币
            $data['data']['lastCoins'] = intval($userAssetsInfo['money']);

            //数数事件--完成打
            $isFriend = oo::commonOprModel('friend')->isfriend($uid,$toUid);
            $petInfo = oo::commonOprModel('pet')->getUserPet($uid,3);
            $attack_pet_remain_time =intval($petInfo['feedEffecteTime'])>time()?$petInfo['feedEffecteTime']-time():0;
            $ssEventData =[
                "attack_target_user"=>$toUid,
                "attack_relation"=>$isFriend?3:2,
                "attack_result"=>intval($ts),
                "attack_bet"=>intval($bet),
                "attack_collect_symbol"=>intval($retData["collectNum"]),
                "attack_rank_symbol"=>intval($retData['rankCollectNum']),
                "attack_coin_basic"=>$baseNumber,
                "attack_coin_final"=>$coins+intval($userPetSkillNum)+intval($data['data']['coin_blast_Coins']),
                "attack_pet_remain_time"=>$attack_pet_remain_time,
                "attack_pet_level"=>intval($petInfo['lv']),
            ];
            oo::commonOprModel('ta')->setEventData($uid,'attack',$ssEventData);
            return $data;
        }


        return $userInfo;
    }

    /**
     * Notes:获取偷取信息
     * User: wsc
     * Time: 2020/10/12 14:17
     * @param $uid
     * @return array
     */
    public function getStealData($uid){
        $bet = oo::commonOprRedis('usercache')->get(okeys::curUserBet($uid)) ?? 1;
        $flag  = false;
        $robot = false;
        $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $kingInfo =  oo::commonOprModel('steal')->getBindKing($uid,$userInfo['levelId']);
        $king  = isset($kingInfo['uid'])?$kingInfo['uid']:'';
        if(!$king){
            $robot = oo::commonOprModel('robot')->getAllRobot();
            $king = $robot[array_rand($robot,1)];
            $coinConfig = self::getCoinConfig(min($userInfo['levelId'],50));
            $coinConfig = json_decode($coinConfig,true);
            $money = random_int(intval($coinConfig[0][0]),intval($coinConfig[0][1]));
            $money = oo::Thousand($money);
            $robot = true;
            $flag  = true;
        }else{
            $stealDataStr = oo::commonOprRedis('usercache')->get(okeys::richestKingCoin($uid,$king));
            if(!empty($stealDataStr)){
                $stealData = explode('&',$stealDataStr);
                $money = $stealData[4];
                if($stealData[5] != $bet){
                    $stealData[5] = $bet;
                    $stealDataStr = implode('&',$stealData);
                    oo::commonOprRedis('usercache')->setex(okeys::richestKingCoin($uid,$king),$stealDataStr,2*3600);
                }
                $robot = $stealData[6];
            }else{
                $money = $this->getStealMoney($uid,$kingInfo['money'],$king,$userInfo['levelId']);
                $money = oo::Thousand($money);
                $flag  = true;
            }
        }
        $dataInfo = oo::commonOprModel('member')->getUserLevel($king);
        if($flag){//获取四个坑分布，并缓存
            $stealData = $this->getOptMoney($uid,$king,$money,$bet,$robot,$userInfo['levelId']);
        }
        //宠物偷信息
        $petStealInfo = oo::commonOprModel('pet')->usePetSkill($uid,1,$stealData[4] * $stealData[5]);
        //获取坑位补全具体信息
        $optInfo = $this->getOptInfo($uid,$userInfo['levelId'],$stealData,$petStealInfo[0]);
        $dataInfo['petCoinsPercent'] = floatval($petStealInfo[1]);//宠物倍率
        $dataInfo['toUid']   = intval($king);
        $dataInfo['toMoney'] = $kingInfo['money'];
        $userInfoKing = oo::commonOprModel('member')->getUserInfo($king);
        $dataInfo['nick']    = oo::commonOprModel('member')->getUserFirstName($userInfoKing['nick']) ?? 'crazyKing';
        $dataInfo['s_picture'] = $userInfoKing['s_picture'];
        $dataInfo['u_flag']  = $userInfoKing['u_flag'];
        $dataInfo['vip']     = $userInfoKing['vip'];
        $dataInfo['vipLv']   = $userInfoKing['vipLv'];
        $dataInfo['vipExpire']    = $userInfoKing['vip_expire'];
        $dataInfo['avatar']  = intval($userInfoKing['avatar']);
        $dataInfo['coins']   = $money;
        $dataInfo['isRobot'] = $robot;
        $dataInfo['optInfo'] = $optInfo;
        if($robot){
            //修改机器人等级
            $curMaxLevel = oo::commonOprModel('config')->getCurMaxLevel();
            $randLevel   = rand(4,8) + $userInfo['levelId'];
            $dataInfo['levelId'] = min($curMaxLevel,$randLevel);
            $kingInfo = ['money'=>$money,"levelId"=>$randLevel,"uid"=>$king];
            oo::commonOprRedis('server')->setex(okeys::richestKing($uid),json_encode($kingInfo),86400);
        }
        $dataInfo['kinglv'] = $kingInfo['levelId'];
        return $dataInfo;
    }



    /**
     * Notes:获取坑位钱分布
     * User: wsc
     * Time: 2020/10/12 14:48
     * @param $uid
     * @param $king
     * @param $money
     * @param $bet
     * @param $robot
     * @return array
     */
    public function getOptMoney($uid,$king,$money,$bet,$robot,$levelId){
        $money = oo::Thousand($money);
        $hole = [
            intval($money*0.65),
            intval($money*0.25),
            intval($money*0.10),
            0
        ];
        $is_two =0;
        $version = oo::commonOprModel('user')->getUserVersion($uid);
        if(oo::compareVersion($version,'1.7.7')){//1.7.7版本修复两个宝箱连续挖问题
            if($bet>=20&&$levelId>2){
                $randNumSel = mt_rand(1,100);
                $index = mt_rand(1,10);
                if($randNumSel<=25){//40%概率走奖励类型② 两金币两宝箱
                    $two = $index<=4?$money*0.65:$money*0.25;
                    $hole = [
                        $two,
                        intval($money*0.10),
                        0,
                        0,
                    ];
                    $is_two =1;
                }
            }
        }

        shuffle($hole);
        $hole[4] = $money;
        $hole[5] = $bet;
        if($robot){
            $hole[6] = 1;
        }else{
            $hole[6] = 0;
        }
        $hole[7] = $is_two;
        $stealData = $hole;
        $stealDataStr = implode('&',$hole);
        oo::commonOprRedis('usercache')->setex(okeys::richestKingCoin($uid,$king),$stealDataStr,2*3600);
        return $stealData;
    }

    /**
     * Notes:获取坑位详情
     * User: wsc
     * Time: 2020/6/23 16:14
     * @param $uid
     * @param $levelId
     * @param $stealData
     * @return array
     */
    public function getOptInfo($uid,$levelId,$stealData,$petStealCoin){
        $data = [];
        $optData = array_slice($stealData,0,4);//四个坑
        foreach ($optData as $k=>$v){
            $data[$k]['bet']  = $stealData[5];//倍率
            $data[$k]['coins'] = $v* $stealData[5];//每个坑的钱，已加倍
            $data[$k]['pet']  = intval($petStealCoin);//宠物触发的额外收益，已加倍
            $data[$k]['petFeed'] = 0;
            $data[$k]['treasureType'] =0;
            $data[$k]['optId'] =$k;
            if($stealData[$k]==0&&$levelId > 2){
                $key1 = okeys::userOtherStealAward($uid,$k,'card');
                $key2 = okeys::userOtherStealAward($uid,$k,'petFeed');
                $card = null;

                //奖励类型②:
                if($stealData[7]){
                    $rand2 = mt_rand(1,100);
                    if($stealData[5]<50){
                        $treasureType = $rand2>95?3:($rand2>70?2:1);
                    }else{
                        $treasureType = $rand2>95?3:($rand2>50?2:1);
                    }
                }else{//奖励类型①：
                    $rand = mt_rand(1,1000);
                    $treasureType = $rand<5?3:($rand<25?2:($rand<105?1:0));
                }

                if($treasureType){//触发卡片奖励
                    oo::commonOprRedis('Userinfo')->setex($key1,$treasureType,5*60);//缓存卡片奖励
                }
                $data[$k]['treasureType'] = $treasureType;
                $rand = mt_rand(0,100);
                if($rand < 1){//触发宠物食物奖励
                    $data[$k]['petFeed'] = 1;
                    oo::commonOprRedis('Userinfo')->setex($key2,1,5*60);//缓存食物奖励
                }

            }
        }
        shuffle($data);
        return $data;
    }

    /**
     * Notes:领取挖坑卡片奖励，宠物食物奖励
     * User: wsc
     * Time: 2020/6/23 10:59
     * @param $uid
     * @return mixed
     */
    public function getOtherStealAward($uid,$optId){
        $data['card'] =[];
        $data['petFeed'] =0;
        //卡片
        $treasureType = oo::commonOprRedis('Userinfo')->get(okeys::userOtherStealAward($uid,$optId,'card'));
        if($treasureType){
            $card = oo::commonOprModel('card')->getCardByType($uid,$treasureType);
            $card = $card['card'];
            $data['card'] = $card;
            oo::commonOprRedis('Userinfo')->delete(okeys::userOtherStealAward($uid,$optId,'card'));
        }
        //宠物粮食
        $optIdFeed = oo::commonOprRedis('Userinfo')->get(okeys::userOtherStealAward($uid,$optId,'petFeed'));
        if($optIdFeed){
            $res = oo::commonOprModel('props')->addUserProps($uid,9,1);
            oo::commonOprRedis('Userinfo')->delete(okeys::userOtherStealAward($uid,$optId,'petFeed'));
            $data['petFeed'] =1;
        }

        return array('code' => 1,'data'=>$data);
    }

    /**
     * 结束偷
     * @param $uid
     * @param $toUid
     * @param $optIds
     * @return array
     * Created by: Owen
     * Created on: 2020/6/23 11:33
     */
    public function overSteal($uid,$toUid,$optIds){
        $data = array('code' => 1, 'desc' => '偷取任务结束');
        $stealData = oo::commonOprRedis('usercache')->get(okeys::richestKingCoin($uid,$toUid));
        $stealData = explode('&',$stealData);
        $symbol = false;
        if(empty($stealData[4])&&empty($stealData[5])){
            $rk = okeys::richestKing($uid);
            $richestKingJson = oo::commonOprRedis('server')->get($rk);//当前King信息
            if($richestKingJson){
                $kingInfo =  json_decode($richestKingJson,true);
                $stealData = oo::commonOprRedis('usercache')->get(okeys::richestKingCoin($uid,$kingInfo['uid']));
                $stealData = explode('&',$stealData);
                if(empty($stealData)){
                    oo::logs()->debug3(["ts"=>date('Y-m-d H:i:s'),"uid"=>$uid,"toUid"=>$toUid,"optIds"=>$optIds,"stealData"=>$stealData,"kingInfo"=>$richestKingJson,"kingUid"=>$kingInfo['uid']],'stealerr.log');
                }else{
                    $toUid = $kingInfo['uid'];
                }
            }
        }
        if(empty($stealData[4])&&empty($stealData[5])){
            $data['symbol'] = $symbol;
            $data['stealAttack'] = false;
            $data['pet'] = false;
            $data['AcRankData'] = false;
            oo::logs()->debug3(["ts"=>date('Y-m-d H:i:s'),"uid"=>$uid,"toUid"=>$toUid,"optIds"=>$optIds,"stealData"=>$stealData,"kingInfo"=>$richestKingJson],'stealerr.log');
            return $data;
        }
        foreach ($optIds as $v){
            $stealRecord[] = $stealData[$v];
        }
        $steal_num= intval(array_sum($stealRecord));//用户当前偷取到的金币总额
        if($steal_num > intval($stealData[4])){//偷取总和大于最大可偷金额
            $error = "(异常偷取金额大于最大金额,使用最大值:$stealData[4]进行结算)";
            $steal_num = $stealData[4];
        }
        $bet = intval($stealData[5])>0?intval($stealData[5]):1;
        $systemPay = false;
        $error = "";
        $petSkill = [];$petId = 1;
        $version = oo::commonOprModel('user')->getUserVersion($uid);

        //宠物偷
        if(oo::compareVersion($version,'1.7.8')){
            $petStealInfo = oo::commonOprModel('pet')->usePetSkill($uid,$petId,$steal_num * $bet);//用实际偷到的金币值来计算宠物偷到的数量
        }else{
            $petStealInfo = oo::commonOprModel('pet')->usePetSkill($uid,$petId,$stealData[4] * $bet);//用showmoney值来计算宠物偷到的数量(老)
        }
        $data['pet'] = intval($petStealInfo[0]);//宠物偷到的钱
//        $petPer = floatval($petStealInfo[1]);//宠物加成比
        $petSkill[$petId] = $data['pet']/$bet;//宠物偷到的基数
        /**
         * 通行证任务5
         */
        if($data['pet']){
            //通行证任务5
            oo::commonOprModel('activitynew')->addTrafficPermitNum($uid,5,$bet);

            //宠物参与统计
            $flag = (int)oo::commonOprRedis('statistics')->get(okeys::participationPetKey($uid, $petId));
            oo::commonOprModel('currency')->participation($uid, 'steal', $flag);
        }

        $userGetCoinNum = $steal_num*$bet + $data['pet'];//用户挖坑总钱*倍数 + 宠物额外收益 = 此次偷取总数
        $beShowStealMoney = $steal_num+ceil($petSkill[$petId]);//用户应该被偷的钱数(被偷基数)
        if($stealData[6] == 1){
            oo::commonOprModel('statistics')->addWarning($uid,"返回RichestKing数据失败，追加机器人：{$toUid} 金币 {$steal_num}",0,$steal_num);
            oo::commonOprModel('member')->optProperty($uid,array('money'=>$userGetCoinNum),'+',9,"机器人补发:{$error}偷到用户:{$toUid}的金币,基数:{$steal_num},宠物:{$petSkill[$petId]}");
            $systemPay = true;
        }else{
            $ttl = oo::commonOprModel('activitynew')->getEndproteTime($toUid)-time();
            if($ttl > 0){
                oo::commonOprModel('member')->optProperty($uid,array('money'=>$userGetCoinNum),'+',10,"{$error}偷到用户:{$toUid}的金币,用户被保护,系统发放");
                $systemPay = true;
            }else{
                $userMoney = oo::commonOprModel('member')->getUserAssetsInfo($toUid)['money'];
                $n=intval($data['pet'])>0?0.85:0.75;
                $canBeSteal = ceil($userMoney*$n);//用户可被偷的最大钱数
                if($canBeSteal>$beShowStealMoney){//用户钱够被偷
                    $beStealMoney =$beShowStealMoney;//实际被偷
                    $personSteal = $steal_num;
                }else{//用户钱不够被偷
                    $beStealMoney =$canBeSteal;//实际被偷
                    $petSkill[$petId] = 0;
                    $personSteal = $canBeSteal;
                }
                oo::commonOprModel('member')->optProperty($toUid,array('money'=>$beStealMoney),'-',7,"{$error}被用户:{$uid}偷取金币,被用户偷了{$personSteal},宠物偷了{$petSkill[$petId]}");
                oo::commonOprModel('member')->optProperty($uid,  array('money'=>$beStealMoney),'+',4,"{$error}偷到用户:{$toUid}的金币");
                //其余部分系统补
                $fromSys = $userGetCoinNum -$beStealMoney;

                if($fromSys>0){
                    oo::commonOprModel('member')->optProperty($uid,array('money'=>$fromSys),'+',10,"{$error}倍率偷取:系统补发（当前倍率：{$bet}，偷到用户{$beStealMoney},宠物偷了{$petSkill[$petId]}，系统补发{$fromSys},实际发放{$userGetCoinNum}）");
                }
            }
        }

        /**
         * VIP 加成
         */
        if(oo::compareVersion($version,'1.7.4')){
            $stealCoinsPro = oo::commonOprModel('newvip')->vipRewardConf($uid,'stealCoinsPro');
            $data['vipCoins']= $vipCoins = $userGetCoinNum* $stealCoinsPro;
            $vipCoins > 0 && oo::commonOprModel('member')->optProperty($uid,['money'=>$vipCoins],'+',353,"VIP加成：偷取 {$toUid}");
        }
        if(oo::compareVersion($version,'1.7.7')){
            //金币爆炸活动加成
            $bet2 = oo::commonOprModel('activitynew')->getCoinBlastBetByType($uid,'steal');
            $data['coin_blast_Coins'] = $steal_num*$bet*$bet2;
            if($bet2>0){
                oo::commonOprModel('member')->optProperty($uid,array('money'=>$data['coin_blast_Coins']),'+',219,"偷取 {$toUid}");
            }
        }

        oo::commonOprRedis('usercache')->delete(okeys::recordUserSteal($uid,$toUid));

        $statistics = [];


        if(!in_array(0,$stealRecord)){
            $statistics['allstealnum'] = 1;
            $ns =5;$ts=1;//完美
        }else{
            $ns =4;$ts=2;//不完美
        }
        if(oo::compareVersion($version,'1.7.1')){
            $data['trafficPermit'] = oo::commonOprModel('activitynew')->getUserActData($uid,'traffic_permit');
        }

        oo::commonOprModel('activitynew')->setRateByDo($uid,'steal',$ts,intval($stealData[5]));
        if(oo::compareVersion($version,'1.7.7')){
            if(oo::commonOprModel('activitynew')->activityLock($uid,'super_collect')){
                $symbol = oo::commonOprModel('activitynew')->getUserActData($uid,'super_collect');
            }
        }
        $data['symbol'] = $symbol;
        $data['stealAttack'] =  oo::commonOprModel('activitynew')->getUserActData($uid,'steal');
        $data['AcRankData'] =  oo::commonOprModel('activitynew')->getUserActData($uid,'rank');
        $data['AcRankNoProData'] =  oo::commonOprModel('activitynew')->getUserActData($uid,'rank2');

        if($steal_num){
            // 成就：抓金之王
//            $statistics['stealnum'] = 1;
//            $statistics['stealcoin'] = $steal_num;
//            oo::commonOprModel('member')->saveStatisticsByArray($uid,$statistics);
//            oo::commonOprModel('member')->saveStatistics($toUid,'stealed',$steal_num);
        };
        oo::commonOprModel('steal')->clearBindKing($uid);//清除$uid与$toUid所有绑定关系,及绑定的钱
        oo::commonOprRedis('common')->delete(okeys::beStealLock($toUid));//清除锁定关系

        if(!$systemPay){
            self::sendMessageTo($uid,$toUid,1,0,$beStealMoney,[1=>$petSkill[1]]);
        }

        oo::commonOprModel('statistics')->attackStealSta('steal',$steal_num,$steal_num*$bet,$uid);//打偷统计

        oo::commonOprRedis('User')->setex(okeys::LastStealCoinsNum($uid),$steal_num*$bet,2*60*60);
        /**
         * 偷追加仇恨值加入仇人列表
         */
        $num = intval(oo::commonOprRedis('common')->hGet(okeys::EnemyID($toUid),$uid));
        oo::commonOprRedis('common')->hDel(okeys::EnemyID($toUid),$uid);
        oo::commonOprRedis('common')->hSet(okeys::EnemyID($toUid),$uid,intval($num)+1);
        oo::commonOprRedis('common')->expire(okeys::EnemyID($toUid),oo::redisRandomExpire(86400*7));

        oo::commonOprModel('pet')->addUserPetExpBy($uid,1,"stealAddExp");

        /**
         * 通行证任务3
         */
        oo::commonOprModel('activitynew')->addTrafficPermitNum($uid,3,$bet);
        return $data;
    }



    /**
     * Notes:偷取基数取值
     * User: wsc
     * Time: 2020/3/26 16:00
     * @param $uid   :窃取者
     * @param $toUid :被偷者
     * @param $money :实时基数
     * @return mixed
     */
    public function getStealMoney2($uid,$kingMoney,$king,$levelId){
        $toUserLevelInfo = oo::commonOprModel('member')->getUserLevel($king);
        $levelCfg =  $this->getLevelConf($levelId);
        $s = $toUserLevelInfo['levelId'] - $levelId;
        if($s<-10){
            $a=1;
        }else if($s<=0){
            $a=0.9;
        }else if($s<=10){
            $a=0.8;
        }else if($s<=20){
            $a=0.4;
        }else{
            $a=0.2;
        }
        $money = $kingMoney*0.75*$a;
        $rand_money = mt_rand(1,50)*1000;
        $bet = oo::commonOprRedis('usercache')->get(okeys::curUserBet($uid))??1;
        $bet =  intval($bet)>=1?intval($bet):1;
        $money = $money>$levelCfg['maxMoney']/2?intval($levelCfg['maxMoney']/2)-$rand_money:$money;
        if($money>$levelCfg['sumMoney']/20){
            //如果bet>=30,showMoney=lvTotal/bet-随机
            if($bet>=30){
                $money = intval($levelCfg['sumMoney']/$bet) -$rand_money;
            }else{
                $money = intval($levelCfg['sumMoney']/20)-$rand_money;
            }
        }
        return intval($money);
    }
    public function getStealMoney($uid,$kingMoney,$king,$levelId){
        $toUserLevelInfo = oo::commonOprModel('member')->getUserLevel($king);
        $levelCfg =  $this->getLevelConf($levelId);
        $s =   $levelId-$toUserLevelInfo['levelId'];
        if($s>=0){
            $a=1;
        }else if($s>-10){
            $a=1/(abs($s));
        }else{
            $a=0.1;
        }
        $money = $kingMoney*0.75*$a;
        $friendlist =  oo::commonOprModel('friend')->getUserAllFriend($uid);
        if(!in_array($king,$friendlist)){
            $money = 0.5*$money;
        }
        $rand_money = mt_rand(1,50)*1000;
        if($levelId<50){
            if($money>$levelCfg['sumMoney']/10){
                $money = $levelCfg['sumMoney']/10-$rand_money;
            }
        }else if ($levelId<100){
            if($money>$levelCfg['sumMoney']/100){
                $money = $levelCfg['sumMoney']/100-$rand_money;
            }
        }else if ($levelId<150){
            if($money>$levelCfg['sumMoney']/500){
                $money = $levelCfg['sumMoney']/500-$rand_money;
            }
        }else if ($levelId<200){
            if($money>$levelCfg['sumMoney']/1000){
                $money = $levelCfg['sumMoney']/1000-$rand_money;
            }
        }else{
            if($money>150*1000*1000){
                $money = 150*1000*1000 -$rand_money;
            }
        }

        return intval($money);
    }
    /**
     * 刷新攻击任务&成就
     * @param $uid
     * @param $toUid
     * @param $type
     * @param bool $dataAbnormal
     * Created by: Owen
     * Created on: 2020/5/16 17:03
     */
    public function addAchiTask($uid,$toUid,$type,$dataAbnormal = false){
        $num = (oo::commonOprRedis('common')->hGet(okeys::EnemyID($toUid),$uid)) ?? 0;
        oo::commonOprRedis('common')->hDel(okeys::EnemyID($toUid),$uid);
        oo::commonOprRedis('common')->hSet(okeys::EnemyID($toUid),$uid,intval($num)+1);
        oo::commonOprRedis('common')->expire(okeys::EnemyID($toUid),oo::redisRandomExpire(86400*7));
        // 成就：复仇之王
        $num = (oo::commonOprRedis('common')->hGet(okeys::EnemyID($uid),$toUid)) ?? 0;
        if($num){
            oo::commonOprRedis('common')->hDel(okeys::EnemyID($uid),$toUid);
        }
        self::updateAttackProtectionTime($toUid,$uid);
    }

    /**
     * 发送消息给被偷玩家 并且入库
     * $uid 当前用户uid $toUid 被偷用户uid $type  所属类型 1被偷钱  2防御成功  3损坏建筑  4摧毁建筑
     */
    public function sendMessageTo($uid,$toUid,$type,$attId = 0,$num = 0,$petSkill = []){
        $toUidInfo = oo::commonOprModel('member')->getUserAssetsInfo($toUid); //被偷用户资产
        $uidInfo = oo::commonOprModel('member')->getUserInfo($uid);
        $nick = oo::commonOprModel('member')->getUserFirstName($uidInfo['nick']);
        $is_read = 1;
        if($type == 1) {//偷
            oo::commonOprModel('member')->setUserStealProtect($toUid,300*4,true);
            oo::commonOprModel('member')->setUserStealProtect($uid,60);
            oo::commonOprModel('Workerman')->push($toUid,ocmd::$SVR_SELF_RAID_MESSAGE,[
                'nick' =>$nick,
                'vip'  =>$uidInfo['vip'],
                'vipLv'=>$uidInfo['vipLv'],
                'vipExpire'=>$uidInfo['vip_expire'],
                'avatar'=>intval($uidInfo['avatar']),
                'u_flag'=>$uidInfo['u_flag'],
                'url'=>$uidInfo['s_picture'],
                'coins'=>intval($num),
                'selfCoin'=>intval($toUidInfo['money']),
                'petCoin'=>intval($petSkill[1])
            ]);

            oo::commonOprModel('push')->pushNews($toUid,'push.title.steal','push.content.steal', [$nick,funs::CoinFormat($num)],'steal');
            oo::commonOprModel('message')->addMessage($toUid,$uid,$nick,$uidInfo['s_picture'],$num,$type,$is_read,$petSkill);
        }else{
            if(intval(oo::commonOprRedis('common')->hGet(okeys::AttackedFreeReBuild(),$toUid))<3){
                if(oo::commonOprModel('newvip')->checkVip($toUid)){
                    $time = 60;
                }else{

                    $time = 30;
                }
                oo::commonOprRedis('usercache')->setex(okeys::AttackedFreeReBuild($toUid),$attId,$time*2);
                oo::commonOprRedis('common')->hIncrBy(okeys::AttackedFreeReBuild(),$toUid,1);
            }else{
                $time = 0;
            }
            oo::commonOprModel('Workerman')->push($toUid,ocmd::$SVR_SELF_ATTACK_MESSAGE,[
                'attId'    =>$attId,
                'freeEnd'  =>time() + $time,
                'nick'     =>$nick,
                'vip'      =>$uidInfo['vip'],
                'vipLv'    =>$uidInfo['vipLv'],
                'vipExpire'=>$uidInfo['vip_expire'],
                'avatar'   =>intval($uidInfo['avatar']),
                'u_flag'   =>$uidInfo['u_flag'],
                'url'      =>$uidInfo['s_picture'],
                'shield'   =>intval($toUidInfo['shield']),
                'isDefense'=>intval($type),
                'star'     =>intval($toUidInfo['star']),
            ]);
            $s_picture = $uidInfo['s_picture'];
            oo::commonOprModel('message')->addMessage($toUid,$uid,$nick,$s_picture,$num,$type,$is_read,['petGetExp'=>$petSkill]);
        }
        if($type == 3 || $type == 4){
            oo::commonOprModel('push')->pushNews($toUid,'push.title.attack','push.content.attack', [$nick],'attack');
        }
    }

    /**
     * 获取岛建筑升级金币配置
     * @param $levelId
     * @return mixed
     * Created by: Owen
     * Created on: 2020/11/20 14:49
     */
    public function getCoinConfig($levelId){
        $conf = $this->getLevelConf($levelId);
        return $conf['coinConfig'];
    }

    public function getLevelConf($levelId,$db=false){
        $cache =[];
        $key   = okeys::LevelConf();
        if(!$db){
            $cfgJson = oo::commonOprRedis('common')->hGet($key,$levelId);
            $cache   = !empty($cfgJson)?json_decode($cfgJson,true):[];
        }
        if(empty($cache)||!is_array($cache)){
            $tb   = otable::coinConfig();
            $sql  = "select * from {$tb} where levelId={$levelId} limit 1";
            $conf = oo::commonOprDb('config')->getOne($sql, MYSQLI_ASSOC);
            if(!empty($conf)&&!empty($conf['coinConfig'])){
                $coinCfgArr = json_decode($conf['coinConfig'],true);
                foreach ($coinCfgArr as $k){
                    foreach ($k as $row){
                        $conf['sumMoney'] += intval($row);
                    }
                }
                $conf['minMoney'] = intval($coinCfgArr[0][0]);
                $conf['maxMoney'] = intval($coinCfgArr[4][4]);
                oo::commonOprRedis('common')->hDel($key,$levelId);
                oo::commonOprRedis('common')->hSet($key,$levelId,json_encode($conf));
                $cache = $conf;
            }
        }
        $data =!empty($cache)&&is_array($cache)?$cache:[];
        return $data;
    }

    /**
     * 过关奖励--后期机器人用
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2019/6/11 20:35
     * Description:
     */
    public function levelReward($uid){
        $userUserLevelInfo = oo::commonOprModel('member')->getUserLevel($uid);
        if($userUserLevelInfo['levelId'] == 1){
            $data = array('code' => -1, 'msg' => '当前操作等级状态不对');
            return $data;
        }
        $actionLevelId = intval($userUserLevelInfo['levelId']) - 1;
        if(empty($userUserLevelInfo)){
            $data = array('code' => -1, 'msg' => '数据异常');
            return $data;
        }else if($userUserLevelInfo['is_reward'] == 1){
            $data = array('code' => -1, 'msg' => '已领取过奖励');
            return $data;
        }else{
            $reward = oo::commonOprModel('level')->getLevelConf($actionLevelId);
            oo::commonOprModel('member')->updateUserLevel($uid,['is_reward'=>1]);
            oo::commonOprModel('member')->optProperty($uid,['money'=>intval($reward['reward_coin']),'spins' =>intval($reward['reward_spin'])],'+',80,'通过关卡:'.$actionLevelId);
            $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $outputReward = [
                ['type'=>'coin','data'=>intval($reward['reward_coin']),'lastCoins'=>$userAssetsInfo['money']],
                ['type'=>'spin','data'=>intval($reward['reward_spin']),'lastSpins'=>$userAssetsInfo['spins']],
            ];
            if($actionLevelId >= 2){
                $pro = [95,60,0];
                $int = mt_rand(1,100);
                foreach ($pro as $k=>$r){
                    if($int>$r){
                        $treasureType = 3-$k;
                        break;
                    }
                }
                oo::commonOprModel('props')->addUserProps($uid,$treasureType,1,0,80);
                $cardData['treasureType'] = $treasureType;
                $outputReward[] = ['type'=>'card','data'=>$cardData];
            }
            $data=[
                'code'  => 1,
                'msg'   => '领取过关奖励成功',
                'data'  => $outputReward
            ];
            return $data;
        }
    }

    /**
     * 获取玩家帮助好友维修建筑记录
     * @param int $uid
     * @return arr
     */
    public function getHelpRepairInfo($uid) {
        $tmp = oo::commonOprRedis('common')->hGet(okeys::helpRepairBuild(), $uid);
        if(empty($tmp)){
            return ['repair' => [], 'berepair' => []];
        }
        return json_decode($tmp, true);
    }

    /**
     * 获取被好友帮修建筑信息uid列表
     */
    public function getRepairInfoArr(array $uids = []) {
        $tmp = $uids ? oo::commonOprRedis('common')->hMGet(okeys::helpRepairBuild(), $uids) : [];
        $arr = [];
        foreach($tmp as $uid => $v){
            $v = json_decode($v, true);
            $arr[$uid] = $v;
        }
        return $arr;
    }

    /**
     * 帮助好友维修建筑
     * @param int $uid
     * @param int $toUid
     */
    public function upHelpRepairInfo($uid, $toUid) {
        $expire = strtotime(date('Y-m-d', strtotime('+1 days')));
        $tmp = oo::commonOprRedis('common')->hMGet(okeys::helpRepairBuild(), [$uid, $toUid]);
        $info = empty($tmp[$uid]) ? [] : (array)json_decode($tmp[$uid], true);
        $info['repair'] = empty($info['repair']) ? ['num' => 0, 'expire' => 0] : $info['repair'];
        $info['repair']['num'] += 1;
        $info['repair']['expire'] = $expire;

        if(oo::commonOprRedis('common')->ttl(okeys::helpRepairBuild()) == -1){
            oo::commonOprRedis('common')->expireAt(okeys::helpRepairBuild(), $expire);
        }

        $fInfo = empty($tmp[$toUid]) ? [] : (array)json_decode($tmp[$toUid], true);
        $fInfo['berepair'] = empty($fInfo['berepair']) ? ['num' => 0, 'expire' => 0] : $fInfo['berepair'];
        $fInfo['berepair']['num'] += 1;
        $fInfo['berepair']['expire'] = $expire;

        oo::commonOprRedis('common')->hMSet(okeys::helpRepairBuild(), [
             $uid => json_encode($info),
             $toUid => json_encode($fInfo),
        ]);
    }

    /**
     * 帮助好修复建筑
     * @param int $uid
     * @param int $toUid
     * @param int $optId
     * @param int $level
     */
    public function helpRepairOperation($uid, $toUid, $optId) {
        $friendLevel = oo::commonOprModel('member')->getUserLevel($toUid);
        $levelId = $friendLevel['levelId'];
        $actionOpt = $optId-1;

        //格式化参数
        $friendElement = $friendLevel['element'];

        //建筑的总等级数  5个建筑 5个级别  最高值等于25 不能操作这个
        $total_level = 1;

        if(!isset($friendElement[$actionOpt]) || empty($friendElement[$actionOpt]['status'])){
            return [
                'code' => -1,
                'msg'  => '好友当前建筑不需要维修-2',
                'param'=> [
                    'uid'      => $uid,
                    'friendid' => $toUid,
                    'optId'    => $optId,
                    'level'    => $levelId,
                    'isVideo'  => 0,
                ]
            ];
        }

        //获取当前建筑的级别
        $optLevelNum = intval($friendElement[$actionOpt]['level']);

        //获取岛建筑升级金币
        $coinConfig = $this->getCoinConfig($levelId);

        //岛建筑需要的金币
        $coinConfig = json_decode($coinConfig,true);
        $coinLevelNum = ($optLevelNum-1) < 0 ? 0 : $optLevelNum-1;
        $optCoinNum = $coinConfig[$actionOpt][$coinLevelNum];
        //$repairNum = intval($optCoinNum*0.5*0.5); //免费修
        $repairNum = 0; //免费修

        //获取用户资产信息
        $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $maxLevel = $friendElement[$actionOpt]['maxLevel'];
        $star = intval($userInfo['star']);
        $userCoin = intval($userInfo['money']);
        $info = [
            'optId'     => $optId,
            'level'     => $optLevelNum,
            //'useUpCoin' => $repairNum,
            'useUpCoin' => 0,
            'lastCoins' => $userCoin,
            'star'      => $star,
            'status'    => 1,
            'maxLevel'  => $maxLevel
        ];

        //if($userCoin < $repairNum){
        //    $data = array('code' => -4, 'msg' => '所需的金币不足','data'=>$info);
        //    return $data;
        //}

        ////先扣金币后修改库
        //$ret = oo::commonOprModel('member')->optProperty($uid,array('money'=>$repairNum),'-',82,'帮好友'.$toUid.'修复建筑扣除金币:关卡'.$levelId."，建築".$optId."，等级".($optLevelNum));
        //if(!$ret){
        //    $data = ['code' => -1, 'msg' => '修复失败，请重新操作1','data'=>$info];
        //    return $data;
        //}
        $friendElement[$actionOpt]['status']  =  0;
        $sqlRet = oo::commonOprModel('member')->setUserLevel($toUid,$levelId,$friendElement);
        if($sqlRet){
            //记录修复建筑奖励
            oo::commonOprModel('member')->optProperty($toUid,['star'=>1],'+',82,'好友'.$uid.'帮助修复建筑加星星:关卡'.$levelId."，建築".$optId."，等级".($optLevelNum));
            $data = array('code' => 1, 'msg' => '修复成功');
            //$lastCoins = $userCoin - $repairNum;
            $lastCoins = 0;
            $data['data'] = ['level'=>$optLevelNum,'useUpCoin'=>0,'lastCoins'=>$lastCoins,'star'=>$star+1,'status'=>0,'maxLevel'=>$maxLevel,'optId'=>$optId];
            oo::commonOprModel('statistics')->todayBuildSta($toUid,'repair',$optCoinNum);//每日建筑记录统计
            oo::commonOprModel('Workerman')->push($toUid,ocmd::$send['Level_helpBuildOperation'],$data);
            $this->upHelpRepairInfo($uid, $toUid);
            //推送
            return $data;
        }
        //记录失败日志
        oo::logs()->debug3(['element' => $friendElement, 'optId' => $optId, 'money' => $repairNum],"helpBuild.php");
        return ['code' => -1, 'msg' => '修复失败，请重新操作2','data'=>$info];
    }

    /**
     * 建建筑操作
     * @param $uid    //用户ID
     * @param $optId  //建筑id
     * @param $level  //当前建筑的当前等级
     * @param int $isVideo 是否看视频 0金币修 1看视频 2直接30内修
     * @return array|string
     * Created by: Owen
     * Created on: 2019/8/21 9:35
     */
    public function levelOperationNoUp($uid,$optId,$level,$isVideo = 0){
        $serverMaxLevel = intval(oo::commonOprModel('readconfig')->getCon('basic','curMaxLevel'))??60;//当前世界最大等级
        $VideoTips = "";
        if($isVideo == 1){
            $VideoTips = "(视频广告)";
        }

        //先查出当前岛的id
        $userLevel = oo::commonOprModel('member')->getUserLevel($uid);
        $levelId = $userLevel['levelId'];
        $actionOpt = $optId-1;

        //格式化参数
        $userElement = $userLevel['element'];

        //建筑的总等级数  5个建筑 5个级别  最高值等于25 不能操作这个
        $total_level = 1;

        //判断当前建筑属于$opt破损
        $opt = 0;

        if($userElement[$actionOpt]['status'] == 1){
            $opt = 1;
        }

        if($isVideo == 2 && $opt != 1){
            return ['code' => -8, 'msg' => '免费修复异常-1','param'=>[
                'uid'   => $uid,
                'optId' => $optId,
                'level' => $level,
                'isVideo' => $isVideo,
            ]];
        }
        //获取用户资产信息
        $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        //建造 升级
        if($opt == 0 && $optId){
            //获取当前建筑的级别
            $optLevelNum = intval($userElement[$actionOpt]['level']);

            //获取当前用户的金币
            $userCoin = intval($userInfo['money']);

            //获取岛建筑升级金币
            $coinConfig = $this->getCoinConfig($levelId);
            $version  = oo::commonOprModel('user')->getUserVersion($uid);
            //岛建筑需要的金币
            $usercoinConfig = json_decode($coinConfig,true);
            if(($levelId == 1 && $optLevelNum == 1) || ($levelId == 2 && $optLevelNum == 1 && oo::compareVersion($version,'1.7.4'))){
                $optLevelNum = $optLevelNum + 1;
            }
            //升级所需要的金币
            $optCoinNum = $usercoinConfig[$actionOpt][$optLevelNum];

            if($isVideo == 1){
                $optCoinNum = 0;
            }
          
            $status   = $userElement[$actionOpt]['status'];
            $maxLevel = $userElement[$actionOpt]['maxLevel'];
            $star = intval($userInfo['star']);
            $info = [
                'optId'=>$optId,
                'level'=>$optLevelNum,
                'useUpCoin'=>$optCoinNum,
                'lastCoins'=>$userCoin,
                'star'=>$star,
                'status'=>$status,
                'maxLevel'=>$maxLevel
            ];

            if($optLevelNum >= $level){//要升级的等级小于等于已存在的等级
                $data = array('code' => -6,'data'=>$info);
                return $data;
            }

            if($optLevelNum >= 5 || $total_level>25){
                $data = array('code' => -3, 'msg' => '当前已经是最高级别建造了','data'=>$info);
                return $data;
            }
            $rid=81;
            if(oo::compareVersion($version,'1.7.1')){
                $aid = oo::commonOprModel('activitynew')->activityLock($uid,'discounts_architecture');
                if($aid){
                    $disNum = oo::commonOprModel('activitynew')->discountsArch($aid,$actionOpt,$uid);//打折力度
                    $optCoinNum = intval($optCoinNum*$disNum);
                    $rid = 86;
                }
            }
            if($userCoin < $optCoinNum){
                $data = array('code' => -4, 'msg' => '所需的金币不足','data'=>$info);
                return $data;
            }

            if($isVideo == 1){
                $getRemainCount = oo::commonOprModel('advertisement')->getRemainCount($uid,4);
                if(empty($getRemainCount)){
                    return oo::response(-5,[],'广告未开启');
                }
                if($getRemainCount['remain']<=0){
                    return oo::response(-6,[],'次数不足');
                }
                oo::commonOprModel('advertisement')->addCount($uid,4);
            }
            //先扣金币后修改库
            $ret = oo::commonOprModel('member')->optProperty($uid,array('money'=>$optCoinNum),'-',$rid,'升级建筑扣除金币:关卡'.$levelId."，建築".$optId."，等级".($optLevelNum+1).$VideoTips);
            if($ret){
                if($userElement[$actionOpt]['level'] < 5 ){
                    if(($levelId == 1 && $userElement[$actionOpt]['level'] == 1) || ($levelId == 2 && $userElement[$actionOpt]['level'] == 1 && oo::compareVersion($version,'1.7.4'))){
                        $userElement[$actionOpt]['level'] += 2;
                    }else{
                        $userElement[$actionOpt]['level'] += 1;
                    }
                    $optLevelNum += 1;
                }
                if($userElement[$actionOpt]['maxLevel'] < 5){
                    $userElement[$actionOpt]['maxLevel'] = max($userElement[$actionOpt]['maxLevel'] + 1,$userElement[$actionOpt]['level']);
                    $maxLevel = $userElement[$actionOpt]['maxLevel'];
                }
                $sqlRet = oo::commonOprModel('member')->setUserLevel($uid,$levelId,$userElement);
                if($sqlRet){
                    //记录升级建筑奖励
                    oo::commonOprRedis('common')->incr(okeys::incr('upBuild'));
                    oo::commonOprModel('member')->optProperty($uid,array('star'=>1),'+',$rid,'升级建筑加星星:关卡'.$levelId."，建築".$optId."，等级".($optLevelNum).$VideoTips);
                    $data = array('code' => 1, 'msg' => '升级成功');
                    $lastCoins = $userCoin - $optCoinNum;
                    //最终当前等级  最终状态  最终的金币 扣掉的金币  星星数量
                    $data['data'] = ['optId'=>$optId,'level'=>$optLevelNum,'useUpCoin'=>$optCoinNum,'lastCoins'=>$lastCoins,'star'=>$star+1,'status'=>$status,'maxLevel'=>$maxLevel];
					oo::commonOprModel('statistics')->todayBuildSta($uid,'build',$optCoinNum);//每日建筑记录统计
                    oo::commonOprModel('attack')->JoinAttackQueue($uid,$levelId,$userInfo["shield"]);//尝试入攻击池
                    //数数事件-建造建筑
                    $eventData =[
                        "build_id"=>$optId,
                        "build_level"=>$userElement[$actionOpt]['level'],
                        "build_type"=>1,
                        "build_coin_basic"=>$info['useUpCoin'],
                        "build_coin_discount"=>$disNum,
                        "build_coin_cost"=>$optCoinNum,
                    ];
                    oo::commonOprModel('ta')->setEventData($uid,'building',$eventData);

                    return $data;
                }
                return array('code' => -7,'data'=>$info);
            }else{
               return  array('code' => -4, 'msg' => '所需的金币不足','data'=>$info);
            }
        }else if($opt == '1' && $optId){
            //获取当前建筑的级别
            $optLevelNum = intval($userElement[$actionOpt]['level']);

            //获取岛建筑升级金币
            $coinConfig = $this->getCoinConfig($levelId);

            //岛建筑需要的金币
            $usercoinConfig = json_decode($coinConfig,true);
            $coinLevelNum = $optLevelNum - 1;
            $optCoinNum = $usercoinConfig[$actionOpt][$coinLevelNum];
            $repairNum = intval($optCoinNum)*0.5;

            if($isVideo == 1 || $isVideo == 2){
                if($isVideo == 2){
                    $attId = intval(oo::commonOprRedis('usercache')->get(okeys::AttackedFreeReBuild($uid)));
                    if(!$attId || $attId != $optId){
                        return ['code' => -8, 'msg' => '免费修复异常-2','param'=>[
                            'uid'   => $uid,
                            'optId' => $optId,
                            'level' => $level,
                            'isVideo' => $isVideo,
                        ]];
                    }
                }
                $repairNum = 0;
            }

            //获取用户资产信息


            $status   = $userElement[$actionOpt]['status'];
            $maxLevel = $userElement[$actionOpt]['maxLevel'];
            $star = intval($userInfo['star']);
            $userCoin = intval($userInfo['money']);
            $info = [
                'optId'=>$optId,
                'level'=>$optLevelNum,
                'useUpCoin'=>$repairNum,
                'lastCoins'=>$userCoin,
                'star'=>$star,
                'status'=>$status,
                'maxLevel'=>$maxLevel
            ];

            if($userCoin < $repairNum){
                $data = array('code' => -4, 'msg' => '所需的金币不足','data'=>$info);
                return $data;
            }

            if($isVideo == 1){
                $getRemainCount = oo::commonOprModel('advertisement')->getRemainCount($uid,3);
                if(empty($getRemainCount)){
                    return oo::response(-5,[],'广告未开启');
                }
                if($getRemainCount['remain']<=0){
                    return oo::response(-6,[],'次数不足');
                }
                oo::commonOprModel('advertisement')->addCount($uid,3);
            }
            //先扣金币后修改库
            $ret = oo::commonOprModel('member')->optProperty($uid,array('money'=>$repairNum),'-',82,'修复建筑扣除金币:关卡'.$levelId."，建築".$optId."，等级".($optLevelNum).$VideoTips);
            if($ret){
                $userElement[$actionOpt]['status']  =  0;
                $sqlRet = oo::commonOprModel('member')->setUserLevel($uid,$levelId,$userElement);
                if($sqlRet){
                    //记录修复建筑奖励
                    oo::commonOprRedis('common')->incr(okeys::incr('reBuild'));
                    oo::commonOprModel('member')->optProperty($uid,array('star'=>1),'+',82,'修复建筑加星星:关卡'.$levelId."，建築".$optId."，等级".($optLevelNum).$VideoTips);
                    $data = array('code' => 1, 'msg' => '修复成功');
                    $lastCoins = $userCoin - $repairNum;
                    $data['data'] = ['level'=>$optLevelNum,'useUpCoin'=>$repairNum,'lastCoins'=>$lastCoins,'star'=>$star+1,'status'=>$status-1,'maxLevel'=>$maxLevel,'optId'=>$optId];
                    
					oo::commonOprModel('statistics')->todayBuildSta($uid,'repair',$optCoinNum);//每日建筑记录统计
                    oo::commonOprModel('attack')->JoinAttackQueue($uid,$levelId,$userInfo["shield"]);//尝试入攻击池
                    //数数事件-建造建筑
                    $eventData =[
                        "build_id"=>$optId,
                        "build_level"=>$userElement[$actionOpt]['level'],
                        "build_type"=>2,
                        "build_coin_basic"=>$repairNum,
                        "build_coin_discount"=>0.5,
                        "build_coin_cost"=>$repairNum,
                    ];
                    oo::commonOprModel('ta')->setEventData($uid,'building',$eventData);
					return $data;
                }
            }
        }
    }

    /**
     * 等级升级
     * @param $uid
     * @return array
     * Created by: Owen
     * Created on: 2019/7/9 16:03
     * Description:
     */
    public function upLevel($uid){
        $serverMaxLevel = intval(oo::commonOprModel('readconfig')->getCon('basic','curMaxLevel'))??75;//当前世界最大等级
        $userLevel = oo::commonOprModel('member')->getUserLevel($uid);
        if($userLevel['levelId']>=$serverMaxLevel){
            return ['code'=>-1,'msg'=>'level is max'];
        }
        $userElement = $userLevel['element'];
        $total_level = 0;
        foreach ($userElement as $k=>$v){
            $total_level += $v['level'];
            if($v['status'] == 1){
                break;
            }
        }
        if($total_level != 25){
            return ['code'=>-1,'msg'=>'level error'];
        }
        $levelId = intval($userLevel['levelId']) + 1;
        if(!funs::concurrentLock($uid,"UPLEVEL")){
            return ['code'=>-1,'msg'=>'level error'];
        }
        oo::commonOprModel('attack')->OutAttackQueue($uid,$userLevel['levelId'],2);//出攻击双池
        /**
         * 建筑大师活动
         */
        $userData = $buildReward =[];
        $version = oo::commonOprModel('user')->getUserVersion($uid);
        $aid =  oo::commonOprModel('activitynew')->activityLock($uid,'architecture');
        if($aid){
            if($aid==219&&$levelId>3){//防止异常过关后不清理长期活动问题
                oo::commonOprModel('activitynew')->clearBindActivity($uid,'architecture',$aid);
            }else{
                $key = okeys::BuildMaster($aid);
                $userData = $buildRewardLv = oo::commonOprRedis('common')->hGet($key,$uid);
                $lv = $buildRewardLv?min(json_decode($buildRewardLv,true)):$userLevel['levelId'];//需要领奖的等级
                $buildReward = oo::commonOprModel('activitynew')->getBuildReward($uid,$aid,$lv);//需要领奖的等级奖励
                $activityName = oo::commonOprModel('activitynew')->getActivity($aid)['imgName'];//资源图名
                if(empty($userData)){
                    $userData = [$userLevel['levelId']];
                    oo::commonOprRedis('common')->hSet($key,$uid,json_encode($userData));//设置需要领奖的等级
                }else{
                    $userData = json_decode($userData,true);
                    $userData[] = $userLevel['levelId'];
                    $userData = array_unique($userData);
                    oo::commonOprRedis('common')->hSet($key,$uid,json_encode($userData));
                }
            }
        }
        //3级永久气球
       $aid2 =  oo::commonOprModel('activitynew')->activityLock($uid,'balloon');
       if(($aid2&&$levelId==4)||$aid2==208&&$levelId>4){//防止异常过关后不清理长期活动问题
           oo::commonOprModel('activitynew')->clearBindActivity($uid,'balloon',$aid2);
       }

       if($levelId==2){//升2级发放收集活动
            oo::commonOprModel('member')->sendReward($uid,35,24*60*3,118,'新手升2级发放收集');
       }
       if($levelId==4){//升4级下掉收集活动
           $aid3 = oo::commonOprModel('activitynew')->activityLock($uid,'super_collect');
           if($aid3){
               $actInfo3 = oo::commonOprModel('activitynew')->getActivity($aid3);
               if($actInfo3['uc_type']==1){
                   oo::commonOprModel('activitynew')->clearBindActivity($uid,'super_collect',$aid3);
               }
           }

       }

        //邀请活动完成模式3
        $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
        if(empty($userInfo['inviteuid'])){
            $inviteUid = oo::commonOprModel('member')->actionAdjustInvite($uid);
            if($inviteUid > 0){
                $userInfo['inviteuid'] = $inviteUid;
            }
        }
        if($userInfo['inviteuid']){
            $fromid = $userInfo['inviteuid'];
            if($userInfo['isFb']&&$fromid){
                $aid3 = oo::commonOprModel('activitynew')->activityLock($fromid,'time_limit_invite');
                if($aid3){
                   oo::commonOprModel('activitynew')->tryFinishIntivityAct($aid3,$fromid,$uid,3,$userInfo['createtime']);
                }
            }
        }
        //召回活动-建造任务
        if(oo::compareVersion($version,'1.8.4')){
            oo::commonOprModel('callback')->doTask($uid, 8, 1);
        }
        /**
         * 通行证任务2
         */
        oo::commonOprModel('activitynew')->addTrafficPermitNum($uid,2);

        oo::commonOprModel('mining')->newLevelMining($uid);//新增矿岛
        oo::commonOprModel('member')->setUserNewLevel($uid,$levelId);//新增等级levelinfo 更新levelinfo_orig
        $config  = oo::commonOprModel('member')->getUserConfig($uid);
        $LandData = oo::commonOprModel('level')->getLandDatas($uid);
        $temp = $this->levelReward($uid);
        if(oo::compareVersion($version,'1.7.0')){
            foreach ($temp['data'] as $row){
                if($row['type'] == "coin"){
                    $reward[] = ['propsId'=>14,'value'=>$row['data'],'num'=>$row['data']];
                }else if($row['type'] == "spin"){
                    $reward[] = ['propsId'=>15,'value'=>$row['data'],'num'=>$row['data']];
                }else if($row['type'] == "card"){
                    $reward[] = ['propsId'=>$row['data']['treasureType'],'value'=>1,'num'=>1];
                }
            }
        }else{
            $reward = $temp['data'];
        }
        $outPut = [
            'code'=>1,
            'data'=>[
                'config'=>$config,
                'land'  =>$LandData,
                'reward'=>$reward,
            ]
        ];
        if($userData){
            $outPut['data']['buildMaster'] = $userData;
        }
        if($aid&&$buildReward){
            $outPut['data']['buildData'] = [
                'buildReward'=>$buildReward,
                'activityName'=>$activityName,
                'aid'=>$aid,
            ];
        }
        //保护升级玩家不被强攻
        $beUid =oo::commonOprRedis('common')->get(okeys::beAttactLock($uid));
        if($beUid){
            oo::commonOprRedis('common')->delete(okeys::DefaultEnemy($beUid));
            oo::commonOprRedis('common')->setex(okeys::beAttactLock($uid),1,60);
        }

        //数数事件-世界升级
        oo::commonOprModel('ta')->setEventData($uid,"level_up",["new_level"=>$levelId]);
        //数数事件用户信息-用户等级
        oo::commonOprModel('ta')->setEventData($uid,"user_set",["current_level"=>$levelId]);

        //百变收集活动-埋雷-雷回收
        $outPut['data']['mineData']=oo::commonOprModel('activitynew')->buryItem($uid,0,$levelId);
        $levelId == oo::commonOprModel('readconfig')->getSysCon('FirstPay','minLevelId') && oo::commonOprRedis('User')->setex(okeys::FirstPayLevelLock($uid),1,7*24*60*60);
        return $outPut;
    }

    /**
     * 設置气泡
     * @param $uid
     * @param $toUid
     * @param $bubble
     * Created by: Owen
     * Created on: 2019/7/31 16:41
     * Description:
     */
    public function setBubble($uid,$toUid,$bubble){
        $tb = otable::messageLog($toUid);
        $sql = "UPDATE {$tb} SET `bubble`={$bubble} WHERE uid={$toUid} AND toUid={$uid} ORDER BY time DESC LIMIT 1";
        oo::commonOprDb('message_log')->query($sql,false);
        if(!oo::commonOprModel('Workerman')->isUidOnline($toUid)){
            $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
            $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $friends = oo::commonOprModel('friend')->getUserAllFriend($toUid);
            oo::commonOprRedis('common')->hSet(okeys::Bubble($toUid),time(),json_encode([
                'toUid'     =>$uid,
                'bubble'    =>$bubble,
                's_picture' =>$userInfo['s_picture'],
              	'vip'       =>$userInfo['vip'],
              	'vipLv'     =>$userInfo['vipLv'],
              	'vipExpire' =>$userInfo['vip_expire'],
                'avatar'    =>$userInfo['avatar'],
                'nick'      =>$userInfo['nick'],
                'u_flag'    =>$userInfo['u_flag'],
                'isFb'      =>$userInfo['isFb'],
                'sex'       =>$userInfo['sex'],
                'signature' =>$userInfo['signature'],
                'isFbFriend'=>(in_array($uid,$friends) && $userInfo['isFb'])?1:0,
                'isFriend'  => (in_array($uid,$friends))?1:0,
                'levelId'   =>intval($userAssetsInfo['levelId']),
                'star'      =>intval($userAssetsInfo['star']),
                'money'     =>intval($userAssetsInfo['money']),
            ],JSON_NUMERIC_CHECK));
            oo::commonOprRedis('common')->expire(okeys::Bubble($toUid),oo::redisRandomExpire(7*24*60*60));
        }
    }

    public function getBubble($uid){
        $bubble = oo::commonOprRedis('common')->hGetAll(okeys::Bubble($uid));
        $time = time();
        $out = [];
        foreach ($bubble as $key=>$row){
            if($key + 24*60*60 < $time){
                oo::commonOprRedis('common')->hDel(okeys::Bubble($uid),$key);
            }else{
                $temp = json_decode($row,true);
                $temp['time'] = $key;
                $out[] = $temp;
            }
        }
        return $out;
    }

    /**
     * @param $uid   被攻击方
     * @param $toUid 攻击方
     * Created by: Owen
     * Created on: 2021/2/20 17:37
     */
    public function updateAttackProtectionTime($uid,$toUid){
        oo::commonOprModel('member')->addUserAttackedNum($uid,1);
        $from = 1;
        if(oo::commonOprModel('friend')->isFriend($uid,$toUid)){
            $from = 3;
        }
        oo::commonOprModel('member')->addToAttackProtectList($uid,$from,5 * 60);
    }



    public function helpBuildOperation($uid,$toUid,$optId){
        $G= date('G', timw());
        $userLevel = oo::commonOprModel('member')->getUserLevel($toUid);
        $levelId = $userLevel['levelId'];
        $actionOpt = $optId-1;
        $userElement = $userLevel['element'];
        $logData = [
            'time' => time(),
            'date' => date('Y-m-d H:i:s',time()),
            'uid'  => $uid,
            'toUid'=> $toUid,
            'originalElement'=> $userElement,
        ];
        if(array_sum(array_column($userElement,'level')) != 0){
            oo::logs()->debug3($logData,"{$G}.php","helpBuildOperation/");
            return false;
        }
        if($userElement[$actionOpt]['status'] == 0){
            if($userElement[$actionOpt]['level']  < 5 ){
                $userElement[$actionOpt]['level'] += 1;
            }
            if($userElement[$actionOpt]['maxLevel'] < $userElement[$actionOpt]['level']){
                $userElement[$actionOpt]['maxLevel'] = $userElement[$actionOpt]['level'];
            }
            oo::commonOprModel('member')->optProperty($toUid,array('star'=>1),'+',83,$uid.'帮助升级建筑,追加星星');
            oo::commonOprModel('member')->setUserLevel($toUid,$levelId,$userElement);
        }else if($userElement[$actionOpt]['status'] == 1){
            $userElement[$actionOpt]['status']  =  0;
            oo::commonOprModel('member')->optProperty($toUid,array('star'=>1),'+',83,$uid.'帮助修复建筑,追加星星');
            oo::commonOprModel('member')->setUserLevel($toUid,$levelId,$userElement);
        }
        oo::commonOprModel('Workerman')->push($toUid,ocmd::$send['Level_helpBuildOperation'],[]);

        $logData['newElement'] = $userElement;
        oo::logs()->debug3($logData,"{$G}.php","helpBuildOperation/");
        return true;
    }

    /**
     * 获取最大等级信息
     * @param $uid
     * @return mixed
     * Created by: Owen
     * Created on: 2020/4/26 14:15
     */
    public function getMaxLevelStatus($uid){
        $userLevel = oo::commonOprModel('member')->getUserLevel($uid);
        $config['curMaxLevel'] = intval(oo::commonOprModel('readconfig')->getCon('basic',"curMaxLevel"));
        if($userLevel['levelId'] < $config['curMaxLevel']){
            $config['isReward'] = -1;
            return $config;
        }
        $element = $userLevel['element'];
        $curBuildLevel = 0;
        foreach ($element as $row){
            $row['status'] ? $curBuildLevel = $curBuildLevel+$row['level'] - 1 : $curBuildLevel += $row['level'];
        }
        if($curBuildLevel != 25){
            $config['isReward'] = -1;
            return $config;
        }
        $tb = otable::MaxLevelReward();
        $sql= "SELECT * FROM {$tb} WHERE uid={$uid} AND levelId={$config['curMaxLevel']} LIMIT 1";
        $ret= oo::commonOprDb('common')->getOne($sql,MYSQLI_ASSOC);
        if(empty($ret)){
            $time = time();
            oo::commonOprDb('common')->query("INSERT INTO {$tb} (uid,levelId,time) VALUES({$uid},{$config['curMaxLevel']},{$time})");
            $config['isReward'] = 0;
        }else{
            $config['isReward'] = $ret['isReward'];
        }
        return $config;
    }

    /**
     * 领取最大奖励
     * @param $uid
     * @return string
     * Created by: Owen
     * Created on: 2020/4/26 12:26
     */
    public function getMaxLevelReward($uid){
        $status = self::getMaxLevelStatus($uid);
        if($status['isReward'] == -1){
            return oo::response(-2,[],'等级未到最大');
        }
        if($status['isReward'] == 1){
            return oo::response(-3,[],'奖励已领取');
        }
        $config = oo::commonOprModel('readconfig')->getSysCon('Reward',"maxLevel");
        $config = json_decode($config,true);
        $coins = oo::commonOprModel('goods')->getGoodCoins($uid,$config['coins']['coins']);
        $coins = intval($coins * $config['coins']['bet']);
        $spins = intval($config['spins']);
        $props = $config['props'];
        $reward= [];
        if($coins != 0){
            $reward['money'] = $coins;
        }
        if($spins != 0){
            $reward['spins'] = $spins;
        }
        if(!empty($reward)){
            oo::commonOprModel('member')->optProperty($uid,$reward,'+',84,'最大关卡奖励:'.$status['curMaxLevel']);
        }
        if(!empty($props)){
            foreach ($props as $row){
                oo::commonOprModel('props')->addUserProps($uid,$row['propsId'],$row['num'],0,84);
            }
        }
        $tb = otable::MaxLevelReward();
        $time = time();
        oo::commonOprDb('common')->query("UPDATE {$tb} SET `isReward`=1,`rewardTime`={$time} WHERE uid={$uid} AND levelId={$status['curMaxLevel']} LIMIT 1");
        return oo::response(1,[
            'reward' => [
                'coins' => $coins,
                'spins' => $spins,
                'props' => $props
            ]
        ]);
    }

    /**
     * 一键建造
     * @param $uid
     * @return string
     * Created by: Owen
     * Created on: 2020/11/20 16:39
     */
    public function oneClick($uid){
        $userLevelInfo  = oo::commonOprModel('member')->getUserLevel($uid);
        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $userCurCoin    = intval($userAssetsInfo['money']);
        $userCurLevelId = intval($userLevelInfo['levelId']);
        $buildCoinConfig= json_decode($this->getCoinConfig($userCurLevelId),true);
        $userCurElement = $userLevelInfo['element'];
        $buildMoney     = [];
        $discount       = [0=>1, 1=>1, 2=>1, 3=>1, 4=>1];
        $aid = oo::commonOprModel('activitynew')->activityLock($uid,'discounts_architecture');
        if($aid){
            foreach ($discount as $key=>$row){
                $discount[$key] = oo::commonOprModel('activitynew')->discountsArch($aid,$key,$uid) ?? 1;
            }
        }
        foreach ($userCurElement as $buildId=>$row){
            if($row['status']){
                $buildMoney[$buildId] = (ceil($buildCoinConfig[$buildId][$row['level'] - 1])/2) * $discount[$buildId];
            }else{
                $buildMoney[$buildId] = ($buildCoinConfig[$buildId][$row['level']]) * $discount[$buildId];
            }
        }
        $buildMoney = array_filter($buildMoney);
        $actionMoney = 0;
        $actionStar  = 0;
        $actionBuild = [];
        $actionBuildStr = [];
        while (count($buildMoney)){
            $curMinMoney = min($buildMoney);
            if($curMinMoney == 0){
                break;
            }
            $tempMoney = $actionMoney + $curMinMoney;
            if($userCurCoin - $tempMoney < 0){
                break;
            }
            $actionMoney += $curMinMoney;
            $actionBuildId = array_search($curMinMoney,$buildMoney);
            $actionBuild[] = $actionBuildId;
            if($userCurElement[$actionBuildId]['status']){
                $userCurElement[$actionBuildId]['status'] = 0;
                $actionBuildStr[] = "修复:{$actionBuildId}";
                $build_type =2;
            }else{
                $userCurElement[$actionBuildId]['level'] += 1;
                $userCurElement[$actionBuildId]['maxLevel'] = max($userCurElement[$actionBuildId]['level'],$userCurElement[$actionBuildId]['maxLevel']);
                $actionBuildStr[] = "升级:{$actionBuildId}";
                $build_type =1;
            }
            $actionStar += 1;
            $newMoney = intval($buildCoinConfig[$actionBuildId][$userCurElement[$actionBuildId]['level']]);
            if($newMoney > 0){
                $buildMoney[$actionBuildId] = $newMoney * $discount[$actionBuildId];
            }else{
                unset($buildMoney[$actionBuildId]);
            }
            //数数事件-建造建筑
            $eventData =[
                "build_id"=>$actionBuildId,
                "build_level"=>$userCurElement[$actionBuildId]['level'],
                "build_type"=>$build_type,
                "build_coin_basic"=>$newMoney,
                "build_coin_discount"=>$discount[$actionBuildId],
                "build_coin_cost"=>$curMinMoney,
            ];
            oo::commonOprModel('ta')->setEventData($uid,'building',$eventData);
        }
        $actionStar  > 0 && oo::commonOprModel('member')->optProperty($uid,['star'=>$actionStar],'+',87,"一键建造：".implode(',',$actionBuildStr));
        if($actionMoney>0){
            oo::commonOprModel('member')->optProperty($uid,['money'=>$actionMoney],'-',87,"一键建造：".implode(',',$actionBuildStr));
            oo::commonOprModel('member')->setUserLevel($uid,$userCurLevelId,$userCurElement);
            oo::commonOprModel('attack')->JoinAttackQueue($uid,$userCurLevelId,$userAssetsInfo["shield"]);//尝试入攻击池
        }
        $userAssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $userAssetsInfo['coins'] = $userAssetsInfo['money'];
        unset($userAssetsInfo['money']);
        return oo::response(1,[
            'element'    => $userCurElement,
            'assetsInfo' => $userAssetsInfo,
        ],"建造成功");
    }
}
