From 69871482099a1c7022cad6c8d8cd90d3b163f0f2 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 25 十二月 2018 21:11:32 +0800
Subject: [PATCH] 5424 【后端】【1.4】跨服竞技场开发(增加赛季时间管理、赛区赛季榜单、玩家各种PK数据、各种奖励领取及邮件补发、王者法宝等级)

---
 ServerPython/CoreServerGroup/GameServer/PyNetPack.ini                                                                 |   22 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py                                                |    4 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py                               |    5 
 ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py                                                    |   80 ++
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py                                                  |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetCrossPK.py                         |  122 ++++
 ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py                                             |   15 
 ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py                                                       |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py                      |  518 +++++++++++++++--
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py                                        |   24 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py                                         |  784 ++++++++++++++++++++++++++-
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py                                     |   10 
 ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py                                                            |    5 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py                                |   12 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py                      |   30 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                       |   14 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossPKSeasonOrder.py |   49 +
 17 files changed, 1,571 insertions(+), 139 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
index 6317eef..fb7b0d9 100644
--- a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
+++ b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
@@ -345,6 +345,28 @@
 PacketSubCMD_4=0x04
 PacketCallFunc_4=OnQueryBossInfo
 
+[CrossRealmPK]
+ScriptName = GameWorldLogic\CrossRealmPK.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 1
+
+PacketCMD_1=0xC0
+PacketSubCMD_1=0x01
+PacketCallFunc_1=OnViewCrossPKBillboard
+
+[CrossRealmPlayer]
+ScriptName = Player\CrossRealmPlayer.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 1
+
+PacketCMD_1=0xC0
+PacketSubCMD_1=0x02
+PacketCallFunc_1=OnViewCrossPlayerInfo
+
 [PlayerXMZZ]
 ScriptName = Player\PlayerXMZZ.py
 Writer = xdh
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
index e068129..d98b5bd 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -373,6 +373,9 @@
 Def_WorldKey_BossRebornNeedPoint = "BossRebornNeedPoint"     #boss复活需要总点数
 Def_WorldKey_BossIsAlive = 'BossIsAlive_%s'                  #boss是否活着
 Def_WorldKey_IsGameWorldInit = 'IsGameWorldInit'             #GameWold是否初始化完成
+Def_WorldKey_CrossPKZoneSeasonID = "CrossPKZoneSeasonID_%s"  #跨服PK赛区对应赛季,跨服服务器控制,参数(zoneID)
+Def_WorldKey_CrossPKZoneSeasonState = "CrossPKZoneSeasonState_%s" #跨服PK赛区赛季状态,跨服服务器控制,参数(zoneID)0-未开启,1-开启中,2-已结束
+Def_WorldKey_CrossPKBillboardSyncTick = "CrossPKBillboardSyncTick_%s_%s" #跨服PK本赛季排行榜同步tick,参数(zoneID, seasonID)
 #---------------------------------------------------------------------
 #个人时间间隔
 TYPE_Player_Tick_Requestkey = 0                       # 玩家请求处理间隔
@@ -656,6 +659,8 @@
 Def_PDict_GeTuiSet = "GetuiSet"     # 推送提醒的设置
 Def_PDict_NoGeTuiTime = "NoGetuiTime"     # 推送提醒免打扰时间,将字符串组合数字
 
