<?php

namespace loyalsoft;

/**
 * 战斗模块
 * @author c'y'zhao
 */
class FightProc {

    public const TowerGateId = 940011999;

    /**
     * 逻辑分发
     * 所有的Proc中必须有这样一个方法
     * @param Req $req
     */
    public static function procMain($req) {
        switch ($req->cmd) {
            case CmdCode::fight_settle:                                         # 6801 主线战斗结算
                return FightProc::Settle();
            case CmdCode::fight_PassGateTsPrizeReceive:                         # 6802 章节宝箱的领取
                return FightProc::PassGateTsPrizeReceive();
            case CmdCode::fight_selectGate:                                     # 6803 主线剧情关卡选择
                return FightProc::SelectGate();
            case CmdCode::fight_gateChallengeRewards:                           # 6804 挑战关卡: 领取奖励
                return FightProc::GateChallengeRewards();
            case CmdCode::fihgt_reliveCost:                                     # 6805 战斗: 复活花费
                return FightProc::ReliveCost();
            case CmdCode::fight_plotSav:                                        # 6806 主线剧情(已播放)回存
                return FightProc::PlotSav();
            case CmdCode::fight_sweep:                                          # 6807 主线扫荡
                return FightProc::FightSweep();
            case CmdCode::fight_startFight:                                     # 6808 主线剧情关卡开始挑战
                return self::StartFight();
            case CmdCode::fight_tower_RefreshSkills:                            # 6809 挑战关卡: 刷新初始技能
                return self::TowerRefreshSkills();
            case CmdCode::fight_tower_updatelocklist:                           # 6810 挑战关卡: 更新技能锁定列表
                return self::TowerUpdateLockskillList();
            case CmdCode::fight_rankInfo:                                       # 6811 获取主线关卡排行榜信息
                return self::GetRankInfo();
            case CmdCode::fight_rank_uidEquipInfo:                              # 6812 获取主线关卡榜内玩家的装备信息
                return self::GetUidEquipInfo_Rank();
            case CmdCode::fight_rank_GetMainGateRankRewardInfo:                 # 6813 获取通关荣誉榜信息
                return self::GetmainGate_RankRewardInfo();
            case CmdCode::fight_rank_GetFightPowerRankRewardInfo:               # 6814 获取战力荣誉榜信息
                return self::GetFightPower_RankRewardInfo();
            case CmdCode::fight_rank_ReceiveRankReward_MainGate:                # 6815 领取通关荣誉榜奖励
                return self::ReceiveRankReward_MainGate();
            case CmdCode::fight_rank_ReceiveRankReward_FightPower:              # 6816 领取战力荣誉榜奖励
                return self::ReceiveRankReward_FightPower();
            case CmdCode::fight_rank_IsExistRankReward:                         # 6817 是否存在未领取的荣誉榜奖励
                return self::IsExistRankReward();
            default:
                Err(ErrCode::cmd_err);
        }
    }

    /**
     * 6807 扫荡
     * @return type
     */
    public static function FightSweep() {
        //list($gateId) = req()->paras;

        $passGateId = ctx()->gates->maxPassGateId();
        my_Assert($passGateId != 0, ErrCode::gate_NoSweep);
        $mo = GameConfig::gate_getItem($passGateId);
        $gateName = $mo->gateName;
        $costTili = glc()->sweep_cost_tili;
        $curTili = ctx()->baseInfo->CurTili();
        my_Assert($curTili >= $costTili, ErrCode::notenough_tili);
        $max = glc()->sweepMaxNum;
        my_Assert(ctx()->gates->fightSweepNum < $max, ErrCode::gate_SweepMaxNum_limit);
        ctx()->gates->fightSweepNum += 1;
        ctx()->baseInfo->Consume_tili($costTili);
        $prizeArr = array();

        $wavesArr = GameConfig::waves_getItemArray($passGateId);
        $count = count($wavesArr);
        $wavesMo = $wavesArr[$count - 1];

        ctx()->baseInfo->Add_Gold($wavesMo->rewardGold);
        $gold = $wavesMo->rewardGold;
        $prizeArr[] = "1," . $gold;
        ctx()->baseInfo->Add_Gold($gold);

        $exp = $wavesMo->rewardExp;
        $prizeArr[] = "4," . $exp;
        ctx()->baseInfo->Add_Exp($exp);
        if ($wavesMo->rewardTuZhi != null) {
            $tuzhi = explode('-', $wavesMo->rewardTuZhi);
            $n = rand($tuzhi[0], $tuzhi[1]);
            $tuzhiArr = array();
            $item = GameConfig::item();
            foreach ($item as $id => $mo) {
                if ($mo->itemType == 100) {
                    $tuzhiArr[] = $id;
                }
            }
            for ($i = 0; $i < $n; $i++) {
                $index = rand(0, count($tuzhiArr) - 1);
                $goodsStr = $tuzhiArr[$index] . ',' . 1;
                $prizeArr[] = $goodsStr;
                StoreProc::AddMultiItemInStore($goodsStr);
            }                    
            
        }

        if ($wavesMo->rewardGem != null) {
            $goodsStr = self::sweepRandReward($wavesMo->rewardGem);
            $str = explode(';', $goodsStr);
            $dic = GameConfig::gem();
            foreach ($str as $value) {
                $list = explode(',', $value);
                $posId = rand(1, 6);
                $qual = $list[0];
                foreach ($dic as $key => $gemMo) {
                    if ($gemMo->qual == $qual && $gemMo->position == $posId) {
                        $prizeArr[] = $gemMo->typeId . ',' . $list[1];

                        SystemProc::GetGem_GreaterOrangeQual_SweepMainGateIndex(req()->zoneid, ctx()->baseInfo->name, Ins_GateInfo::gateNum($passGateId), $gateName, $gemMo->typeId);
                        StoreProc::PutGemInStore($gemMo->typeId, $list[1]);
                        break;
                    }
                }
            }
        }


        UserProc::updateUserInfo();
        $ret = array(
            'tili' => ctx()->baseInfo->tili,
            'fightSweepNum' => ctx()->gates->fightSweepNum,
            'prizeArr' => $prizeArr,
            'store' => ctx()->store,
            'task' => ctx()->task,
        );
        return Resp::ok($ret);
    }

