<?php
defined( 'IN_WEB') or die( 'Include Error!');
class ModelGameinfo {
   public $stealCfg;
   public $tb_arr = [];
   public $steal_allow =["mid","levelId","money","createtime","stealedNum","stealProtectionTime","levelMinMoney"];
   public $this_allow = [];//当前模式规则
   public $this_tb='crazygod_api_user.gh_gameinfo_steal';//当前模式表
   public $tb_str = 'tb_steal'; //当前表标志

    public function __construct(){
       $this->stealCfg = oo::cfg('stealattack')['steal'];
       $this->tb_arr =[
           "tb_steal"=>'crazygod_api_user.gh_gameinfo_steal',
           "tb"=>otable::gh_gameserver(1),
       ];
       $this->this_allow =$this->steal_allow;
    }

    /**
     * Notes:获取满足条件的steal表信息
     * User: wsc
     * Time: 2020/4/20 15:36
     * @param string $field
     * @param bool $w
     * @param string $order
     * @param string $limit
     * @return array
     */
   public function getDataFromDB($field="*",$w=false,$order="",$limit=""){
       $data = [];
       $where = " 1=1 ";
       if($w&&is_array($w)){
           $where .= " AND ";
           $where .= implode(" AND ",array_values($w));
       }
       $tb = strstr($field,'rNum')?$this->this_tb.',(SELECT @rowNum:=0) b':$this->this_tb;
       $sql = "SELECT {$field} FROM {$tb} WHERE {$where} {$order} {$limit}";
       $data = oo::commonOprDb('ghgames')->getAll($sql,1);
       return $data;
   }

    /**
     * Notes:获取用户GameInfoSteal
     * User: wsc
     * Time: 2020/4/11 10:13
     * @param $uid
     * @param bool $db
     * @return array
     */
    public function getGameInfoSteal($uid,$db=false){
        $cache = [];
        if(!$uid){
            return $cache;
        }
        $key = okeys::UserGameInfoSteal($this->tb_str.'-'.$uid);
        if(!$db){
           $cache  = oo::commonOprRedis('Userinfo')->hGetAll($key);
        }
        if(empty($cache['mid'])){
            $sql = "SELECT * FROM {$this->this_tb} WHERE mid={$uid} limit 1";
            $info = oo::commonOprDb('ghgames')->getOne($sql,1);
            oo::commonOprRedis('Userinfo')->delete($key);
            if(!empty($info)&&is_array($info)){
                $cache = $info;
                $ts = timeFuns::today()[1];
                oo::commonOprRedis('Userinfo')->hMset($key,$cache);
                oo::commonOprRedis('Userinfo')->expireAt($key,oo::redisRandomExpire($ts));
            }
        }
        return $cache;
    }

    /**
     * Notes:更新GameInfoSteal
     * User: wsc
     * Time: 2020/4/11 10:21
     * @param $uid
     * @param $arr
     * @return bool
     */
    public function upDateGameInfoSteal($uid,$arr,$limit=false){
        $res = false;
        $info = $this->getGameInfoSteal($uid);
        $gameInfo = $arr;
        if(empty($info)||!is_array($info)){
            $gameInfo =  oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $minLevelMoney = oo::commonOprModel('level')->getLevelConf($gameInfo['levelId'])['minMoney'];
            if(empty(array_intersect(array_keys($arr),$this->this_allow))){
                return false;
            }
            foreach($arr as $k=>$v){
                $gameInfo[$k] = $v;
            }
            $gameInfo['mid'] =$uid;
            $gameInfo['createtime'] =time();
            $gameInfo['levelMinMoney'] = $minLevelMoney;
        }
        $allow_kv = $this->allowField($gameInfo);
        if(!$uid||empty($allow_kv)||!is_array($allow_kv)){
            return $res;
        }
        if(!empty($info)&&is_array($info)){
            $valArr = [];
            foreach($allow_kv as $k=>$v){
                $valArr[] = $k.'='.$v;
            }
            $valStr = trim(implode(',', $valArr));
            $sql = "UPDATE {$this->this_tb} SET {$valStr} WHERE mid = {$uid} limit 1";
            $res =  oo::commonOprDb('ghgames')->query($sql);
            if($res){
                $this->getGameInfoSteal($uid,true);
            }
        }else{
            if($gameInfo['money']<$minLevelMoney||$gameInfo['levelId']<$this->stealCfg['minLv']){
                return true;
            }
            if(funs::concurrentLock($uid,'insertSteal')){
                $res = $this->insertGameInfoSteal($allow_kv);
            }

        }
        return $res;
    }