+Def_PlayerKey_ViewCrossPKBillboardTick = "ViewCrossPKBillboardTick_%s_%s"  #查询PK排行榜tick,参数(zoneID, seasonID)
+
 #跨服服务器广播类型
 (
 Def_PreeSetPlayer,                  #添加跨服预选赛参赛人员 0
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
index b5b217c..101d467 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
@@ -55,6 +55,9 @@
             
         elif msgType == ShareDefine.ClientServerMsg_PKPrepareOK:
             CrossRealmPK.ClientServerMsg_PKPrepareOK(msgData, tick)
+            
+        elif msgType == ShareDefine.ClientServerMsg_PKBillboard:
+            CrossRealmPK.ClientServerMsg_PKBillboard(serverGroupID, msgData)
                         
         elif msgType == ShareDefine.ClientServerMsg_GMCMD:
             GMShell.ClientServerMsg_GMCMD(msgData, tick)
@@ -134,6 +137,12 @@
         elif msgType == ShareDefine.CrossServerMsg_PKOverInfo:
             CrossRealmPK.CrossServerMsg_PKOverInfo(msgData)
             
+        elif msgType == ShareDefine.CrossServerMsg_PKSeasonInfo:
+            CrossRealmPK.CrossServerMsg_PKSeasonInfo(msgData)
+            
+        elif msgType == ShareDefine.CrossServerMsg_PKSyncBillboard:
+            CrossRealmPK.CrossServerMsg_PKSyncBillboard(msgData)
+            
         else:
             GameWorld.ErrLog("没有该信息类型逻辑处理!")
             
@@ -151,8 +160,17 @@
     ## 子服收到跨服服务器信息
     dataPack = IPY_GameServer.IPY_LGCrossLoginResult()
     result = dataPack.GetResult()
-    if result == 1:
-        GameWorld.Log("OnConnCorossServer conn success!!!")
-    else:
+    if result != 1:
         GameWorld.Log("--OnClientServerReceiveMsg  disconn")
+        return
+    
+    GameWorld.Log("OnConnCorossServer conn success!!!")
+    serverGroupID = GameWorld.GetServerGroupID()
+    if GameWorld.IsCrossRealmOpen() and not GameWorld.IsCrossServer():
+        GameWorld.Log("通知跨服主服务器链接成功, 可接收最新跨服活动状态及数据...")
+        dataMsg = {"ServerGroupID":serverGroupID}
+        SendMsgToCrossServer(ShareDefine.ClientServerMsg_ServerInitOK, dataMsg)
+        
+    return
+
     
\ No newline at end of file
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
index 9d4f853..24fca7d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
@@ -18,19 +18,22 @@
 import GameWorld
 import PlayerControl
 import CrossRealmMsg
-import CrossRealmPlayer
 import ChPyNetSendPack
+import CrossRealmPlayer
+import PyGameDataStruct
+import PlayerDBGSEvent
+import PyDataManager
 import NetPackCommon
 import IpyGameDataPY
 import ShareDefine
 import PyGameData
+import CommFunc
 import ChConfig
 
+import datetime
 import operator
 import random
-    
-PKPlayerState_Matching = 0
-PKPlayerState_Fighting = 1
+import time
 
 class CrossPKPlayer():
     ## 跨服PK玩家类
@@ -43,6 +46,7 @@
         self.playerLV = 0
         self.maxHP = 0
         self.fightPower = 0
+        self.realmLV = 0
         self.pkScore = 0
         self.danLV = 0
         self.matchTick = 0
@@ -58,6 +62,7 @@
     
     def __init__(self):
         self.pkZoneID = 0
+        self.seasonID = 0
         self.roomID = 0
         self.mapID = 0
         self.openTick = 0 # 开房时间
@@ -68,11 +73,669 @@
         self.isMapOpen = False # 地图是否已经开启该房间,未开启的房间超时后,本次匹配视为无效,有玩家进地图才会开启副本分线
         return
     
+#跨服PK排行榜管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
+class CrossPKBillboardManager(object):
+    
+    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 UpdClientServerPKBillboard(self, zoneID, seasonID, syncBillboardList, isFinalBillboardData):
+        ## 先直接清除本服数据,然后直接覆盖更新
+        billboardList = self.GetCrossPKBillboardInfo(zoneID, seasonID)[0]
+        billboardList = billboardList[:len(syncBillboardList)] # 直接用本服以后的排行数据实例clear后覆盖更新,不足的创建新实例
+        orderDict = {} # 排行信息重新更新
+        for i, syncData in enumerate(syncBillboardList):
+            playerID, playerName, job, fightPower, realmLV, pkScore, danLV, billTime, order = syncData
+            if i < len(billboardList):
+                billboardData = billboardList[i]
+                billboardData.clear()
+            else:
+                billboardData = PyGameDataStruct.tagDBCrossPKBillboard()
+                billboardList.append(billboardData)
+            billboardData.ZoneID = zoneID
+            billboardData.SeasonID = seasonID
+            billboardData.PlayerID = playerID
+            billboardData.PlayerName = playerName
+            billboardData.Job = job
+            billboardData.FightPower = fightPower
+            billboardData.RealmLV = realmLV
+            billboardData.PKScore = pkScore
+            billboardData.DanLV = danLV
+            billboardData.Time = billTime
+            orderDict[playerID] = order
+            
+        listAttrName = self.__ZoneSeasonDataList % (zoneID, seasonID)
+        orderDictAttrName = self.__ZoneSeasonPlayerOrderDict % (zoneID, seasonID)
+        setattr(self, listAttrName, billboardList)
+        setattr(self, orderDictAttrName, orderDict)
+        dbIsFinalData = PlayerDBGSEvent.GetDBGSTrig_ByKey(self.DBKEY_CrossPKFinalBillboardData % (zoneID, seasonID))
+        isFinalBillboardData = 1 if isFinalBillboardData else 0
+        if dbIsFinalData != isFinalBillboardData:
+            PlayerDBGSEvent.SetDBGSTrig_ByKey(self.DBKEY_CrossPKFinalBillboardData % (zoneID, seasonID), isFinalBillboardData)
+            GameWorld.Log("更新子服榜单数据是否是最终榜单数据!zoneID=%s,seasonID=%s,isFinalBillboardData=%s" 
+                          % (zoneID, seasonID, isFinalBillboardData))
+        return billboardList, orderDict
+    
+    def IsFinalBillboardData(self, zoneID, seasonID):
+        ## 子服的赛区赛季榜单数据是否最终榜单数据
+        return PlayerDBGSEvent.GetDBGSTrig_ByKey(self.DBKEY_CrossPKFinalBillboardData % (zoneID, seasonID))
+    
+    ## ===========================================================================================
+    
+    # 保存数据 存数据库和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" % cnt)
+        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)))
+            
+        return pos
+    
+def UpdateCrossPKBillboard(zoneID, seasonID, winner, loser):
+    ## 更新跨服PK排行榜,跨服服务器结算调用,子服不调用
+    
+    curZoneSeasonID = GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonID % zoneID)
+    if curZoneSeasonID != seasonID:
+        GameWorld.ErrLog("不是当前赛季,不更新排行榜! zoneID=%s,seasonID=%s,curZoneSeasonID=%s" % (zoneID, seasonID, curZoneSeasonID))
+        return
+    billboardCfg = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKCfg", 1, [])
+    if not billboardCfg or len(billboardCfg) != 2:
+        GameWorld.ErrLog("跨服竞技场排行榜配置错误!")
+        return
+    maxCount, danLVLimit = billboardCfg
+    if maxCount <= 0:
+        return
+    maxCount = min(2000, maxCount)
+    upBillboardList = []
+    if winner.danLV >= danLVLimit:
+        upBillboardList.append(winner)
+    else:
+        GameWorld.DebugLog("    段位不足,无法上榜! winnerDanLV=%s < danLVLimit=%s" % (winner.danLV, danLVLimit), winner.playerID)
+    if loser.danLV >= danLVLimit:
+        upBillboardList.append(loser)
+    else:
+        GameWorld.DebugLog("    段位不足,无法上榜! loserDanLV=%s < danLVLimit=%s" % (loser.danLV, danLVLimit), loser.playerID)
+    if not upBillboardList:
+        return
+    
+    crossPKBillboardMgr = PyDataManager.GetCrossPKBillboardManager()
+    billboardList, orderDict = crossPKBillboardMgr.GetCrossPKBillboardInfo(zoneID, seasonID)
+    
+    isUpd = False
+    curTime = int(time.time())
+    billboardTime = max(0, GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00") - curTime) # 因为先上榜排前面,所以时间记录值得反减,倒序排
+    for pkPlayer in upBillboardList:
+        playerID = pkPlayer.playerID
+        if playerID in orderDict:
+            order = orderDict[playerID]
+            billboardData = billboardList[order - 1]
+            GameWorld.DebugLog("    已经在榜单上!playerID=%s,order=%s" % (playerID, order), playerID)
+        else:
+            if len(billboardList) < maxCount:
+                newBillboardData = PyGameDataStruct.tagDBCrossPKBillboard()
+                billboardList.append(newBillboardData)
+                order = len(billboardList)
+                GameWorld.DebugLog("    添加新上榜榜单!playerID=%s,order=%s" % (playerID, order), playerID)
+            else:
+                lastBillboardData = billboardList[-1]
+                # 分数如果超过最后一个,则顶掉最后一个
+                if lastBillboardData.PKScore >= pkPlayer.pkScore:
+                    GameWorld.DebugLog("    PK积分不超过最后一名玩家,无法上榜! pkScore=%s <= lastPKScore=%s" 
+                                       % (pkPlayer.pkScore, lastBillboardData.PKScore), playerID)
+                    continue
+                order = orderDict.pop(lastBillboardData.PlayerID, len(billboardList))
+                GameWorld.DebugLog("    顶掉最后一个榜单!playerID=%s,lastPlayer=%s,lastScore=%s,order=%s" 
+                                   % (playerID, lastBillboardData.PlayerID, lastBillboardData.PKScore, order))
+                newBillboardData = PyGameDataStruct.tagDBCrossPKBillboard()
+                billboardList[-1] = newBillboardData
+            billboardData = newBillboardData
+            orderDict[playerID] = order
+            
+        isUpd = True
+        # 更新值
+        billboardData.ZoneID = zoneID
+        billboardData.SeasonID = seasonID
+        billboardData.PlayerID = playerID
+        billboardData.PlayerName = pkPlayer.playerName
+        billboardData.Job = pkPlayer.playerJob
+        billboardData.FightPower = pkPlayer.fightPower
+        billboardData.RealmLV = pkPlayer.realmLV
+        billboardData.PKScore = pkPlayer.pkScore
+        billboardData.DanLV = pkPlayer.danLV
+        billboardData.Time = billboardTime
+        GameWorld.Log("    更新PK积分排行榜: playerID=%s,pkScore=%s,order=%s" % (playerID, billboardData.PKScore, order), playerID)
+        
+    # 战斗结算更新榜单先不排序,只设置需要排序
+    if isUpd:
+        crossPKBillboardMgr.SetNeedSort(zoneID, seasonID)
+        
+    # 如果匹配已经结束,且没有战斗中的房间了,则处理本阶段匹配总结算
+    matchState = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)
+    if not matchState and not PyGameData.g_crossPKRoomDict:
+        GameWorld.Log("匹配已结束,且当前没有PK中的房间了!主动广播子服最新榜单! ")
+        zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKZone", zoneID)
+        if zoneIpyData:
+            serverGroupIDList = zoneIpyData.GetServerGroupIDList()
+            SyncPKSyncBillboardToClientServer(zoneID, seasonID, serverGroupIDList)
+            
+    return
+
+#// C0 01 查看跨服竞技场赛季排行榜 #tagCGViewCrossPKBillboard
+#
+#struct    tagCGViewCrossPKBillboard
+#{
+#    tagHead        Head;
+#    BYTE        ZoneID;    // 赛区ID    
+#    BYTE        SeasonID;    // 赛季ID    
+#};
+def OnViewCrossPKBillboard(index, clientData, tick):
+    ''' 赛区赛季榜单同步规则,这里以多台跨服服务器为考虑
+            每台跨服服务器单独管理自己关联的子服赛区榜单
+                    每日匹配结束结算时间点主动同步所有子服本台跨服服务器的所有赛区当前赛季榜单,这样能确保所有子服的赛区榜单是最新的
+                    匹配期间,子服设置同步CD,如果有玩家查询,则每1分钟可向跨服服务器同步当前赛区赛季最新榜单信息,同步后发送玩家
+                    非匹配期间,只要子服有数据则可直接发送给玩家,没有的话向跨服服务器同步后再发送玩家
+                    历史赛季,因为每日跨服服务器都有主动广播,所以历史赛季只要子服有数据则可直接发送给玩家,没有的话向跨服服务器同步后再发送玩家
+                    赛季结束 或 历史赛季 只要不是最终榜单数据的,则需主动向跨服服务器请求同步数据后再发送玩家
+                    不同跨服服务器赛区的话由跨服服务器之间自己同步数据,子服只管向自己所属跨服服务器同步数据即可
+                    
+            跨服服务器与跨服服务器之间的赛区榜单同步,同步规则类似子服与跨服服务器,相互之间做好数据同步即可
+            数据同步后再同步各自所有子服,确保子服也是最新的,可考虑匹配结算结束同步一次即可
+            这样玩家查看其它跨服服务器赛区数据可能会延迟一次匹配阶段结算的时间,比如两个小时,这个等以后需要多台跨服服务器时再讨论
+    '''
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    if GameWorld.IsCrossServer():
+        return
+    playerID = curPlayer.GetPlayerID()
+    zoneID, seasonID = clientData.ZoneID, clientData.SeasonID
+    tickKey = ChConfig.Def_PlayerKey_ViewCrossPKBillboardTick % (zoneID, seasonID)
+    if tick - curPlayer.GetDictByKey(tickKey) < 60000:
+        GameWorld.DebugLog("玩家查询跨服PK排行榜CD中: zoneID=%s, seasonID=%s" % (zoneID, seasonID), playerID)
+        return
+    curPlayer.SetDict(tickKey, tick)
+    gameWorld = GameWorld.GetGameWorld()
+    serverZoneID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+
+    crossPKBillboardMgr = PyDataManager.GetCrossPKBillboardManager()
+    billboardList = crossPKBillboardMgr.GetCrossPKBillboardInfo(zoneID, seasonID)[0]
+    isFinalBillboardData = crossPKBillboardMgr.IsFinalBillboardData(zoneID, seasonID)
+    
+    GameWorld.DebugLog("玩家请求查看跨服PK排行榜: zoneID=%s,seasonID=%s,serverZoneID=%s,isFinalBillboardData=%s" 
+                       % (zoneID, seasonID, serverZoneID, isFinalBillboardData))
+    
+    # 本服赛区
+    if zoneID == serverZoneID:
+        curSeasonID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+        seasonState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)
+        
+    # 其他赛区
+    else:
+        serverTime = GameWorld.GetServerTime()
+        curSeasonID = 0
+        seasonState = 0
+        seasonList = IpyGameDataPY.GetIpyGameDataList("CrossRealmPKSeason", zoneID)
+        seasonList = [] if not seasonList else seasonList
+        for seasonIpyData in seasonList:
+            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 serverTime < startDateTime:
+                break
+            if serverTime <= endDateTime:
+                curSeasonID = seasonIpyData.GetSeasonID()
+                seasonState = 1
+            else:
+                break
+            
+    # 查询当前进行中的赛季
+    if seasonID == curSeasonID:
+        matchState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)
+        # 非匹配中的
+        if not matchState:
+            # 最终数据 or 赛季进行中 直接同步
+            if isFinalBillboardData or (seasonState == 1 and billboardList):
+                SyncCrossPKBillboard(curPlayer, zoneID, seasonID, billboardList)
+                return
+            
+        # 正在匹配中的,验证本服数据同步CD,暂定1分钟同步一次
+        else:
+            syncTickKey = ChConfig.Def_WorldKey_CrossPKBillboardSyncTick % (zoneID, seasonID)
+            if matchState and billboardList and tick - gameWorld.GetDictByKey(syncTickKey) < 60000:
+                SyncCrossPKBillboard(curPlayer, zoneID, seasonID, billboardList)
+                return
+            gameWorld.SetDict(syncTickKey, tick)
+            
+    # 查询历史赛季的
+    else:
+        # 如果是最终数据则直接同步
+        if isFinalBillboardData and billboardList:
+            SyncCrossPKBillboard(curPlayer, zoneID, seasonID, billboardList)
+            return
+        
+    # 请求查询跨服服务器
+    dataMsg = {"ZoneID":zoneID, "SeasonID":seasonID, "ExData":{"EventName":"View", "PlayerID":playerID}}
+    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PKBillboard, dataMsg)
+    return
+
+def MapServer_QueryCrossPKSeasonOrder(curPlayer, msgList):
+    ## 地图服务器查询玩家赛区赛季PK榜排名
+    playerID = curPlayer.GetPlayerID()
+    zoneID, seasonID, eventName, eventData = msgList
+    crossPKBillboardMgr = PyDataManager.GetCrossPKBillboardManager()
+    billboardList, orderDict = crossPKBillboardMgr.GetCrossPKBillboardInfo(zoneID, seasonID) # 子服的数据一定是排完序同步过来的,所以这里就不需要再排序了
+    if not billboardList:
+        # 本服没榜单数据,查询跨服服务器
+        # 请求查询跨服服务器
+        dataMsg = {"ZoneID":zoneID, "SeasonID":seasonID, "ExData":{"EventName":eventName, "PlayerID":playerID, "EventData":eventData}}
+        CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PKBillboard, dataMsg)
+        return
+    
+    order = orderDict.get(playerID, 0)
+    sysMsg = str([zoneID, seasonID, eventName, eventData, order])
+    curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossPKSeasonOrder", sysMsg, len(sysMsg))
+    return
+
+def ClientServerMsg_PKBillboard(serverGroupID, msgData):
+    ## 收到子服请求查询PK排行榜信息
+    zoneID = msgData["ZoneID"]
+    seasonID = msgData["SeasonID"]
+    exData = msgData.get("ExData", {}) # 原数据返回子服
+    SyncPKSyncBillboardToClientServer(zoneID, seasonID, [serverGroupID], exData)
+    return
+
+def SyncPKSyncBillboardToClientServer(zoneID, seasonID, serverGroupIDList, exData={}):
+    ## 同步赛区赛季榜单到子服
+    crossPKBillboardMgr = PyDataManager.GetCrossPKBillboardManager()
+    billboardList, orderDict  = crossPKBillboardMgr.GetCrossPKBillboardInfo(zoneID, seasonID, True) # 同步子服前需触发排序
+    isFinalBillboardData = False # 是否最终的榜单数据
+    gameWorld = GameWorld.GetGameWorld()
+    curZoneSeasonID = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonID % zoneID)
+    if seasonID < curZoneSeasonID:
+        isFinalBillboardData = True # 历史赛季在跨服服务器中的一定是最终榜单数据
+    elif seasonID == curZoneSeasonID:
+        seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID)
+        if seasonState == 2:
+            isFinalBillboardData = True # 当前赛季已经是赛季结算状态的了,代表是最终榜单数据
+            
+    syncBillboardList = []
+    for billboardData in billboardList:
+        playerID = billboardData.PlayerID
+        playerName = billboardData.PlayerName
+        job = billboardData.Job
+        fightPower = billboardData.FightPower
+        realmLV = billboardData.RealmLV
+        pkScore = billboardData.PKScore
+        danLV = billboardData.DanLV
+        billTime = billboardData.Time
+        order = orderDict.get(playerID, 0)
+        syncBillboardList.append([playerID, playerName, job, fightPower, realmLV, pkScore, danLV, billTime, order])
+        
+    syncInfo = [zoneID, seasonID, syncBillboardList, exData, isFinalBillboardData]
+    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKSyncBillboard, syncInfo, serverGroupIDList)
+    return
+
+def CrossServerMsg_PKSyncBillboard(syncInfo):
+    ## 收到跨服服务器同步的排行榜信息
+    zoneID, seasonID, syncBillboardList, exData, isFinalBillboardData = syncInfo
+    GameWorld.Log("收到跨服服务器同步的排行榜信息: zoneID=%s,seasonID=%s,billboardDataCount=%s,exData=%s,isFinalBillboardData=%s" 
+                  % (zoneID, seasonID, len(syncBillboardList), exData, isFinalBillboardData))
+    
+    crossPKBillboardMgr = PyDataManager.GetCrossPKBillboardManager()
+    billboardList, orderDict = crossPKBillboardMgr.UpdClientServerPKBillboard(zoneID, seasonID, syncBillboardList, isFinalBillboardData)
+    if not exData:
+        return
+    eventName = exData.get("EventName")
+    eventData = exData.get("EventData")
+    queryPlayerID = exData.get("PlayerID", 0)
+    if not eventName or not queryPlayerID:
+        return
+    
+    queryPlayer = GameWorld.GetPlayerManager().FindPlayerByID(queryPlayerID)
+    if not queryPlayer:
+        return
+    
+    if eventName == "View":        
+        SyncCrossPKBillboard(queryPlayer, zoneID, seasonID, billboardList)
+    else:
+        order = orderDict.get(queryPlayerID, 0)
+        sysMsg = str([zoneID, seasonID, eventName, eventData, order])
+        queryPlayer.MapServer_QueryPlayerResult(0, 0, "CrossPKSeasonOrder", sysMsg, len(sysMsg))
+        
+    return
+
+def SyncCrossPKBillboard(curPlayer, zoneID, seasonID, billboardList):
+    ## 同步给玩家跨服PK榜单
+    billboardInfo = ChPyNetSendPack.tagGCCrossRealmPKBillboardInfo()
+    billboardInfo.ZoneID = zoneID
+    billboardInfo.SeasonID = seasonID
+    billboardInfo.PKBillboardList = []
+    for billboardData in billboardList:
+        billboardInfoData = ChPyNetSendPack.tagGCCrossRealmPKBillboardData()
+        billboardInfoData.PlayerID = billboardData.PlayerID
+        billboardInfoData.PlayerName = billboardData.PlayerName
+        billboardInfoData.NameLen = len(billboardInfoData.PlayerName)
+        billboardInfoData.Job = billboardData.Job
+        billboardInfoData.FightPower = billboardData.FightPower
+        billboardInfoData.RealmLV = billboardData.RealmLV
+        billboardInfoData.PKScore = billboardData.PKScore
+        billboardInfoData.DanLV = billboardData.DanLV
+        billboardInfo.PKBillboardList.append(billboardInfoData)
+    billboardInfo.Count = len(billboardInfo.PKBillboardList)
+    NetPackCommon.SendFakePack(curPlayer, billboardInfo)
+    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()
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for index in xrange(ipyDataMgr.GetCrossRealmPKZoneCount()):
+        zoneIpyData = ipyDataMgr.GetCrossRealmPKZoneByIndex(index)
+        zoneID = zoneIpyData.GetZoneID()
+        
+        # 规定每个赛区的赛季时间需按顺序配置
+        seasonIpyDataList = []
+        for sIndex in xrange(ipyDataMgr.GetCrossRealmPKSeasonCount()):
+            seasonIpyData = ipyDataMgr.GetCrossRealmPKSeasonByIndex(sIndex)
+            if zoneID == seasonIpyData.GetZoneID():
+                seasonIpyDataList.append(seasonIpyData)
+                
+        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():
+        return
+    
+    zoneSeasonTimeDict = __GetCrossPKZoneSeasonTimeInfo()
+    if not zoneSeasonTimeDict:
+        return
+    
+    gameWorld = GameWorld.GetGameWorld()
+    serverTime = GameWorld.GetServerTime()
+    for zoneID, seasonTimeInfo in zoneSeasonTimeDict.items():
+        zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKZone", 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:
+            SyncPKSyncBillboardToClientServer(zoneID, seasonID, serverGroupIDList)
+            
+        # 广播当前赛区的所有子服跨服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 OnCrossRealmPKDailyActionStateChange(isOpen):
+    ## 跨服PK每日活动匹配状态变更
+    
+    if not GameWorld.IsCrossServer():
+        return
+    
+    gameWorld = GameWorld.GetGameWorld()
+    gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK, isOpen)
+    
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for index in xrange(ipyDataMgr.GetCrossRealmPKZoneCount()):
+        zoneIpyData = ipyDataMgr.GetCrossRealmPKZoneByIndex(index)
+        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 ClientServerMsg_ServerInitOK(serverGroupID, tick):
+    ## 子服启动成功
+    GameWorld.Log("子服启动成功,同步给子服对应的赛季信息: serverGroupID=%s" % (serverGroupID))
+    zoneID = GetCrossPKServerGroupZoneID(serverGroupID)
+    if not zoneID:
+        GameWorld.Log("    该子服没有分配赛区,不同步!")
+        return
+    gameWorld = GameWorld.GetGameWorld()
+    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}
+    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKSeasonInfo, seasonInfo, [serverGroupID])
+    return
+
+def GetCrossPKServerGroupZoneID(serverGroupID):
+    ## 获取服务器组ID对应的跨服PK所属赛区,返回0代表该服务器没有分配赛区
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for index in xrange(ipyDataMgr.GetCrossRealmPKZoneCount()):
+        zoneIpyData = ipyDataMgr.GetCrossRealmPKZoneByIndex(index)
+        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.GetZoneID()
+    return 0
+
+def OnPlayerLogin(curPlayer):
+    
+    # 本服登录处理
+    if not GameWorld.IsCrossServer():
+        # 本服没有分配赛区不处理
+        if not GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID):
+            return
         __OnLoginNotifyPKOverInfo(curPlayer)
