| | |
| | | #------------------------------------------------------------------------------
|
| | | #"""Version = 2016-12-02 11:00"""
|
| | | #------------------------------------------------------------------------------
|
| | | import ReadChConfig
|
| | | import IPY_GameWorld
|
| | | import PlayerControl
|
| | | import GameWorld
|
| | | import FBCommon
|
| | | import ChConfig
|
| | | import FBLogic
|
| | | import ChPyNetSendPack
|
| | | import NetPackCommon
|
| | | import PlayerSuccess
|
| | | import ItemCommon
|
| | | import IpyGameDataPY
|
| | | import ShareDefine
|
| | | import GameFuncComm
|
| | | import SkillShell
|
| | | import PyGameData
|
| | | import PetControl
|
| | | import NPCCommon
|
| | | import GameObj
|
| | |
|
| | | import time
|
| | | import math
|
| | | #---------------------------------------------------------------------
|
| | | def OnLogin(curPlayer):
|
| | | return
|
| | |
| | | actionType = clientData.ActionType # 行为类型
|
| | | actionInfo = clientData.ActionInfo # 行为信息
|
| | | FBLogic.DoFBAction(curPlayer, actionType, actionInfo, tick)
|
| | | return
|
| | |
|
| | | ## A2 10 清除副本CD#tagCMClearFBCD
|
| | | # @param playerIndex 玩家索引 |
| | | # @param clientData 客户端封包 |
| | | # @param tick 时间
|
| | | # @return None
|
| | | def OnClearFBCD(playerIndex, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
|
| | | mapID = clientData.MapID # mapID
|
| | | GameWorld.DebugLog("OnClearFBCD mapID=%s" % mapID)
|
| | | if not mapID:
|
| | | return
|
| | | |
| | | enterCDTick = FBCommon.GetFBEnterCD(curPlayer, mapID)
|
| | | if enterCDTick <= 0:
|
| | | GameWorld.DebugLog(" CD时间已过,不需要清除, cdTick=%s" % enterCDTick)
|
| | | return
|
| | | clearEnterCDDict = IpyGameDataPY.GetFuncEvalCfg('FBEnterCD', 2)
|
| | | if mapID not in clearEnterCDDict:
|
| | | return
|
| | | costMoney = clearEnterCDDict[mapID]
|
| | | costMoneyList = PlayerControl.HaveMoneyEx(curPlayer, ShareDefine.TYPE_Price_Gold_Paper_Money, costMoney)
|
| | | if not costMoneyList:
|
| | | return
|
| | | second = enterCDTick # 参数秒
|
| | | # 扣除消耗
|
| | | infoDict = {"MapID":mapID, "CDSecond":second}
|
| | | for moneyType, moneyCnt in costMoneyList:
|
| | | if not PlayerControl.PayMoney(curPlayer, moneyType, moneyCnt, ChConfig.Def_Cost_ClearFBCD, infoDict):
|
| | | return
|
| | | |
| | |
|
| | | GameWorld.DebugLog(" mapID=%s 清除副本CD second=%s,costMoneyList=%s" |
| | | % (mapID, second, costMoneyList), curPlayer.GetPlayerID())
|
| | | |
| | | FBCommon.SetFBPDictValue(curPlayer, ChConfig.Def_PDict_LastEnterFBTick % mapID, 0)
|
| | | FBCommon.SyncFBEnterTick(curPlayer)
|
| | | return
|
| | |
|
| | | #---封包开始扫荡-------------------------------------
|
| | |
|
| | | (
|
| | | PCDFB_MapIDList, # 副本地图ID列表
|
| | | PCDFB_NeedTime, # 扫荡时间, 秒
|
| | | PCDFB_FinishTimeGold, # 立即完成消耗钻石公式
|
| | | ) = range(3)
|
| | |
|
| | |
|
| | | ## 判断是否当前公共CD副本扫荡中
|
| | | def IsCurPubCDFBSweeping(curPlayer, mapID):
|
| | | sweepCfg = GetPubCDFBSweepCfg(curPlayer, mapID)
|
| | | if not sweepCfg:
|
| | | return False
|
| | | groupNum = sweepCfg[0]
|
| | | return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_MapID % groupNum) == mapID
|
| | |
|
| | | ## 获取公共CD副本扫荡配置信息
|
| | | def GetPubCDFBSweepCfg(curPlayer, mapID):
|
| | | PubCDFBSweepDict = ReadChConfig.GetEvalChConfig("PubCDFBSweep")
|
| | | for groupNum, sweepInfo in PubCDFBSweepDict.items():
|
| | | mapIDGroup = sweepInfo[0]
|
| | | if mapID not in mapIDGroup:
|
| | | continue
|
| | | |
| | | return groupNum, sweepInfo
|
| | | |
| | | return
|
| | |
|
| | | ## 开始公共CD副本扫荡
|
| | | def __DoStartPubCDFBSweep(curPlayer, mapID, lineID, cnt, isFinish, dataEx, groupNum, sweepInfo):
|
| | | curSweepMapID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_MapID % groupNum)
|
| | | if curSweepMapID > 0:
|
| | | GameWorld.DebugLog("公共CD副本扫荡中, 无法扫荡!groupNum=%s,curSweepMapID=%s" |
| | | % (groupNum, curSweepMapID), curPlayer.GetPlayerID())
|
| | | return
|
| | | |
| | | if not FBLogic.OnStartPubCDFBSweep(curPlayer, mapID, lineID, cnt, dataEx):
|
| | | return
|
| | | |
| | | curTime = int(time.time())
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PubCDFBS_MapID % groupNum, mapID)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PubCDFBS_LineID % groupNum, lineID)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PubCDFBS_Cnt % groupNum, cnt)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PubCDFBS_DataEx % groupNum, dataEx)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PubCDFBS_Time % groupNum, curTime)
|
| | | GameWorld.DebugLog("公共CD副本开始扫荡 mapID=%s,lineID=%s,cnt=%s,dataEx=%s,groupNum=%s,curTime=%s" |
| | | % (mapID, lineID, cnt, dataEx, groupNum, curTime), curPlayer.GetPlayerID())
|
| | | |
| | | |
| | | Sync_PubFBSweepData(curPlayer, groupNum)
|
| | | return
|
| | |
|
| | | ## 完成公共CD副本扫荡
|
| | | def __DoFinishPubCDFB(curPlayer, mapID, isFinish, groupNum, sweepInfo):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | curSweepMapID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_MapID % groupNum)
|
| | | if curSweepMapID <= 0 or curSweepMapID != mapID:
|
| | | GameWorld.DebugLog("未扫荡 或 不是当前正在扫荡的公共CD副本, 无法完成!curSweepMapID=%s,mapID=%s" |
| | | % (curSweepMapID, mapID), playerID)
|
| | | return
|
| | | |
| | | sweepTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_Time % groupNum)
|
| | | lineID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_LineID % groupNum)
|
| | | sweepCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_Cnt % groupNum)
|
| | | dataEx = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_DataEx % groupNum)
|
| | | |
| | | sweepNeedTime = sweepInfo[PCDFB_NeedTime] # 单次耗时
|
| | | finishCostGoldFormat = sweepInfo[PCDFB_FinishTimeGold]
|
| | | needTotalTime = sweepNeedTime * sweepCnt
|
| | | |
| | | curTime = int(time.time())
|
| | | passTime = max(0, curTime - sweepTime)
|
| | | second = max(0, needTotalTime - passTime)
|
| | | |
| | | # 正常完成
|
| | | if isFinish == 2 and second > 0:
|
| | | GameWorld.DebugLog("扫荡时间未到,无法完成,剩余%s秒, mapID=%s" % (second, mapID), playerID)
|
| | | return
|
| | | |
| | | addDataDict = {"curTime":curTime, "startSweepTime":sweepTime, "sweepCnt":sweepCnt, |
| | | "needTotalTime":needTotalTime, "passTime":passTime, "remainSecond":second, |
| | | "costGold":0, "mapID":mapID, "lineID":lineID, "dataEx":dataEx, ChConfig.Def_Cost_Reason_SonKey:mapID}
|
| | | |
| | | # 钻石立即完成
|
| | | if isFinish == 1:
|
| | | costGold = eval(finishCostGoldFormat)
|
| | | if costGold > 0:
|
| | | addDataDict["costGold"] = costGold
|
| | | if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGold, |
| | | ChConfig.Def_Cost_FinishFBSweep, addDataDict):
|
| | | return
|
| | | |
| | | GameWorld.DebugLog("公共CD副本扫荡完成: %s" % str(addDataDict), playerID)
|
| | | # 给奖励
|
| | | FBLogic.OnGivePubCDFBSweepPrize(curPlayer, mapID, lineID, sweepCnt, dataEx)
|
| | | |
| | | # 重置扫荡数据
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PubCDFBS_MapID % groupNum, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PubCDFBS_LineID % groupNum, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PubCDFBS_Cnt % groupNum, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PubCDFBS_DataEx % groupNum, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PubCDFBS_Time % groupNum, 0)
|
| | | Sync_PubFBSweepData(curPlayer, groupNum)
|
| | | return
|
| | |
|
| | | ## 同步公共CD副本扫荡信息
|
| | | def Sync_PubFBSweepData(curPlayer, groupNum=-1):
|
| | | |
| | | PubCDFBSweepDict = ReadChConfig.GetEvalChConfig("PubCDFBSweep")
|
| | | allGroupNumList = PubCDFBSweepDict.keys()
|
| | | if groupNum == -1:
|
| | | groupNumList = allGroupNumList
|
| | | else:
|
| | | if groupNum not in allGroupNumList:
|
| | | return
|
| | | groupNumList = [groupNum]
|
| | | |
| | | pubSweepData = ChPyNetSendPack.tagMCPubFBSweepData()
|
| | | pubSweepData.Clear()
|
| | | pubSweepData.SweepDatList = []
|
| | | |
| | | for gNum in groupNumList:
|
| | | sweepInfo = ChPyNetSendPack.tagMCPubFBSweep()
|
| | | sweepInfo.Clear()
|
| | | sweepInfo.PubNum = gNum
|
| | | sweepInfo.FBMapID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_MapID % gNum)
|
| | | sweepInfo.LineID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_LineID % gNum)
|
| | | sweepInfo.SweepTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_Time % gNum)
|
| | | sweepInfo.SweepCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PubCDFBS_Cnt % gNum)
|
| | | pubSweepData.SweepDatList.append(sweepInfo)
|
| | | |
| | | pubSweepData.Cnt = len(pubSweepData.SweepDatList)
|
| | | NetPackCommon.SendFakePack(curPlayer, pubSweepData)
|
| | | return
|
| | |
|
| | | #//A5 05 玩家开始副本扫荡 #tagCMBeginFBWipeOut
|
| | |
| | | % (mapID, lineID, sweepItemID, sweepCostCnt), curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | |
| | | |
| | | #公共CD扫荡模式暂屏蔽,有需要再修改
|
| | | #===============================================================================================
|
| | | # groupNum = -1
|
| | | # sweepInfo = None
|
| | | # PubCDFBSweepDict = ReadChConfig.GetEvalChConfig("PubCDFBSweep")
|
| | | # for gNum, sInfo in PubCDFBSweepDict.items():
|
| | | # if mapID in sInfo[PCDFB_MapIDList]:
|
| | | # groupNum = gNum
|
| | | # sweepInfo = sInfo
|
| | | # break
|
| | | # |
| | | # # 公共CD副本扫荡
|
| | | # if groupNum >= 0:
|
| | | # if not isFinish:
|
| | | # __DoStartPubCDFBSweep(curPlayer, mapID, lineID, cnt, isFinish, dataEx, groupNum, sweepInfo)
|
| | | # else:
|
| | | # __DoFinishPubCDFB(curPlayer, mapID, isFinish, groupNum, sweepInfo)
|
| | | # return
|
| | | #===============================================================================================
|
| | | |
| | | # 副本是否可扫荡, 这里只判断副本自身的特殊条件, 公共条件上面已经判断
|
| | | if not FBLogic.OnPlayerFBSweepAsk(curPlayer, mapID, lineID, cnt, isFinish, dataEx):
|
| | | return
|
| | |
| | |
|
| | | #扫荡结果给奖励等
|
| | | FBLogic.OnPlayerFBSweepResult(curPlayer, mapID, lineID, cnt, isFinish, dataEx)
|
| | | return
|
| | |
|
| | |
|
| | | #// A5 1B 购买挑战副本精力 #tagCMBuyFBEnergy
|
| | | #
|
| | | #struct tagCMBuyFBEnergy
|
| | | #{
|
| | | # tagHead Head;
|
| | | #};
|
| | | def OnPlayerBuyFBEnergy(playerIndex, clientData, tick):
|
| | | #curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
|
| | | return
|
| | |
|
| | |
|
| | | ## 玩家副本功能时间处理
|
| | | def DoPlayerFBTimeProcess(curPlayer, tick):
|
| | | |
| | | checkInterval = ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_FBTimeProcess]
|
| | | if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_FBTimeProcess) < checkInterval:
|
| | | return |
| | | |
| | | curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_FBTimeProcess, tick)
|
| | | |
| | | # 领主霸业玩家功能时间处理
|
| | | FBCommon.RegainFBCntProcess(curPlayer)
|
| | | return
|
| | |
|
| | |
|
| | | #// B1 02 领取多倍副本奖励 #tagCMGetMultiFBPrize
|
| | | #
|
| | | #struct tagCMGetMultiFBPrize
|
| | | #{
|
| | | # tagHead Head;
|
| | | # DWORD MapID;
|
| | | # WORD LineID;
|
| | | # WORD Percent; // 额外奖励百分比奖励等级
|
| | | #};
|
| | | def OnPlayerGetMultiFBPrize(playerIndex, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
|
| | | mapID = clientData.MapID
|
| | | lineID = clientData.LineID
|
| | | prizeExLV = clientData.Percent
|
| | | FBLogic.OnGetMultiFBPrize(curPlayer, mapID, lineID, prizeExLV)
|
| | | return
|
| | |
|
| | |
|
| | | #//A5 60 重置副本挑战次数 #tagCMResetFBJoinCnt
|
| | | #
|
| | | #struct tagCMResetFBJoinCnt
|
| | | #{
|
| | | # tagHead Head;
|
| | | #};
|
| | | def OnPlayerResetFBJoinCnt(playerIndex, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
|
| | | return
|
| | |
|
| | |
|
| | | #// B1 01 客户端副本发送结束 #tagCMClientEndFB
|
| | | #
|
| | | #struct tagCMClientEndFB
|
| | | #{
|
| | | # tagHead Head;
|
| | | # DWORD MapID;
|
| | | # WORD LineID;
|
| | | # DWORD Data; //副本数据
|
| | | #};
|
| | | def OnClientEndFB(playerIndex, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
|
| | | mapID = clientData.MapID
|
| | | lineID = clientData.LineID
|
| | | data1 = clientData.Data1
|
| | | data2 = clientData.Data2
|
| | | dataList = [data1, data2]
|
| | | FBLogic.OnClientEndFB(curPlayer, mapID, lineID, dataList)
|
| | | GameWorld.DebugLog(' 客户端副本发送结束mapID=%s,lineID=%s,dataList=%s'%(mapID,lineID,dataList))
|
| | | return
|
| | |
|
| | |
|
| | | #// B1 04 客户端发送开始副本 #tagCMClientStartFB
|
| | | #
|
| | | #struct tagCMClientStartFB
|
| | | #{
|
| | | # tagHead Head;
|
| | | #};
|
| | | def OnClientStartFB(playerIndex, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
|
| | | FBLogic.OnClientStartFB(curPlayer, tick)
|
| | | return
|
| | |
|
| | | #// A2 31 前端开始自定义场景 #tagCMClientStartCustomScene
|
| | | #
|
| | | #struct tagCMClientStartCustomScene
|
| | | #{
|
| | | # tagHead Head;
|
| | | # DWORD MapID;
|
| | | # WORD FuncLineID;
|
| | | #};
|
| | | def OnClientStartCustomScene(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | mapID = clientData.MapID
|
| | | funcLineID = clientData.FuncLineID
|
| | | DoEnterCustomScene(curPlayer, mapID, funcLineID, tick)
|
| | | return
|
| | |
|
| | | #// A2 33 前端退出自定义场景 #tagCMClientExitCustomScene
|
| | | #
|
| | | #struct tagCMClientExitCustomScene
|
| | | #{
|
| | | # tagHead Head;
|
| | | #};
|
| | | def OnClientExitCustomScene(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | DoExitCustomScene(curPlayer)
|
| | | return
|
| | |
|
| | | def DoEnterCustomScene(curPlayer, mapID, lineID, tick):
|
| | | ## 进入自定义场景状态
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.Log("玩家请求进入自定义场景!mapID=%s,lineID=%s" % (mapID, lineID), playerID)
|
| | | if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene):
|
| | | curMapID = PlayerControl.GetCustomMapID(curPlayer)
|
| | | curLineID = PlayerControl.GetCustomLineID(curPlayer)
|
| | | if mapID == curMapID and lineID == curLineID:
|
| | | GameWorld.Log(" 玩家当前已经在自定义场景中!无需重新请求!", playerID)
|
| | | result = 1
|
| | | else:
|
| | | GameWorld.Log(" 玩家当前在不同的自定义场景中!不允许进入!curMapID=%s,curLineID=%s" |
| | | % (curMapID, curLineID), playerID)
|
| | | result = 0
|
| | | StartCustomSceneResult(curPlayer, mapID, lineID, result)
|
| | | return result
|
| | | |
| | | #进入副本通用检查
|
| | | if mapID:
|
| | | fbIpyData = FBCommon.GetFBIpyData(mapID)
|
| | | fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, lineID)
|
| | | if PlayerControl.CheckMoveToFB(curPlayer, mapID, lineID, fbIpyData, fbLineIpyData, tick) != ShareDefine.EntFBAskRet_OK:
|
| | | StartCustomSceneResult(curPlayer, mapID, lineID, 0)
|
| | | return 0
|
| | | |
| | | PlayerControl.SetPlayerSightLevel(curPlayer, curPlayer.GetID())
|
| | | |
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomScene, 1) # 由于前端不一定有发mapID,所以这里额外记录这个状态,不能直接用mapID判断
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneStepTick, tick)
|
| | | PlayerControl.SetCustomMap(curPlayer, mapID, lineID)
|
| | | NPCCommon.ClearPriWoodPile(curPlayer)
|
| | | GameWorld.Log("玩家开始自定义场景!mapID=%s,lineID=%s" % (mapID, lineID), playerID)
|
| | | if mapID:
|
| | | PetControl.DoLogic_PetLoadMapOK(curPlayer)
|
| | | FBLogic.OnEnterCustomScene(curPlayer, mapID, lineID)
|
| | | |
| | | #默认回满血
|
| | | if GameObj.GetHP(curPlayer) < GameObj.GetMaxHP(curPlayer):
|
| | | GameObj.SetHPFull(curPlayer)
|
| | | |
| | | #通知进入状态
|
| | | StartCustomSceneResult(curPlayer, mapID, lineID, 1)
|
| | | return 1
|
| | |
|
| | | def StartCustomSceneResult(curPlayer, mapID, lineID, result):
|
| | | if result != 1:
|
| | | DoExitCustomScene(curPlayer)
|
| | | resultPack = ChPyNetSendPack.tagMCStartCustomSceneResult()
|
| | | resultPack.MapID = mapID
|
| | | resultPack.FuncLineID = lineID
|
| | | resultPack.Result = result
|
| | | NetPackCommon.SendFakePack(curPlayer, resultPack)
|
| | | return
|
| | |
|
| | | def DoExitCustomScene(curPlayer):
|
| | | ## 退出自定义场景状态
|
| | | PlayerControl.SetPlayerSightLevel(curPlayer, 0)
|
| | | mapID = PlayerControl.GetCustomMapID(curPlayer)
|
| | | lineID = PlayerControl.GetCustomLineID(curPlayer)
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomScene, 0)
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneStepTick, 0)
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneGrade, 0)
|
| | | PlayerControl.SetCustomMap(curPlayer, 0, 0)
|
| | | if mapID and FBCommon.GetCustomMapStep(curPlayer, mapID, lineID) != ChConfig.CustomMapStep_Over:
|
| | | FBCommon.SetCustomMapStep(curPlayer, mapID, lineID, ChConfig.CustomMapStep_Over)
|
| | | NPCCommon.ClearPriWoodPile(curPlayer)
|
| | | |
| | | #默认回满血
|
| | | if GameObj.GetHP(curPlayer) > 0 and curPlayer.GetPlayerAction() != IPY_GameWorld.paDie and GameObj.GetHP(curPlayer) < GameObj.GetMaxHP(curPlayer):
|
| | | GameObj.SetHPFull(curPlayer)
|
| | | |
| | | GameWorld.Log("玩家退出自定义场景!", curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | #// B1 08 快速一键过关副本 #tagCMFBQuickPass
|