    static function sweepRandReward($rewardStr) {
        $ctxArr = explode(';', $rewardStr);
        $numArr = explode('-', $ctxArr[0]);
        $num = rand($numArr[0], $numArr[1]);

        $rand = 0;
        $itemArr = explode(',', $ctxArr[1]);
        foreach ($itemArr as $value) {
            $arr = explode(':', $value);
            $itemId = $arr[0];
            $per = $arr[1];

            $rand += $per;
        }

        $res = "";
        for ($i = 0; $i < $num; $i++) {
            $start = 0;
            $end = 0;
            $randNum = rand(1, $rand);
            $id = 0;
            foreach ($itemArr as $str) {
                $arr = explode(':', $str);
                $itemId = $arr[0];
                $per = $arr[1];

                $end += $per;
                if ($randNum > $start && $randNum <= $end) {
                    $id = $itemId;
                    break;
                }
                $start = $end;
            }

            if ($id != 0) {
                $str = $id . ',1';
                if ($res == "") {
                    $res = $str;
                } else {
                    $res = $res . ';' . $str;
                }
            }
        }

        return $res;
    }

    /**
     * 6808 开始挑战 (主线关卡:扣除体力, 挑战关卡: 增加次数)
     */
    private static function StartFight() {
        list($gateId, $layerNum) = req()->paras;
        my_Assert($gateId > 0, ErrCode::paras_err);
        $mo = GameConfig::gate_getItem($gateId);
        my_Assert(null != $mo, ErrCode::err_const_no);

        if (Ints::Slice($gateId, 0, 1) == 9) {                                  # 爬塔模式
//            list($layerNum) = req()->paras;
            if ($layerNum != ctx()->gates()->TowerGateInfo()->CurLayer) {       # 起始层数校验
                Err(ErrCode::tower_layerNum);
            }
            if (ctx()->gates()->TowerGateInfo()->TodayChanNum < 1) {           # 剩余次数校验
                Err(ErrCode::tower_timeNo);
            }
            ctx()->gates()->TowerGateInfo()->TodayChanNum--;                        # 增加次数
        } else {                                                                # 主线剧情
            my_Assert(ctx()->base()->Consume_tili($mo->cost_tili), ErrCode::notenough_tili);
        }
        UserProc::updateUserInfo();
        return Resp::ok(array("tili" => ctx()->baseInfo->tili, "tili_ts" => ctx()->baseInfo->tili_ts));
    }

    public static function FightDailyClear() {
        //ctx()->gates->xunluo_quick_buyRecord = 0;
        ctx()->gates->fightSweepNum = 0;
        ctx()->gates()->TowerGateInfo()->RefreshSkillTimes = 0;
        ctx()->gates()->TowerGateInfo()->TodayChanNum = glc()->tower_daily_chanceNum;
    }

    /**
     * 6806 剧情回存
     * @return type
     */
    public static function PlotSav() {
        list($gateId) = req()->paras;

        my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::err_const_no);
        ctx()->gates->GateList->$gateId->plotStart = 1;

        UserProc::updateUserInfo();
        $ret = array(
            'ok' => 1,
        );
        return Resp::ok($ret);
    }