+        
+        # 同步所有赛区赛季信息
+        zoneSeasonInfo = ChPyNetSendPack.tagGCCrossRealmPKSeasonInfo()
+        zoneSeasonInfo.ZoneList = []
+        ipyDataMgr = IpyGameDataPY.IPY_Data()
+        for index in xrange(ipyDataMgr.GetCrossRealmPKZoneCount()):
+            zoneIpyData = ipyDataMgr.GetCrossRealmPKZoneByIndex(index)
+            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", 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)
+        NetPackCommon.SendFakePack(curPlayer, seasonStatePack)
+        
+    # 跨服登录处理
+    else:
+        # 比如验证房间ID是否合法
+        pass
+    
     return
 
 ## 玩家离线处理
@@ -81,17 +744,10 @@
     SendCancelCrossRealmPKMatch(curPlayer, "PlayerDisconnect")
     return
 
-def IsCrossRealmPKOpen():
+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
+    return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState \
+                                                 % ShareDefine.DailyActionID_CrossReamPK) == ChConfig.Def_Action_Open
 
 def SendCancelCrossRealmPKMatch(curPlayer, reason):   
     ## 发送取消匹配
@@ -101,7 +757,7 @@
         return
     
     # 非活动中不处理
-    if not IsCrossRealmPKOpen():
+    if not IsCrossRealmPKMatchState():
         return
     
 #    # 如果是要登陆到跨服服务器的,不发送取消
@@ -133,7 +789,7 @@
         GameWorld.ErrLog("非跨服服务器不处理跨服PK匹配请求!")
         return
     
-    if not IsCrossRealmPKOpen():
+    if not IsCrossRealmPKMatchState():
         GameWorld.Log("跨服匹配PK活动未开启,不允许请求匹配!")
         return
     
@@ -146,6 +802,7 @@
     playerLV = playerInfoDict["playerLV"] # 职业
     maxHP = playerInfoDict["maxHP"] # 职业
     fightPower = playerInfoDict["fightPower"] # 战斗力
+    realmLV = playerInfoDict["realmLV"] # 境界
     pkScore = playerInfoDict["pkScore"] # 当前积分
     danLV = playerInfoDict["danLV"] # 当前段位
     cWinCount = playerInfoDict["cWinCount"] # 连胜次数
@@ -171,6 +828,7 @@
     pkPlayer.pkScore = pkScore
     pkPlayer.danLV = danLV
     pkPlayer.fightPower = fightPower
+    pkPlayer.realmLV = realmLV
     pkPlayer.matchTick = tick
     pkPlayer.cWinCount = cWinCount
     pkPlayer.ondayScore = ondayScore
@@ -197,7 +855,7 @@
         return
     
     # 非活动中不处理
-    if not IsCrossRealmPKOpen():
+    if not IsCrossRealmPKMatchState():
         return
     
     accID = playerInfoDict["accID"] # 角色账号
@@ -327,11 +985,12 @@
     if not GameWorld.IsCrossServer():
         return
     
-    if not IsCrossRealmPKOpen():
+    if not IsCrossRealmPKMatchState():
         return
     
-    # 同步子服排行榜
-    #__SyncBillboardToClientServer(False, tick)
+    # 定时更新排行榜
+    crossPKBillboardMgr = PyDataManager.GetCrossPKBillboardManager()
+    crossPKBillboardMgr.PKBillboardSortByTime(tick)
     
     processTick = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 1) * 1000
     processTickKey = "PKMatchLastTick"
@@ -528,6 +1187,7 @@
         
         newRoom = CrossPKRoom()
         newRoom.pkZoneID = pkZoneID
+        newRoom.seasonID = aPlayer.seasonID # 因为匹在一起的玩家一定是同一赛区同一赛季的,所以随便取一个玩家的赛季ID信息即可
         newRoom.roomID = roomID
         newRoom.mapID = mapID
         newRoom.openTick = tick
@@ -570,8 +1230,7 @@
     
     timeoutRoomDict = {}
     serverGroupIDList = []
-    #roomTimeout = IpyGameDataPY.GetFuncCfg("CheckRoomTimeout", 1) * 1000 # 这个时间尽量长点,目前暂时不确定玩家从准备好到进入到地图的时长
-    roomTimeout = 180 * 1000 # 这个时间尽量长点,目前暂时不确定玩家从准备到进入到地图的时长
+    roomTimeout = IpyGameDataPY.GetFuncCfg("CrossRealmPKCfg", 2) * 1000 # 这个时间尽量长点,目前暂时不确定玩家从准备到进入到地图的时长
     for roomID, pkRoom in PyGameData.g_crossPKRoomDict.items():
         if pkRoom.isMapOpen or not pkRoom.readyTick:
             continue
@@ -647,7 +1306,8 @@
     loser = PyGameData.g_crossPKPlayerDict.pop(loserID)
     #winner = PyGameData.g_crossPKPlayerDict[winnerID]
     #loser = PyGameData.g_crossPKPlayerDict[loserID]
-    seasonID = winner.seasonID
+    zoneID = vsRoom.pkZoneID
+    seasonID = vsRoom.seasonID
     
     cWinCount = winner.cWinCount
     winnerScore, loserScore = winner.pkScore, loser.pkScore
@@ -693,6 +1353,9 @@
     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))
     
+    # 更新排行榜
+    UpdateCrossPKBillboard(zoneID, seasonID, winner, loser)
+    
     timeStr = GameWorld.GetCurrentDataTimeStr()
     playerOverDict = {}
     # 通知客户端战斗结果
