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