// <editor-fold defaultstate="collapsed" desc="挑战模块">

    /**
     * 6810 挑战关卡: 更新锁定技能列表
     */
    public static function TowerUpdateLockskillList() {
        list($li_zd, $li_bd, $li_zds, $li_bds) = req()->paras;                  # 参数解析
        $t = ctx()->gates()->TowerGateInfo();                                   # 记忆技能刷新结果
        $t->skill_zhudong = $li_zd;
        $t->skill_beidong = $li_bd;
        $t->skill_zhudong_lockState = $li_zds;
        $t->skill_beidong_lockState = $li_bds;
        UserProc::updateUserInfo();
        return Resp::ok();
    }

    /**
     * 6809 挑战关卡: 刷新初始技能(扣除免费次数/cost)
     */
    public static function TowerRefreshSkills() {
        list($isFree, $li_zd, $li_bd, $li_zds, $li_bds) = req()->paras;         # 参数解析
        if ($isFree) {
            if (ctx()->gates()->TowerGateInfo()->RefreshSkillTimes > glc()->tower_daily_refreshChanceNum) {
                Err(ErrCode::tower_refreshNo);                                  # 免费次数不足
            }
        } else {
            list($type, $num) = explode(':', glc()->tower_refreshCost);         # 二级货币类型(1:金币,2:元宝):数量
            if ($type == 1) {                                                   # 金币
                my_Assert(ctx()->base()->Consume_Gold($num), ErrCode::notenough_gold_msg);
            } else if ($type == 2) {                                            # 元宝
                my_Assert(ctx()->base()->Consume_Cash($num), ErrCode::notenough_cash_msg);
            } else {
                Err(ErrCode::err_const_no, "检查刷新扣费配置信息!");
            }
        }
        $t = ctx()->gates()->TowerGateInfo();                                   # 记忆技能刷新结果
        $t->RefreshSkillTimes++;
        $t->skill_zhudong = $li_zd;
        $t->skill_beidong = $li_bd;
        $t->skill_zhudong_lockState = $li_zds;
        $t->skill_beidong_lockState = $li_bds;
        UserProc::updateUserInfo();

        $ret = array(
            'task' => ctx()->task,
        );
        return Resp::ok($ret);
    }

    /**
     * 6805 战斗: 复活花费
     * @return type
     * @version 2024年5月17日 重整利用为复活扣除消耗功能
     */
    public static function ReliveCost() {
        // 复活可以扣除复活币(暂无)或者元宝,(客户端看广告复活不需要跟服务器通讯)
        list($reliveNum) = req()->paras;
        $arr = explode(',', glc()->Relive_cost);
        my_Assert($reliveNum >= 0 && $reliveNum <= Count($arr), ErrCode::paras_err); # 参数范围>0
        $amt = $arr[$reliveNum - 1];
        my_Assert(ctx()->base()->Consume_Cash($amt), ErrCode::notenought_yuanbao);
        UserProc::updateUserInfo();
        return Resp::ok();
    }

    /**
     * 6804 挑战关卡: 奖励领取
     * @return type
     */
    public static function GateChallengeRewards() {
        list($finalLayer) = req()->paras;                                       # 战斗结束时的层数

        $lastLayer = ctx()->gates()->TowerGateInfo()->CurLayer;
        $arr = GameConfig::waves_getItemArray(self::TowerGateId);
        if ($finalLayer > $lastLayer) {
            foreach ($arr as $layerId => $layerMo) {
                if ($layerId >= $lastLayer && $layerId < $finalLayer) {
                    my_Assert($layerMo != null, ErrCode::err_const_no);
                    StoreProc::AddMultiItemInStore($layerMo->rewards);              # 发放奖励
                }
            }
            ctx()->gates()->TowerGateInfo()->CurLayer = $finalLayer;
            UserProc::updateUserInfo();
            $ret = array(
                'store' => ctx()->store,
                'gold' => ctx()->base()->gold,
                'cash' => ctx()->base()->cash,
                'task' => ctx()->task,
            );
            return Resp::ok($ret);
        } else if ($finalLayer == $lastLayer) {
            $ret = array(
                'store' => ctx()->store,
                'gold' => ctx()->base()->gold,
                'cash' => ctx()->base()->cash,
                'task' => ctx()->task,
            );
            return Resp::ok($ret);
        }
        return Resp::err(ErrCode::tower_rewardNo);                              # 没有奖励
    }