@@ -707,7 +1370,7 @@
         player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
         notifyState = True if player else False
         
-        playerOverDict[playerID] = [roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList] \
+        playerOverDict[playerID] = [roomID, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList] \
                                     + [serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]
         if not player:
             continue
@@ -737,6 +1400,69 @@
     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
+    
+    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)
+    
+    if curSeasonState == 1 and seasonState == 2:
+        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
+    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匹配请求结果
@@ -876,13 +1602,13 @@
     GameWorld.Log("===收到跨服服务器同步的跨服PK结果=== curServerGroupID=%s" % curServerGroupID)
     
     for playerID, overInfo in playerOverDict.items():
-        roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, \
+        roomID, zoneID, 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))
             continue
         
-        sendMapOverInfo = [roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]
+        sendMapOverInfo = [roomID, zoneID, 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))
@@ -891,8 +1617,8 @@
         
         sysMsg = str(sendMapOverInfo)
         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.Log("通知地图跨服PK结算: roomID=%s,zoneID=%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, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, notifyState, player.GetMapID()), playerID)
     return
 
 def __OnLoginNotifyPKOverInfo(curPlayer):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
index 70ac533..b09183a 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
@@ -32,7 +32,7 @@
 import GameWorldAverageLv
 #import GameWorldMergeBoss
 #import GameWorldMergeKing
-#import GameWorldMergePK
+import CrossRealmPK
 import GameWorldFamilyWar
 import PlayerFamilyParty
 import IpyGameDataPY
@@ -1240,6 +1240,9 @@
     #骑宠争夺
     elif dictName == ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyRobBoss:
         GameWorldBoss.OnHorsePetRobBossActionChange(isOpen)
+    #跨服PK
+    elif dictName == ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossReamPK:
+        CrossRealmPK.OnCrossRealmPKDailyActionStateChange(isOpen)
     return
 
 #------------------------------------------------------------------------------ 
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
index 4e9df57..00398dc 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
@@ -352,7 +352,8 @@
     GameWorldActionControl.Dispose_OperationActionState()
     GameWorldActionControl.Dispose_DailyActionState()
     GameWorldActionControl.Dispose_FBStateTime()
-    
+    #跨服PK
+    CrossRealmPK.OnMinuteProcess()
     #处理重开服务器后, 活动继续开启逻辑根据天数
     #GameWorldActionControl.Dispose_Action_GoOn_ByDay(tick)
     #触发世界等级
@@ -1252,11 +1253,6 @@
     #GameWorldActionTeHui.OnGameServerInitOK() # 特惠活动初始化
     #子服启动成功告知跨服主服
     serverGroupID = GameWorld.GetServerGroupID()
-    if GameWorld.IsCrossRealmOpen() and not GameWorld.IsCrossServer():
-        GameWorld.Log("通知跨服主服务器启动成功, 可接收最新跨服活动状态及数据...")
-        dataMsg = {"ServerGroupID":serverGroupID}
-        CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_ServerInitOK, dataMsg)
-        
     GameWorld.Log("服务器启动成功: ServerGroupID=%s" % serverGroupID)
     return
 
@@ -1418,7 +1414,7 @@
     #GameWorldShopItem.OnMapServerInitOK()
     
     # 跨服PK
-    #GameWorldMergePK.OnMapServerInitOK()
+    CrossRealmPK.OnMapServerInitOK()
     #GameWorldMergeKing.OnMapServerInitOK()
     
     SendAllMapGlobalDropInfo() # 全局掉落控制
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py
index df2e73b..d2ce0f7 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py
@@ -112,4 +112,17 @@
 #    NetPackCommon.SendFakePack(curPlayer, canEnterMServer)
     return
 
-
+#// C0 02 查看跨服玩家信息 #tagCGViewCrossPlayerInfo
+#
+#struct    tagCGViewCrossPlayerInfo
+#{
+#    tagHead        Head;
+#    DWORD        PlayerID;    // 跨服玩家ID
+#};
+def OnViewCrossPlayerInfo(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    
+    return
+    
+    
+    
\ No newline at end of file
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
index dbdc17d..915349e 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
@@ -53,9 +53,9 @@
     curPlayer.NotifyCode(msgMark, __GetNotifyCodeList(msgParamList))
     return
 
-def NotifyCodeToClientServer(serverGroupID, playerID, msgMark, msgParamList=[]):
+def NotifyCodeToClientServer(serverGroupIDList, playerID, msgMark, msgParamList=[]):
     dataMsg = {"Type":"Player", "ID":playerID, "Mark":msgMark, "Param":msgParamList}
-    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Notify, dataMsg, [serverGroupID])
+    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Notify, dataMsg, serverGroupIDList)
     return
 
 def CrossServerMsg_Notify(notifyInfoDict):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
index 2f5eb69..bd2ca70 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -566,6 +566,14 @@
         CrossRealmPK.SendCancelCrossRealmPKMatch(curPlayer, resultName)
         return
     
+    #跨服PK请求玩家当前排名
+    if callName == "CrossPKSeasonOrder":
+        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
+        if not curPlayer:
+            return
+        CrossRealmPK.MapServer_QueryCrossPKSeasonOrder(curPlayer, eval(resultName))
+        return
+    
     #跨服注册结果
     if callName == "CrossRealmReg":
         CrossRealmPlayer.OnCrossRealmRegOK(srcPlayerID, eval(resultName), tick)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
index 84e9d51..f0c6132 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
@@ -21,6 +21,7 @@
 import PlayerXMZZ
 import binascii
 import PyGameData
+import CrossRealmPK
 
 def GetSavePyData():
     result = PyGameData.g_pyGameDataManager.GetSaveData()
@@ -43,6 +44,7 @@
 
 class PyGameDataManager(object):
     def __init__(self):
+        self.crossPKBillboard = CrossRealmPK.CrossPKBillboardManager()
         self.XMZZManager = PlayerXMZZ.XMZZManager()
         self.sealDemonManager = PlayerSealDemon.SealDemonManager()
         self.bossAttentionManager = GameWorldBoss.BossAttentionManager()
@@ -58,6 +60,7 @@
 
     def GetSaveData(self):
         buff = ""
+        buff += self.crossPKBillboard.GetSaveData()
         buff += self.XMZZManager.GetSaveData()
         buff += self.sealDemonManager.GetSaveData()
         buff += self.bossAttentionManager.GetSaveData()
@@ -72,6 +75,7 @@
         return buff
     
     def LoadGameData(self, gameBuffer, pos):
+        pos = self.crossPKBillboard.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.XMZZManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.sealDemonManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         pos = self.bossAttentionManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
@@ -85,6 +89,10 @@
         pos = self.socialInfoManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
         return pos
 
+# 跨服竞技场排行榜管理
+def GetCrossPKBillboardManager():
+    return PyGameData.g_pyGameDataManager.crossPKBillboard
+
 # 仙魔之争管理
 def GetXMZZManager():
     return PyGameData.g_pyGameDataManager.XMZZManager
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py b/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
index 8be9ddc..aa2cd6e 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
@@ -15,6 +15,86 @@
 from ctypes import (Structure, memset, memmove, sizeof, addressof, create_string_buffer, string_at)
 import CommFunc
 
+# 跨服竞技场PK排行榜 #tagDBCrossPKBillboard
+class tagDBCrossPKBillboard(Structure):
+    _pack_ = 1
+    _fields_ = [
+        ('ZoneID', ctypes.c_ubyte),
+        ('SeasonID', ctypes.c_ubyte),
+        ('PlayerID', ctypes.c_ulong),
+        ('PlayerName', ctypes.c_char * 33),
+        ('Job', ctypes.c_ubyte),
+        ('FightPower', ctypes.c_ulong),
+        ('RealmLV', ctypes.c_ushort),
+        ('PKScore', ctypes.c_ulong),
+        ('DanLV', ctypes.c_ubyte),
+        ('Time', ctypes.c_ulong),
+        ('ADOResult', ctypes.c_ulong),
+    ]
+
+    def __init__(self):
+        Structure.__init__(self)
+        self.clear()
+
+
+    def clear(self):
+        memset(addressof(self), 0, self.getLength())
+
+
+    def readData(self, buf, pos = 0, length = 0):
+        if not pos <= length:
+            return -1
+        if len(buf) < pos + self.getLength():
+            return -1
+        self.clear()
+        memmove(addressof(self), buf[pos:], self.getLength())
+        return self.getLength()
+
+
+    def getBuffer(self):
+        buf = create_string_buffer(self.getLength())
+        memmove(addressof(buf), addressof(self), self.getLength())
+        return string_at(addressof(buf), self.getLength())
+
+    def getLength(self):
+        return sizeof(tagDBCrossPKBillboard)
+
+    def outputString(self):
+        output = '''// 跨服竞技场PK排行榜 #tagDBCrossPKBillboard:
+            ZoneID = %s,
+            SeasonID = %s,
+            PlayerID = %s,
+            PlayerName = %s,
+            Job = %s,
+            FightPower = %s,
+            RealmLV = %s,
+            PKScore = %s,
+            DanLV = %s,
+            Time = %s,
+            ADOResult = %s,
+            '''%(
+                self.ZoneID,
+                self.SeasonID,
+                self.PlayerID,
+                self.PlayerName,
+                self.Job,
+                self.FightPower,
+                self.RealmLV,
+                self.PKScore,
+                self.DanLV,
+                self.Time,
+                self.ADOResult,
+            )
+        return output
+
+    #Char数组类型Set接口,使用该接口对此类型数据赋值,防止赋值的数据过长报错
+    def SetPlayerName(self,Str):
+        if len(Str)<=33:
+            self.PlayerName = Str
+        else:
+            self.PlayerName = Str[:33]
+            
+
 #仙魔之争记录表#tagDBPyXMZZ
 class tagDBPyXMZZ(Structure):
     _pack_ = 1
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index d80113d..0887c79 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -3850,7 +3850,17 @@
 Def_PDict_CrossPK_WinCount = "CrossPK_WinCount" # 当前胜利次数
 Def_PDict_CrossPK_CWinCount = "CrossPK_CWinCount" # 跨当前连胜次数
 Def_PDict_CrossPK_TodayPKCount = "CrossPK_TodayPKCount" # 今日已PK次数
+Def_PDict_CrossPK_TodayWinCount = "CrossPK_TodayWinCount" # 今日已胜利次数
 Def_PDict_CrossPK_TodayBuyCount = "CrossPK_TodayBuyCount" # 今日已购买PK次数
+Def_PDict_CrossPK_DayPKCountAwardState = "CrossPK_DayPKCountAwardState" # 每日匹配次数奖励记录,二进制位存储是否已领取,按匹配次数升序排序索引代表奖励位
+Def_PDict_CrossPK_DayWinCountAwardState = "CrossPK_DayWinCountAwardState" # 每日胜利次数奖励记录,二进制位存储是否已领取,按胜利次数升序排序索引代表奖励位
+Def_PDict_CrossPK_DanLVAwardState = "CrossPK_DanLVAwardState" # 段位达标奖励记录,二进制位存储是否已领取,按段位代表奖励位
+Def_PDict_CrossPK_SeasonAwardState = "CrossPK_SeasonAwardState" # 赛季结算奖励是否已领取,优先排名奖励,未上榜可领段位奖励
+Def_PDict_CrossPK_ZoneID = "CrossPK_ZoneID" # 玩家上次参与的赛区ID
+Def_PDict_CrossPK_SeasonID = "CrossPK_SeasonID" # 玩家上次参与的赛季ID
+Def_PDict_CrossPK_SeasonDanLV = "CrossPK_SeasonDanLV_%s" # 历史赛季段位,参数,赛季ID
+Def_PDict_CrossPK_SeasonOrder = "CrossPK_SeasonOrder_%s" # 历史赛季名次,参数,赛季ID
+Def_PDict_CrossPK_SeasonAwardLV = "CrossPK_SeasonAwardLV_%s" # 历史赛季奖励等级(一般是段位等级,排行奖励的在最高段位等级基础上增加),参数,赛季ID
 
 #自动战斗设置记录
 Def_PDict_AutoFightSetting = "AFSetting_%s_%s"