    /**
     * Notes:写入GameInfoSteal
     * User: wsc
     * Time: 2020/4/11 10:36
     * @param $arr
     * @return bool
     */
    public function insertGameInfoSteal($arr){
        $allow_kv = [];
        $res = false;
        $allow_kv = $this->allowField($arr);
        if(!isset($allow_kv['mid'])||empty($allow_kv)){
            return $res;
        }
        $uid = intval($arr['mid']);
        $info = $this->getGameInfoSteal($uid);

        if(empty($info)){
            $keys = implode(",",array_keys($allow_kv));
            $values = implode(",",array_values($allow_kv));
            $sql = "INSERT INTO {$this->this_tb}({$keys}) values ({$values})";
            $res =  oo::commonOprDb('ghgames')->query($sql);
        }
        return $res;
    }
    /**
     * Notes:删除GameInfoSteal
     * User: wsc
     * Time: 2020/4/11 17:34
     * @param $uids
     * @return bool
     */
    public function deleteGameInfoSteal($uids){
        $res = false;
        if(empty($uids)){
            return $res;
        }
        if(is_array($uids)){
            $uidStr =  implode(",",array_values($uids));
            $w = " mid IN ({$uidStr})";
        }else{
            $w = " mid={$uids}";
        }
        if(!empty($w)){
            $sql = "DELETE FROM {$this->this_tb} WHERE {$w}";
            $res =  oo::commonOprDb('ghgames')->query($sql);
            if($res&&!empty($uids)&&is_array($uids)){//更新缓存
                foreach ($uids as $v){
                    $this->getGameInfoSteal($v,true);
                }
            }
        }
        return $res;
    }

    /**
     * Notes:过滤非法字段
     * User: wsc
     * Time: 2020/4/11 17:34
     * @param $arr
     * @return array
     */
    public function allowField($arr){
        $allow_kv = [];
        foreach ($arr as $k=>$v){
            if(!in_array($k,$this->this_allow)){//非法字段过滤
                continue;
            }
            $allow_kv[$k] = $v;
        }
        return $allow_kv;
    }

    /**
     * Notes:不满足条件
     * User: wsc
     * Time: 2020/4/14 14:59
     * @return array
     */
    public function noSatisfyStealDte(){
        $ts = time();
        $where ="(money < levelMinMoney OR levelId < {$this->stealCfg['minLv']}) AND stealProtectionTime<{$ts}";
        $sql = "SELECT mid FROM {$this->this_tb} WHERE {$where}";
        $data = oo::commonOprDb('ghgames')->getAll($sql,1);
        return $data;
    }

    public function updateStatus($w,$arr){
        $res =false;
        $uList = $this->getDataFromDB('mid',$w);
        $uids = !empty($uList)?array_column($uList,'mid'):[];//不满足条件的
        if(!empty($uids)){
            //更新db
            $allow_kv = $this->allowField($arr);
            foreach($allow_kv as $k=>$v){
                $valArr[] = $k.'='.$v;
            }
            $valStr = trim(implode(',', $valArr));
            $uidStr =  implode(",",array_values($uids));
            $w = " mid IN ({$uidStr})";
            $sql = "UPDATE {$this->this_tb} SET {$valStr} WHERE {$w}";
            $res =  oo::commonOprDb('ghgames')->query($sql);
            //更新缓存
            if($res&&!empty($uids)&&is_array($uids)){
                foreach ($uids as $v){
                    $this->getGameInfoSteal($v,true);
                }
            }
        }
        return $res;
    }
    /**
     * Notes:定时操作
     * User: wsc
     * Time: 2020/4/11 15:28
     */
    public function cornTabUpTable(){
        //清除表里不满足条件的用户
        $list = $this->noSatisfyStealDte();
        $uidList = !empty($list)?array_column($list,'mid'):[];//不满足条件的
        $res['del']=$this->deleteGameInfoSteal($uidList);

        //更新用户状态
        $w = ["stealedNum!=0"];
        $arr=["stealedNum"=>0];
        $res['upd']= $this->updateStatus($w,$arr);
        return $res;
    }


}