// </editor-fold>

    /**
     * 6803 关卡选择
     * @return type
     */
    public static function SelectGate() {
        list($gateId) = req()->paras;

        ctx()->gates->CurrentGateId = $gateId;

        UserProc::updateUserInfo();
        $ret = array(
            'gates' => ctx()->gates,
        );
        return Resp::ok($ret);
    }

    /**
     * 6802 章节宝箱的领取
     * @return type
     */
    public static function PassGateTsPrizeReceive() {
        list($gateId, $index) = req()->paras;

        $gateMo = GameConfig::gate_getItem($gateId);
        my_Assert($gateMo != null, ErrCode::err_const_no);

        my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::gate_NoUserGateInfo);
        $gateInfo = ctx()->gates->GateList->$gateId;

        $tag = false;
        $prize = "";
        $mask = 0;
        switch ($index) {
            case 1:
                $ts = $gateMo->first_ts1 * 60;
                if ($gateInfo->MaxSeconds >= $ts) {
                    $tag = true;
                }
                $mask = 1;
                $prize = $gateMo->first_reward1;
                break;
            case 2:
                $ts = $gateMo->first_ts2 * 60;
                if ($gateInfo->MaxSeconds >= $ts) {
                    $tag = true;
                }
                $mask = 2;
                $prize = $gateMo->first_reward2;
                break;
            case 3:
                if ($gateInfo->pass > 0) {
                    $tag = true;
                }
                $mask = 3;
                $prize = $gateMo->first_reward3;
                break;
            default:
                break;
        }

        if ($tag) {
            my_Assert(!in_array($mask, $gateInfo->FirstReward), ErrCode::gate_GatePriceHasReceive);
            $gateInfo->FirstReward[] = $mask;
            StoreProc::AddMultiItemInStore($prize);
        }
        ctx()->gates->GateList->$gateId = $gateInfo;

        UserProc::updateUserInfo();
        $ret = array(
            'gates' => ctx()->gates,
            'store' => ctx()->store,
            'task' => ctx()->task,
            'gold' => ctx()->baseInfo->gold,
            'reward' => StoreProc::$reward,
        );
        return Resp::ok($ret);
    }

    /**
     * [6801]关卡战斗结算
     * @return type
     */
    public static function Settle() {
        list($resultType, $gateId, $gold, $curTs, $pickups,
                $finalLayer, $finalHpPercent, $killMonsterNum, $killBossNum) = req()->paras;
        # 客户端需要增加参数: killmonserNum,killBosssNum, finalHpPercent(最终血量百分比)
        $gateMo = GameConfig::gate_getItem($gateId);
        my_Assert($gateMo != null, ErrCode::err_const_no);
        my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::gate_NoUserGateInfo);
        $gateInfo = ctx()->gates->GateList->$gateId;
        $ts = $gateInfo->MaxSeconds;
        if ($curTs >= $ts) {
            $gateInfo->MaxSeconds = $curTs;
        }
        if ($resultType) {                                                      # 胜利
            if (ctx()->gates->GateList->$gateId->pass == 0) {
                ctx()->gates->GateList->$gateId->pass = 1;
                TaskProc::Day7TaskReset($gateId);                               # 刷新七日任务
                $maxGateId = ctx()->gates->maxPassGateNumId();

                if ($maxGateId > 0) {
                    self::Ranking_MainGateIndex($maxGateId);
                    self::IsAchievedMainGate_PassReward($maxGateId);
                }
            }

            TaskProc::OnPassGate_X($gateId);                                    # 刷新任务进度: 通关第X关

            if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainStoryGate) {
                ctx()->gates()->UnlockNextPlotGate($gateId);                    # 解锁下一主线关卡
//                ctx()->gates()->UnlockMainChallengeGate($gateId);              # 挑战关卡解锁逻辑. -gwang 2024年4月15日
            } else {                                                            # 不是主线关卡, 暂时没有其他逻辑
            }
//            StoreProc::AddMultiItemInStore($gateMo->reward_win);                # 发放胜利奖励(2024.5.30 过期)
        }