@@ -4603,6 +4613,7 @@
 Def_Cost_GodWeapon, # 神兵
 Def_Cost_FBHelpBattle, # 副本助战
 Def_Cost_FBGatherSoulBoss, # 聚魂副本BOSS召唤 40
+Def_Cost_CrossRealmPK, # 跨服PK
 #-----------以下为暂时没用的,先不删除,如有新增消费点则放在这些之前------------
 Def_Cost_RefreshArrestTask, # 刷新悬赏任务
 Def_Cost_OffLineExp, # 兑换离线经验
@@ -4623,7 +4634,7 @@
 Def_Cost_Trade, # 交易
 Def_Cost_Rename, # 改名
 Def_Cost_SkillLvUp, # 技能升级
-) = range(2000, 2000 + 60)
+) = range(2000, 2000 + 61)
 
 Def_Cost_Reason_SonKey = "reason_name_son" # 消费点原因子类说明key
 
@@ -4711,6 +4722,7 @@
 Def_Cost_GodWeapon:"GodWeapon",
 Def_Cost_FBHelpBattle:"FBHelpBattle",
 Def_Cost_FBGatherSoulBoss:"FBGatherSoulBoss",
+Def_Cost_CrossRealmPK:"CrossRealmPK",
 }
 ## -----------------------------------------------------
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetCrossPK.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetCrossPK.py
new file mode 100644
index 0000000..b395c93
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetCrossPK.py
@@ -0,0 +1,122 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.SetCrossPK
+#
+# @todo:设置玩家跨服PK活动数据
+# @author hxp
+# @date 2018-12-25
+# @version 1.0
+#
+# 详细描述: 设置玩家跨服PK活动数据
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2018-12-25 21:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PlayerControl
+import PlayerCrossRealmPK
+import ShareDefine
+import ChConfig
+
+#---------------------------------------------------------------------
+#逻辑实现
+## GM命令执行入口
+#  @param curPlayer 当前玩家
+#  @param list 参数列表 [npcID]
+#  @return None
+#  @remarks 函数详细说明.
+def OnExec(curPlayer, msgList):
+    
+    if not msgList:
+        __PrintHelp(curPlayer)
+        return
+    
+    if len(msgList) == 1:
+        if msgList[0] != 0:
+            __PrintHelp(curPlayer)
+            return
+        
+        # 重置数据
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TotalScore, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_OnDayScore, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DanLV, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_PKCount, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_WinCount, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_CWinCount, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayPKCount, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayWinCount, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayBuyCount, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DayPKCountAwardState, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DayWinCountAwardState, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DanLVAwardState, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonAwardState, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_ZoneID, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonID, 0)
+        for i in xrange(1, 20):
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonDanLV % i, 0)
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonOrder % i, 0)
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonAwardLV % i, 0)
+            
+        GameWorld.DebugAnswer(curPlayer, "重置跨服PK数据OK!")
+        PlayerCrossRealmPK.SyncCrossRealmPKPlayerInfo(curPlayer)
+        PlayerCrossRealmPK.SyncCrossRealmPKAwardState(curPlayer)
+        PlayerCrossRealmPK.SyncCrossRealmPKHisSeasonInfo(curPlayer)
+        return
+    
+    if len(msgList) == 2 or len(msgList) % 2 == 0:
+        setTypeDict = {0:[ChConfig.Def_PDict_CrossPK_TotalScore, "积分"],
+                       1:[ChConfig.Def_PDict_CrossPK_OnDayScore, "过天积分"],
+                       2:[ChConfig.Def_PDict_CrossPK_DanLV, "段位"],
+                       3:[ChConfig.Def_PDict_CrossPK_PKCount, "PK次数"],
+                       4:[ChConfig.Def_PDict_CrossPK_WinCount, "胜利次数"],
+                       5:[ChConfig.Def_PDict_CrossPK_CWinCount, "连胜次数"],
+                       6:[ChConfig.Def_PDict_CrossPK_TodayPKCount, "今日PK次数"],
+                       7:[ChConfig.Def_PDict_CrossPK_TodayWinCount, "今日胜利次数"],
+                       8:[ChConfig.Def_PDict_CrossPK_TodayBuyCount, "今日购买次数"],
+                       }
+        indexList = range(len(msgList))
+        for i in indexList[::2]:
+            setType, value = msgList[i:i+2]
+            if setType not in setTypeDict:
+                continue
+            dictName, chName = setTypeDict[setType]
+            PlayerControl.NomalDictSetProperty(curPlayer, dictName, value)
+            GameWorld.DebugAnswer(curPlayer, "设置%s: %s" % (chName, value))
+            
+        mapZoneID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+        mapSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_ZoneID, mapZoneID)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonID, mapSeasonID)
+        PlayerCrossRealmPK.SyncCrossRealmPKPlayerInfo(curPlayer)
+        return
+    
+    if len(msgList) == 3:
+        seasonID, setType, value = msgList
+        setTypeDict = {0:[ChConfig.Def_PDict_CrossPK_SeasonDanLV, "段位"],
+                       1:[ChConfig.Def_PDict_CrossPK_SeasonOrder, "名次"],
+                       2:[ChConfig.Def_PDict_CrossPK_SeasonAwardLV, "奖励等级"],
+                       }
+        if setType not in setTypeDict:
+            __PrintHelp(curPlayer)
+            return
+        dictName, chName = setTypeDict[setType]
+        PlayerControl.NomalDictSetProperty(curPlayer, dictName % seasonID, value)
+        GameWorld.DebugAnswer(curPlayer, "设置赛季%s%s: %s" % (seasonID, chName, value))
+        return
+    
+    __PrintHelp(curPlayer)
+    return
+
+def __PrintHelp(curPlayer):
+    GameWorld.DebugAnswer(curPlayer, "重置数据: SetCrossPK 0")
+    GameWorld.DebugAnswer(curPlayer, "设置数据: SetCrossPK 类型  值")
+    GameWorld.DebugAnswer(curPlayer, "类型:0-积分,1-过天积分,2-段位,3-PK次数,4-胜利次数,5-连胜次数")
+    GameWorld.DebugAnswer(curPlayer, "6-今日PK次数,7-今日胜利次数,8-今日购买次数")
+    GameWorld.DebugAnswer(curPlayer, "设置历史记录: SetCrossPK 赛季ID 类型 数值")
+    GameWorld.DebugAnswer(curPlayer, "类型:0-段位,1-名次,2-奖励等级")
+    return
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index 9f9f3ca..ec43b70 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -18,7 +18,6 @@
 import GameMap
 import ChConfig
 import EventShell
-import SkillShell
 import BuffSkill
 import PlayerEventCounter
 import PlayerTeam
@@ -57,10 +56,8 @@
 import PlayerLoginDayAward
 import PlayerGodWeapon
 import PlayerWorldAverageLv
-import GameLogic_ManorWar
 import PlayerGoldInvest
 import PlayerActivity
-import PlayerTeHui
 import FBCommon
 import PlayerBindJadeWheel
 import BossHurtMng
@@ -70,15 +67,12 @@
 import PlayerDienstgrad
 import PlayerMixLoginDayAward
 import PlayerFreeGoods
-import ShopItemManage
 import PlayerRecover
 import GameLogic_IceLode
 import PlayerEquipDecompose
-import PlayerCoat
 import PlayerGreatMaster
 import PlayerGatherSoul
-import PlayerMergeKing
-import PlayerMergePK
+import PlayerCrossRealmPK
 import GameFuncComm
 import PlayerMagicWeapon
 import GameLogic_TrialTower
@@ -101,14 +95,12 @@
 import QuestCommon
 import PlayerTJG
 import GameLogic_XMZZ
-import GameLogic_SealDemon
 import PlayerFlashSale
 import PlayerFlashGiftbag
 import PlayerCostRebate
 import PlayerActTotalRecharge
 import PlayerSpringSale
 import PlayerFairyCeremony
-import CrossRealmPlayer
 import ChNetSendPack
 import FamilyRobBoss
 import FBHelpBattle
@@ -490,6 +482,8 @@
 #    # 跨服匹配
 #    PlayerMergePK.MergePKOnLogin(curPlayer)
 #    PlayerMergeKing.MergePKOnLogin(curPlayer)
+    # 跨服PK
+    PlayerCrossRealmPK.DoPlayerLogin(curPlayer)
     
     # 自定义货币值同步
     PlayerControl.NotifyPlayerAllCurrency(curPlayer)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py
index 813dc47..3e926b1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossRealmPK.py
@@ -17,33 +17,156 @@
 
 import ShareDefine
 import PlayerControl
-import CrossRealmPlayer
-import ChPyNetSendPack
 import NetPackCommon
+import IpyGameDataPY
+import ChPyNetSendPack
+import CrossRealmPlayer
+import DataRecordPack
+import IPY_GameWorld
+import ItemControler
+import ItemCommon
 import GameWorld
 import ChConfig
 
 def DoPlayerOnDay(curPlayer):
+    if GameWorld.IsCrossServer():
+        return
     totalScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TotalScore)
+    if not totalScore:
+        return
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_OnDayScore, totalScore)
+    
+    zoneID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_ZoneID)
+    seasonID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonID)
+    
+    # 邮件发放未领取的每日PK次数奖励
+    dayPKCountAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKAward", 1, {})
+    dayPKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount)
+    dayPKCountAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DayPKCountAwardState)
+    SendDayPKAwardByMail(curPlayer, zoneID, seasonID, "PKCount", dayPKCount, dayPKCountAwardState, dayPKCountAwardDict, "CrossServer1")
+    
+    # 邮件发放未领取的每日胜利次数奖励
+    dayWinCountAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKAward", 2, {})
+    dayWinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayWinCount)
+    dayWinCountAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DayWinCountAwardState)
+    SendDayPKAwardByMail(curPlayer, zoneID, seasonID, "WinCount", dayWinCount, dayWinCountAwardState, dayWinCountAwardDict, "CrossServer2")
+    
+    # 重置每日奖励状态
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayPKCount, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayWinCount, 0)
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayBuyCount, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DayPKCountAwardState, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DayWinCountAwardState, 0)
+    SyncCrossRealmPKPlayerInfo(curPlayer)
+    SyncCrossRealmPKAwardState(curPlayer)
     return
 
-def IsCrossRealmPKOpen():
+def DoPlayerLogin(curPlayer):
+    if GameWorld.IsCrossServer():
+        return
+    
+    mapZoneID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+    mapSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+    if not mapZoneID or not mapSeasonID:
+        return
+    
+    if not __CheckResetPlayerCrossPKData(curPlayer, mapZoneID, mapSeasonID):
+        SyncCrossRealmPKPlayerInfo(curPlayer)
+        SyncCrossRealmPKAwardState(curPlayer)
+        SyncCrossRealmPKHisSeasonInfo(curPlayer)
+    return
+
+def IsCrossRealmPKMatchState():
     ## 跨服PK匹配赛是否开启
