From 3543895ddc549721077098362f22a83e5dfe6941 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 26 二月 2025 01:31:54 +0800
Subject: [PATCH] 10385 【越南】【英语】【BT】【GM】【砍树】福地新增鼠管及优化-服务端(修复疲劳满后还允许拉物品bug)
---
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py | 1657 ++++++++++++++++++++++++++++++----------------------------
1 files changed, 846 insertions(+), 811 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
index 9d4f853..67b2687 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
@@ -18,892 +18,927 @@
import GameWorld
import PlayerControl
import CrossRealmMsg
-import CrossRealmPlayer
+import DataRecordPack
import ChPyNetSendPack
+import PyGameDataStruct
+import PlayerDBGSEvent
+import CrossBillboard
+import PyDataManager
import NetPackCommon
import IpyGameDataPY
import ShareDefine
import PyGameData
+import CommFunc
import ChConfig
+import datetime
import operator
import random
+import time
+
+#跨服PK排行榜管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
+class CrossPKBillboardManager(object):
-PKPlayerState_Matching = 0
-PKPlayerState_Fighting = 1
+ DBKEY_CrossPKFinalBillboardData = "CrossPKFinalBillboard_%s_%s" # 是否收到赛区赛季最终榜单同步,参数(zoneID, seasonID)
+
+ def __init__(self):
+ self.__ZoneSeasonDataList = "ZoneSeasonDataList_%s_%s" # 分区赛季排行数据列表 [tagDBCrossPKBillboard, ...]
+ self.__ZoneSeasonPlayerOrderDict = "ZoneSeasonPlayerOrderDict_%s_%s" # 分区赛季排行数据字典 {playerID:rank, ...}
+ self.__ZoneSeasonList = [] # 分区赛季列表 [(zoneID, seasonID), ...]
+ self.__UnSortZoneSeasonTimeDict = {} # 未排序的分区赛季排行 {(zoneID, seasonID):tick, ...}
+ return
+
+ def GetCrossPKBillboardInfo(self, zoneID, seasonID, isSort=False):
+ ## 获取跨服PK排行榜信息
+ # @return: billboardList, orderDict
+ listAttrName = self.__ZoneSeasonDataList % (zoneID, seasonID)
+ orderDictAttrName = self.__ZoneSeasonPlayerOrderDict % (zoneID, seasonID)
+ if not hasattr(self, listAttrName):
+ setattr(self, listAttrName, [])
+ setattr(self, orderDictAttrName, {})
+ self.__ZoneSeasonList.append((zoneID, seasonID))
+ billboardList = getattr(self, listAttrName)
+ if isSort:
+ self.__PKBillboardSort(zoneID, seasonID, billboardList)
+ orderDict = getattr(self, orderDictAttrName)
+ return billboardList, orderDict
+
+ def __PKBillboardSort(self, zoneID, seasonID, billboardList):
+ ## 排序
+ if (zoneID, seasonID) not in self.__UnSortZoneSeasonTimeDict:
+ return
+ self.__UnSortZoneSeasonTimeDict.pop((zoneID, seasonID))
+ billboardList.sort(key=operator.attrgetter("PKScore", "Time"), reverse=True)
+ orderDict = {}
+ for order, billboardData in enumerate(billboardList, 1):
+ orderDict[billboardData.PlayerID] = order # 缓存赛季玩家排名
+ orderDictAttrName = self.__ZoneSeasonPlayerOrderDict % (zoneID, seasonID)
+ setattr(self, orderDictAttrName, orderDict)
+ GameWorld.DebugLog("跨服PK榜单排序: zoneID=%s,seasonID=%s,orderDict=%s" % (zoneID, seasonID, orderDict))
+ return
+
+ def PKBillboardSortByTime(self, tick):
+ ## 定时排序
+ if not self.__UnSortZoneSeasonTimeDict:
+ return
+ sortCD = 60 * 1000 # 超过1分钟强制排序
+ for key, updTick in self.__UnSortZoneSeasonTimeDict.items():
+ zoneID, seasonID = key
+ if tick - updTick < sortCD:
+ continue
+ self.GetCrossPKBillboardInfo(zoneID, seasonID, True)
+ return
+
+ def SetNeedSort(self, zoneID, seasonID):
+ if (zoneID, seasonID) not in self.__UnSortZoneSeasonTimeDict:
+ self.__UnSortZoneSeasonTimeDict[(zoneID, seasonID)] = GameWorld.GetGameWorld().GetTick()
+ return
+ ## ===========================================================================================
+
+ def CopyToCrossBillboard(self):
+ toBillboardType = ShareDefine.Def_CBT_CrossRealmPK
+ billboardMgr = PyDataManager.GetCrossBillboardManager()
+ for zoneID, seasonID in self.__ZoneSeasonList:
+ groupValue1, groupValue2 = zoneID, seasonID
+ toBillboardObj = billboardMgr.GetCrossBillboard(toBillboardType, groupValue1, groupValue2)
+ billboardList = self.GetCrossPKBillboardInfo(zoneID, seasonID)[0]
+ GameWorld.Log("CopyToCrossBillboard: zoneID=%s,seasonID=%s,%s" % (zoneID, seasonID, len(billboardList)))
+ for billboardData in billboardList:
+ tobillboardData = PyGameDataStruct.tagDBCrossBillboard()
+ tobillboardData.GroupValue1 = groupValue1
+ tobillboardData.GroupValue2 = groupValue2
+ tobillboardData.BillboardType = toBillboardType
+ tobillboardData.ID = billboardData.PlayerID
+ tobillboardData.Name1 = billboardData.PlayerName
+ tobillboardData.Type2 = billboardData.Job
+ tobillboardData.Value1 = billboardData.RealmLV
+ tobillboardData.Value2 = billboardData.DanLV
+ tobillboardData.Value3 = billboardData.Face
+ tobillboardData.Value4 = billboardData.FacePic
+ tobillboardData.CmpValue = billboardData.PKScore
+ tobillboardData.CmpValue3 = billboardData.Time
+ toBillboardObj.AddBillboardData(tobillboardData)
+
+ self.__ZoneSeasonList = []
+ return
+
+ # 保存数据 存数据库和realtimebackup
+ def GetSaveData(self):
+ savaData = ""
+ cntData = ""
+ cnt = 0
+ for zoneID, seasonID in self.__ZoneSeasonList:
+ billboardList = self.GetCrossPKBillboardInfo(zoneID, seasonID)[0]
+ for billboardData in billboardList:
+ cnt += 1
+ savaData += billboardData.getBuffer()
+
+ GameWorld.Log("SaveCrossPKBillboard cnt :%s len=%s" % (cnt, len(savaData)))
+ return CommFunc.WriteDWORD(cntData, cnt) + savaData
+
+ # 从数据库载入数据
+ def LoadPyGameData(self, datas, pos, dataslen):
+ cnt, pos = CommFunc.ReadDWORD(datas, pos)
+ GameWorld.Log("LoadCrossPKBillboard cnt :%s" % cnt)
+
+ for _ in xrange(cnt):
+ billboardData = PyGameDataStruct.tagDBCrossPKBillboard()
+ billboardData.clear()
+ pos += billboardData.readData(datas, pos, dataslen)
+
+ zoneID = billboardData.ZoneID
+ seasonID = billboardData.SeasonID
+ billboardList = self.GetCrossPKBillboardInfo(zoneID, seasonID)[0]
+ billboardList.append(billboardData)
+
+ # 排序
+ for zoneID, seasonID in self.__ZoneSeasonList:
+ self.SetNeedSort(zoneID, seasonID)
+ billboardList = self.GetCrossPKBillboardInfo(zoneID, seasonID, True)[0]
+ GameWorld.Log(" zoneID=%s, seasonID=%s, count=%s" % (zoneID, seasonID, len(billboardList)))
+
+ self.CopyToCrossBillboard()
+ return pos
+
+def MapServer_QueryCrossPKSeasonOrder(curPlayer, msgList):
+ ## 地图服务器查询玩家赛区赛季PK榜排名
+ playerID = curPlayer.GetPlayerID()
+ zoneID, seasonID, eventName, eventData = msgList
+ funcData = {"zoneID":zoneID, "seasonID":seasonID, "eventName":eventName, "eventData":eventData}
+ CrossBillboard.OnQueryPlayerBillboardRank(playerID, "QueryCrossPKSeasonOrder", funcData, ShareDefine.Def_CBT_CrossRealmPK, zoneID, seasonID)
+ return
-class CrossPKPlayer():
- ## 跨服PK玩家类
-
- def __init__(self):
- self.accID = ""
- self.playerID = 0
- self.playerName = ""
- self.playerJob = 0
- self.playerLV = 0
- self.maxHP = 0
- self.fightPower = 0
- self.pkScore = 0
- self.danLV = 0
- self.matchTick = 0
- self.cWinCount = 0 # 连胜次数
- self.ondayScore = 0 # 过天时的积分
- self.serverGroupID = 0 # 所属服务器ID,一个服务器ID由多个服组成
- self.pkZoneID = 0 # 所属赛区ID,一个赛区由多个服务器ID组成
- self.seasonID = 0 # 赛季ID
+def OnQueryCrossPKSeasonOrderRet(playerID, funcData, orderIndex):
+ ## 查询排名返回
+ queryPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+ if not queryPlayer:
return
-
-class CrossPKRoom():
- ## 跨服PK房间类
-
- def __init__(self):
- self.pkZoneID = 0
- self.roomID = 0
- self.mapID = 0
- self.openTick = 0 # 开房时间
- self.readyTick = 0 # 玩家都准备好的时间
- self.roomState = ShareDefine.Def_VsRoom_State_WaitPlayer # 默认状态
- self.roomPlayerIDList = [] # 对战玩家ID列表
- self.readyPlayerIDList = [] # 已经准备好的玩家ID列表
- self.isMapOpen = False # 地图是否已经开启该房间,未开启的房间超时后,本次匹配视为无效,有玩家进地图才会开启副本分线
- return
-
+ zoneID = funcData["zoneID"]
+ seasonID = funcData["seasonID"]
+ eventName = funcData["eventName"]
+ eventData = funcData["eventData"]
+ order = orderIndex + 1
+ sysMsg = str([zoneID, seasonID, eventName, eventData, order])
+ queryPlayer.MapServer_QueryPlayerResult(0, 0, "CrossPKSeasonOrder", sysMsg, len(sysMsg))
+ return
+
################################################################################
-def OnPlayerLogin(curPlayer):
+def __GetCrossPKZoneSeasonTimeInfo():
+ key = "CrossPKZoneSeasonTimeInfo"
+ openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1
+ ZoneSeasonTimeInfo = IpyGameDataPY.GetConfigEx(key)
+
+ if ZoneSeasonTimeInfo and ZoneSeasonTimeInfo[0] == openServerDay:
+ #GameWorld.DebugLog("已经加载过本日跨服PK赛季处理信息!openServerDay=%s" % openServerDay)
+ return ZoneSeasonTimeInfo[1]
+
+ GameWorld.Log("加载跨服PK赛季时间信息: openServerDay=%s" % (openServerDay))
+
+ zoneSeasonTimeDict = {}
+ serverTime = GameWorld.GetServerTime()
+ crossZoneName = GameWorld.GetCrossZoneName()
+ crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
+ if not crossZoneList:
+ return zoneSeasonTimeDict
+
+ for zoneIpyData in crossZoneList:
+ zoneID = zoneIpyData.GetZoneID()
+
+ # 规定每个赛区的赛季时间需按顺序配置
+ seasonIpyDataList = IpyGameDataPY.GetIpyGameDataList("CrossRealmPKSeason", crossZoneName, zoneID)
+ if not seasonIpyDataList:
+ continue
+
+ for i, seasonIpyData in enumerate(seasonIpyDataList):
+ seasonID = seasonIpyData.GetSeasonID()
+ startDateStr = seasonIpyData.GetStartDate()
+ endDateStr = seasonIpyData.GetEndDate()
+ endTimeStr = seasonIpyData.GetEndTime()
+
+ startDateTime = datetime.datetime.strptime("%s 00:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
+ endDateTime = datetime.datetime.strptime("%s %s:00" % (endDateStr, endTimeStr), ChConfig.TYPE_Time_Format)
+
+ # 最后一个赛季
+ if i == len(seasonIpyDataList) - 1:
+ nextSeasonIpyData = None
+ else:
+ nextSeasonIpyData = seasonIpyDataList[i + 1]
+
+ if serverTime < startDateTime:
+ GameWorld.Log(" 赛季未开始! zoneID=%s,seasonID=%s,startDateStr=%s,endDateStr=%s" % (zoneID, seasonID, startDateStr, endDateStr))
+ break
+
+ elif startDateTime <= serverTime <= endDateTime:
+ pass
+
+ elif endDateTime < serverTime:
+ if nextSeasonIpyData:
+ nestStartDateStr = nextSeasonIpyData.GetStartDate()
+ nextStartDateTime = datetime.datetime.strptime("%s 00:00:00" % (nestStartDateStr), ChConfig.TYPE_Time_Format)
+ if serverTime >= nextStartDateTime:
+ GameWorld.Log(" 赛季已过期! zoneID=%s,seasonID=%s,startDateStr=%s,endDateStr=%s" % (zoneID, seasonID, startDateStr, endDateStr))
+ continue
+ else:
+ pass
+
+ else:
+ continue
+
+ nextSeasonID = 0 if not nextSeasonIpyData else nextSeasonIpyData.GetSeasonID()
+ zoneSeasonTimeDict[zoneID] = [seasonIpyData]
+ GameWorld.Log(" 赛季活动中! zoneID=%s,seasonID=%s,startDateStr=%s,endDateStr=%s,nextSeasonID=%s" % (zoneID, seasonID, startDateStr, endDateStr, nextSeasonID))
+ break
+
+ ZoneSeasonTimeInfo = IpyGameDataPY.SetConfigEx(key, [openServerDay, zoneSeasonTimeDict])
+ GameWorld.Log("跨服PK赛季时间信息加载完毕!")
+ GameWorld.Log("=============================================================")
+ return ZoneSeasonTimeInfo[1]
+
+def OnMinuteProcess():
+ ## 每分钟处理
+
if not GameWorld.IsCrossServer():
- __OnLoginNotifyPKOverInfo(curPlayer)
+ return
+
+ zoneSeasonTimeDict = __GetCrossPKZoneSeasonTimeInfo()
+ if not zoneSeasonTimeDict:
+ return
+
+ gameWorld = GameWorld.GetGameWorld()
+ serverTime = GameWorld.GetServerTime()
+ crossZoneName = GameWorld.GetCrossZoneName()
+ for zoneID, seasonTimeInfo in zoneSeasonTimeDict.items():
+ zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, zoneID)
+ if not zoneIpyData:
+ continue
+
+ curSeasonIpyData = seasonTimeInfo[0]
+ if not curSeasonIpyData:
+ continue
+
+ seasonID = curSeasonIpyData.GetSeasonID()
+ startDateStr = curSeasonIpyData.GetStartDate()
+ endDateStr = curSeasonIpyData.GetEndDate()
+ endTimeStr = curSeasonIpyData.GetEndTime()
+
+ startDateTime = datetime.datetime.strptime("%s 00:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
+ endDateTime = datetime.datetime.strptime("%s %s:00" % (endDateStr, endTimeStr), ChConfig.TYPE_Time_Format)
+
+ seasonState = 0
+ if startDateTime <= serverTime < endDateTime:
+ seasonState = 1
+ elif serverTime >= endDateTime:
+ seasonState = 2
+
+ zoneSeasonIDDictName = ChConfig.Def_WorldKey_CrossPKZoneSeasonID % zoneID
+ seasonStateDictName = ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID
+ dictSeasonID = gameWorld.GetDictByKey(zoneSeasonIDDictName)
+ curSeasonState = gameWorld.GetDictByKey(seasonStateDictName)
+ if curSeasonState == seasonState and dictSeasonID == seasonID:
+ #已经是这个状态了
+ continue
+ gameWorld.SetDict(zoneSeasonIDDictName, seasonID)
+ gameWorld.SetDict(seasonStateDictName, seasonState)
+ GameWorld.Log("跨服PK赛季状态变更: zoneID=%s,seasonID=%s,seasonState=%s" % (zoneID, seasonID, seasonState))
+
+ serverGroupIDList = zoneIpyData.GetServerGroupIDList()
+ # 赛季结束
+ if seasonState == 2:
+ PyGameData.g_crossPKMatchDict = {}
+
+ # 广播当前赛区的所有子服跨服PK赛季状态变更
+ matchState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)
+ seasonInfo = {"ZoneID":zoneID, "SeasonID":seasonID, "SeasonState":seasonState, "MatchState":matchState}
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKSeasonInfo, seasonInfo, serverGroupIDList)
+
return
-## 玩家离线处理
-def OnLeaveServer(curPlayer):
- # 发送取消匹配
- SendCancelCrossRealmPKMatch(curPlayer, "PlayerDisconnect")
+def OnCrossRealmPKDailyActionStateChange(isOpen):
+ ## 跨服PK每日活动匹配状态变更
+
+ if not GameWorld.IsCrossServer():
+ return
+
+ gameWorld = GameWorld.GetGameWorld()
+ preState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)
+ gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK, isOpen)
+
+ # 匹配状态从关闭到开启
+ if not preState and isOpen:
+ GameWorld.Log("跨服PK匹配状态开启,重置相关匹配数据!")
+
+ crossZoneName = GameWorld.GetCrossZoneName()
+ crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
+ if not crossZoneList:
+ return
+
+ for zoneIpyData in crossZoneList:
+ zoneID = zoneIpyData.GetZoneID()
+
+ # 广播当前赛区的所有子服跨服PK赛季状态变更
+ serverGroupIDList = zoneIpyData.GetServerGroupIDList()
+ seasonID = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonID % zoneID)
+ seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID)
+ seasonInfo = {"ZoneID":zoneID, "SeasonID":seasonID, "SeasonState":seasonState, "MatchState":isOpen}
+ GameWorld.Log("跨服PK匹配状态变更: zoneID=%s,seasonID=%s,seasonState=%s,matchState=%s" % (zoneID, seasonID, seasonState, isOpen))
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKSeasonInfo, seasonInfo, serverGroupIDList)
+
return
-def IsCrossRealmPKOpen():
+def Sync_CrossPKInitDataToClientServer(tick, serverGroupID=0):
+ ''' 同步跨服PK活动数据到子服务器
+ @param serverGroupID: 为0时同步所有子服
+ '''
+
+ GameWorld.Log("同步给子服对应的赛季信息: syncServerGroupID=%s" % (serverGroupID))
+ if serverGroupID:
+ ipyData = GetCrossPKServerGroupZone(serverGroupID)
+ if not ipyData:
+ return
+ crossZoneList = [ipyData]
+ else:
+ crossZoneName = GameWorld.GetCrossZoneName()
+ crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
+ if not crossZoneList:
+ return
+ gameWorld = GameWorld.GetGameWorld()
+ for zoneIpyData in crossZoneList:
+ zoneID = zoneIpyData.GetZoneID()
+ seasonID = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonID % zoneID)
+ seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID)
+ matchState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)
+ seasonInfo = {"ZoneID":zoneID, "SeasonID":seasonID, "SeasonState":seasonState, "MatchState":matchState}
+ serverGroupIDList = [serverGroupID] if serverGroupID else zoneIpyData.GetServerGroupIDList()
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKSeasonInfo, seasonInfo, serverGroupIDList)
+
+ return
+
+def GetCrossPKServerGroupZone(serverGroupID):
+ ## 获取服务器组ID对应的跨服PK所属赛区,返回0代表该服务器没有分配赛区
+ crossZoneName = GameWorld.GetCrossZoneName()
+ crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
+ if not crossZoneList:
+ return
+
+ for zoneIpyData in crossZoneList:
+ for groupInfo in zoneIpyData.GetServerGroupIDList():
+ if (isinstance(groupInfo, int) and serverGroupID == groupInfo) \
+ or (isinstance(groupInfo, tuple) and len(groupInfo) == 2 and groupInfo[0] <= serverGroupID <= groupInfo[1]):
+ return zoneIpyData
+ return
+
+def OnPlayerLogin(curPlayer):
+ # 本服登录处理
+
+ # 本服没有分配赛区不处理
+ if not GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID):
+ return
+ __OnLoginNotifyPKOverInfo(curPlayer)
+
+ crossZoneName = GameWorld.GetCrossZoneName()
+ crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
+ if not crossZoneList:
+ return
+ # 同步所有赛区赛季信息
+ zoneSeasonInfo = ChPyNetSendPack.tagGCCrossRealmPKSeasonInfo()
+ zoneSeasonInfo.ZoneList = []
+ for zoneIpyData in crossZoneList:
+ zoneID = zoneIpyData.GetZoneID()
+ zoneInfo = ChPyNetSendPack.tagGCCrossRealmPKZone()
+ zoneInfo.ZoneID = zoneID
+ zoneInfo.ZoneName = zoneIpyData.GetZoneName().decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
+ zoneInfo.ZoneNameLen = len(zoneInfo.ZoneName)
+ zoneInfo.SeasonList = []
+ seasonList = IpyGameDataPY.GetIpyGameDataList("CrossRealmPKSeason", crossZoneName, zoneID)
+ seasonList = [] if not seasonList else seasonList
+ for seasonIpyData in seasonList:
+ seasonInfo = ChPyNetSendPack.tagGCCrossRealmPKSeason()
+ seasonInfo.SeasonID = seasonIpyData.GetSeasonID()
+ seasonInfo.StartDate = seasonIpyData.GetStartDate()
+ seasonInfo.EndDate = seasonIpyData.GetEndDate()
+ seasonInfo.EndTime = seasonIpyData.GetEndTime()
+ zoneInfo.SeasonList.append(seasonInfo)
+ zoneInfo.SeasonCount = len(zoneInfo.SeasonList)
+ zoneSeasonInfo.ZoneList.append(zoneInfo)
+ zoneSeasonInfo.ZoneCount = len(zoneSeasonInfo.ZoneList)
+ NetPackCommon.SendFakePack(curPlayer, zoneSeasonInfo)
+
+ # 同步本服赛季状态
+ gameWorld = GameWorld.GetGameWorld()
+ seasonStatePack = ChPyNetSendPack.tagGCCrossRealmPKSeasonState()
+ seasonStatePack.ZoneID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+ seasonStatePack.SeasonID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+ seasonStatePack.SeasonState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)
+ seasonStatePack.MatchState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)
+ seasonStatePack.CrossZoneName = GameWorld.GetCrossZoneName()
+ seasonStatePack.CrossZoneNameLen = len(seasonStatePack.CrossZoneName)
+ NetPackCommon.SendFakePack(curPlayer, seasonStatePack)
+
+ return
+
+def IsCrossRealmPKMatchState():
## 跨服PK匹配赛是否开启
- return 1
- return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_MergePKState) == ChConfig.Def_Action_Open
-
-def ClientServerMsg_ServerInitOK(serverGroupID, tick):
- ## 子服启动成功
- GameWorld.Log("同步跨服PK赛季信息及状态到子服: serverGroupID=%s" % (serverGroupID))
- seasonInfo = {"SeasonID":1, "SeasonState":1, "MatchState":1}
- CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKSeasonInfo, seasonInfo, [serverGroupID])
- return
-
-def SendCancelCrossRealmPKMatch(curPlayer, reason):
- ## 发送取消匹配
-
- # 跨服服务器不处理
- if GameWorld.IsCrossServer():
- return
-
- # 非活动中不处理
- if not IsCrossRealmPKOpen():
- return
-
-# # 如果是要登陆到跨服服务器的,不发送取消
-# if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_IsLoginToMergeServer):
-# GameWorld.DebugLog("本次离线为要登陆跨服服务器的自动离线行为,不发送取消匹配!", curPlayer.GetPlayerID())
-# curPlayer.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 0)
-# return
-
- vsRoomID = curPlayer.GetVsRoomId()
- if vsRoomID and PlayerControl.GetCrossRealmState(curPlayer) == 1:
- GameWorld.DebugLog("玩家跨服PK状态,不能取消匹配!vsRoomID=%s" % vsRoomID, curPlayer.GetPlayerID())
- return
-
- dataMsg = {"accID":curPlayer.GetAccID(), # 账号
- "playerID":curPlayer.GetPlayerID(), # 玩家ID
- "playerName":curPlayer.GetName(), # 跨服子服玩家名
- "reason":reason, # 取消原因
- "vsRoomID":vsRoomID, # 对战房间ID
- }
- CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PKCancel, dataMsg)
- PlayerControl.SetVsRoomId(curPlayer, 0)
- GameWorld.Log("发送取消跨服PK匹配到跨服服务器:dataMsg=%s" % str(dataMsg), curPlayer.GetPlayerID())
- return
+ return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState \
+ % ShareDefine.DailyActionID_CrossReamPK) == ChConfig.Def_Action_Open
def ClientServerMsg_PKMatch(serverGroupID, playerInfoDict, tick):
## 请求匹配
-
- if not GameWorld.IsCrossServer():
- GameWorld.ErrLog("非跨服服务器不处理跨服PK匹配请求!")
- return
-
- if not IsCrossRealmPKOpen():
- GameWorld.Log("跨服匹配PK活动未开启,不允许请求匹配!")
- return
-
seasonID = playerInfoDict["seasonID"] # 赛季ID
- pkZoneID = playerInfoDict["pkZoneID"] # 所属赛区
- accID = playerInfoDict["accID"] # 角色账号
+ zoneID = playerInfoDict["zoneID"] # 所属赛区
+
playerID = playerInfoDict["playerID"] # 角色ID
- playerName = playerInfoDict["playerName"] # 玩家名
- job = playerInfoDict["playerJob"] # 职业
- playerLV = playerInfoDict["playerLV"] # 职业
- maxHP = playerInfoDict["maxHP"] # 职业
- fightPower = playerInfoDict["fightPower"] # 战斗力
- pkScore = playerInfoDict["pkScore"] # 当前积分
- danLV = playerInfoDict["danLV"] # 当前段位
- cWinCount = playerInfoDict["cWinCount"] # 连胜次数
- ondayScore = playerInfoDict["ondayScore"] # 过天时的积分
+ fightPower = playerInfoDict["fightPower"]
+ requestType = playerInfoDict.get("requestType", 0)
- zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])
-# if playerID in zoneMatchPlayerList:
-# GameWorld.Log("玩家正在匹配中,无法重复发起匹配!playerID=%s,accID=%s" % (playerID, accID))
-# CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, 1], [serverGroupID])
-# return
-# if playerID in PyGameData.g_crossPKPlayerDict:
-# GameWorld.Log("玩家正在战斗中,无法重复发起匹配!playerID=%s,accID=%s" % (playerID, accID))
-# CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, -2], [serverGroupID])
-# return
-
- pkPlayer = CrossPKPlayer()
- pkPlayer.accID = accID
- pkPlayer.playerID = playerID
- pkPlayer.playerName = playerName
- pkPlayer.playerJob = job
- pkPlayer.playerLV = playerLV
- pkPlayer.maxHP = maxHP
- pkPlayer.pkScore = pkScore
- pkPlayer.danLV = danLV
- pkPlayer.fightPower = fightPower
- pkPlayer.matchTick = tick
- pkPlayer.cWinCount = cWinCount
- pkPlayer.ondayScore = ondayScore
- pkPlayer.serverGroupID = serverGroupID
- pkPlayer.pkZoneID = pkZoneID
- pkPlayer.seasonID = seasonID
- PyGameData.g_crossPKPlayerDict[playerID] = pkPlayer
-
- # 加入赛区匹配列表
- zoneMatchPlayerList.append(playerID)
- PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList
-
- GameWorld.Log("玩家加入匹配: seasonID=%s,pkZoneID=%s,serverGroupID=%s,accID=%s,playerID=%s,pkScore=%s,fightPower=%s,cWinCount=%s,len(zoneMatchPlayerList)=%s"
- % (seasonID, pkZoneID, serverGroupID, accID, playerID, pkScore, fightPower, cWinCount, len(zoneMatchPlayerList)))
-
- CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, 1], [serverGroupID])
+ isRefresh = requestType == 1
+ OnRefreshPKMatch(zoneID, seasonID, playerID, fightPower, serverGroupID, isRefresh)
return
-def ClientServerMsg_PKCancel(playerInfoDict, tick):
- ## 取消匹配
+def ClientServerMsg_PKOver(serverGroupID, playerInfoDict, tick):
+ ## 收到子服同步的PK结算
- if not GameWorld.IsCrossServer():
- GameWorld.ErrLog("非跨服服务器不处理取消跨服PK匹配!")
+ playerID = playerInfoDict["playerID"] # 角色ID
+ tagPlayerID = playerInfoDict["tagPlayerID"] # 目标玩家ID
+ isWinner = playerInfoDict["isWinner"] # 是否获胜
+ zoneID = playerInfoDict["pkZoneID"]
+ seasonID = playerInfoDict["seasonID"]
+ playerName = playerInfoDict["playerName"]
+ playerJob = playerInfoDict["playerJob"]
+ face = playerInfoDict["face"]
+ facePic = playerInfoDict["facePic"]
+ realmLV = playerInfoDict["realmLV"]
+ fightPower = playerInfoDict["fightPower"]
+ pkScore = playerInfoDict["pkScore"]
+ danLV = playerInfoDict["danLV"]
+ cWinCount = playerInfoDict["cWinCount"]
+
+ if playerID not in PyGameData.g_crossPKMatchDict:
+ GameWorld.ErrLog("玩家匹配,无法结算跨服PK奖励! tagPlayerID=%s,isWinner=%s,pkScore=%s,cWinCount=%s"
+ % (tagPlayerID, isWinner, pkScore, cWinCount), playerID)
return
-
- # 非活动中不处理
- if not IsCrossRealmPKOpen():
+ matchIDList = PyGameData.g_crossPKMatchDict[playerID]
+ if tagPlayerID not in matchIDList:
+ GameWorld.ErrLog("目标玩家ID不在玩家匹配列表里,无法结算跨服PK奖励! tagPlayerID=%s not in %s ,isWinner=%s,pkScore=%s,cWinCount=%s"
+ % (tagPlayerID, matchIDList, isWinner, pkScore, cWinCount), playerID)
return
+ matchIndex = matchIDList.index(tagPlayerID)
- accID = playerInfoDict["accID"] # 角色账号
- playerID = playerInfoDict["playerID"] # 玩家ID
- reason = playerInfoDict["reason"] # 取消原因
- vsRoomID = playerInfoDict["vsRoomID"] # 所属对战房间ID
- if vsRoomID in PyGameData.g_crossPKRoomDict:
- pkRoom = PyGameData.g_crossPKRoomDict[vsRoomID]
- if pkRoom.isMapOpen or pkRoom.readyTick:
- GameWorld.Log("跨服对战房间已经开启了线路,或者双方数据都已传输完毕,不可再取消匹配!vsRoomID=%s" % vsRoomID)
- return
+ addScore = IpyGameDataPY.GetFuncCfg("CrossRealmPKScore2", 2) # 默认失败积分
+ if isWinner:
+ baseScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKScore2", 1)
+ baseScore = baseScoreList[matchIndex] if len(baseScoreList) > matchIndex else 0
+ wExScore = eval(IpyGameDataPY.GetFuncCompileCfg("CrossRealmPKScore2", 3)) # 胜方附加分
+ addScore = baseScore + wExScore
+ cWinCount += 1
+ else:
+ cWinCount = 0
- GameWorld.Log("玩家取消匹配: reason=%s,accID=%s,playerID=%s,vsRoomID=%s" % (reason, accID, playerID, vsRoomID))
+ updScore = pkScore + addScore
+ pkDanIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", danLV)
+ if pkDanIpyData and pkDanIpyData.GetLVUpScore() and updScore >= pkDanIpyData.GetLVUpScore():
+ danLV += 1
+
+ GameWorld.Log("结算跨服PK奖励: tagPlayerID=%s,isWinner=%s,pkScore=%s,cWinCount=%s,addScore=%s,updScore=%s,danLV=%s"
+ % (tagPlayerID, isWinner, pkScore, cWinCount, addScore, updScore, danLV), playerID)
- pkZoneID = 0
- if playerID in PyGameData.g_crossPKPlayerDict:
- pkPlayer = PyGameData.g_crossPKPlayerDict.pop(playerID)
- pkZoneID = pkPlayer.pkZoneID
- GameWorld.Log(" 移除PK玩家: pkZoneID=%s,accID=%s,playerID=%s" % (pkZoneID, accID, playerID))
-
- zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])
- if playerID in zoneMatchPlayerList:
- zoneMatchPlayerList.remove(playerID)
- GameWorld.Log(" 从匹配队列中删除,匹配队列剩余人数=%s" % (len(zoneMatchPlayerList)))
-
- #取消所有存在该玩家的房间,子服不一定知道玩家当前最新所属房间ID, 故只能通过遍历删除已经为玩家创建的房间
- for roomID, pkRoom in PyGameData.g_crossPKRoomDict.items():
- if playerID not in pkRoom.roomPlayerIDList:
- continue
-
- for roomPlayerID in pkRoom.roomPlayerIDList:
- if roomPlayerID == playerID:
- GameWorld.Log(" 自己不处理: roomID=%s,playerID=%s" % (roomID, playerID))
- continue
-
- zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])
- zoneMatchPlayerList.append(roomPlayerID)
- PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList
- GameWorld.Log(" 将之前匹配的对手重新加入匹配队列: roomID=%s,roomPlayerID=%s,当前匹配人数=%s"
- % (roomID, roomPlayerID, len(zoneMatchPlayerList)))
-
- PyGameData.g_crossPKRoomDict.pop(roomID)
- GameWorld.Log(" 移除房间: popRoomID=%s" % (roomID))
- break
+ # 更新榜单
+ groupValue1, groupValue2 = zoneID, seasonID
+ name2, type2 = "", playerJob
+ value1, value2 = realmLV, danLV
+ cmpValue = updScore
+ CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_CrossRealmPK, groupValue1, playerID, playerName, name2, type2,
+ value1, value2, cmpValue, groupValue2=groupValue2, value3=face, value4=facePic)
- return
-
-def ClientServerMsg_PKPrepareOK(playerInfoDict, tick):
- ## 玩家跨服对战数据准备OK
-
- if not GameWorld.IsCrossServer():
- GameWorld.ErrLog("非跨服服务器不处理取消跨服PK匹配!")
- return
-
- accID = playerInfoDict["accID"] # 玩家账号
- playerID = playerInfoDict["playerID"] # 玩家ID
- vsRoomID = playerInfoDict["vsRoomID"] # 所属对战房间ID
- if playerID not in PyGameData.g_crossPKPlayerDict:
- GameWorld.ErrLog("玩家跨服对战数据准备OK, 但找不到该对战玩家信息!vsRoomID=%s,playerID=%s" % (vsRoomID, playerID))
- return
- #pkPlayer = PyGameData.g_crossPKPlayerDict[playerID]
-
- if vsRoomID not in PyGameData.g_crossPKRoomDict:
- GameWorld.ErrLog("玩家跨服对战数据准备OK, 但找不到该对战房间(%s)!可能对手已取消!" % vsRoomID)
- return
- vsRoom = PyGameData.g_crossPKRoomDict[vsRoomID]
-
- if vsRoom.roomState != ShareDefine.Def_VsRoom_State_WaitPlayer:
- GameWorld.ErrLog("玩家跨服对战数据准备OK, 但房间状态非等待状态, state=%s!" % vsRoom.roomState)
- return
-
- if playerID not in vsRoom.readyPlayerIDList:
- vsRoom.readyPlayerIDList.append(playerID)
-
- GameWorld.Log("玩家跨服PK准备完毕: accID=%s,playerID=%s,vsRoomID=%s" % (accID, playerID, vsRoomID))
- return
-
-def __ReadyOKRoomPlayerProcess(tick):
- ## 玩家跨服PK已准备好的房间处理
-
- #GameWorld.Log("===已准备好的对战房间处理===")
- serverGroupIDList = []
- sendReadyOKRoomList = []
- for roomID, vsRoom in PyGameData.g_crossPKRoomDict.items():
-
- # 非等待状态的房间不处理
- if vsRoom.roomState != ShareDefine.Def_VsRoom_State_WaitPlayer:
- continue
-
- if not vsRoom.roomPlayerIDList:
- continue
-
- pkZoneID = 0
- isAllReady = True
- roomGroupIDList = []
- readyMemberDict = {} # 已准备好的玩家信息
- for roomPlayerID in vsRoom.roomPlayerIDList:
- if roomPlayerID not in vsRoom.readyPlayerIDList or roomPlayerID not in PyGameData.g_crossPKPlayerDict:
- isAllReady = False
- break
- roomPlayer = PyGameData.g_crossPKPlayerDict[roomPlayerID]
- pkZoneID = roomPlayer.pkZoneID
- roomGroupIDList.append(roomPlayer.serverGroupID)
- readyMemberDict[roomPlayerID] = {"ServerGroupID":roomPlayer.serverGroupID, "Name":roomPlayer.playerName,
- "Job":roomPlayer.playerJob, "LV":roomPlayer.playerLV, "MaxHP":roomPlayer.maxHP}
-
- if not isAllReady:
- continue
- vsRoom.roomState = ShareDefine.Def_VsRoom_State_PrepareFight
- vsRoom.readyTick = tick
- GameWorld.Log(" 准备好的房间: pkZoneID=%s,roomID=%s,mapID=%s,readyMemberDict=%s" % (pkZoneID, roomID, vsRoom.mapID, str(readyMemberDict)))
-
- sendReadyOKRoomList.append([roomID, readyMemberDict])
- serverGroupIDList += roomGroupIDList
-
- # 将已准备好的房间广播到子服
- if sendReadyOKRoomList:
- GameWorld.Log(" 已准备好的对战房间数: %s" % len(sendReadyOKRoomList))
- CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKReadyOKRoomList, sendReadyOKRoomList, serverGroupIDList)
-
- return
-
-def OnPKMatchProcess(tick):
- ## 玩家跨服PK匹配定时处理逻辑
-
- # 非跨服服务器不处理跨服PK匹配逻辑
- if not GameWorld.IsCrossServer():
- return
-
- if not IsCrossRealmPKOpen():
- return
-
- # 同步子服排行榜
- #__SyncBillboardToClientServer(False, tick)
-
- processTick = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 1) * 1000
- processTickKey = "PKMatchLastTick"
- lastProcessTick = GameWorld.GetGameWorld().GetDictByKey(processTickKey)
- if tick - lastProcessTick < processTick:
- return
- GameWorld.GetGameWorld().SetDict(processTickKey, tick)
-
- # 处理超时的房间
- __DoCheckRoomTimeout(tick)
- # 通知已准备好的房间玩家可进入跨服
- __ReadyOKRoomPlayerProcess(tick)
-
- maxGroupCnt = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 2)
- outTimeTick = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 3) * 1000
-
- # 每个赛区单独匹配
- for pkZoneID, matchPlayerIDList in PyGameData.g_crossPKZoneMatchPlayerDict.items():
- matchPlayerCount = len(matchPlayerIDList)
- if matchPlayerCount < 2:
- #GameWorld.Log("匹配PK人数不足,不处理!pkZoneID=%s, 总人数:%s" % (pkZoneID, matchPlayerCount))
- continue
-
- GameWorld.Log("★★★★★★★★★★开始跨服PK匹配(pkZoneID=%s, 总人数:%s)★★★★★★★★★★" % (pkZoneID, matchPlayerCount))
-
- matchPlayerList = []
- for matchPlayerID in matchPlayerIDList:
- if matchPlayerID not in PyGameData.g_crossPKPlayerDict:
- continue
- matchPlayerList.append(PyGameData.g_crossPKPlayerDict[matchPlayerID])
- # 按匹配时间、积分升序排序
- matchTickSortList = sorted(matchPlayerList, key=operator.attrgetter("matchTick"))
- scoreSortList = sorted(matchPlayerList, key=operator.attrgetter("pkScore"))
-
- matchPlayerVSList = [] # 成功匹配玩家对战列表
-
- # 优先匹配等待超时玩家
- __DoMatch_OutTimePlayer(matchTickSortList, scoreSortList, outTimeTick, matchPlayerVSList, tick)
-
- if len(matchPlayerVSList) < maxGroupCnt:
- # 再按积分段匹配玩家
- __DoMatch_DanScorePlayer(scoreSortList, maxGroupCnt, matchPlayerVSList)
-
- # 给成功匹配的玩家非配对战房间
- matchPlayerVSList = matchPlayerVSList[:maxGroupCnt]
- __DoSetVSRoom(pkZoneID, matchPlayerVSList, tick)
- GameWorld.Log("==========匹配结束(总匹配队伍:%s)==========" % len(matchPlayerVSList))
- return
-
-
-def __DoMatch_OutTimePlayer(matchTickSortList, scoreSortList, outTimeTick, matchPlayerVSList, tick):
- '''匹配超时玩家
- 匹配中的玩家按积分排序,最后一个默认匹配上一个,第一个默认匹配下一个,其他匹配前后积分差绝对值较小的一个
- '''
- GameWorld.Log(" ==优先匹配超时等待玩家==最大等待时间:%s, tick=%s" % (outTimeTick, tick))
- GameWorld.Log(" scoreSortListLen=%s" % len(scoreSortList))
- for i, matchPlayer in enumerate(matchTickSortList):
- # 只有一个玩家
- if len(scoreSortList) <= 1:
- GameWorld.Log(" 当前玩家数%s<=1,不再匹配!" % len(scoreSortList))
- break
-
- if tick - matchPlayer.matchTick < outTimeTick:
- GameWorld.Log(" i=%s,玩家未超时,不再匹配!" % (i))
- break
-
- GameWorld.Log(" i=%s,超时玩家, %s-%s=%s >= outTimeTick(%s)"
- % (i, tick, matchPlayer.matchTick, tick - matchPlayer.matchTick, outTimeTick))
- # 已经被匹配走了
- if matchPlayer not in scoreSortList:
- GameWorld.Log(" 已经被匹配走了!")
- continue
-
- outTimeIndex = scoreSortList.index(matchPlayer)
- # 最后一个默认匹配上一个
- if outTimeIndex == len(scoreSortList) - 1:
- vsIndex = outTimeIndex - 1
- GameWorld.Log(" 超时玩家积分排序索引%s,最后一个,默认匹配上一个索引%s!" % (outTimeIndex, vsIndex))
- # 第一个默认匹配下一个
- elif outTimeIndex == 0:
- vsIndex = outTimeIndex + 1
- GameWorld.Log(" 超时玩家积分排序索引%s,第一个,默认匹配下一个索引%s!" % (outTimeIndex, vsIndex))
- # 其他情况匹配积分较近的一个
- else:
- preIndex = outTimeIndex - 1
- nextIndex = outTimeIndex + 1
- prePlayer = scoreSortList[preIndex]
- nextPlayer = scoreSortList[nextIndex]
- preDiff = abs(prePlayer.pkScore - matchPlayer.pkScore)
- nextDiff = abs(matchPlayer.pkScore - nextPlayer.pkScore)
- vsIndex = preIndex if preDiff <= nextDiff else nextIndex
- GameWorld.Log(" 超时玩家积分排序索引-积分(%s-%s),上一个(%s-%s),下一个(%s-%s),preDiff=%s,nextDiff=%s,vsIndex=%s"
- % (outTimeIndex, matchPlayer.pkScore, preIndex, prePlayer.pkScore,
- nextIndex, nextPlayer.pkScore, preDiff, nextDiff, vsIndex))
-
- if outTimeIndex > vsIndex:
- scoreSortList.pop(outTimeIndex)
- vsPlayer = scoreSortList.pop(vsIndex)
- elif outTimeIndex < vsIndex:
- vsPlayer = scoreSortList.pop(vsIndex)
- scoreSortList.pop(outTimeIndex)
- else:
- continue
-
- # 加入成功匹配列表
- matchPlayerVSList.append([matchPlayer, vsPlayer])
-
- return
-
-def __DoMatch_DanScorePlayer(scoreSortList, maxGroupCnt, matchPlayerVSList):
- ''' 匹配积分分段玩家
- 匹配中的玩家按段位积分归组,归组后,随机段位顺序,每个段位组中的玩家随机两两PK
- '''
- GameWorld.Log(" ==匹配积分分段玩家== maxGroupCnt=%s,scoreSortListLen=%s" % (maxGroupCnt, len(scoreSortList)))
- danPlayerListDict = {} # 按积分分段列表分散玩家
- for matchPlayer in scoreSortList:
- danLV = matchPlayer.danLV
- danPlayerList = danPlayerListDict.get(danLV, [])
- danPlayerList.append(matchPlayer)
- danPlayerListDict[danLV] = danPlayerList
-
- # 按分段玩家随机匹配
- danList = danPlayerListDict.keys()
- random.shuffle(danList) # 打乱段位顺序
-
- GameWorld.Log(" 积分分段个数: %s, %s" % (len(danList), danList))
-
- # 日志输出分组明细
- for danLV in danList:
- strList = []
- for player in danPlayerListDict[danLV]:
- strList.append((player.playerID, player.pkScore, player.fightPower))
- GameWorld.Log(" 积分段组, danLV=%s, %s" % (danLV, str(strList)))
-
- doCount = 0
- while len(matchPlayerVSList) < maxGroupCnt and doCount < maxGroupCnt:
- doCount += 1
- isMatchOK = False
- for danLV in danList:
- danPlayerList = danPlayerListDict[danLV]
- danPlayerCount = len(danPlayerList)
- if danPlayerCount < 2:
- GameWorld.Log(" 段位人数少于2个,此段位本轮轮空!doCount=%s,danLV=%s" % (doCount, danLV))
- continue
-
- vsIndexList = random.sample(xrange(danPlayerCount), 2) # 随机取两个索引对战
- vsIndexList.sort()
- aPlayer = danPlayerList.pop(vsIndexList[1])
- bPlayer = danPlayerList.pop(vsIndexList[0])
-
- matchPlayerVSList.append([aPlayer, bPlayer])
- isMatchOK = True
- GameWorld.Log(" 成功匹配玩家: aPlayerID=%s,aScore=%s,aFP=%s VS bPlayerID=%s,bScore=%s,bFP=%s"
- % (aPlayer.playerID, aPlayer.pkScore, aPlayer.fightPower, bPlayer.playerID, bPlayer.pkScore, bPlayer.fightPower))
-
- if len(matchPlayerVSList) >= maxGroupCnt:
- GameWorld.Log(" 已经达到最大匹配数! 已匹配对战数=%s, 不再匹配!doCount=%s" % (len(matchPlayerVSList), doCount))
- break
-
- if not isMatchOK:
- GameWorld.Log(" 已经没有满足匹配条件的玩家! 不再匹配!doCount=%s" % (doCount))
- break
-
- return
-
-def __DoSetVSRoom(pkZoneID, matchPlayerVSList, tick):
- ## 设置对战房间
-
- if not matchPlayerVSList:
- return
-
- vsRoomDict = {}
- serverGroupIDList = []
- zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])
-
- mapIDList = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 4)
- GameWorld.Log("===给配对的玩家开房间(pkZoneID=%s,配对数:%s)===" % (pkZoneID, len(matchPlayerVSList)))
- for aPlayer, bPlayer in matchPlayerVSList:
-
- if not aPlayer or not bPlayer:
- continue
-
- aPlayerID = aPlayer.playerID
- bPlayerID = bPlayer.playerID
- if aPlayerID not in PyGameData.g_crossPKPlayerDict or bPlayerID not in PyGameData.g_crossPKPlayerDict:
- GameWorld.ErrLog("玩家匹配数据异常!aPlayerID=%s,bPlayerID=%s" % (aPlayerID, bPlayerID))
- continue
-
- roomID = __GetNewRoomID()
- if not roomID:
- GameWorld.ErrLog("无法创建房间!该房间已经存在!PyGameData.g_crossPKRoomID=%s" % PyGameData.g_crossPKRoomID)
- continue
- mapID = random.choice(mapIDList)
-
- newRoom = CrossPKRoom()
- newRoom.pkZoneID = pkZoneID
- newRoom.roomID = roomID
- newRoom.mapID = mapID
- newRoom.openTick = tick
- newRoom.roomPlayerIDList = [aPlayerID, bPlayerID]
- PyGameData.g_crossPKRoomDict[roomID] = newRoom
-
- aServerGroupID, bServerGroupID = aPlayer.serverGroupID, bPlayer.serverGroupID
- GameWorld.Log(" 开房:pkZoneID=%s,mapID=%s,roomID=%s,aPlayerID=%s,bPlayerID=%s" % (pkZoneID, mapID, roomID, aPlayerID, bPlayerID))
- vsRoomDict[roomID] = [mapID, [[aServerGroupID, aPlayerID], [bServerGroupID, bPlayerID]]]
-
- serverGroupIDList.append(aServerGroupID)
- serverGroupIDList.append(bServerGroupID)
-
- # 移除匹配队列
- if aPlayerID in zoneMatchPlayerList:
- zoneMatchPlayerList.remove(aPlayerID)
- if bPlayerID in zoneMatchPlayerList:
- zoneMatchPlayerList.remove(bPlayerID)
- PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList
-
- # 将匹配结果广播到子服
- if vsRoomDict:
- CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchResult, vsRoomDict, serverGroupIDList)
-
- return
-
-def __GetNewRoomID():
- ## 获取新房间ID, 房间号直接自增,一定不会重复,除非自增一轮后房间ID还没有释放
- for _ in xrange(100):
- newRoomID = PyGameData.g_crossPKRoomID + 1
- if newRoomID > 65530:
- newRoomID = 1
- PyGameData.g_crossPKRoomID = newRoomID
- if newRoomID not in PyGameData.g_crossPKRoomDict:
- return newRoomID
- return 0
-
-def __DoCheckRoomTimeout(tick):
- ## 处理超时的房间
-
- timeoutRoomDict = {}
- serverGroupIDList = []
- #roomTimeout = IpyGameDataPY.GetFuncCfg("CheckRoomTimeout", 1) * 1000 # 这个时间尽量长点,目前暂时不确定玩家从准备好到进入到地图的时长
- roomTimeout = 180 * 1000 # 这个时间尽量长点,目前暂时不确定玩家从准备到进入到地图的时长
- for roomID, pkRoom in PyGameData.g_crossPKRoomDict.items():
- if pkRoom.isMapOpen or not pkRoom.readyTick:
- continue
- if tick - pkRoom.readyTick <= roomTimeout:
- continue
- pkZoneID = pkRoom.pkZoneID
- GameWorld.Log("PK房间等待玩家进来超时,没有玩家进来,关闭该房间!pkZoneID=%s,roomID=%s,openTick=%s,readyTick=%s,tick=%s"
- % (pkZoneID, roomID, pkRoom.openTick, pkRoom.readyTick, tick))
- roomPlayerInfo = []
- for roomPlayerID in pkRoom.roomPlayerIDList:
- pkPlayer = PyGameData.g_crossPKPlayerDict.pop(roomPlayerID, None)
- if not pkPlayer:
- continue
- serverGroupID = pkPlayer.serverGroupID
- GameWorld.Log(" 移除玩家,玩家需重新手动匹配,serverGroupID=%s,roomPlayerID=%s" % (serverGroupID, roomPlayerID))
- serverGroupIDList.append(serverGroupID)
- roomPlayerInfo.append([serverGroupID, roomPlayerID])
- timeoutRoomDict[roomID] = roomPlayerInfo
- PyGameData.g_crossPKRoomDict.pop(roomID)
-
- # 将超时房间广播到子服
- if timeoutRoomDict:
- CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKTimeoutRoomList, timeoutRoomDict, serverGroupIDList)
- return
-
-def MapServer_CrossPKRoomOpen(msgList):
- roomID = msgList[0]
- if roomID not in PyGameData.g_crossPKRoomDict:
- GameWorld.ErrLog("MapServer_CrossPKRoomOpen => PK房间不存在!roomID=%s" % roomID)
- return
- pkRoom = PyGameData.g_crossPKRoomDict[roomID]
- pkRoom.isMapOpen = True
- GameWorld.Log("MapServer_CrossPKRoomOpen => roomID=%s" % roomID)
- return
-
-def MapServer_MergePKOver(infoList):
- ## 收到MapServer副本跨服PK结果同步
-
- GameWorld.Log("收到MapServer_跨服PK战斗结果: %s" % str(infoList))
-
- roomID, winnerID, loserID, roundWinnerIDList, overType = infoList
-
- if roomID not in PyGameData.g_crossPKRoomDict:
- GameWorld.ErrLog("跨服PK房间数据不存在!roomID=%s" % roomID)
- return
- vsRoom = PyGameData.g_crossPKRoomDict.pop(roomID)
- #vsRoom = PyGameData.g_crossPKRoomDict[roomID]
- roomPlayerIDList = vsRoom.roomPlayerIDList
- if not winnerID and not loserID:
- GameWorld.ErrLog("地图没有结算跨服PK胜负玩家,随机玩家获胜!")
- if not roomPlayerIDList or len(roomPlayerIDList) != 2:
- return
- winnerID, loserID = roomPlayerIDList
- elif not loserID:
- for roomPlayerID in roomPlayerIDList:
- if roomPlayerID != winnerID:
- loserID = roomPlayerID
- break
-
- if winnerID not in roomPlayerIDList or loserID not in roomPlayerIDList:
- GameWorld.ErrLog("跨服PK房间及玩家不匹配,不结算!roomID=%s,winnerID=%s,loserID=%s,roomPlayerIDList=%s"
- % (roomID, winnerID, loserID, vsRoom.roomPlayerIDList))
- return
-
- if winnerID not in PyGameData.g_crossPKPlayerDict:
- GameWorld.ErrLog("跨服PK房间获取不到玩家PK数据, roomID=%s,winnerID=%s" % (roomID, winnerID))
- return
- if loserID not in PyGameData.g_crossPKPlayerDict:
- GameWorld.ErrLog("跨服PK房间获取不到玩家PK数据, roomID=%s,loserID=%s" % (roomID, loserID))
- return
-
- winner = PyGameData.g_crossPKPlayerDict.pop(winnerID)
- loser = PyGameData.g_crossPKPlayerDict.pop(loserID)
- #winner = PyGameData.g_crossPKPlayerDict[winnerID]
- #loser = PyGameData.g_crossPKPlayerDict[loserID]
- seasonID = winner.seasonID
-
- cWinCount = winner.cWinCount
- winnerScore, loserScore = winner.pkScore, loser.pkScore
- winnerDanLV, loserDanLV = winner.danLV, loser.danLV
- winnerDayScore, loserDayScore = max(0, winnerScore - winner.ondayScore), max(0, loserScore - loser.ondayScore) # 今日已获得积分,正积分
-
- GameWorld.Log("winnerDayScore=%s,winnerScore=%s,winnerDanLV=%s,cWinCount=%s" % (winnerDayScore, winnerScore, winnerDanLV, cWinCount))
- GameWorld.Log("loserDayScore=%s,loserScore=%s,loserDanLV=%s" % (loserDayScore, loserScore, loserDanLV))
-
- winIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", winnerDanLV)
- loseIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", loserDanLV)
- if not winIpyData or not loseIpyData:
- GameWorld.ErrLog("跨服PK房间段位数据异常! roomID=%s,winnerDanLV=%s,loserDanLV=%s" % (roomID, winnerDanLV, loserDanLV))
-
- baseScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKScore", 2) # 胜负保底分
- wBaseScore = baseScoreList[0] if len(baseScoreList) > 0 else 0
- lBaseScore = baseScoreList[1] if len(baseScoreList) > 1 else 0
- wExScore = eval(IpyGameDataPY.GetFuncCompileCfg("CrossRealmPKScore", 3)) # 胜方附加分
- lExScore = 0
-
- winnerAddScore = wBaseScore + wExScore
- loserAddScore = lBaseScore + lExScore
-
- dayMaxScore = IpyGameDataPY.GetFuncCfg("CrossRealmPKScore", 1) # 每日获得积分上限,0为不限制
- if dayMaxScore:
- if winnerAddScore > 0:
- winnerAddScore = min(dayMaxScore - winnerDayScore, winnerAddScore)
- if loserAddScore > 0:
- loserAddScore = min(dayMaxScore - loserDayScore, loserAddScore)
-
- winner.pkScore += winnerAddScore
- loser.pkScore += loserAddScore
-
- winner.cWinCount += 1
- loser.cWinCount = 0
-
- if winIpyData and winIpyData.GetLVUpScore() and winner.pkScore >= winIpyData.GetLVUpScore():
- winner.danLV += 1
-
- if loseIpyData and loseIpyData.GetLVUpScore() and loser.pkScore >= loseIpyData.GetLVUpScore():
- loser.danLV += 1
-
- GameWorld.Log("wBaseScore=%s,wExScore=%s,winnerAddScore=%s,updScore=%s,updDanLV=%s,updCWinCount=%s" % (wBaseScore, wExScore, winnerAddScore, winner.pkScore, winner.danLV, winner.cWinCount))
- GameWorld.Log("lBaseScore=%s,lExScore=%s,loserAddScore=%s,updScore=%s,updDanLV=%s,updCWinCount=%s" % (lBaseScore, lExScore, loserAddScore, loser.pkScore, loser.danLV, loser.cWinCount))
-
+ # 通知子服
+ pkScore = updScore
+ packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
+ tagPackObj = packDataMgr.GetPlayerPackObj(tagPlayerID)
+ tagPlayerName = tagPackObj.playerName if tagPackObj else ""
+ winnerID = playerID if isWinner else tagPlayerID
timeStr = GameWorld.GetCurrentDataTimeStr()
playerOverDict = {}
- # 通知客户端战斗结果
- for playerID in [winnerID, loserID]:
- if playerID == winnerID:
- serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName = \
- winner.serverGroupID, winner.pkScore, winner.danLV, winner.cWinCount, winnerAddScore, loser.playerID, loser.playerName
- else:
- serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName = \
- loser.serverGroupID, loser.pkScore, loser.danLV, loser.cWinCount, loserAddScore, winner.playerID, winner.playerName
-
- player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
- notifyState = True if player else False
-
- playerOverDict[playerID] = [roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList] \
- + [serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]
- if not player:
- continue
-
- overPack = ChPyNetSendPack.tagGCCrossRealmPKOverInfo()
- overPack.TimeStr = timeStr
- overPack.OverType = overType
- overPack.WinnerID = winnerID
- overPack.RoundWinnerID = roundWinnerIDList
- overPack.RoundCount = len(overPack.RoundWinnerID)
- overPack.AddScore = addScore
- overPack.Score = pkScore
- overPack.DanLV = danLV
- overPack.CWinCnt = cWinCount
- overPack.TagName = tagPlayerName
- overPack.TagNameLen = len(overPack.TagName)
- NetPackCommon.SendFakePack(player, overPack)
-
- GameWorld.Log("同步玩家PK结果: serverGroupID=%s,roomID=%s,addScore=%s,pkScore=%s,danLV=%s,cWinCount=%s,tagPlayerID=%s"
- % (serverGroupID, roomID, addScore, pkScore, danLV, cWinCount, tagPlayerID), playerID)
-
- serverGroupIDList = [winner.serverGroupID, loser.serverGroupID]
- GameWorld.Log("同步子服战斗结果: seasonID=%s,timeStr=%s,roomID=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s"
- % (seasonID, timeStr, roomID, overType, winnerID, roundWinnerIDList))
- # 同步子服
+ playerOverDict[playerID] = [zoneID, seasonID, timeStr, winnerID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName]
+ serverGroupIDList = [serverGroupID]
CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKOverInfo, playerOverDict, serverGroupIDList)
+
+ # 系统重新刷新匹配
+ OnRefreshPKMatch(zoneID, seasonID, playerID, fightPower, serverGroupID, True)
return
+def OnRefreshPKMatch(zoneID, seasonID, playerID, fightPower, serverGroupID, isRefresh):
+ # 刷新匹配数据
+ # @param isRefresh: 是否强制重新刷新
+
+ if isRefresh or playerID not in PyGameData.g_crossPKMatchDict:
+ # 执行匹配逻辑
+ matchIDList = __DoPKMatch(zoneID, seasonID, playerID, fightPower)
+ if matchIDList: # 有新结果才替换
+ PyGameData.g_crossPKMatchDict[playerID] = matchIDList
+
+ packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
+ matchIDList = PyGameData.g_crossPKMatchDict.get(playerID, [])
+ matchInfoDict = {}
+ for matchID in matchIDList:
+ packObj = packDataMgr.GetPlayerPackObj(matchID)
+ if not packObj:
+ continue
+ matchInfoDict[matchID] = packObj.GetBaseDict()
+
+ dataMsg = {"playerID":playerID, "matchIDList":matchIDList, "matchInfoDict":matchInfoDict}
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, dataMsg, [serverGroupID])
+ return
+
+def __DoPKMatch(zoneID, seasonID, playerID, fightPower):
+ ## 执行匹配
+
+ if not IsCrossRealmPKMatchState():
+ GameWorld.DebugLog("非匹配阶段,不允许刷新匹配! zoneID=%s,seasonID=%s" % (zoneID, seasonID), playerID)
+ return
+
+ matchCount = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch3", 1)
+ rankRange = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch3", 2) # 名次范围段
+ totalRange = rankRange * matchCount # 总匹配名次范围
+
+ matchIDList = [] # 匹配ID结果列表
+
+ billboardType = ShareDefine.Def_CBT_CrossRealmPK
+ groupValue1, groupValue2 = zoneID, seasonID
+ billboardMgr = PyDataManager.GetCrossBillboardManager()
+ billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
+ billDataCount = billboardObj.GetCount()
+ playerBillIndex = billboardObj.IndexOfByID(playerID)
+
+ GameWorld.DebugLog("===执行匹配: zoneID=%s,seasonID=%s,playerID=%s,fightPower=%s,playerBillIndex=%s,matchCount=%s"
+ % (zoneID, seasonID, playerID, fightPower, playerBillIndex, matchCount), playerID)
+ if playerBillIndex <= 0:
+ playerBillIndex = billDataCount
+ GameWorld.DebugLog("玩家未上积分榜,视为排在榜上最后一名之后! playerBillIndex=%s" % playerBillIndex, playerID)
+ billStartIndex = max(0, playerBillIndex - totalRange / 2) # 以自己的排名为中心索引
+ billLoopIndexList = range(billStartIndex, billStartIndex + totalRange + 1)
+ if playerBillIndex in billLoopIndexList:
+ billLoopIndexList.remove(playerBillIndex) # 移除自己
+ loopBillPlayerIDList = []
+ for index in billLoopIndexList:
+ if index >= billDataCount:
+ break
+ billData = billboardObj.At(index)
+ loopBillPlayerIDList.append(int(billData.ID))
+ GameWorld.DebugLog("积分榜可匹配的排名玩家ID列表: %s,%s" % (len(loopBillPlayerIDList), loopBillPlayerIDList), playerID)
+ randPackPlayerIDList = None # 可随机匹配的打包数据战力排名玩家ID列表
+
+ for matchIndex in range(matchCount):
+ GameWorld.DebugLog("匹配第%s个: matchIndex=%s,playerBillIndex=%s,billLoopIndexList=%s" % (matchIndex + 1, matchIndex, playerBillIndex, billLoopIndexList), playerID)
+ matchID = 0
+ randIDList = []
+ # 1. 优先赛季积分排行榜
+ if billDataCount:
+ __addRandMatchID(playerID, matchIndex, rankRange, randIDList, matchIDList, loopBillPlayerIDList, 1)
+
+ # 有需要用到战力匹配的,加载一次
+ if not randIDList and randPackPlayerIDList == None:
+ zonePackPlayerIDList = __getZonePackPlayerIDList(zoneID, playerID)
+ playerPackIndex = -1
+ randPackPlayerIDList = []
+ if playerID in zonePackPlayerIDList:
+ playerPackIndex = zonePackPlayerIDList.index(playerID)
+ startIndex = max(0, playerPackIndex - totalRange / 2) # 以自己的排名为中心索引
+ randPackPlayerIDList = [int(packID) for packID in zonePackPlayerIDList[startIndex:totalRange + 1]] # 因为包含自己,所以加1
+ if playerID in randPackPlayerIDList:
+ randPackPlayerIDList.remove(playerID) # 移除自己
+ GameWorld.DebugLog(" 赛区战力榜玩家排名: playerPackIndex=%s,%s,%s" % (playerPackIndex, len(zonePackPlayerIDList), zonePackPlayerIDList), playerID)
+ GameWorld.DebugLog(" 赛区战力榜随机玩家: %s,%s" % (len(randPackPlayerIDList), randPackPlayerIDList), playerID)
+
+ # 2. 该范围段没有的话匹配打包数据战力榜
+ if not randIDList and randPackPlayerIDList:
+ __addRandMatchID(playerID, matchIndex, rankRange, randIDList, matchIDList, randPackPlayerIDList, 2)
+
+ if randIDList:
+ matchID = random.choice(randIDList)
+
+ # 3. 最终还没有,直接机器人
+ if not matchID:
+ matchID = matchIndex + 1 # 机器人ID固定为 matchIndex + 1
+ matchIDList.append(matchID)
+ GameWorld.DebugLog(" 本段随机匹配结果: matchIndex=%s,matchID=%s,randIDList=%s,matchIDList=%s" % (matchIndex, matchID, randIDList, matchIDList), playerID)
+
+ GameWorld.DebugLog("最终匹配结果: matchIDList=%s" % str(matchIDList), playerID)
+ return matchIDList
+
+def __addRandMatchID(playerID, matchIndex, rankRange, randIDList, matchIDList, loopPlayerIDList, sign):
+ ## 根据所有可循环玩家ID列表,添加对应匹配轮次可随机匹配的玩家
+ packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
+ indexStart = matchIndex * rankRange
+ indexEnd = indexStart + rankRange - 1
+ loopIDCount = len(loopPlayerIDList)
+ if sign == 1:
+ GameWorld.DebugLog(" 匹配赛区积分榜: matchIndex=%s,loopIndex=%s~%s,loopIDCount=%s" % (matchIndex, indexStart, indexEnd, loopIDCount), playerID)
+ else:
+ GameWorld.DebugLog(" 匹配赛区战力榜: matchIndex=%s,loopIndex=%s~%s,loopIDCount=%s" % (matchIndex, indexStart, indexEnd, loopIDCount), playerID)
+ for index in range(indexStart, indexEnd + 1):
+ if index >= loopIDCount:
+ break
+ dataID = loopPlayerIDList[index]
+ if not dataID or dataID == playerID or dataID in randIDList:
+ GameWorld.DebugLog(" 不可匹配空或自己或已添加: dataID=%s,randIDList=%s" % (dataID, randIDList), playerID)
+ continue
+ if dataID in matchIDList:
+ GameWorld.DebugLog(" 不可添加已匹配过玩家: dataID=%s,randIDList=%s,matchIDList=%s" % (dataID, randIDList, matchIDList), playerID)
+ continue
+ if not packDataMgr.IsPlayerIn(dataID):
+ GameWorld.DebugLog(" 不匹配无打包数据玩家: dataID=%s,randIDList=%s" % (dataID, randIDList), playerID)
+ continue
+ randIDList.append(dataID)
+ GameWorld.DebugLog(" 添加可以随机匹配玩家: dataID=%s,randIDList=%s" % (dataID, randIDList), playerID)
+
+ return
+
+def __getZonePackPlayerIDList(zoneID, playerID):
+ ## 获取分区打包数据玩家ID列表
+ crossZoneName = GameWorld.GetCrossZoneName()
+ zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, zoneID)
+ if zoneIpyData:
+ packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
+ packDataMgr.Sort()
+ serverIDList = zoneIpyData.GetServerGroupIDList()
+ zonePackPlayerIDList = packDataMgr.GetPlayerIDListByServerIDInfo(zoneIpyData.GetServerGroupIDList())
+ GameWorld.DebugLog(" 获得赛区活跃打包数据玩家: zoneID=%s,serverIDList=%s,%s,%s"
+ % (zoneID, serverIDList, len(zonePackPlayerIDList), zonePackPlayerIDList), playerID)
+ return zonePackPlayerIDList
+ return []
+
+def ClientServerMsg_PKBillboard(serverGroupID, msgData):
+ ## 收到子服GM同步的设置跨服PK数据
+
+ zoneID = msgData["ZoneID"]
+ seasonID = msgData["SeasonID"]
+ playerInfoDict = msgData["PlayerInfo"]
+
+ accID = playerInfoDict["accID"]
+ playerID = playerInfoDict["playerID"]
+ playerName = playerInfoDict["playerName"]
+ playerJob = playerInfoDict["playerJob"]
+ face = playerInfoDict.get("face", 0)
+ facePic = playerInfoDict.get("facePic", 0)
+ realmLV = playerInfoDict["realmLV"]
+ pkScore = playerInfoDict["pkScore"]
+ danLV = playerInfoDict["danLV"]
+ cWinCount = playerInfoDict["cWinCount"]
+
+ # 更新排行榜
+ groupValue1, groupValue2 = zoneID, seasonID
+ name2, type2 = "", playerJob
+ value1, value2 = realmLV, danLV
+ cmpValue = pkScore
+ isOK = CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_CrossRealmPK, groupValue1, playerID, playerName, name2, type2,
+ value1, value2, cmpValue, groupValue2=groupValue2, value3=face, value4=facePic)
+ GameWorld.Log("GM设置跨服PK榜单玩家数据: isOK=%s,zoneID=%s,seasonID=%s,pkScore=%s,danLV=%s,cWinCount=%s,accID=%s"
+ % (isOK, zoneID, seasonID, pkScore, danLV, cWinCount, accID), playerID)
+ return
##================================== 以下是子服逻辑 ==========================================
+
+def OnGameServerInitOK():
+
+ if GameWorld.IsCrossServer():
+ return
+
+ dbZoneID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+ dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+ dbSeasonState = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)
+ GameWorld.Log("OnGameServerInitOK dbZoneID=%s,dbSeasonID=%s,dbSeasonState=%s" % (dbZoneID, dbSeasonID, dbSeasonState))
+
+ gameWorld = GameWorld.GetGameWorld()
+ zoneID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+ if not zoneID:
+ gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID, dbZoneID)
+ gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID, dbSeasonID)
+ gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState, dbSeasonState)
+ GameWorld.Log(" 服务器启动取DB值设置本服赛区赛季信息: ")
+
+ return
+
+def OnMapServerInitOK():
+ # 通知地图服务器状态
+
+ if GameWorld.IsCrossServer():
+ return
+
+ gameWorld = GameWorld.GetGameWorld()
+ zoneID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+ seasonID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+ seasonState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)
+ matchState = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)
+
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID, zoneID)
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID, seasonID)
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState, seasonState)
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK, matchState)
+ return
+
+def CrossServerMsg_PKSeasonInfo(seasonInfo):
+ ## 收到跨服服务器同步的赛季信息
+ #seasonInfo = {"ZoneID":zoneID, "SeasonID":seasonID, "SeasonState":seasonState, "MatchState":matchState}
+ GameWorld.Log("收到跨服服务器同步的赛季信息...")
+ if not seasonInfo:
+ return
+ zoneID = seasonInfo.get("ZoneID", 0)
+ seasonID = seasonInfo.get("SeasonID", 0)
+ seasonState = seasonInfo.get("SeasonState", 0)
+ matchState = seasonInfo.get("MatchState", 0)
+ GameWorld.Log(" zoneID=%s,seasonID=%s,seasonState=%s,matchState=%s" % (zoneID, seasonID, seasonState, matchState))
+ if not zoneID:
+ return
+ if not seasonID:
+ dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+ if dbSeasonID:
+ GameWorld.ErrLog(" 已经有分配赛季ID的暂定不能被置为0! dbSeasonID=%s" % dbSeasonID)
+ return
+
+ gameWorld = GameWorld.GetGameWorld()
+ curSeasonState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)
+
+ gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID, zoneID)
+ gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID, seasonID)
+ gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState, seasonState)
+ gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK, matchState)
+
+ # 强制覆盖存DB
+ dbZoneID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+ dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+ dbSeasonState = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)
+ GameWorld.Log(" before dbZoneID=%s,dbSeasonID=%s,dbSeasonState=%s" % (dbZoneID, dbSeasonID, dbSeasonState))
+
+ PlayerDBGSEvent.SetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID, zoneID)
+ PlayerDBGSEvent.SetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID, seasonID)
+ PlayerDBGSEvent.SetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState, seasonState)
+ dbZoneID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+ dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+ dbSeasonState = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)
+ GameWorld.Log(" update dbZoneID=%s,dbSeasonID=%s,dbSeasonState=%s" % (dbZoneID, dbSeasonID, dbSeasonState))
+
+ if curSeasonState == 1 and seasonState == 2:
+ pass
+ #PlayerControl.WorldNotify(0, "NotifySeasonOver")
+
+ # 通知地图服务器状态
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID, zoneID)
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID, seasonID)
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState, seasonState)
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK, matchState)
+
+ # 广播玩家赛季相关状态变更
+ seasonStatePack = ChPyNetSendPack.tagGCCrossRealmPKSeasonState()
+ seasonStatePack.ZoneID = zoneID
+ seasonStatePack.SeasonID = seasonID
+ seasonStatePack.SeasonState = seasonState
+ seasonStatePack.MatchState = matchState
+ seasonStatePack.CrossZoneName = GameWorld.GetCrossZoneName()
+ seasonStatePack.CrossZoneNameLen = len(seasonStatePack.CrossZoneName)
+ playerManager = GameWorld.GetPlayerManager()
+ for i in xrange(playerManager.GetPlayerCount()):
+ curPlayer = playerManager.GetPlayerByIndex(i)
+ if curPlayer == None or not curPlayer.GetInitOK():
+ continue
+ NetPackCommon.SendFakePack(curPlayer, seasonStatePack)
+ return
def CrossServerMsg_PKMatchReqRet(retInfo):
## 跨服PK匹配请求结果
- playerID, result = retInfo
+ playerID = retInfo["playerID"]
+ matchIDList = retInfo["matchIDList"]
+ matchInfoDict = retInfo["matchInfoDict"]
+
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
if not curPlayer:
return
- if result == -2:
- PlayerControl.NotifyCode(curPlayer, "InCrossPKing")
- return
-
- if result == 1:
- NetPackCommon.SendFakePack(curPlayer, ChPyNetSendPack.tagGCCrossRealmPKStartMatch())
-
+ matchOKPack = ChPyNetSendPack.tagGCCrossRealmPKMatchOK()
+ matchOKPack.MatchPlayer = []
+ for matchID in matchIDList:
+ matchPlayer = ChPyNetSendPack.tagGCCrossRealmPKMatchPlayer()
+ if matchID not in matchInfoDict:
+ matchPlayer.PlayerID = matchID
+ matchOKPack.MatchPlayer.append(matchPlayer)
+ continue
+ matchInfo = matchInfoDict[matchID]
+ matchPlayer.PlayerID = matchInfo["playerID"]
+ matchPlayer.PlayerName = matchInfo["playerName"]
+ matchPlayer.NameLen = len(matchPlayer.PlayerName)
+ matchPlayer.Job = matchInfo["job"]
+ matchPlayer.LV = matchInfo["lv"]
+ matchPlayer.RealmLV = matchInfo["realmLV"]
+ matchPlayer.Face = matchInfo["face"]
+ matchPlayer.FacePic = matchInfo["facePic"]
+ matchPlayer.FightPower = matchInfo["fightPower"] % ChConfig.Def_PerPointValue
+ matchPlayer.FightPowerEx = matchInfo["fightPower"] / ChConfig.Def_PerPointValue
+ matchOKPack.MatchPlayer.append(matchPlayer)
+ matchOKPack.MatchPlayerCount = len(matchOKPack.MatchPlayer)
+ NetPackCommon.SendFakePack(curPlayer, matchOKPack)
return
-def CrossServerMsg_PKMatchResult(vsRoomDict):
- ## 跨服PK匹配结果
- curServerGroupID = GameWorld.GetServerGroupID()
- actionType = ShareDefine.Def_MergeAction_MergePK
- mapPosList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKMatch", 5)
- GameWorld.Log("=== 收到PK匹配结果处理 === curServerGroupID=%s" % curServerGroupID)
- if not mapPosList:
- GameWorld.ErrLog("没有配置对战地图进入坐标!")
+
+#跨服竞技场未通知玩家的比赛结果,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
+class CrossPKUnNotifyOverInfoManager(object):
+
+ def __init__(self):
+ self.__unNotifyOverInfoDict = {} # {playerID:tagDBCrossPKUnNotifyOverInfo, ...}
return
- for roomID, roomInfo in vsRoomDict.items():
- mapID, playerList = roomInfo
- GameWorld.Log(" roomID=%s,playerList=%s" % (roomID, playerList))
- for i, playerInfo in enumerate(playerList):
- serverGroupID, playerID = playerInfo
- if serverGroupID != curServerGroupID:
- GameWorld.DebugLog(" 不是本服玩家,不处理!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))
- continue
- player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
- if not player:
- GameWorld.DebugLog(" 玩家不在线, playerID=%s" % (playerID))
- continue
- if PlayerControl.GetIsTJG(player):
- GameWorld.DebugLog(" 玩家脱机中, playerID=%s" % (playerID))
- continue
- PlayerControl.SetVsRoomId(player, roomID, True)
- # 通知地图玩家匹配成功, 上传数据, 准备进入跨服服务器
- posX, posY = mapPosList[i] if len(mapPosList) > i else mapPosList[0]
- CrossRealmPlayer.SendCrossRealmReg(player, actionType, mapID, mapID, 0, posX, posY)
-
- return
-
-def CrossServerMsg_PKReadyOKRoomList(readyOKRoomList):
- ## 子服接收玩家已准备好的PK房间信息, 此房间里的玩家可传送进入跨服
+ def AddUnNotifyOverInfo(self, playerID, overInfoData):
+ self.__unNotifyOverInfoDict[playerID] = overInfoData
+ return
- curServerGroupID = GameWorld.GetServerGroupID()
- GameWorld.Log("===收到跨服服务器通知已准备好的对战PK房间信息处理=== curServerGroupID=%s" % curServerGroupID)
- # serverGroupID, playerName, playerJob
+ def GetPlayerUnNotifyOverInfo(self, playerID): return self.__unNotifyOverInfoDict.pop(playerID, None)
- for roomID, readyMemberDict in readyOKRoomList:
- for playerID, playerInfo in readyMemberDict.items():
- serverGroupID = playerInfo["ServerGroupID"]
- playerName = playerInfo["Name"]
-
- if serverGroupID != curServerGroupID:
- GameWorld.DebugLog(" 不是本服玩家,不处理!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))
- continue
-
- player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
- if not player:
- GameWorld.DebugLog(" 玩家不在线 , playerID=%s" % (playerID))
- continue
- if PlayerControl.GetIsTJG(player):
- GameWorld.DebugLog(" 玩家脱机中, playerID=%s" % (playerID))
- continue
- player.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 1)
-
- matchPlayer = ChPyNetSendPack.tagGCCrossRealmPKMatchPlayer()
- for readyPlayerID, readyPlayerInfo in readyMemberDict.items():
- if readyPlayerID != playerID:
- matchPlayer.PlayerID = readyPlayerID
- matchPlayer.PlayerName = readyPlayerInfo["Name"]
- matchPlayer.NameLen = len(matchPlayer.PlayerName)
- matchPlayer.Job = readyPlayerInfo["Job"]
- matchPlayer.LV = readyPlayerInfo["LV"]
- matchPlayer.MaxHP = readyPlayerInfo["MaxHP"]
- break
+ # 保存数据 存数据库和realtimebackup
+ def GetSaveData(self):
+ savaData = ""
+ cntData = ""
+ cnt = 0
+ for overInfoData in self.__unNotifyOverInfoDict.values():
+ cnt += 1
+ savaData += overInfoData.getBuffer()
- PlayerControl.SetCrossRealmState(player, 1)
-
- # 通知匹配成功,可进入跨服
- matchOKPack = ChPyNetSendPack.tagGCCrossRealmPKMatchOK()
- matchOKPack.RoomID = roomID
- matchOKPack.PlayerName = playerName
- matchOKPack.NameLen = len(matchOKPack.PlayerName)
- matchOKPack.MatchPlayer = [matchPlayer]
- matchOKPack.MatchPlayerCount = len(matchOKPack.MatchPlayer)
- NetPackCommon.SendFakePack(player, matchOKPack)
- GameWorld.Log(" 通知玩家进入跨服PK对战房间! roomID=%s,playerID=%s,matchPlayerID=%s" % (roomID, playerID, matchPlayer.PlayerID))
-
- # 到这里默认认为一定会有结果的,所以本服直接增加次数
- #player.MapServer_QueryPlayerResult(0, 0, 'MergePKAddCnt', "", 0)
- return
-
-def CrossServerMsg_PKTimeoutRoomList(timeoutRoomDict):
- ## 子服接收已超时的PK房间信息, 此房间里的玩家重置跨服状态
+ GameWorld.Log("SaveDBCrossPKUnNotifyOverInfo cnt :%s len=%s" % (cnt, len(savaData)))
+ return CommFunc.WriteDWORD(cntData, cnt) + savaData
- curServerGroupID = GameWorld.GetServerGroupID()
- GameWorld.Log("===收到跨服服务器通知已超时的对战PK房间信息处理=== curServerGroupID=%s" % curServerGroupID)
+ # 从数据库载入数据
+ def LoadPyGameData(self, datas, pos, dataslen):
+ cnt, pos = CommFunc.ReadDWORD(datas, pos)
+ GameWorld.Log("LoadDBCrossPKUnNotifyOverInfo cnt :%s" % cnt)
+
+ for _ in xrange(cnt):
+ overInfoData = PyGameDataStruct.tagDBCrossPKUnNotifyOverInfo()
+ overInfoData.clear()
+ pos += overInfoData.readData(datas, pos, dataslen)
+ self.__unNotifyOverInfoDict[overInfoData.PlayerID] = overInfoData
+
+ return pos
- for roomID, roomPlayerInfo in timeoutRoomDict.items():
- if not roomPlayerInfo:
- continue
- serverGroupID, playerID = roomPlayerInfo
-
- if serverGroupID != curServerGroupID:
- GameWorld.DebugLog(" 不是本服玩家,不处理!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))
- continue
-
- player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
- if not player:
- GameWorld.DebugLog(" 玩家不在线 , playerID=%s" % (playerID))
- continue
- if PlayerControl.GetIsTJG(player):
- GameWorld.DebugLog(" 玩家脱机中, playerID=%s" % (playerID))
- continue
- playerVSRoomID = player.GetVsRoomId()
- if playerVSRoomID and playerVSRoomID != roomID:
- GameWorld.DebugLog(" 房间ID不同, playerID=%s" % (playerID))
- continue
- player.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 0)
- PlayerControl.SetCrossRealmState(player, 0)
-
- return
-
def CrossServerMsg_PKOverInfo(playerOverDict):
## 子服接收跨服PK结果信息
curServerGroupID = GameWorld.GetServerGroupID()
- GameWorld.Log("===收到跨服服务器同步的跨服PK结果=== curServerGroupID=%s" % curServerGroupID)
+ GameWorld.DebugLog("===收到跨服服务器同步的跨服PK结果=== curServerGroupID=%s" % curServerGroupID)
for playerID, overInfo in playerOverDict.items():
- roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, \
- serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState = overInfo
- if serverGroupID != curServerGroupID:
- GameWorld.DebugLog(" 不是本服玩家,不处理!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))
+ zoneID, seasonID, timeStr, winnerID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName = overInfo
+ if not PlayerControl.GetDBPlayerAccIDByID(playerID):
+ GameWorld.DebugLog(" 不是本服玩家,不处理! playerID=%s" % (playerID))
continue
- sendMapOverInfo = [roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]
player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
if not player or PlayerControl.GetIsTJG(player):
- GameWorld.Log(" 玩家不在线 或脱机中,先缓存,玩家上线后再同步,playerID=%s" % (playerID))
- PyGameData.g_crossPKUnNotifyOverInfo[playerID] = sendMapOverInfo
+ GameWorld.DebugLog(" 玩家不在线 或脱机中,先缓存,玩家上线后再同步,playerID=%s" % (playerID))
+ overInfoData = PyGameDataStruct.tagDBCrossPKUnNotifyOverInfo()
+ overInfoData.clear()
+ overInfoData.ZoneID = zoneID
+ overInfoData.SeasonID = seasonID
+ overInfoData.RoomID = 0
+ overInfoData.TimeStr = timeStr
+ overInfoData.OverType = 0
+ overInfoData.PlayerID = playerID
+ overInfoData.WinnerID = winnerID
+ overInfoData.RoundWinnerInfo = str([])
+ overInfoData.RoundWinnerLen = len(overInfoData.RoundWinnerInfo)
+ overInfoData.PKScore = pkScore
+ overInfoData.DanLV = danLV
+ overInfoData.CWinCount = cWinCount
+ overInfoData.AddScore = addScore
+ overInfoData.TagPlayerID = tagPlayerID
+ overInfoData.TagPlayerName = tagPlayerName
+ PyDataManager.GetCrossPKUnNotifyOverInfoManager().AddUnNotifyOverInfo(playerID, overInfoData)
continue
- sysMsg = str(sendMapOverInfo)
+ sysMsg = str(overInfo)
player.MapServer_QueryPlayerResult(0, 0, "CrossPKOverInfo", sysMsg, len(sysMsg))
- GameWorld.Log("通知地图跨服PK结算: roomID=%s,seasonID=%s,timeStr=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s, pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,notifyState=%s,mapID=%s"
- % (roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, notifyState, player.GetMapID()), playerID)
+ GameWorld.DebugLog("通知地图跨服PK结算: zoneID=%s,seasonID=%s,timeStr=%s,winnerID=%s, pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,mapID=%s"
+ % (zoneID, seasonID, timeStr, winnerID, pkScore, danLV, cWinCount, addScore, tagPlayerID, player.GetMapID()), playerID)
return
def __OnLoginNotifyPKOverInfo(curPlayer):
playerID = curPlayer.GetPlayerID()
- if playerID not in PyGameData.g_crossPKUnNotifyOverInfo:
+ overInfoData = PyDataManager.GetCrossPKUnNotifyOverInfoManager().GetPlayerUnNotifyOverInfo(playerID)
+ if not overInfoData:
return
- overInfo = PyGameData.g_crossPKUnNotifyOverInfo.pop(playerID)
- PlayerControl.SetCrossRealmState(curPlayer, 0)
- sysMsg = str(overInfo)
+ zoneID = overInfoData.ZoneID
+ seasonID = overInfoData.SeasonID
+ timeStr = overInfoData.TimeStr
+ winnerID = overInfoData.WinnerID
+ pkScore = overInfoData.PKScore
+ danLV = overInfoData.DanLV
+ cWinCount = overInfoData.CWinCount
+ addScore = overInfoData.AddScore
+ tagPlayerID = overInfoData.TagPlayerID
+ tagPlayerName = overInfoData.TagPlayerName
+ sysMsg = str([zoneID, seasonID, timeStr, winnerID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName])
curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossPKOverInfo", sysMsg, len(sysMsg))
- GameWorld.Log("玩家上线通知地图未结算的跨服PK结算: mapID=%s,overInfo=%s" % (curPlayer.GetMapID(), overInfo), playerID)
+ GameWorld.DebugLog("玩家上线通知地图未结算的跨服PK结算: zoneID=%s,seasonID=%s,timeStr=%s,winnerID=%s,pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,mapID=%s"
+ % (zoneID, seasonID, timeStr, winnerID, pkScore, danLV, cWinCount, addScore, tagPlayerID, curPlayer.GetMapID()), playerID)
return
-
+def DR_CrossReamlPK(eventName, dataDict={}):
+ drDataDict = {}
+ drDataDict.update(dataDict)
+ DataRecordPack.SendEventPack("CrossPK_%s" % eventName, drDataDict)
+ return
--
Gitblit v1.8.0