//        else {                                                                # 失败
////            StoreProc::AddMultiItemInStore($gateMo->reward_fail);               # 发放失败奖励(2024.5.30 过期)
//        }

        StoreProc::AddMultiItemInStore($pickups);                               # 战场拾取道具直接入背包
        ctx()->base()->Add_Gold($gold);                                         # 战场拾取的金币直接入背包
        //ctx()->base()->Add_Exp($exp);
        $waveMo = GameConfig::waveItem_getItem($gateId, $finalLayer);
        my_Assert(null != $waveMo, ErrCode::err_const_no);
        ctx()->base()->Add_Exp($waveMo->rewardExp);                             # 指挥官经验
        ctx()->base()->Add_Gold($waveMo->rewardGold);                           # 金币奖励
        $pickups .= ";1," . $gold + $waveMo->rewardGold;
        # 图纸奖励: 数量min-max, 部位随机
        if (strlen($waveMo->rewardTuZhi) > 0 && str_contains($waveMo->rewardTuZhi, '-')) {
            list($tz_min, $tz_max) = explode('-', $waveMo->rewardTuZhi);        # 图纸数量
            $tz_n = rand($tz_min, $tz_max);
            # 图纸部位数据源 1001, 1002, 1003, 1004, 1005, 1006
            for ($i = 0; $i < $tz_n; $i++) {
                $id = 1000 + rand(1, 6);
                StoreProc::AddMultiItemInStore("$id,1");                        # 获得图纸
                $pickups .= ";$id,1";
            }
        }
        # 宝石奖励: 数量min-max;品质:权重,品质:权重...
        if (strlen($waveMo->rewardGem) > 0) {
            list($gs_num, $gs_props) = explode(';', $waveMo->rewardGem);
            list($gem_min, $gem_max) = explode('-', $gs_num);                   # 宝石数量
            $gem_n = rand($gem_min, $gem_max);
            $arr = explode(",", $gs_props);
            $pool = array();
            $n = 0;
            foreach ($arr as $str) {
                list($qual, $props) = explode(':', $str);
                $pool[] = array('q' => $qual, 'p' => $props);
                $n += $props;
            }
            for ($i = 0; $i < $gem_n; $i++) {                                   # 随机n块宝石
                $r = rand(1, $n);                                                  # 投色子
                $l = 0;
                foreach ($pool as $item) {
                    if ($r <= ($l + $item['p'])) {
                        $gemId = $item['q'] * 100000 + rand(1, 6) * 1000;
                        SystemProc::GetGem_GreaterOrangeQual_MainGate(req()->zoneid, ctx()->baseInfo->name, Ins_GateInfo::gateNum($gateId), $gateMo->gateName, $gemId); //广播
                        StoreProc::PutGemInStore($gemId);                       # 发放宝石并退出本次投色子
                        $pickups .= ";$gemId,1";
                        break;
                    }
                    $l += $item['p'];                                             # 累计到下一段
                }
            }
        }

        if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainStoryGate) {            # 主线剧情,
            TaskProc::OnFightNumMainGate();
        } else if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainChallengeGate) { # 主线剧情对应的难度挑战
            TaskProc::OnFightNumChallengeGate();
        }
        TaskProc::OnKillCommonNumMonster($killMonsterNum);
        TaskProc::OnKillleaderNumMonster($killBossNum);

        UserProc::updateUserInfo();
        $ret = array(
            'gates' => ctx()->gates,
            'store' => ctx()->store,
            'task' => ctx()->task,
            'baseInfo' => ctx()->base(),
            'gold' => $gold + $waveMo->rewardGold,
            'exp' => $waveMo->rewardExp,
            'rewardStr' => $pickups
        );
        return Resp::ok($ret);
    }