-    return 1
-    return GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_MergePKState) == ChConfig.Def_Action_Open
+    return GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState \
+                                                          % ShareDefine.DailyActionID_CrossReamPK) == ChConfig.Def_Action_Open
 
-def GetCrossPKZoneID():
-    ## 获取本服跨服PK所属赛区
-    return 1
+def OnCrossRealmPKSeasonChange(value):
+    ## 赛区赛季状态变更,规定所有赛区的赛季ID都一样,且赛季ID一定是自增的,所以这里只判断赛季ID变更即可
+    
+    if GameWorld.IsCrossServer():
+        return
+    
+    mapZoneID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+    mapSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+    
+    if mapSeasonID == value:
+        GameWorld.DebugLog("跨服PK赛季信息与地图当前值相同,不处理!")
+        return
+    GameWorld.Log("跨服PK赛季信息变更: mapSeasonID=%s,value=%s" % (mapSeasonID, value))
+    mapSeasonID = value
+    
+    playerManager = GameWorld.GetPlayerManager()
+    for i in xrange(playerManager.OnlineCount()):
+        curPlayer = playerManager.OnlineAt(i)
+        if not curPlayer or curPlayer.IsEmpty():
+            continue
+        
+        #检查重置玩家信息
+        __CheckResetPlayerCrossPKData(curPlayer, mapZoneID, mapSeasonID)
+        
+    return
 
-def GetSeasonID():
-    ## 获取当前赛季ID
-    return 1
+def __CheckResetPlayerCrossPKData(curPlayer, mapZoneID, mapSeasonID):
+    ## 检查玩家赛区赛季状态数据
+    
+    playerID = curPlayer.GetPlayerID()
+    zoneID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_ZoneID)
+    seasonID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonID)
+    if mapSeasonID == seasonID:
+        GameWorld.DebugLog("玩家跨服PK赛季信息相同,不处理! mapSeasonID=%s,seasonID=%s" % (mapSeasonID, seasonID), playerID)
+        return
+    GameWorld.Log("玩家跨服PK赛区赛季信息不同! 处理相关数据! mapSeasonID=%s,seasonID=%s" % (mapSeasonID, seasonID), playerID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonID, mapSeasonID)
+    
+    playerDanLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV)
+    danLVAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLVAwardState)
 
-def IsCrossRealmPKSeasonOpen():
+    GameWorld.Log("开始新赛季,发放上赛季未领取的奖励,重置赛季数据! zoneID=%s,seasonID=%s,newSeasonID=%s,playerDanLV=%s,danLVAwardState=%s" 
+                  % (zoneID, seasonID, mapSeasonID, playerDanLV, danLVAwardState), playerID)
+    
+    # 邮件发放上赛季未领取的段位奖励、赛季奖励(排名或段位)
+    for awardDanLV in xrange(playerDanLV + 1):
+        danLVIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", awardDanLV)
+        if not danLVIpyData:
+            continue
+        awardItemList = danLVIpyData.GetDanLVAwardList()
+        if not awardItemList:
+            continue
+        if pow(2, awardDanLV) & danLVAwardState:
+            GameWorld.DebugLog("    已经领取过该段位达标奖励!awardDanLV=%s,danLVAwardState=%s" % (awardDanLV, danLVAwardState), playerID)
+            continue
+        eventName = "DanLV"
+        GameWorld.Log("    邮件补发未领取的段位达标奖励!awardDanLV=%s,danLVAwardState=%s,awardItemList=%s" 
+                      % (awardDanLV, danLVAwardState, awardItemList), playerID)
+        mailDetail = {"EventName":eventName, "zoneID":zoneID, "seasonID":seasonID, "awardDanLV":awardDanLV, 
+                      "danLVAwardState":danLVAwardState, "mapSeasonID":mapSeasonID}
+        PlayerControl.SendMailByKey("CrossServer3", [playerID], awardItemList, [seasonID, awardDanLV], detail=mailDetail)
+        DR_GetCrossPKAward(curPlayer, zoneID, seasonID, eventName, True, mailDetail)
+        
+    # 查询 GameServer 玩家赛季排名
+    if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonAwardState):
+        OnQueryCrossPKSeasonOrderAward(curPlayer, zoneID, seasonID, True)
+        
+    # 重置状态
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TotalScore, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_OnDayScore, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DanLV, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_PKCount, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_WinCount, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_CWinCount, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayPKCount, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayWinCount, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayBuyCount, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DayPKCountAwardState, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DayWinCountAwardState, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DanLVAwardState, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonAwardState, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_ZoneID, mapZoneID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonID, mapSeasonID)
+    
+    SyncCrossRealmPKPlayerInfo(curPlayer)
+    SyncCrossRealmPKAwardState(curPlayer)
     return True
 
 #// C1 01 跨服PK匹配 #tagCMCrossRealmPKMatch
@@ -62,45 +185,33 @@
     if GameWorld.IsCrossServer():
         GameWorld.DebugLog("跨服服务器无法发起匹配!")
         return
-        
-    if not IsCrossRealmPKOpen():
-        GameWorld.Log("OnRequestMergePK 跨服活动未开启,不可进行匹配!", playerID)
-        PlayerControl.NotifyCode(curPlayer, "GeRen_hgg_21675")
+    
+    if GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState) != 1:
+        GameWorld.DebugLog("OnRequestMergePK 跨服赛季未开启,不可进行匹配!", playerID)
+        PlayerControl.NotifyCode(curPlayer, "SeasonIsNotOpen")
+        return
+    
+    if not IsCrossRealmPKMatchState():
+        GameWorld.DebugLog("OnRequestMergePK 跨服匹配未开启,不可进行匹配!", playerID)
+        PlayerControl.NotifyCode(curPlayer, "MatchIsNotOpen")
         return
     
     GameWorld.Log("收到跨服PK匹配: type=%s,accID=%s" % (requestType, accID), playerID)
     
     # 进行匹配
     if requestType == 1:
-#        pkCnt = __GetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_Cnt)
-#        buyCnt = __GetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_BuyCnt)
-#        unUsedBuyCnt = __GetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_UnUsedBuyCnt)
-#        freeCnt, maxBuyCnt, moneyType, buyCostFormat = ReadChConfig.GetEvalChConfig("MergePK_BuyCost")
-#        
-#        # 超出免费次数 且 无可用的已购买次数  则需购买次数
-#        if pkCnt >= freeCnt and unUsedBuyCnt <= 0:
-#            
-#            if buyCnt >= maxBuyCnt:
-#                GameWorld.Log("    已达到最大可购买PK次数,不可再买!:buyCnt=%s,maxBuyCnt=%s,pkCnt=%s,unUsedBuyCnt=%s" 
-#                              % (buyCnt, maxBuyCnt, pkCnt, unUsedBuyCnt), playerID)
-#                return
-#            
-#            buyCost = eval(buyCostFormat)
-#            infoDict = {"pkCnt":pkCnt, "freeCnt":freeCnt, "buyCnt":buyCnt, "buyCost":buyCost}
-#            if not PlayerControl.PayMoney(curPlayer, moneyType, buyCost, ChConfig.Def_Cost_BuyMergePKCnt, infoDict):
-#                return
-#            
-#            # 增加购买次数 及 未使用的购买次数
-#            __SetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_BuyCnt, buyCnt + 1)
-#            __SetMergePKPDictValue(curPlayer, ChConfig.Def_PDict_MergePK_UnUsedBuyCnt, unUsedBuyCnt + 1)
-#            Sync_MergePKCnt(curPlayer)
-#        
-#            GameWorld.Log("    购买PK次数消耗: pkCnt=%s,freeCnt=%s,buyCnt=%s,moneyType=%s,buyCost=%s" 
-#                              % (pkCnt, freeCnt, buyCnt, moneyType, buyCost), playerID)
-        
+        dayFreeMatchCountMax = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatchCount", 1)
+        if dayFreeMatchCountMax:
+            todayPKCount  = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount)
+            todayBuyCount  = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayBuyCount)
+            if todayPKCount >= (dayFreeMatchCountMax + todayBuyCount):
+                GameWorld.DebugLog("PK次数不足,无法发起匹配! todayPKCount=%s >= (dayFreeMatchCountMax=%s + todayBuyCount=%s)" 
+                                   % (todayPKCount, dayFreeMatchCountMax, todayBuyCount), playerID)
+                return
+            
         dataMsg = {
-                   "seasonID":GetSeasonID(), # 赛季ID
-                   "pkZoneID":GetCrossPKZoneID(), # PK赛区
+                   "seasonID":GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID), # 赛季ID
+                   "pkZoneID":GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID), # PK赛区
                    "accID":accID,
                    "playerID":playerID,
                    "playerName":CrossRealmPlayer.GetCrossPlayerName(curPlayer),
@@ -108,8 +219,9 @@
                    "playerLV":curPlayer.GetLV(),
                    "maxHP":curPlayer.GetMaxHP(),
                    "fightPower":curPlayer.GetFightPower(),
+                   "realmLV":curPlayer.GetOfficialRank(),
                    "pkScore":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TotalScore), # 当前积分
-                   "danLV":1, #curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV), # 当前段位
+                   "danLV":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV), # 当前段位
                    "cWinCount":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_CWinCount), # 连胜次数
                    "ondayScore":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_OnDayScore), # 过天时的积分
                    }
@@ -127,19 +239,23 @@
 def CrossServerMsg_PKOverInfo(curPlayer, overInfo):
     ## 收到跨服服务器的PK结算信息
     playerID = curPlayer.GetPlayerID()
-    roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState = overInfo
+    roomID, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState = overInfo
     isWinner = winnerID == playerID
-    GameWorld.Log("地图收到跨服PK结算: isWinner=%s,roomID=%s,seasonID=%s,timeStr=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s,pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,notifyState=%s" 
-                  % (isWinner, roomID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, notifyState), playerID)
-    curSeasonID = GetSeasonID()
+    GameWorld.Log("地图收到跨服PK结算: isWinner=%s,roomID=%s,zoneID=%s,seasonID=%s,timeStr=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s,pkScore=%s,danLV=%s,cWinCount=%s,addScore=%s,tagPlayerID=%s,notifyState=%s" 
+                  % (isWinner, roomID, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, notifyState), playerID)
+    curSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
     if curSeasonID != seasonID:
         GameWorld.Log("    非本赛季的结算信息,不处理!curSeasonID=%s,seasonID=%s" % (curSeasonID, seasonID), playerID)
         return
     
-    # 赛季是否已结算
-    if not IsCrossRealmPKSeasonOpen():
-        GameWorld.Log("    赛季已经结算过了,不处理!seasonID=%s" % (seasonID), playerID)
+    # 赛季已关闭
+    if GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState) != 1:
+        GameWorld.Log("    赛季已关闭,不处理!seasonID=%s" % (seasonID), playerID)
         return
+    
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_ZoneID, zoneID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonID, seasonID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonDanLV % seasonID, danLV)
     
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TotalScore, pkScore)
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_DanLV, danLV)
@@ -157,7 +273,12 @@
     if GameWorld.CheckTimeIsSameServerDayEx(GameWorld.ChangeTimeStrToNum(timeStr)):
         todayPKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount) + 1
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayPKCount, todayPKCount)
-        
+        if isWinner:
+            todayWinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayWinCount) + 1
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayWinCount, todayWinCount)
+            
+    SyncCrossRealmPKPlayerInfo(curPlayer)
+    
     ## 跨服已经通知过了,证明还在跨服服务器,不做以下的处理
     if notifyState:
         return
