From d7e6ef56122500442ccee80ffeb29091e3fd0ce9 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期四, 06 六月 2024 11:17:58 +0800 Subject: [PATCH] 10130 【后端】福地争夺资源功能(增加摇人功能) --- ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py | 204 +++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 174 insertions(+), 30 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py index 86b653f..262c804 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py @@ -54,6 +54,7 @@ value2:hmNum 时分场次编号 value3:playerID 购买的玩家ID value4:factionID 所选择的阵营ID +value5:serverOnly 是否仅本服玩家可加入,0-否,1-是 StrValue3:[callPlayerID,...] 召集来的玩家ID,包含自己 ''' @@ -71,6 +72,7 @@ self.zoneID = 0 self.playerID = 0 self.factionID = 0 + self.serverOnly = 0 self.callPlayerIDList = [] # 子服用,跨服服务器同步数据时负值; 不存库,玩家属性缓存信息,本服玩家取自己服务器最新缓存 @@ -88,7 +90,7 @@ "RealmLV":cacheDict["RealmLV"], "FightPower":cacheDict["FightPower"]} return {"buyTime":self.buyTime, "hmNum":self.hmNum, "zoneID":self.zoneID, "playerID":self.playerID, "factionID":self.factionID, - "callPlayerIDList":self.callPlayerIDList, "callPlayerDict":self.callPlayerDict} + "serverOnly":self.serverOnly, "callPlayerIDList":self.callPlayerIDList, "callPlayerDict":self.callPlayerDict} def SetAttr(self, attrDict): for k, v in attrDict.items(): @@ -112,6 +114,7 @@ hmNum = recData.GetValue2() playerID = recData.GetValue3() factionID = recData.GetValue4() + serverOnly = recData.GetValue5() strValue3 = recData.GetStrValue3() @@ -121,6 +124,7 @@ buyRec.hmNum = hmNum buyRec.playerID = playerID buyRec.factionID = factionID + buyRec.serverOnly = serverOnly buyRec.callPlayerIDList = eval(strValue3) if strValue3 else [] buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum) @@ -152,6 +156,7 @@ recData.SetValue2(buyRec.hmNum) recData.SetValue3(buyRec.playerID) recData.SetValue4(buyRec.factionID) + recData.SetValue5(buyRec.serverOnly) recData.SetStrValue3(str(buyRec.callPlayerIDList).replace(" ", "")) @@ -214,14 +219,20 @@ playerID = billboardData.ID cmpValue = billboardData.CmpValue rank = i + 1 - awardItemList = GameWorld.GetOrderValueByDict(awardDict, rank) + awardItemList = [] + rankAwardItemList = GameWorld.GetOrderValueByDict(awardDict, rank, False, []) + if rankAwardItemList: + awardItemList.extend(rankAwardItemList) paramList = [rank] if billboardType == ShareDefine.Def_CBT_BattlefieldWJoin and enterWeekMoneyItemID: - moneyBaseCount, multiValue = GameWorld.GetOrderValueByDict(enterWeekMoneyMultiIntDict, rank) # 奖励货币倍值 + moneyBaseCount, multiValue = GameWorld.GetOrderValueByDict(enterWeekMoneyMultiIntDict, rank, False, [0, 0]) # 奖励货币倍值 #基础保底值(不同名次可能不一样) + 名次倍率*次数 awardMoneyCount = int(moneyBaseCount + multiValue * cmpValue) awardItemList.append([enterWeekMoneyItemID, awardMoneyCount, 0]) - PlayerCompensation.SendMailByKey(mailKey, [playerID], awardItemList, paramList, crossMail=True) + GameWorld.Log(" billboardType=%s,rank=%s,playerID=%s,cmpValue=%s,awardItemList=%s" + % (billboardType, rank, playerID, cmpValue, awardItemList)) + if awardItemList: + PlayerCompensation.SendMailByKey(mailKey, [playerID], awardItemList, paramList, crossMail=True) billboardObj.ClearData() @@ -396,6 +407,7 @@ if openDateTime <= curDateTime < closeDateTime: battlefieldState = openHour * 100 + openMinute + PyGameData.g_openDateTime = openDateTime stateKey = ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield gameWorld = GameWorld.GetGameWorld() @@ -413,6 +425,8 @@ if battlefieldState and beforeState != battlefieldState: # 移除已经存在的副本线路 PyGameData.g_crossDynamicLineInfo.pop(ChConfig.Def_FBMapID_CrossBattlefield, None) + + PyGameData.g_overPlayerIDList = [] crossZoneName = GameWorld.GetCrossZoneName() crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True) @@ -493,36 +507,38 @@ continue zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByZoneID(ChConfig.Def_FBMapID_CrossBattlefield, zoneID) - if zoneIpyData: + if not zoneIpyData: continue serverGroupIDList = zoneIpyData.GetServerGroupIDList() if curHMNum not in buyHMInfo: continue - buyPlayerInfo = buyHMInfo[curHMNum] - if not buyPlayerInfo: - continue - - matchTickSortList = sorted(buyPlayerInfo.values(), key=operator.attrgetter("buyTime")) - buyRec = matchTickSortList[0] - - PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "CrossBattlefieldOpenPlayer", [buyRec.playerName, notifyOpenMinute]) + PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "CrossBattlefieldOpenSys", [notifyOpenMinute]) return -def GetCrossBattlefieldOpenTime(zoneID): +def GetCrossBattlefieldOpenTime(serverGroupID, zoneID, playerID): ## 获取跨服战场副本当前是否开放的时间点 # @return: None-当前未开放; - # @return: hour, minute - 当前开放中的时间时分,可进入 + # @return: isCallBattle, openHour, openMinute - 当前开放中的时间时分,可进入 gameWorld = GameWorld.GetGameWorld() hmNum = GetCrossBattlefieldState() if not hmNum: + GameWorld.Log("当前时间战场未开启!", playerID) + PlayerControl.NotifyCodeCross(serverGroupID, playerID, "FBIsNotOpen") return seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID) if seasonState != 1: + GameWorld.Log("赛季未开启!", playerID) + PlayerControl.NotifyCodeCross(serverGroupID, playerID, "NotifySeasonOver") + return + + if playerID in PyGameData.g_overPlayerIDList: + # 您已经参加过该场次,无法再进入! + PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossBattlefieldAlreadyJoin") return openHour, openMinute = GetHMByNum(hmNum) @@ -530,12 +546,48 @@ isCallBattle = [openHour, openMinute] not in sysOpenHMList if isCallBattle: if zoneID not in PyGameData.g_crossBattlefieldBuyInfo: - GameWorld.DebugLog("该分区没有使用召集令! zoneID=%s" % zoneID) + GameWorld.Log("该分区没有使用召集令! zoneID=%s" % zoneID, playerID) + PlayerControl.NotifyCodeCross(serverGroupID, playerID, "FBIsNotOpen") return buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo[zoneID] if hmNum not in buyHMInfo: - GameWorld.DebugLog("该时段还未使用召集令! zoneID=%s,hmNum=%s" % (zoneID, hmNum)) + GameWorld.Log("该时段还未使用召集令! zoneID=%s,hmNum=%s" % (zoneID, hmNum), playerID) + PlayerControl.NotifyCodeCross(serverGroupID, playerID, "FBIsNotOpen") return + + # 召集场只有一条线,如果有人结算则代表已经结束了 + if PyGameData.g_overPlayerIDList: + # 该召集场次已结算,无法进入! + PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossBattlefieldCallOver") + return + + if PyGameData.g_openDateTime: + serverTime = GameWorld.GetServerTime() + passSeconds = (serverTime - PyGameData.g_openDateTime).seconds + closeEnterMinutes = IpyGameDataPY.GetFuncCfg("CrossBattlefieldOpen", 5) # 开启X分钟后不可进入,不包含已进入玩家及召集队伍中的玩家 + closeSeconds = closeEnterMinutes * 60 + if passSeconds > closeSeconds: + GameWorld.DebugLog("迟到了! passSeconds=%s > %s" % (passSeconds, closeSeconds), playerID) + isBelate = True + for _, copyMapObj in PyGameData.g_crossDynamicLineCopyMapInfo.items(): + if copyMapObj.IsMustCopyMapPlayer(playerID): + isBelate = False + GameWorld.DebugLog("已进入的重复进入不限制时间! playerID=%s" % playerID) + break + + if isCallBattle: + buyPlayerInfo = buyHMInfo[hmNum] + for buyRec in buyPlayerInfo.values(): + if playerID in buyRec.callPlayerIDList: + isBelate = False + GameWorld.DebugLog("召集令成员不受人时间限制! playerID=%s" % playerID) + break + + if isBelate: + PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossBattlefieldBelate", [closeEnterMinutes]) + return + #else: + # GameWorld.DebugLog("没有迟到!passSeconds=%s <= %s" % (passSeconds, closeSeconds), playerID) return isCallBattle, openHour, openMinute @@ -613,6 +665,7 @@ openHour = msgData["openHour"] openMinute = msgData["openMinute"] faction = msgData["faction"] + serverOnly = msgData.get("serverOnly", 0) hmNum = GetHMNum(openHour, openMinute) @@ -628,16 +681,16 @@ return curFactionCount, othFactionCount = 0, 0 - for callPlayerID, buyRec in buyPlayerInfo.items(): + for _, buyRec in buyPlayerInfo.items(): if buyRec.factionID == faction: curFactionCount += 1 else: othFactionCount += 1 - if playerID in buyRec.callPlayerIDList: - GameWorld.Log("玩家已经在该召集场次阵营里! zoneID=%s,openHour=%s,openMinute=%s,callPlayerID=%s,callPlayerIDList=%s" - % (zoneID, openHour, openMinute, callPlayerID, buyRec.callPlayerIDList), playerID) - return +# if playerID in buyRec.callPlayerIDList: +# GameWorld.Log("玩家已经在该召集场次阵营里! zoneID=%s,openHour=%s,openMinute=%s,callPlayerID=%s,callPlayerIDList=%s" +# % (zoneID, openHour, openMinute, callPlayerID, buyRec.callPlayerIDList), playerID) +# return if curFactionCount > othFactionCount: GameWorld.Log("阵营平衡限制,不可再购买该跨服战场阵营! zoneID=%s,openHour=%s,openMinute=%s,faction=%s,curFactionCount(%s) > othFactionCount(%s)" @@ -665,7 +718,11 @@ buyRec.playerID = playerID buyRec.factionID = faction buyRec.callPlayerIDList = [playerID] + buyRec.serverOnly = serverOnly buyPlayerInfo[playerID] = buyRec + + GameWorld.DebugLog("玩家购买开启召集场次! zoneID=%s,openHour=%s,openMinute=%s,faction=%s,serverOnly=%s" + % (zoneID, openHour, openMinute, faction, serverOnly), playerID) # 上榜 billboardCallCountLimit = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboard", 1) # 周召集榜上榜至少次数 @@ -675,6 +732,13 @@ if cmpValue >= billboardCallCountLimit: CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BattlefieldWCall, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue) + for otherBuyPlayerID, otherRec in buyPlayerInfo.items(): + if otherBuyPlayerID == playerID: + continue + if playerID in otherRec.callPlayerIDList: + otherRec.callPlayerIDList.remove(playerID) + GameWorld.DebugLog(" 从已加入的其他召集队伍移除: otherBuyPlayerID=%s,playerID=%s" % (otherBuyPlayerID, playerID), playerID) + SyncMapServerCrossBattlefieldBuyInfo() # 通知子服 @@ -699,6 +763,9 @@ hmNum = GetHMNum(openHour, openMinute) buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum) + if tagPlayerID in buyPlayerInfo: + GameWorld.ErrLog("玩家已购买该场次召集队伍,无法加入其他召集队伍! hmNum=%s,tagPlayerID=%s in %s" % (hmNum, tagPlayerID, buyPlayerInfo.keys()), playerID) + return if buyPlayerID not in buyPlayerInfo: GameWorld.ErrLog("跨服战场不存在该玩家的召集队伍! hmNum=%s,buyPlayerID=%s" % (hmNum, buyPlayerID), playerID) return @@ -709,9 +776,19 @@ GameWorld.ErrLog("跨服战场召集人数已满! hmNum=%s,buyPlayerID=%s,callPlayerIDList=%s" % (hmNum, buyPlayerID, buyRec.callPlayerIDList), playerID) return + GameWorld.DebugLog("玩家加入召集队伍! zoneID=%s,openHour=%s,openMinute=%s,buyPlayerID=%s,tagPlayerID=%s" + % (zoneID, openHour, openMinute, buyPlayerID, tagPlayerID), playerID) + if tagPlayerID not in buyRec.callPlayerIDList: buyRec.callPlayerIDList.append(tagPlayerID) + for otherBuyPlayerID, otherRec in buyPlayerInfo.items(): + if otherBuyPlayerID == buyPlayerID: + continue + if tagPlayerID in otherRec.callPlayerIDList: + otherRec.callPlayerIDList.remove(tagPlayerID) + GameWorld.DebugLog(" 从已加入的其他召集队伍移除: otherBuyPlayerID=%s,tagPlayerID=%s" % (otherBuyPlayerID, tagPlayerID), playerID) + SyncMapServerCrossBattlefieldBuyInfo() serverGroupIDList = zoneIpyData.GetServerGroupIDList() @@ -746,6 +823,9 @@ return buyRec.callPlayerIDList.remove(tagPlayerID) + GameWorld.DebugLog("玩家召集队伍踢人! zoneID=%s,openHour=%s,openMinute=%s,buyPlayerID=%s,tagPlayerID=%s" + % (zoneID, openHour, openMinute, buyPlayerID, tagPlayerID), playerID) + SyncMapServerCrossBattlefieldBuyInfo() serverGroupIDList = zoneIpyData.GetServerGroupIDList() @@ -753,11 +833,40 @@ Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, msgData) return +def ClientServerMsg_BattlefieldCallChange(serverGroupID, msgData): + + openHour = msgData["openHour"] + openMinute = msgData["openMinute"] + serverOnly = msgData["serverOnly"] + playerID = msgData["playerID"] + + zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID) + if not zoneIpyData: + return + zoneID = zoneIpyData.GetZoneID() + + hmNum = GetHMNum(openHour, openMinute) + buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum) + if playerID not in buyPlayerInfo: + GameWorld.ErrLog("跨服战场不存在该玩家的召集队伍! hmNum=%s,playerID=%s" % (hmNum, playerID), playerID) + return + buyRec = buyPlayerInfo[playerID] + buyRec.serverOnly = 1 if serverOnly else 0 + + GameWorld.DebugLog("玩家召集队伍修改! zoneID=%s,openHour=%s,openMinute=%s,serverOnly=%s" + % (zoneID, openHour, openMinute, serverOnly), playerID) + + #SyncMapServerCrossBattlefieldBuyInfo() + + serverGroupIDList = zoneIpyData.GetServerGroupIDList() + msgData.update({"opType":"CallChange"}) + Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, msgData) + return + def MapServer_CrossBattlefieldOver(msgList): ## 跨服战场地图结算 overTime = int(time.time()) - hmNum = GetCrossBattlefieldState() - fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, finalSuperItemPlayerID, finalSuperItemPlayerName, superItemPlayerIDList, scoreKingID, scoreKingName, battlePlayerList = msgList + hmNum, fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, finalSuperItemPlayerID, finalSuperItemPlayerName, superItemPlayerIDList, scoreKingID, scoreKingName, battlePlayerList = msgList GameWorld.Log("跨服战场地图同步结果: hmNum=%s,zoneID=%s,funcLineID=%s,winnerFaction=%s,superItemInfo=%s,finalSuperItemPlayerID=%s,superItemPlayerIDList=%s,scoreKingID=%s,battlePlayerCount=%s" % (hmNum, zoneID, funcLineID, winnerFaction, superItemInfo, finalSuperItemPlayerID, superItemPlayerIDList, scoreKingID, len(battlePlayerList)), fbPropertyID) @@ -780,20 +889,23 @@ factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt \ = playerInfo + PyGameData.g_overPlayerIDList.append(playerID) + paramList = [rank] if faction == winnerFaction: winnerPlayerIDList.append(playerID) orderAwardMailKey = "CrossBattlefieldOrderWin" - orderAwardItemList = GameWorld.GetOrderValueByDict(winnerOrderIntAwardDict, rank) + orderAwardItemList = GameWorld.GetOrderValueByDict(winnerOrderIntAwardDict, rank, False) GameWorld.Log(" 获胜阵营玩家: faction=%s,rank=%s,playerID=%s" % (faction, rank, playerID), fbPropertyID) else: loserPlayerIDList.append(playerID) orderAwardMailKey = "CrossBattlefieldOrderLose" - orderAwardItemList = GameWorld.GetOrderValueByDict(loserOrderIntAwardDict, rank) + orderAwardItemList = GameWorld.GetOrderValueByDict(loserOrderIntAwardDict, rank, False) GameWorld.Log(" 失败阵营玩家: faction=%s,rank=%s,playerID=%s" % (faction, rank, playerID), fbPropertyID) # 排名奖励邮件 - PlayerCompensation.SendMailByKey(orderAwardMailKey, [playerID], orderAwardItemList, paramList, crossMail=True) + if orderAwardItemList: + PlayerCompensation.SendMailByKey(orderAwardMailKey, [playerID], orderAwardItemList, paramList, crossMail=True) # 更新周参与榜单 groupValue1, dataID, name1, name2 = zoneID, playerID, name, "" @@ -851,7 +963,7 @@ nextBattleTimeStr = "%02d:%02d" % (nextOpenHour, nextOpenMinute) # 本分区全服:XX阵营胜利,xxx为本场积分王,xxx获得了古神大奖XXX,下个场次预计将在XX点开放。 - if battlePlayerList: + if finalSuperItemPlayerName: msgParamList = [winnerFaction, scoreKingName, finalSuperItemPlayerName, superItemID, superItemCount, nextBattleTimeStr] PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "CrossBattlefieldOver", msgParamList) return @@ -893,7 +1005,7 @@ for playerID, playerData in syncPlayerDataInfo.items(): if PlayerControl.GetDBPlayerAccIDByID(playerID): msgInfo = ["BattlefieldOver", [overTime] + playerData] - CrossRealmPlayer.MapServer_QueryCrossPlayerResult(playerID, "CrossBattlefield", msgInfo) + CrossRealmPlayer.MapServer_QueryCrossPlayerResult(playerID, "CrossBattlefield", msgInfo, True) return @@ -950,6 +1062,9 @@ elif opType == "CallKick": pass + elif opType == "CallChange": + pass + return def SyncCrossBattlefieldBuyInfo(curPlayer, zoneID, hmNum=None): @@ -972,6 +1087,7 @@ buyPlayerPack = ChPyNetSendPack.tagGCCrossBattlefieldBuyPlayer() buyPlayerPack.BuyPlayerID = buyPlayerID buyPlayerPack.Faction = buyRec.factionID + buyPlayerPack.ServerOnly = buyRec.serverOnly buyPlayerPack.FactionPlayerList = [] for callPlayerID in buyRec.callPlayerIDList: @@ -1057,6 +1173,11 @@ GameWorld.DebugLog("召集人数已满! hmNum=%s,buyPlayerID=%s,callPlayerIDList=%s" % (hmNum, buyPlayerID, buyRec.callPlayerIDList), playerID) return + if buyRec.serverOnly and not PlayerControl.GetDBPlayerAccIDByID(buyPlayerID): + PlayerControl.NotifyCode(curPlayer, "CrossBattlefieldCallServerOnly") + #GameWorld.DebugLog("非本服玩家,无法加入其购买的召集队伍! hmNum=%s,buyPlayerID=%s,serverOnly=%s" % (hmNum, buyPlayerID, buyRec.serverOnly), playerID) + return + # 请求查询跨服服务器 dataMsg = {"openHour":openHour, "openMinute":openMinute, "buyPlayerID":buyPlayerID, "tagPlayerID":tagPlayerID, "playerID":playerID} CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BattlefieldCallJoin, dataMsg) @@ -1082,7 +1203,7 @@ openMinute = clientData.Minute tagPlayerID = clientData.TagPlayerID buyPlayerID = playerID - + GameWorld.DebugLog("召集场次踢人: tagPlayerID=%s,openHour=%s,openMinute=%s" % (tagPlayerID, openHour, openMinute), playerID) if buyPlayerID == tagPlayerID: return @@ -1121,3 +1242,26 @@ CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BattlefieldCallKick, dataMsg) return +#// C0 09 跨服战场召集场次修改 #tagCGCrossBattlefieldCallChange +# +#struct tagCGCrossBattlefieldCallChange +#{ +# tagHead Head; +# BYTE Hour; //战场开启时 +# BYTE Minute; //战场开启分 +# BYTE ServerOnly; //是否仅本服玩家可加入,0-否,1-是 +#}; +def OnCrossBattlefieldCallChange(index, clientData, tick): + if GameWorld.IsCrossServer(): + return + + curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) + playerID = curPlayer.GetPlayerID() + openHour = clientData.Hour + openMinute = clientData.Minute + serverOnly = clientData.ServerOnly + + # 请求查询跨服服务器 + dataMsg = {"openHour":openHour, "openMinute":openMinute, "serverOnly":serverOnly, "playerID":playerID} + CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BattlefieldCallChange, dataMsg) + return -- Gitblit v1.8.0