//    /**
//     * [6801]关卡战斗结算
//     * @return type
//     */
//    public static function Settle_bak() {
//        list($resultType, $gateId, $gold, $curTs, $pickups) = req()->paras;
//        # 客户端需要增加参数: killmonserNum,killBosssNum, finalHpPercent(最终血量百分比)
//        $gateMo = GameConfig::gate_getItem($gateId);
//        my_Assert($gateMo != null, ErrCode::err_const_no);
//        my_Assert(StlUtil::dictHasProperty(ctx()->gates->GateList, $gateId), ErrCode::gate_NoUserGateInfo);
//        $gateInfo = ctx()->gates->GateList->$gateId;
//        $ts = $gateInfo->MaxSeconds;
//        if ($curTs >= $ts) {
//            $gateInfo->MaxSeconds = $curTs;
//        }
//        if ($resultType) {                                                      # 胜利
//            if (ctx()->gates->GateList->$gateId->pass == 0) {
//                ctx()->gates->GateList->$gateId->pass = 1;
//                TaskProc::Day7TaskReset($gateId);
//            }
//            TaskProc::OnPassGate_X($gateId);
//            StoreProc::AddMultiItemInStore($gateMo->reward_win);
//            if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainStoryGate) {
//                ctx()->gates->UnlockNextPlotGate();
//                $dic = GameConfig::gate();
//                $index = 0;                                                   # 挑战关卡解锁逻辑. -gwang 2024年4月15日
//                foreach ($dic as $id => $item) {
//                    if (Ins_GateInfo::GateTypeFromId($id) == Enum_GateType::MainChallengeGate && $item->challengeGateId == $gateId) {
//                        $index += 1;
//                        $gate = new Ins_GateInfo();
//                        $gate->GateId = $id;
//                        ctx()->gates->GateList->$id = $gate;
//                    }
//                    if ($index >= 3) {
//                        break;
//                    }
//                }
//            } else {
//
//            }
//        } else {                                                                # 失败
//            StoreProc::AddMultiItemInStore($gateMo->reward_fail);
//        }
//
//        StoreProc::AddMultiItemInStore($pickups);                               # 战场拾取道具
//        ctx()->baseInfo->Add_Gold($gold);
//        //ctx()->baseInfo->Add_Exp($exp);
//
//        if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainStoryGate) {
//            TaskProc::OnFightNumMainGate();
//        } else if (Ins_GateInfo::GateTypeFromId($gateId) == Enum_GateType::MainChallengeGate) {
//            TaskProc::OnFightNumChallengeGate();
//        }
//        TaskProc::OnKillCommonNumMonster(1000);
//        TaskProc::OnKillleaderNumMonster(500);
//
//        UserProc::updateUserInfo();
//        $ret = array(
//            'gates' => ctx()->gates,
//            'store' => ctx()->store,
//            'task' => ctx()->task,
//        );
//        return Resp::ok($ret);
//    }
// <editor-fold defaultstate="collapsed" desc="排行榜">

    /**
     * 参与主线关卡排行榜
     * @param type $gateIndex
     */
    public static function Ranking_MainGateIndex($maxGateIndex) {
        $memKey = MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid);
        $mem = gMem();

        $index = 9999999999 - now();
        $uid = $index . "-" . req()->uid;
        $arr = self::GetRankUid(req()->uid, 1);
        $gateId = 0;
        if (count($arr) > 0) {
            $uid = $arr[0];
            $gateId = $arr[1];
        }

        if ($maxGateIndex > $gateId) {
            $arr2 = array();
            $arr2["$uid"] = $maxGateIndex;
            $mem->zadd($memKey, $arr2);
        }

        $length = $mem->zlen($memKey);
        if ($length > glc()->Rank_MainGateIndex_OnListRank) {
            $num = $length - glc()->Rank_MainGateIndex_OnListRank;
            $mem->zremrangebyrank($memKey, 0, $num - 1);
        }
    }

    /**
     * 战力榜
     * @param type $gateIndex
     */
    public static function Ranking_FightPower() {
        $memKey = MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid);
        $mem = gMem();

        $index = 9999999999 - now();
        $uid = $index . "-" . req()->uid;
        $lastPower = 0;
        $arr = self::GetRankUid(req()->uid, 2);
        if (count($arr) > 0) {
            $uid = $arr[0];
            $lastPower = $arr[1];
        }

        $power = self::countUserFightPower();
        if ($power > $lastPower) {
            $arr2["$uid"] = $power;
            $mem->zadd($memKey, $arr2);
            self::IsAchievedFightPower_PassReward($power);
        }

        $length = $mem->zlen($memKey);
        if ($length > glc()->Rank_FightPower_OnListRank) {
            $num = $length - glc()->Rank_FightPower_OnListRank;
            $mem->zremrangebyrank($memKey, 0, $num - 1);
        }
    }

    public static function GetRankUid($uid_rank, $type) {
        if ($type == 1) {
            $dic = gMem()->zrevrange(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), 0, glc()->Rank_MainGateIndex_OnListRank, true);
        } else {
            $dic = gMem()->zrevrange(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), 0, glc()->Rank_FightPower_OnListRank, true);
        }

        $arr = array();
        foreach ($dic as $uid => $score) {
            $strUid = explode('-', $uid);
            if ($strUid[1] == $uid_rank) {
                $arr[] = $uid;
                $arr[] = $score;
                break;
            }
        }
        return $arr;
    }

    /**
     * 6811 获取主线关卡排行榜信息
     * @return type
     */
    public static function GetRankInfo() {
        list($type) = req()->paras;

        $selfIsHasRank = 0; //本人是否上榜 0未上榜没有排名 1上榜则selfRank就是排名
        $selfExtraInfo = 0;
        $isExistFinishReward = false;
        if ($type == 1) {
            $list = gMem()->zrevrange(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), 0, glc()->Rank_MainGateIndex_OnListRank, true);
            $selfExtraInfo = ctx()->gates->maxPassGateNumId();

            $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
            $dic = gMem()->hgetall($memKey);
            foreach ($dic as $gateId => $ins_rank) {
                if (!in_array($gateId, ctx()->privateState->rankReward_drawed_MainGate)) {
                    $isExistFinishReward = true;
                    break;
                }
            }
        } else {
            $list = gMem()->zrevrange(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), 0, glc()->Rank_FightPower_OnListRank, true);
            $selfExtraInfo = self::countUserFightPower();

            $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
            $dic = gMem()->hgetall($memKey);
            foreach ($dic as $fightPower => $ins_rank) {
                if (!in_array($fightPower, ctx()->privateState->rankReward_drawed_fightPower)) {
                    $isExistFinishReward = true;
                    break;
                }
            }
        }

        $selfRank = null;
        $retArr = array();
        if (count($list) > 0) {
            foreach ($list as $uid => $score) {
                $rankInfo = self::initOtherUidRankInfo($uid, $score, $type);
                if ($rankInfo->uid == req()->uid) {
                    $selfIsHasRank = 1;
                    $selfRank = $rankInfo;
                }

                $retArr[] = $rankInfo;
            }
        }

        if ($selfRank == null) {
            $index = 9999999999 - now();
            $uid = $index . "-" . req()->uid;
            $selfRank = self::initOtherUidRankInfo($uid, $selfExtraInfo, $type);
        }

        UserProc::updateUserInfo();
        $ret = array(
            'rankInfo' => $retArr,
            'selfRank' => $selfRank,
            'selfIsHasRank' => $selfIsHasRank,
            'isExistFinishReward' => $isExistFinishReward,
        );
        return Resp::ok($ret);
    }

    /**
     * 初始化玩家rank
     * @param type $uid
     * @param type $score
     * @return \loyalsoft\Ins_rank
     */
    static function initOtherUidRankInfo($uid, $score, $type = null) {
        $ins_rank = new Ins_rank();

        if ($type == 1) {
            $lv = gMem()->zrevrank(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), $uid);
        } else {
            $lv = gMem()->zrevrank(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), $uid);
        }

        if ($lv == null) {
            $lv = 0;
        }

        $strUid = explode('-', $uid);
        $ins_rank->rank = $lv + 1;
        $ins_rank->uid = $strUid[1];
        $userInfo = UserProc::getUserGame(req()->zoneid, $strUid[1]);
        $ins_rank->name = $userInfo->baseInfo->name;
        $ins_rank->headImg = $userInfo->baseInfo->headImg;

        $ins_rank->score = $score;
        return $ins_rank;
    }

    /**
     * 6812 获取排行榜内玩家的装备信息
     * @return type
     */
    public static function GetUidEquipInfo_Rank() {
        list($uid) = req()->paras;
        $userInfo = UserProc::getUserGame(req()->zoneid, $uid);

        $store = $userInfo->store;
        $heros = $userInfo->heros;

        UserProc::updateUserInfo();
        $ret = array(
            'store' => $store,
            'heros' => $heros,
        );
        return Resp::ok($ret);
    }

    /**
     * 通关奖励是否达成
     * @param type $maxGateIndex
     */
    public static function IsAchievedMainGate_PassReward($maxGateIndex) {
        $rewards = GameConfig::rank_passgatereward();

        $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        foreach ($rewards as $passGateId => $mo) {
            if ($passGateId == $maxGateIndex && !gMem()->hexists($memKey, $maxGateIndex)) {
                $ins_rank = new Ins_rank();
                $ins_rank->uid = req()->uid;
                $ins_rank->name = ctx()->baseInfo->name;
                $ins_rank->headImg = ctx()->baseInfo->headImg;
                $ins_rank->score = $passGateId;
                gMem()->hset($memKey, $maxGateIndex, $ins_rank);
                break;
            }
        }
    }

    /*
     * 战力奖励是否达成
     */

    public static function IsAchievedFightPower_PassReward($power) {
        $rewards = GameConfig::rank_fightpowerreward();

        $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        foreach ($rewards as $fightPower => $mo) {
            if ($power >= $fightPower && !gMem()->hexists($memKey, $fightPower)) {
                $ins_rank = new Ins_rank();
                $ins_rank->uid = req()->uid;
                $ins_rank->name = ctx()->baseInfo->name;
                $ins_rank->headImg = ctx()->baseInfo->headImg;
                $ins_rank->score = $fightPower;
                gMem()->hset($memKey, $fightPower, $ins_rank);
            }
        }
    }

    /**
     * 6813
     * @return type
     */
    public static function GetmainGate_RankRewardInfo() {
        //list($type) = req()->paras;

        $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey);

        if ($dic == null) {
            $dic = new \stdClass();
        }

        UserProc::updateUserInfo();
        $ret = array(
            'rankReward' => $dic,
        );
        return Resp::ok($ret);
    }

    /**
     * 6814
     * @return type
     */
    public static function GetFightPower_RankRewardInfo() {
        //list($type) = req()->paras;

        $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey);

        if ($dic == null) {
            $dic = new \stdClass();
        }

        UserProc::updateUserInfo();
        $ret = array(
            'rankReward' => $dic,
        );
        return Resp::ok($ret);
    }

    /**
     * 6815 领取通关荣誉榜奖励
     * @return type
     */
    public static function ReceiveRankReward_MainGate() {
        list($gateId) = req()->paras;

        my_Assert(!in_array($gateId, ctx()->privateState->rankReward_drawed_MainGate), ErrCode::rankReward_HasReceive);

        $mo = GameConfig::rank_passgatereward_getItem($gateId);
        my_Assert($mo != null, ErrCode::err_const_no);

        $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        if (gMem()->hexists($memKey, $gateId)) {
            StoreProc::AddMultiItemInStore($mo->reward);
            ctx()->privateState->rankReward_drawed_MainGate[] = $gateId;
        }

        UserProc::updateUserInfo();
        $ret = array();
        return Resp::ok($ret);
    }

    /**
     * 6816 领取战力荣誉榜奖励
     * @return type
     */
    public static function ReceiveRankReward_FightPower() {
        list($fightPower) = req()->paras;

        my_Assert(!in_array($fightPower, ctx()->privateState->rankReward_drawed_fightPower), ErrCode::rankReward_HasReceive);

        $mo = GameConfig::rank_fightpowerreward_getItem($fightPower);
        my_Assert($mo != null, ErrCode::err_const_no);

        $memKey = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        if (gMem()->hexists($memKey, $fightPower)) {
            StoreProc::AddMultiItemInStore($mo->reward);
            ctx()->privateState->rankReward_drawed_fightPower[] = $fightPower;
        }

        UserProc::updateUserInfo();
        $ret = array();
        return Resp::ok($ret);
    }

    /**
     * 6817
     */
    public static function IsExistRankReward() {
        //list($type) = req()->paras;

        $type = 0;
        $isExistFinishReward = false;
        $memKey = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey);
        foreach ($dic as $gateId => $ins_rank) {
            if (!in_array($gateId, ctx()->privateState->rankReward_drawed_MainGate)) {
                $isExistFinishReward = true;
                $type = 1;
                break;
            }
        }

        $memKey2 = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        $dic2 = gMem()->hgetall($memKey2);
        foreach ($dic2 as $fightPower => $ins_rank) {
            if (!in_array($fightPower, ctx()->privateState->rankReward_drawed_fightPower)) {
                $isExistFinishReward = true;
                $type = 2;
                break;
            }
        }

        UserProc::updateUserInfo();
        $ret = array(
            'isExistFinishReward' => $isExistFinishReward,
            'type' => $type,
        );
        return Resp::ok($ret);
    }

    /*
     * 删除排行榜内注销账号的玩家
     */

    public static function DeleteRankInvalidUser($uid2) {
        $dic1 = gMem()->zrevrangebyscore(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), 0, glc()->Rank_MainGateIndex_OnListRank, true);
        $key1 = "";
        foreach ($dic1 as $uid => $score) {
            $strUid = explode('-', $uid);
            if ($strUid[1] == $uid2) {
                $key1 = $uid;
                break;
            }
        }

        $dic2 = gMem()->zrevrangebyscore(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), 0, glc()->Rank_FightPower_OnListRank, true);
        $key2 = "";
        foreach ($dic2 as $uid => $score) {
            $strUid = explode('-', $uid);
            if ($strUid[1] == $uid2) {
                $key2 = $uid;
                break;
            }
        }
        if ($key1 != "") {
            gMem()->zrem(MemKey_GameRun::Rank_MainGateIndex_Zone_zset(req()->zoneid), $key1);
        }
        if ($key1 != "") {
            gMem()->zrem(MemKey_GameRun::Rank_FightPower_Zone_zset(req()->zoneid), $key2);
        }
    }

    /*
     * 排行玩家头像变动
     */

    public static function UpdateRankUserHeadImg($uid, $headImg) {
        $memKey1 = MemKey_GameRun::RankReward_MainGateIndex_Zone_hash(req()->zoneid);
        $dic = gMem()->hgetall($memKey1);
        foreach ($dic as $gateId => $ins_rank) {
            if ($ins_rank->uid == $uid) {
                $ins_rank->headImg = $headImg;
                gMem()->hset($memKey1, $gateId, $ins_rank);
            }
        }

        $memKey2 = MemKey_GameRun::RankReward_FightPower_Zone_hash(req()->zoneid);
        $dic2 = gMem()->hgetall($memKey2);
        foreach ($dic2 as $fightPower => $ins_rank) {
            if ($ins_rank->uid == $uid) {
                $ins_rank->headImg = $headImg;
                gMem()->hset($memKey2, $fightPower, $ins_rank);
            }
        }
    }

    /*
     * 统计战力 战斗力=攻击x（生命-伤害减免值）x（1+暴击率/100x（暴击伤害倍率-1））
     */

    public static function countUserFightPower() {
        $CurrentHeroId = ctx()->heros->CurrentHeroId;
        //$hero = ctx()->heros->Dic->$CurrentHeroId;

        $mo = GameConfig::hero_getItem($CurrentHeroId);
        my_Assert($mo != null, ErrCode::err_const_no);

        $heroBashAttack = $mo->attack;
        $heroBashHp = $mo->hp;

        $equipDic = ctx()->store->equip;
        $attck = 0;
        $hp = 0;
        foreach ($equipDic as $index => $ins_equip) {
            $Ins_Equip = new Ins_Equip($ins_equip);
            if ($Ins_Equip->mo()->upgradeType == 1) {//攻击力
                $attck += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->attckNum;
            } elseif ($Ins_Equip->mo()->upgradeType == 2) {
                $hp += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->hpNum;
            } else {
                $attck += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->attckNum;
                $hp += GameConfig::equip_levelupgrade_getItem($ins_equip->level)->hpNum;
            }
        }

        $heroAttck = $heroBashAttack + $attck;
        $heroHp = $heroBashHp + $hp;

        $dec_demage = $mo->dec_demage;
        $bigHit_Val = $mo->bigHit_Val / 100;
        $bigHit_rate = $mo->bigHit_rate / 100;

        $val = $heroAttck * ($heroHp - $dec_demage) * (1 + $bigHit_rate * ($bigHit_Val - 1));

        return intval($val);
    }

    // </editor-fold>
}