@@ -186,7 +307,30 @@
 #};
 def OnCrossRealmPKBuy(index, clientData, tick):
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    dayFreeMatchCountMax = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatchCount", 1)
+    if not dayFreeMatchCountMax:
+        GameWorld.DebugLog("每日匹配次数没有限制,不需要购买次数!", playerID)
+        return
+    dayBuyCountMax = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatchCount", 2)
+    todayBuyCount  = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayBuyCount)
+    if dayBuyCountMax and todayBuyCount >= dayBuyCountMax:
+        GameWorld.DebugLog("今日购买次数已满,无法购买!todayBuyCount=%s" % (todayBuyCount), playerID)
+        return
     
+    costGold = eval(IpyGameDataPY.GetFuncCompileCfg("CrossRealmPKMatchCount", 3))
+    costMoneyList = PlayerControl.HaveMoneyEx(curPlayer, ShareDefine.TYPE_Price_Gold_Paper_Money, costGold)
+    if not costMoneyList:
+        GameWorld.DebugLog("仙玉绑玉不足: todayBuyCount=%s,costGold=%s" % (todayBuyCount, costGold), playerID)
+        return
+    
+    infoDict = {"Event":"BuyPKCount", "todayBuyCount":todayBuyCount}
+    for moneyType, moneyNum in costMoneyList:
+        PlayerControl.PayMoney(curPlayer, moneyType, moneyNum, ChConfig.Def_Cost_CrossRealmPK, infoDict)
+        
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_TodayBuyCount, todayBuyCount + 1)
+    GameWorld.DebugLog("购买跨服PK次数: todayBuyCount=%s" % (todayBuyCount), playerID)
+    SyncCrossRealmPKPlayerInfo(curPlayer)
     return
 
 
@@ -200,31 +344,269 @@
 #};
 def OnCrossRealmPKGetAward(index, clientData, tick):
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    if not curPlayer:
+        return
+    playerID = curPlayer.GetPlayerID()
+    awardType = clientData.AwardType
+    awardData = clientData.AwardData
+    zoneID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+    seasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+    if not zoneID or not seasonID:
+        GameWorld.DebugLog("当前没有跨服PK赛季, 无法领取奖励! zoneID=%s,seasonID=%s" % (zoneID, seasonID))
+        return
     
+    if awardType == 1:
+        awardPKCount = awardData
+        playerTodayPKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount)
+        GameWorld.DebugLog("玩家领取每日匹配次数奖励! awardPKCount=%s,playerTodayPKCount=%s" % (awardPKCount, playerTodayPKCount), playerID)
+        if playerTodayPKCount < awardPKCount:
+            GameWorld.DebugLog("    PK次数不足,无法领取!", playerID)
+            return
+        dayPKCountAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKAward", 1, {}) # {"次数":[[物品ID,个数,是否绑定], ...], ...}
+        awardPKCountList = dayPKCountAwardDict.keys()
+        awardPKCountList.sort()
+        awardPKCountStr = str(awardPKCount)
+        if awardPKCountStr not in awardPKCountList:
+            GameWorld.DebugLog("    没有该PK次数奖励!")
+            return
+        awardIndex = awardPKCountList.index(awardPKCountStr)
+        awardStateDictName = ChConfig.Def_PDict_CrossPK_DayPKCountAwardState
+        awardItemList = dayPKCountAwardDict[awardPKCountStr]
+        eventName = "PKCount"
+        drDataDict = {"awardPKCount":awardPKCount}
+        
+    elif awardType == 2:
+        awardWinCount = awardData
+        playerTodayWinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayWinCount)
+        GameWorld.DebugLog("玩家领取每日胜利次数奖励! awardWinCount=%s,playerTodayWinCount=%s" % (awardWinCount, playerTodayWinCount), playerID)
+        if playerTodayWinCount < awardWinCount:
+            GameWorld.DebugLog("    胜利次数不足,无法领取!", playerID)
+            return
+        dayWinCountAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKAward", 2, {}) # {"次数":[[物品ID,个数,是否绑定], ...], ...}
+        awardWinCountList = dayWinCountAwardDict.keys()
+        awardWinCountList.sort()
+        awardWinCountStr = str(awardWinCount)
+        if awardWinCountStr not in awardWinCountList:
+            GameWorld.DebugLog("    没有该胜利次数奖励!", playerID)
+            return
+        awardIndex = awardWinCountList.index(awardWinCountStr)
+        awardStateDictName = ChConfig.Def_PDict_CrossPK_DayWinCountAwardState
+        awardItemList = dayWinCountAwardDict[awardWinCountStr]
+        eventName = "WinCount"
+        drDataDict = {"awardWinCount":awardWinCount}
+        
+    elif awardType == 3:
+        awardDanLV = awardData
+        playerDanLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV)
+        GameWorld.DebugLog("玩家领取段位达标奖励! awardDanLV=%s,playerDanLV=%s" % (awardDanLV, playerDanLV), playerID)
+        if playerDanLV < awardDanLV:
+            GameWorld.DebugLog("    段位未达标,无法领取!", playerID)
+            return
+        danLVIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", awardDanLV)
+        if not danLVIpyData:
+            return
+        awardIndex = awardDanLV
+        awardStateDictName = ChConfig.Def_PDict_CrossPK_DanLVAwardState
+        awardItemList = danLVIpyData.GetDanLVAwardList()
+        eventName = "DanLV"
+        drDataDict = {"awardDanLV":awardDanLV}
+        
+    elif awardType == 4:
+        GameWorld.DebugLog("玩家领取赛季结算奖励!", playerID)
+        if GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState) != 2:
+            GameWorld.DebugLog("非赛季结算阶段,不可领取!", playerID)
+            return
+        if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonAwardState):
+            GameWorld.DebugLog("已经领取过该奖励,不可领取!", playerID)            
+            return
+        # 查询 GameServer 玩家赛季排名
+        OnQueryCrossPKSeasonOrderAward(curPlayer, zoneID, seasonID, False)
+        return
+    
+    else:
+        return
+    
+    if not awardItemList:
+        GameWorld.DebugLog("该奖励没有配置奖励物品!", playerID)
+        return
+    
+    awardState = curPlayer.NomalDictGetProperty(awardStateDictName)
+    if pow(2, awardIndex) & awardState:
+        GameWorld.DebugLog("    已经领取过该奖励!awardIndex=%s,awardState=%s" % (awardIndex, awardState), playerID)
+        return
+    
+    needSpace = len(awardItemList)
+    # 背包空间
+    packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace)
+    if packSpace < needSpace:
+        PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_202580")
+        return
+    
+    awardState |= pow(2, awardIndex)
+    PlayerControl.NomalDictSetProperty(curPlayer, awardStateDictName, awardState)
+    SyncCrossRealmPKAwardState(curPlayer)
+    GameWorld.DebugLog("玩家领取跨服PK奖励! awardType=%s,awardData=%s,awardIndex=%s,awardState=%s,awardItemList=%s" 
+                       % (awardType, awardData, awardIndex, awardState, awardItemList), playerID)
+    drDataDict.update({"awardIndex":awardIndex, "awardState":awardState, "awardItemList":awardItemList})
+    for itemID, itemCnt, isBind in awardItemList:
+        ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [IPY_GameWorld.rptItem])
+        
+    DR_GetCrossPKAward(curPlayer, zoneID, seasonID, eventName, False, drDataDict)
     return
 
+def SendDayPKAwardByMail(curPlayer, zoneID, seasonID, eventName, dataCount, awardState, awardItemDict, mailTypeKey):
+    ## 邮件发放未领取的每日奖励
+    playerID = curPlayer.GetPlayerID()
+    awardCountList = awardItemDict.keys()
+    awardCountList.sort()
+    for i, awardCountStr in enumerate(awardCountList):
+        awardCount = int(awardCountStr)
+        if dataCount < awardCount:
+            GameWorld.DebugLog("跨服PK每日奖励次数不足: eventName=%s,i=%s,awardCount=%s > dataCount=%s" % (eventName, i, awardCount, dataCount), playerID)
+            break
+        if pow(2, i) & awardState:
+            GameWorld.DebugLog("已领取该跨服PK每日奖励: eventName=%s,i=%s,awardCount=%s" % (eventName, i, awardCount), playerID)
+            continue
+        awardItemList = awardItemDict[awardCountStr]
+        GameWorld.Log("邮件发放跨服PK未领取的每日奖励: zoneID=%s,seasonID=%s,eventName=%s,i=%s,awardCount=%s,dataCount=%s,awardState=%s,awardItemList=%s" 
+                      % (zoneID, seasonID, eventName, i, awardCount, dataCount, awardState, awardItemList), playerID)
+        
+        mailDetail = {"EventName":eventName, "zoneID":zoneID, "seasonID":seasonID, "awardCount":awardCount, "awardState":awardState}
+        PlayerControl.SendMailByKey(mailTypeKey, [playerID], awardItemList, [awardCount], detail=mailDetail)
+        DR_GetCrossPKAward(curPlayer, zoneID, seasonID, eventName, True, mailDetail)
+        
+    return
+
+def OnQueryCrossPKSeasonOrderAward(curPlayer, zoneID, seasonID, isMail):
+    # 查询 GameServer 玩家赛季排名
+    playerID = curPlayer.GetPlayerID()
+    danLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV)
+    eventName, eventData = "SeasonAward", [danLV, isMail]
+    sendMsg = str([zoneID, seasonID, eventName, eventData])
+    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "CrossPKSeasonOrder", sendMsg, len(sendMsg))
+    GameWorld.Log("查询GameServer玩家赛区赛季排名: zoneID=%s, seasonID=%s, sendMsg=%s" % (zoneID, seasonID, sendMsg), playerID)
+    return
+
+def GameServer_CrossPKSeasonOrder(curPlayer, msgList):
+    zoneID, seasonID, eventName, eventData, order = msgList
+    
+    # 领取赛季奖励
+    if eventName == "SeasonAward":
+        danLV, isMail = eventData
+        DoGetPKSeasonAward(curPlayer, eventName, zoneID, seasonID, order, danLV, isMail)
+        
+    return
+
+def DoGetPKSeasonAward(curPlayer, eventName, zoneID, seasonID, order, danLV, isMail):
+    ## 执行发放赛季结算奖励,名次奖励与最高段位奖励互斥,优先名次奖励
+    
+    awardItemList = []
+    seasonAwardLV = danLV
+    playerID = curPlayer.GetPlayerID()
+    mapSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+    GameWorld.Log("发放玩家跨服PK赛季结算奖励! zoneID=%s,seasonID=%s,order=%s,danLV=%s,isMail=%s,seasonAwardLV=%s,mapSeasonID=%s" 
+                  % (zoneID, seasonID, order, danLV, isMail, seasonAwardLV, mapSeasonID), playerID)
+    mailTypeKey, mailParamList, mailDetail = "", [], {"EventName":eventName, "zoneID":zoneID, "seasonID":seasonID, 
+                                                      "order":order, "danLV":danLV, "mapSeasonID":mapSeasonID}
+    if order > 0:
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonOrder % seasonID, order)
+        seasonOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKAward", 3, {}) # {"名次":[[物品ID,个数,是否绑定], ...], ...}
+        fromOrder, toOrder = 1, 1
+        awardOrderList = sorted(seasonOrderAwardDict.keys())
+        for i, awardOrderStr in enumerate(awardOrderList):
+            awardOrder = int(awardOrderStr)
+            if order <= awardOrder:
+                toOrder = awardOrder
+                awardItemList = seasonOrderAwardDict[awardOrderStr]
+                maxDanLV = IpyGameDataPY.IPY_Data().GetCrossRealmPKDanCount() - 1 # 因为段位等级从0开始,所以最大段位等级要减1
+                seasonAwardLV = maxDanLV + (len(awardOrderList) - i)
+                GameWorld.Log("获得排名奖励, 更新奖励等级: awardOrderList=%s,i=%s,maxDanLV=%s,seasonAwardLV=%s" % (awardOrderList, i, maxDanLV, seasonAwardLV), playerID)
+                mailTypeKey = "CrossServer4"
+                mailParamList = [seasonID, fromOrder, toOrder]
+                break
+            fromOrder = awardOrder + 1
+            
+    # 没有奖励的话取段位奖励    
+    if not awardItemList:
+        danLVIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", danLV)
+        if not danLVIpyData:
+            return
+        awardItemList = danLVIpyData.GetSeasonDanLVAwardList()
+        mailTypeKey = "CrossServer5"
+        mailParamList = [seasonID, danLV]
+        
+    if not awardItemList:
+        GameWorld.Log("没有玩家对应的赛季结算奖励!", playerID)
+        return
+    ## 发奖励之前需再判断一次,防止重复发包重复领取
+    if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonAwardState):
+        GameWorld.Log("已经发放过赛季结算奖励!", playerID)
+        return
+    if seasonID == mapSeasonID:
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonAwardState, 1)
+        SyncCrossRealmPKAwardState(curPlayer)
+        GameWorld.Log("还是同一个赛季,设置赛季奖励已领取!")
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CrossPK_SeasonAwardLV % seasonID, seasonAwardLV)
+    
+    if not isMail:
+        needSpace = len(awardItemList)
+        packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace)
+        if packSpace < needSpace:
+            isMail = True
+            
+    if isMail:
+        PlayerControl.SendMailByKey(mailTypeKey, [playerID], awardItemList, mailParamList, detail=mailDetail)
+    else:
+        for itemID, itemCnt, isBind in awardItemList:
+            ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [IPY_GameWorld.rptItem])
+            
+    GameWorld.Log("领取成功! awardItemList=%s" % (awardItemList), playerID)
+    drDataDict = {"awardItemList":awardItemList, "order":order, "danLV":danLV, "seasonAwardLV":seasonAwardLV, "isMail":isMail}
+    DR_GetCrossPKAward(curPlayer, zoneID, seasonID, eventName, isMail, drDataDict)
+    return
 
 def SyncCrossRealmPKPlayerInfo(curPlayer):
-#    DWORD        Score;    // 当前积分
-#    BYTE        DanLV;    // 当前段位
-#    WORD        PKCount;    // PK次数
-#    WORD        WinCount;    // 胜利次数
-#    WORD        CWinCount;    // 连胜次数
-#    BYTE        DayPKCount;    // 当日已PK次数
-#    BYTE        DayWinCount;    // 当日已胜利次数
-#    BYTE        DayBuyCount; // 当日已购买次数
+    ## 同步玩家跨服PK玩家相关信息,积分、段位、相关次数等信息
     pkPlayerInfo = ChPyNetSendPack.tagMCCrossRealmPKPlayerInfo()
-    pkPlayerInfo.Score = 0
-    pkPlayerInfo.DanLV = 0
+    pkPlayerInfo.Score = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TotalScore)
+    pkPlayerInfo.DanLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLV)
+    pkPlayerInfo.PKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_PKCount)
+    pkPlayerInfo.WinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_WinCount)
+    pkPlayerInfo.CWinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_CWinCount)
+    pkPlayerInfo.DayPKCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayPKCount)
+    pkPlayerInfo.DayWinCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayWinCount)
+    pkPlayerInfo.DayBuyCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_TodayBuyCount)
+    NetPackCommon.SendFakePack(curPlayer, pkPlayerInfo)
     return
     
 def SyncCrossRealmPKAwardState(curPlayer):
-#    DWORD        DayPKCountAwardState;    // 每日匹配次数奖励记录,二进制位存储是否已领取,按匹配次数升序排序索引代表奖励位
-#    DWORD        DayWinCountAwardState;    // 每日胜利次数奖励记录,二进制位存储是否已领取,按胜利次数升序排序索引代表奖励位
-#    DWORD        DanLVAwardState;        // 段位达标奖励记录,二进制位存储是否已领取,按段位代表奖励位
-#    BYTE        SeasonAwardState;    // 赛季结算奖励是否已领取
+    ## 同步玩家跨服PK相关奖励状态
+    pkAwardPack = ChPyNetSendPack.tagMCCrossRealmPKAwardState()
+    pkAwardPack.DayPKCountAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DayPKCountAwardState)
+    pkAwardPack.DayWinCountAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DayWinCountAwardState)
+    pkAwardPack.DanLVAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_DanLVAwardState)
+    pkAwardPack.SeasonAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonAwardState)
+    NetPackCommon.SendFakePack(curPlayer, pkAwardPack)
     return
 
+def SyncCrossRealmPKHisSeasonInfo(curPlayer):
+    mapSeasonID = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)
+    hisSeasonInfo = ChPyNetSendPack.tagMCCrossRealmPKPlayerHisSeasonInfo()
+    hisSeasonInfo.SeasonList = []
+    for seasonID in xrange(1, mapSeasonID + 1):
+        seasonInfo = ChPyNetSendPack.tagMCCrossRealmPKPlayerHisSeason()
+        seasonInfo.SeasonID = seasonID
+        seasonInfo.DanLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonDanLV % seasonID)
+        seasonInfo.Order = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonOrder % seasonID)
+        seasonInfo.AwardLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_SeasonAwardLV % seasonID)
+        hisSeasonInfo.SeasonList.append(seasonInfo)
+    hisSeasonInfo.Count = len(hisSeasonInfo.SeasonList)
+    NetPackCommon.SendFakePack(curPlayer, hisSeasonInfo)
+    return
 
-
+def DR_GetCrossPKAward(curPlayer, zoneID, seasonID, eventName, isMail, drDataDict):
+    ## 记录领奖流向
+    drDataDict.update({"zoneID":zoneID, "seasonID":seasonID, "isMail":isMail})
+    DataRecordPack.SendEventPack("GetCrossPKAward_%s" % eventName, drDataDict, curPlayer)
+    return
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
index 89b4bae..6f7e2d2 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -38,9 +38,7 @@
 import GameLogInfo
 import GameServerRefresh
 import ShareDefine
-import ReadCaptchaImage
 import PlayerGameWallow
-import ItemCommon
 import Operate_PlayerBuyZhenQi
 import PlayerSignDay
 import PlayerCoin
@@ -52,30 +50,22 @@
 import PlayerHorse
 import PlayerLoginDayAward
 import NPCCommon
-import GameLogic_MergeBoss
-import GameLogic_ManorWar
 import FunctionNPCCommon
 import PlayerGoldGift
 import PlayerActivity
 import PlayerTeHui
 import PlayerBindJadeWheel
 import PlayerAction
-import PlayerTruck
 import FBCommon
-import PlayerDienstgrad
 import PlayerSuccess
-import PlayerMixLoginDayAward
 import PlayerFreeGoods
 import PlayerMagicWeapon
 import ShopItemManage
 import ChItem
 import PlayerGoldInvest
 import PlayerNewGuyCard
-import PlayerMergeKing
-import PlayerMergePK
 import PlayerCrossRealmPK
 import PlayerPet
-import ReloadModule
 import BossHurtMng
 import PlayerRecover
 import GameLogic_FamilyParty
@@ -1337,24 +1327,28 @@
     #===============================================================================================
     
     #领地争夺战
-    elif key == ShareDefine.Def_Notify_WorldKey_ManorWar:
-        GameLogic_ManorWar.OnManorWarStateChange(value, tick)
+    #elif key == ShareDefine.Def_Notify_WorldKey_ManorWar:
+    #    GameLogic_ManorWar.OnManorWarStateChange(value, tick)
 
     #定时商店刷新
     elif key.startswith(ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime[:-2]):
         ShopItemManage.OnTimeShopRefresh(key, value, tick)
         
     #跨服boss
-    elif key == ShareDefine.Def_Notify_WorldKey_MergeBoss:
-        GameLogic_MergeBoss.OnMergeBossStateChange(value, tick)
+    #elif key == ShareDefine.Def_Notify_WorldKey_MergeBoss:
+    #    GameLogic_MergeBoss.OnMergeBossStateChange(value, tick)
         
     # 跨服PK, 赛季开始时间不用处理,仅存储即可
-    elif key in [ShareDefine.Def_Notify_WorldKey_MergePKDayID, ShareDefine.Def_Notify_WorldKey_MergePKSeasonID]:
-        PlayerMergePK.OnMergePKActionChange(key, value)
+    #elif key in [ShareDefine.Def_Notify_WorldKey_MergePKDayID, ShareDefine.Def_Notify_WorldKey_MergePKSeasonID]:
+    #    PlayerMergePK.OnMergePKActionChange(key, value)
         
     # 跨服王者争霸
-    elif key in [ShareDefine.Def_Notify_WorldKey_Merge_KingStartID, ShareDefine.Def_Notify_WorldKey_Merge_KingOverID]:
-        PlayerMergeKing.OnMergeKingActionChange(key, value)
+    #elif key in [ShareDefine.Def_Notify_WorldKey_Merge_KingStartID, ShareDefine.Def_Notify_WorldKey_Merge_KingOverID]:
+    #    PlayerMergeKing.OnMergeKingActionChange(key, value)
+    
+    # 跨服PK
+    elif key == ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID:
+        PlayerCrossRealmPK.OnCrossRealmPKSeasonChange(value)
         
     # 仙盟宴会
     elif key == ShareDefine.Def_Notify_WorldKey_FBFuncState % ChConfig.Def_FBMapID_FamilyParty:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossPKSeasonOrder.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossPKSeasonOrder.py
new file mode 100644
index 0000000..64d5ec7
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossPKSeasonOrder.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.RemoteQuery.GY_Query_CrossPKSeasonOrder
+#
+# @todo:跨服PK赛季名次
+# @author hxp
+# @date 2018-12-25
+# @version 1.0
+#
+# 详细描述: 跨服PK赛季名次
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2018-12-25 21:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PlayerCrossRealmPK
+
+
+#------------------------------------------------------------------------------ 
+## 跨服赛报名调用接口
+#  @param query_Type 请求类型
+#  @param query_ID 请求的玩家ID
+#  @param packCMDList 发包命令
+#  @param tick 当前时间
+#  @return "True" or "False" or ""
+#  @remarks 函数详细说明.
+def DoLogic(query_Type, query_ID, packCMDList, tick): 
+    return
+
+#------------------------------------------------------------------------------ 
+## 执行结果
+#  @param curPlayer 发出请求的玩家
+#  @param callFunName 功能名称
+#  @param funResult 查询的结果
+#  @param tick 当前时间
+#  @return None
+#  @remarks 函数详细说明.
+def DoResult(curPlayer, callFunName, funResult, tick):
+    msgList = eval(funResult)
+    playerID = curPlayer.GetPlayerID()
+    GameWorld.Log("GY_Query_CrossPKSeasonOrder msgList=%s" % (msgList), playerID)
+    PlayerCrossRealmPK.GameServer_CrossPKSeasonOrder(curPlayer, msgList)
+    return
+    
+    
+    

--
Gitblit v1.8.0