| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package CrossRealmPK  | 
| #  | 
| # @todo:¿ç·þPK¾º¼¼³¡  | 
| # @author hxp  | 
| # @date 2018-12-21  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ¿ç·þPK¾º¼¼³¡  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2018-12-21 18:00"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import GameWorld  | 
| import PlayerControl  | 
| import CrossRealmMsg  | 
| import DataRecordPack  | 
| 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  | 
| import time  | 
|   | 
| class CrossPKPlayer():  | 
|     ## ¿ç·þPKÍæ¼ÒÀà  | 
|       | 
|     def __init__(self):  | 
|         self.accID = ""  | 
|         self.playerID = 0  | 
|         self.playerName = ""  | 
|         self.playerJob = 0  | 
|         self.playerLV = 0  | 
|         self.maxHP = 0  | 
|         self.maxProDef = 0  | 
|         self.fightPower = 0  | 
|         self.realmLV = 0  | 
|         self.pkScore = 0  | 
|         self.danLV = 0  | 
|         self.matchTick = 0  | 
|         self.prepareOKTick = 0  | 
|         self.cWinCount = 0 # Á¬Ê¤´ÎÊý  | 
|         self.ondayScore = 0 # ¹ýÌìʱµÄ»ý·Ö  | 
|         self.serverGroupID = 0 # ËùÊô·þÎñÆ÷ID£¬Ò»¸ö·þÎñÆ÷IDÓɶà¸ö·þ×é³É  | 
|         self.pkZoneID = 0 # ËùÊôÈüÇøID£¬Ò»¸öÈüÇøÓɶà¸ö·þÎñÆ÷ID×é³É  | 
|         self.seasonID = 0 # Èü¼¾ID  | 
|         return  | 
|       | 
|     def GetDRInfo(self):  | 
|         ## Á÷Ïò¼Ç¼ÐÅÏ¢  | 
|         return {"accID":self.accID, "playerID":self.playerID, "fightPower":self.fightPower, "pkScore":self.pkScore,   | 
|                 "danLV":self.danLV, "matchTick":self.matchTick, "prepareOKTick":self.prepareOKTick, "cWinCount":self.cWinCount,   | 
|                 "ondayScore":self.ondayScore, "serverGroupID":self.serverGroupID, "ondayScore":self.ondayScore}  | 
|       | 
| class CrossPKRoom():  | 
|     ## ¿ç·þPK·¿¼äÀà  | 
|       | 
|     def __init__(self):  | 
|         self.pkZoneID = 0  | 
|         self.seasonID = 0  | 
|         self.roomID = 0  | 
|         self.mapID = 0  | 
|         self.openTick = 0 # ¿ª·¿Ê±¼ä  | 
|         self.readyTick = 0 # Íæ¼Ò¶¼×¼±¸ºÃµÄʱ¼ä  | 
|         self.roomState = ShareDefine.Def_VsRoom_State_WaitPlayer # Ä¬ÈÏ״̬  | 
|         self.roomPlayerIDList = [] # ¶ÔÕ½Íæ¼ÒIDÁÐ±í  | 
|         self.readyPlayerIDList = [] # ÒѾ׼±¸ºÃµÄÍæ¼ÒIDÁÐ±í  | 
|         self.mapFBOpenTick = 0 # µØÍ¼¿ªÆô¸Ã·¿¼ätick£¬Î´¿ªÆôµÄ·¿¼ä³¬Ê±ºó£¬±¾´ÎÆ¥ÅäÊÓΪÎÞЧ£¬ÓÐÍæ¼Ò½øµØÍ¼²Å»á¿ªÆô¸±±¾·ÖÏß  | 
|         return  | 
|       | 
|     def GetDRInfo(self):  | 
|         return {"zoneID":self.pkZoneID, "seasonID":self.seasonID, "roomID":self.roomID, "mapID":self.mapID, "openTick":self.openTick,   | 
|                 "readyTick":self.readyTick, "roomPlayerIDList":self.roomPlayerIDList, "mapFBOpenTick":self.mapFBOpenTick}  | 
|           | 
| #¿ç·þ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.DebugLog("    ¸üÐÂ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Öеķ¿¼äÁË£¡Ö÷¶¯¹ã²¥×Ó·þ×îаñµ¥! ")  | 
|         crossZoneName = GameWorld.GetCrossZoneName()  | 
|         zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, 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  | 
|         crossZoneName = GameWorld.GetCrossZoneName()  | 
|         seasonList = IpyGameDataPY.GetIpyGameDataList("CrossRealmPKSeason", crossZoneName, 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.DebugLog("ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄÅÅÐаñÐÅÏ¢: 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 __GetCrossPKZoneSeasonTimeInfo():  | 
|     key = "CrossPKZoneSeasonTimeInfo"  | 
|     openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1  | 
|     ZoneSeasonTimeInfo = IpyGameDataPY.GetConfigEx(key)  | 
|       | 
|     if ZoneSeasonTimeInfo and ZoneSeasonTimeInfo[0] == openServerDay:  | 
|         #GameWorld.DebugLog("ÒѾ¼ÓÔØ¹ý±¾ÈÕ¿ç·þPKÈü¼¾´¦ÀíÐÅÏ¢£¡openServerDay=%s" % openServerDay)  | 
|         return ZoneSeasonTimeInfo[1]  | 
|       | 
|     GameWorld.Log("¼ÓÔØ¿ç·þPKÈü¼¾Ê±¼äÐÅÏ¢: openServerDay=%s" % (openServerDay))  | 
|       | 
|     zoneSeasonTimeDict = {}  | 
|     serverTime = GameWorld.GetServerTime()  | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)  | 
|     if not crossZoneList:  | 
|         return zoneSeasonTimeDict  | 
|       | 
|     for zoneIpyData in crossZoneList:  | 
|         zoneID = zoneIpyData.GetZoneID()  | 
|           | 
|         # ¹æ¶¨Ã¿¸öÈüÇøµÄÈü¼¾Ê±¼äÐ谴˳ÐòÅäÖà  | 
|         seasonIpyDataList = IpyGameDataPY.GetIpyGameDataList("CrossRealmPKSeason", crossZoneName, zoneID)  | 
|         if not seasonIpyDataList:  | 
|             continue  | 
|           | 
|         for i, seasonIpyData in enumerate(seasonIpyDataList):  | 
|             seasonID = seasonIpyData.GetSeasonID()  | 
|             startDateStr = seasonIpyData.GetStartDate()  | 
|             endDateStr = seasonIpyData.GetEndDate()  | 
|             endTimeStr = seasonIpyData.GetEndTime()  | 
|               | 
|             startDateTime = datetime.datetime.strptime("%s 00:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)  | 
|             endDateTime = datetime.datetime.strptime("%s %s:00" % (endDateStr, endTimeStr), ChConfig.TYPE_Time_Format)  | 
|               | 
|             # ×îºóÒ»¸öÈü¼¾  | 
|             if i == len(seasonIpyDataList) - 1:  | 
|                 nextSeasonIpyData = None  | 
|             else:  | 
|                 nextSeasonIpyData = seasonIpyDataList[i + 1]  | 
|                   | 
|             if serverTime < startDateTime:  | 
|                 GameWorld.Log("    Èü¼¾Î´¿ªÊ¼! zoneID=%s,seasonID=%s,startDateStr=%s,endDateStr=%s" % (zoneID, seasonID, startDateStr, endDateStr))  | 
|                 break  | 
|               | 
|             elif startDateTime <= serverTime <= endDateTime:  | 
|                 pass  | 
|               | 
|             elif endDateTime < serverTime:  | 
|                 if nextSeasonIpyData:  | 
|                     nestStartDateStr = nextSeasonIpyData.GetStartDate()  | 
|                     nextStartDateTime = datetime.datetime.strptime("%s 00:00:00" % (nestStartDateStr), ChConfig.TYPE_Time_Format)  | 
|                     if serverTime >= nextStartDateTime:  | 
|                         GameWorld.Log("    Èü¼¾ÒѹýÆÚ! zoneID=%s,seasonID=%s,startDateStr=%s,endDateStr=%s" % (zoneID, seasonID, startDateStr, endDateStr))  | 
|                         continue  | 
|                 else:  | 
|                     pass  | 
|                   | 
|             else:  | 
|                 continue  | 
|               | 
|             nextSeasonID = 0 if not nextSeasonIpyData else nextSeasonIpyData.GetSeasonID()  | 
|             zoneSeasonTimeDict[zoneID] = [seasonIpyData]  | 
|             GameWorld.Log("    Èü¼¾»î¶¯ÖÐ! zoneID=%s,seasonID=%s,startDateStr=%s,endDateStr=%s,nextSeasonID=%s" % (zoneID, seasonID, startDateStr, endDateStr, nextSeasonID))  | 
|             break  | 
|           | 
|     ZoneSeasonTimeInfo = IpyGameDataPY.SetConfigEx(key, [openServerDay, zoneSeasonTimeDict])  | 
|     GameWorld.Log("¿ç·þPKÈü¼¾Ê±¼äÐÅÏ¢¼ÓÔØÍê±Ï!")  | 
|     GameWorld.Log("=============================================================")  | 
|     return ZoneSeasonTimeInfo[1]  | 
|   | 
| def OnMinuteProcess():  | 
|     ## Ã¿·ÖÖÓ´¦Àí  | 
|       | 
|     if not GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     zoneSeasonTimeDict = __GetCrossPKZoneSeasonTimeInfo()  | 
|     if not zoneSeasonTimeDict:  | 
|         return  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     serverTime = GameWorld.GetServerTime()  | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     for zoneID, seasonTimeInfo in zoneSeasonTimeDict.items():  | 
|         zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, zoneID)  | 
|         if not zoneIpyData:  | 
|             continue  | 
|           | 
|         curSeasonIpyData = seasonTimeInfo[0]  | 
|         if not curSeasonIpyData:  | 
|             continue  | 
|           | 
|         seasonID = curSeasonIpyData.GetSeasonID()  | 
|         startDateStr = curSeasonIpyData.GetStartDate()  | 
|         endDateStr = curSeasonIpyData.GetEndDate()  | 
|         endTimeStr = curSeasonIpyData.GetEndTime()  | 
|           | 
|         startDateTime = datetime.datetime.strptime("%s 00:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)  | 
|         endDateTime = datetime.datetime.strptime("%s %s:00" % (endDateStr, endTimeStr), ChConfig.TYPE_Time_Format)  | 
|           | 
|         seasonState = 0  | 
|         if startDateTime <= serverTime < endDateTime:  | 
|             seasonState = 1  | 
|         elif serverTime >= endDateTime:  | 
|             seasonState = 2  | 
|               | 
|         zoneSeasonIDDictName = ChConfig.Def_WorldKey_CrossPKZoneSeasonID % zoneID  | 
|         seasonStateDictName = ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID  | 
|         dictSeasonID = gameWorld.GetDictByKey(zoneSeasonIDDictName)  | 
|         curSeasonState = gameWorld.GetDictByKey(seasonStateDictName)  | 
|         if curSeasonState == seasonState and dictSeasonID == seasonID:  | 
|             #ÒѾÊÇÕâ¸ö״̬ÁË  | 
|             continue  | 
|         gameWorld.SetDict(zoneSeasonIDDictName, seasonID)  | 
|         gameWorld.SetDict(seasonStateDictName, seasonState)  | 
|         GameWorld.Log("¿ç·þPKÈü¼¾×´Ì¬±ä¸ü: zoneID=%s,seasonID=%s,seasonState=%s" % (zoneID, seasonID, seasonState))  | 
|           | 
|         serverGroupIDList = zoneIpyData.GetServerGroupIDList()  | 
|         # Èü¼¾×ܽáË㣬Ϊȷ±£×Ó·þ°ñµ¥µÄʵʱÐÔ£¬ÕâÀïÐèÔÙͬ²½×Ó·þ×îÖÕ°ñµ¥ÐÅÏ¢£¬ÐèÔÚͬ²½Èü¼¾×´Ì¬Ö®Ç°Í¬²½  | 
|         if seasonState == 2:  | 
|             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()  | 
|     preState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)  | 
|     gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK, isOpen)  | 
|               | 
|     # Æ¥Åä״̬´Ó¹Ø±Õµ½¿ªÆô   | 
|     if not preState and isOpen:  | 
|         PyGameData.g_crossPKPlayerDict = {}  | 
|         PyGameData.g_crossPKZoneMatchPlayerDict = {}  | 
|         PyGameData.g_crossPKRoomDict = {}  | 
|         GameWorld.Log("¿ç·þPKÆ¥Åä״̬¿ªÆô£¬ÖØÖÃÏà¹ØÆ¥ÅäÊý¾Ý!")  | 
|           | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)  | 
|     if not crossZoneList:  | 
|         return  | 
|       | 
|     for zoneIpyData in crossZoneList:  | 
|         zoneID = zoneIpyData.GetZoneID()  | 
|           | 
|         # ¹ã²¥µ±Ç°ÈüÇøµÄËùÓÐ×Ó·þ¿ç·þPKÈü¼¾×´Ì¬±ä¸ü  | 
|         serverGroupIDList = zoneIpyData.GetServerGroupIDList()  | 
|         seasonID = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonID % zoneID)  | 
|         seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID)  | 
|         seasonInfo = {"ZoneID":zoneID, "SeasonID":seasonID, "SeasonState":seasonState, "MatchState":isOpen}  | 
|         GameWorld.Log("¿ç·þPKÆ¥Åä״̬±ä¸ü: zoneID=%s,seasonID=%s,seasonState=%s,matchState=%s" % (zoneID, seasonID, seasonState, isOpen))  | 
|         CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKSeasonInfo, seasonInfo, serverGroupIDList)  | 
|           | 
|     return  | 
|   | 
| def Sync_CrossPKInitDataToClientServer(tick, serverGroupID=0):  | 
|     ''' Í¬²½¿ç·þPK»î¶¯Êý¾Ýµ½×Ó·þÎñÆ÷  | 
|     @param serverGroupID: Îª0ʱͬ²½ËùÓÐ×Ó·þ  | 
|     '''  | 
|       | 
|     GameWorld.Log("ͬ²½¸ø×Ó·þ¶ÔÓ¦µÄÈü¼¾ÐÅÏ¢: syncServerGroupID=%s" % (serverGroupID))  | 
|     if serverGroupID:  | 
|         ipyData = GetCrossPKServerGroupZone(serverGroupID)  | 
|         if not ipyData:  | 
|             return  | 
|         crossZoneList = [ipyData]  | 
|     else:  | 
|         crossZoneName = GameWorld.GetCrossZoneName()  | 
|         crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)  | 
|     if not crossZoneList:  | 
|         return  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     for zoneIpyData in crossZoneList:  | 
|         zoneID = zoneIpyData.GetZoneID()  | 
|         seasonID = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonID % zoneID)  | 
|         seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID)  | 
|         matchState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)  | 
|         seasonInfo = {"ZoneID":zoneID, "SeasonID":seasonID, "SeasonState":seasonState, "MatchState":matchState}  | 
|         serverGroupIDList = [serverGroupID] if serverGroupID else zoneIpyData.GetServerGroupIDList()  | 
|         CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKSeasonInfo, seasonInfo, serverGroupIDList)  | 
|           | 
|     return  | 
|   | 
| def GetCrossPKServerGroupZone(serverGroupID):  | 
|     ## »ñÈ¡·þÎñÆ÷×éID¶ÔÓ¦µÄ¿ç·þPKËùÊôÈüÇø£¬·µ»Ø0´ú±í¸Ã·þÎñÆ÷ûÓзÖÅäÈüÇø  | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)  | 
|     if not crossZoneList:  | 
|         return  | 
|       | 
|     for zoneIpyData in crossZoneList:  | 
|         for groupInfo in zoneIpyData.GetServerGroupIDList():  | 
|             if (isinstance(groupInfo, int) and serverGroupID == groupInfo) \  | 
|                 or (isinstance(groupInfo, tuple) and len(groupInfo) == 2 and groupInfo[0] <= serverGroupID <= groupInfo[1]):  | 
|                 return zoneIpyData  | 
|     return  | 
|   | 
| def OnPlayerLoginCrossServer(curPlayer):  | 
|     # ¿ç·þµÇ¼´¦Àí  | 
|       | 
|     mapID = curPlayer.GetMapID()  | 
|     mapIDList = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 4)  | 
|     if mapID not in mapIDList:  | 
|         return  | 
|       | 
|     GameWorld.Log("Íæ¼ÒµÇ¼¿ç·þPKµØÍ¼, mapID=%s" % mapID, curPlayer.GetPlayerID())  | 
|     if not __CheckCanLoginCrossServerPKMap(curPlayer):  | 
|         CrossRealmPlayer.PlayerExitCrossServer(curPlayer)  | 
|         return  | 
|       | 
|     return  | 
|   | 
| def OnPlayerLogin(curPlayer):  | 
|     # ±¾·þµÇ¼´¦Àí  | 
|       | 
|     # ±¾·þûÓзÖÅäÈüÇø²»´¦Àí  | 
|     if not GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID):  | 
|         return  | 
|     __OnLoginNotifyPKOverInfo(curPlayer)  | 
|       | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)  | 
|     if not crossZoneList:  | 
|         return  | 
|     # Í¬²½ËùÓÐÈüÇøÈü¼¾ÐÅÏ¢  | 
|     zoneSeasonInfo = ChPyNetSendPack.tagGCCrossRealmPKSeasonInfo()  | 
|     zoneSeasonInfo.ZoneList = []  | 
|     for zoneIpyData in crossZoneList:  | 
|         zoneID = zoneIpyData.GetZoneID()  | 
|         zoneInfo = ChPyNetSendPack.tagGCCrossRealmPKZone()  | 
|         zoneInfo.ZoneID = zoneID  | 
|         zoneInfo.ZoneName = zoneIpyData.GetZoneName().decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())  | 
|         zoneInfo.ZoneNameLen = len(zoneInfo.ZoneName)  | 
|         zoneInfo.SeasonList = []  | 
|         seasonList = IpyGameDataPY.GetIpyGameDataList("CrossRealmPKSeason", crossZoneName, zoneID)  | 
|         seasonList = [] if not seasonList else seasonList  | 
|         for seasonIpyData in seasonList:  | 
|             seasonInfo = ChPyNetSendPack.tagGCCrossRealmPKSeason()  | 
|             seasonInfo.SeasonID = seasonIpyData.GetSeasonID()  | 
|             seasonInfo.StartDate = seasonIpyData.GetStartDate()  | 
|             seasonInfo.EndDate = seasonIpyData.GetEndDate()  | 
|             seasonInfo.EndTime = seasonIpyData.GetEndTime()  | 
|             zoneInfo.SeasonList.append(seasonInfo)  | 
|         zoneInfo.SeasonCount = len(zoneInfo.SeasonList)  | 
|         zoneSeasonInfo.ZoneList.append(zoneInfo)  | 
|     zoneSeasonInfo.ZoneCount = len(zoneSeasonInfo.ZoneList)  | 
|     NetPackCommon.SendFakePack(curPlayer, zoneSeasonInfo)  | 
|       | 
|     # Í¬²½±¾·þÈü¼¾×´Ì¬  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     seasonStatePack = ChPyNetSendPack.tagGCCrossRealmPKSeasonState()  | 
|     seasonStatePack.ZoneID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)  | 
|     seasonStatePack.SeasonID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)  | 
|     seasonStatePack.SeasonState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)  | 
|     seasonStatePack.MatchState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)  | 
|     seasonStatePack.CrossZoneName = GameWorld.GetCrossZoneName()  | 
|     seasonStatePack.CrossZoneNameLen = len(seasonStatePack.CrossZoneName)  | 
|     NetPackCommon.SendFakePack(curPlayer, seasonStatePack)  | 
|           | 
|     return  | 
|   | 
| def __CheckCanLoginCrossServerPKMap(curPlayer):  | 
|     # ¼ì²éÍæ¼Ò¿É·ñµÇ¼¿ç·þPK·¿¼ä  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     vsRoomID = curPlayer.GetVsRoomId()  | 
|     if not vsRoomID:  | 
|         GameWorld.ErrLog("Íæ¼ÒûÓжÔÕ½·¿¼äID£¬²»¿É½øÈë¶ÔÕ½µØÍ¼! Ç¿ÖÆÌß³ö¿ç·þ·þÎñÆ÷!", playerID)  | 
|         return False  | 
|       | 
|     if vsRoomID not in PyGameData.g_crossPKRoomDict:  | 
|         GameWorld.ErrLog("Íæ¼Ò¶ÔÕ½·¿¼äIDÒѾ²»´æÔÚ£¬²»¿É½øÈë¶ÔÕ½µØÍ¼! Ç¿ÖÆÌß³ö¿ç·þ·þÎñÆ÷!vsRoomID=%s" % vsRoomID, playerID)  | 
|         return False  | 
|       | 
|     vsRoom = PyGameData.g_crossPKRoomDict[vsRoomID]  | 
|     if playerID not in vsRoom.roomPlayerIDList:  | 
|         GameWorld.ErrLog("Íæ¼Ò¶ÔÕ½·¿¼äID²»´æÔÚ¸ÃÍæ¼ÒID£¬²»¿É½øÈë¶ÔÕ½µØÍ¼! Ç¿ÖÆÌß³ö¿ç·þ·þÎñÆ÷!vsRoomID=%s,roomPlayerIDList=%s"   | 
|                          % (vsRoomID, vsRoom.roomPlayerIDList), playerID)  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
| ## Íæ¼ÒÀëÏß´¦Àí  | 
| def OnLeaveServer(curPlayer):      | 
|     # ·¢ËÍÈ¡ÏûÆ¥Åä  | 
|     SendCancelCrossRealmPKMatch(curPlayer, "PlayerDisconnect")  | 
|     return  | 
|   | 
| def IsCrossRealmPKMatchState():  | 
|     ## ¿ç·þPKÆ¥ÅäÈüÊÇ·ñ¿ªÆô  | 
|     return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState \  | 
|                                                  % ShareDefine.DailyActionID_CrossReamPK) == ChConfig.Def_Action_Open  | 
|   | 
| def SendCancelCrossRealmPKMatch(curPlayer, reason):     | 
|     ## ·¢ËÍÈ¡ÏûÆ¥Åä  | 
|       | 
|     # ¿ç·þ·þÎñÆ÷²»´¦Àí  | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     # ·Ç»î¶¯Öв»´¦Àí  | 
|     if not IsCrossRealmPKMatchState():  | 
|         return  | 
|       | 
| #    # Èç¹ûÊÇÒªµÇ½µ½¿ç·þ·þÎñÆ÷µÄ£¬²»·¢ËÍÈ¡Ïû  | 
| #    if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_IsLoginToMergeServer):  | 
| #        GameWorld.DebugLog("±¾´ÎÀëÏßΪҪµÇ½¿ç·þ·þÎñÆ÷µÄ×Ô¶¯ÀëÏßÐÐΪ£¬²»·¢ËÍÈ¡ÏûÆ¥Å䣡", curPlayer.GetPlayerID())  | 
| #        curPlayer.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 0)  | 
| #        return  | 
|   | 
|     vsRoomID = curPlayer.GetVsRoomId()  | 
|     if vsRoomID and PlayerControl.GetCrossMapID(curPlayer) == ChConfig.Def_FBMapID_CrossRealmPK:  | 
|         GameWorld.DebugLog("Íæ¼Ò¿ç·þPK״̬£¬²»ÄÜÈ¡ÏûÆ¥Å䣡vsRoomID=%s" % vsRoomID, curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     dataMsg = {"accID":curPlayer.GetAccID(), # Õ˺Š | 
|                "playerID":curPlayer.GetPlayerID(), # Íæ¼ÒID  | 
|                "playerName":curPlayer.GetName(), # ¿ç·þ×Ó·þÍæ¼ÒÃû  | 
|                "reason":reason, # È¡ÏûÔÒò  | 
|                "vsRoomID":vsRoomID, # ¶ÔÕ½·¿¼äID  | 
|                }  | 
|     CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PKCancel, dataMsg)  | 
|     PlayerControl.SetVsRoomId(curPlayer, 0)  | 
|     SetIsCrossPKMatching(curPlayer, 0)  | 
|     GameWorld.DebugLog("·¢ËÍÈ¡Ïû¿ç·þPKÆ¥Åäµ½¿ç·þ·þÎñÆ÷£ºdataMsg=%s" % str(dataMsg), curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def ClientServerMsg_PKMatch(serverGroupID, playerInfoDict, tick):  | 
|     ## ÇëÇóÆ¥Åä  | 
|       | 
|     if not GameWorld.IsCrossServer():  | 
|         GameWorld.ErrLog("·Ç¿ç·þ·þÎñÆ÷²»´¦Àí¿ç·þPKÆ¥ÅäÇëÇó£¡")  | 
|         return  | 
|       | 
|     if not IsCrossRealmPKMatchState():  | 
|         GameWorld.Log("¿ç·þÆ¥ÅäPK»î¶¯Î´¿ªÆô£¬²»ÔÊÐíÇëÇóÆ¥Å䣡")  | 
|         return  | 
|       | 
|     seasonID = playerInfoDict["seasonID"] # Èü¼¾ID  | 
|     pkZoneID = playerInfoDict["pkZoneID"] # ËùÊôÈüÇø  | 
|     accID = playerInfoDict["accID"] # ½ÇÉ«Õ˺Š | 
|     playerID = playerInfoDict["playerID"] # ½ÇÉ«ID  | 
|     playerName = playerInfoDict["playerName"] # Íæ¼ÒÃû  | 
|     job = playerInfoDict["playerJob"] # Ö°Òµ  | 
|     playerLV = playerInfoDict["playerLV"] # Ö°Òµ  | 
|     maxHP = playerInfoDict["maxHP"] # Ö°Òµ  | 
|     maxProDef = playerInfoDict["maxProDef"] # »¤¶Ü  | 
|     fightPower = playerInfoDict["fightPower"] # Õ½¶·Á¦  | 
|     realmLV = playerInfoDict["realmLV"] # ¾³½ç  | 
|     pkScore = playerInfoDict["pkScore"] # µ±Ç°»ý·Ö  | 
|     danLV = playerInfoDict["danLV"] # µ±Ç°¶Îλ  | 
|     cWinCount = playerInfoDict["cWinCount"] # Á¬Ê¤´ÎÊý  | 
|     ondayScore = playerInfoDict["ondayScore"] # ¹ýÌìʱµÄ»ý·Ö  | 
|       | 
|     zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])  | 
|     if playerID in zoneMatchPlayerList:  | 
|         GameWorld.Log("Íæ¼ÒÕýÔÚÆ¥ÅäÖУ¬ÎÞ·¨Öظ´·¢ÆðÆ¥Å䣡playerID=%s,accID=%s" % (playerID, accID))  | 
|         CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, 1], [serverGroupID])  | 
|         return  | 
|     if playerID in PyGameData.g_crossPKPlayerDict:  | 
|         GameWorld.Log("Íæ¼ÒÕýÔÚÕ½¶·ÖУ¬ÎÞ·¨Öظ´·¢ÆðÆ¥Å䣡playerID=%s,accID=%s" % (playerID, accID))  | 
|         CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, -2], [serverGroupID])  | 
|         return  | 
|       | 
|     pkPlayer = CrossPKPlayer()  | 
|     pkPlayer.accID = accID  | 
|     pkPlayer.playerID = playerID  | 
|     pkPlayer.playerName = playerName  | 
|     pkPlayer.playerJob = job  | 
|     pkPlayer.playerLV = playerLV  | 
|     pkPlayer.maxHP = maxHP  | 
|     pkPlayer.maxProDef = maxProDef  | 
|     pkPlayer.pkScore = pkScore  | 
|     pkPlayer.danLV = danLV  | 
|     pkPlayer.fightPower = fightPower  | 
|     pkPlayer.realmLV = realmLV  | 
|     pkPlayer.matchTick = tick  | 
|     pkPlayer.cWinCount = cWinCount  | 
|     pkPlayer.ondayScore = ondayScore  | 
|     pkPlayer.serverGroupID = serverGroupID  | 
|     pkPlayer.pkZoneID = pkZoneID  | 
|     pkPlayer.seasonID = seasonID  | 
|     PyGameData.g_crossPKPlayerDict[playerID] = pkPlayer  | 
|       | 
|     # ¼ÓÈëÈüÇøÆ¥ÅäÁÐ±í  | 
|     zoneMatchPlayerList.append(playerID)  | 
|     PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList  | 
|       | 
|     GameWorld.DebugLog("Íæ¼Ò¼ÓÈëÆ¥Åä: seasonID=%s,pkZoneID=%s,serverGroupID=%s,accID=%s,playerID=%s,pkScore=%s,fightPower=%s,cWinCount=%s,len(zoneMatchPlayerList)=%s"   | 
|                        % (seasonID, pkZoneID, serverGroupID, accID, playerID, pkScore, fightPower, cWinCount, len(zoneMatchPlayerList)))  | 
|       | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, [playerID, 1], [serverGroupID])  | 
|     return  | 
|   | 
| def ClientServerMsg_PKCancel(playerInfoDict, tick):  | 
|     ## È¡ÏûÆ¥Åä  | 
|       | 
|     if not GameWorld.IsCrossServer():  | 
|         GameWorld.ErrLog("·Ç¿ç·þ·þÎñÆ÷²»´¦ÀíÈ¡Ïû¿ç·þPKÆ¥Å䣡")  | 
|         return  | 
|       | 
|     # ·Ç»î¶¯Öв»´¦Àí  | 
|     if not IsCrossRealmPKMatchState():  | 
|         return  | 
|       | 
|     accID = playerInfoDict["accID"] # ½ÇÉ«Õ˺Š | 
|     playerID = playerInfoDict["playerID"] # Íæ¼ÒID  | 
|     reason = playerInfoDict["reason"] # È¡ÏûÔÒò  | 
|     vsRoomID = playerInfoDict["vsRoomID"] # ËùÊô¶ÔÕ½·¿¼äID  | 
|     if vsRoomID in PyGameData.g_crossPKRoomDict:  | 
|         pkRoom = PyGameData.g_crossPKRoomDict[vsRoomID]  | 
|         if pkRoom.mapFBOpenTick or pkRoom.readyTick:  | 
|             GameWorld.Log("¿ç·þ¶ÔÕ½·¿¼äÒѾ¿ªÆôÁËÏß·£¬»òÕßË«·½Êý¾Ý¶¼ÒÑ´«ÊäÍê±Ï£¬²»¿ÉÔÙÈ¡ÏûÆ¥Å䣡vsRoomID=%s" % vsRoomID)  | 
|             return  | 
|           | 
|     GameWorld.DebugLog("Íæ¼ÒÈ¡ÏûÆ¥Åä: reason=%s,accID=%s,playerID=%s,vsRoomID=%s" % (reason, accID, playerID, vsRoomID))  | 
|       | 
|     pkZoneID = 0  | 
|     if playerID in PyGameData.g_crossPKPlayerDict:  | 
|         pkPlayer = PyGameData.g_crossPKPlayerDict.pop(playerID)  | 
|         pkZoneID = pkPlayer.pkZoneID  | 
|         GameWorld.DebugLog("    ÒƳýPKÍæ¼Ò: pkZoneID=%s,accID=%s,playerID=%s" % (pkZoneID, accID, playerID))  | 
|           | 
|     zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])  | 
|     if playerID in zoneMatchPlayerList:  | 
|         zoneMatchPlayerList.remove(playerID)  | 
|         GameWorld.DebugLog("    ´ÓÆ¥Åä¶ÓÁÐÖÐɾ³ý£¬Æ¥Åä¶ÓÁÐÊ£ÓàÈËÊý=%s" % (len(zoneMatchPlayerList)))  | 
|           | 
|     #È¡ÏûËùÓдæÔÚ¸ÃÍæ¼ÒµÄ·¿¼ä£¬×Ó·þ²»Ò»¶¨ÖªµÀÍæ¼Òµ±Ç°×îÐÂËùÊô·¿¼äID£¬ ¹ÊÖ»ÄÜͨ¹ý±éÀúɾ³ýÒÑ¾ÎªÍæ¼Ò´´½¨µÄ·¿¼ä  | 
|     for roomID, pkRoom in PyGameData.g_crossPKRoomDict.items():  | 
|         if playerID not in pkRoom.roomPlayerIDList:  | 
|             continue  | 
|           | 
|         for roomPlayerID in pkRoom.roomPlayerIDList:  | 
|             if roomPlayerID == playerID:  | 
|                 GameWorld.DebugLog("    ×Ô¼º²»´¦Àí: roomID=%s,playerID=%s" % (roomID, playerID))  | 
|                 continue  | 
|               | 
|             zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])  | 
|             zoneMatchPlayerList.append(roomPlayerID)  | 
|             PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList  | 
|             GameWorld.DebugLog("    ½«Ö®Ç°Æ¥ÅäµÄ¶ÔÊÖÖØÐ¼ÓÈëÆ¥Åä¶ÓÁÐ: roomID=%s,roomPlayerID=%s,µ±Ç°Æ¥ÅäÈËÊý=%s"   | 
|                                % (roomID, roomPlayerID, len(zoneMatchPlayerList)))  | 
|               | 
|         PyGameData.g_crossPKRoomDict.pop(roomID)  | 
|         GameWorld.DebugLog("    ÒƳý·¿¼ä: popRoomID=%s" % (roomID))  | 
|           | 
|         # ¼Ç¼Á÷Ïò  | 
|         dataDict = {"cancelPlayerID":playerID}  | 
|         dataDict.update(pkRoom.GetDRInfo())  | 
|         DR_CrossReamlPK("CancelRoom", dataDict)  | 
|         break  | 
|       | 
|     return  | 
|   | 
| def ClientServerMsg_PKPrepareOK(playerInfoDict, tick):  | 
|     ## Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK  | 
|       | 
|     if not GameWorld.IsCrossServer():  | 
|         GameWorld.ErrLog("·Ç¿ç·þ·þÎñÆ÷²»´¦ÀíÈ¡Ïû¿ç·þPKÆ¥Å䣡")  | 
|         return  | 
|       | 
|     accID = playerInfoDict["accID"] # Íæ¼ÒÕ˺Š | 
|     playerID = playerInfoDict["playerID"] # Íæ¼ÒID  | 
|     vsRoomID = playerInfoDict["vsRoomID"] # ËùÊô¶ÔÕ½·¿¼äID  | 
|     if playerID not in PyGameData.g_crossPKPlayerDict:  | 
|         GameWorld.ErrLog("Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK, µ«ÕÒ²»µ½¸Ã¶ÔÕ½Íæ¼ÒÐÅÏ¢£¡vsRoomID=%s,playerID=%s" % (vsRoomID, playerID))  | 
|         return  | 
|     pkPlayer = PyGameData.g_crossPKPlayerDict[playerID]  | 
|     pkPlayer.prepareOKTick = tick  | 
|       | 
|     if vsRoomID not in PyGameData.g_crossPKRoomDict:  | 
|         GameWorld.ErrLog("Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK, µ«ÕÒ²»µ½¸Ã¶ÔÕ½·¿¼ä(%s)£¡¿ÉÄܶÔÊÖÒÑÈ¡Ïû£¡" % vsRoomID)  | 
|         return  | 
|     vsRoom = PyGameData.g_crossPKRoomDict[vsRoomID]  | 
|       | 
|     if vsRoom.roomState != ShareDefine.Def_VsRoom_State_WaitPlayer:  | 
|         GameWorld.ErrLog("Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK, µ«·¿¼ä״̬·ÇµÈ´ý״̬, state=%s£¡" % vsRoom.roomState)  | 
|         return  | 
|       | 
|     if playerID not in vsRoom.readyPlayerIDList:  | 
|         vsRoom.readyPlayerIDList.append(playerID)  | 
|           | 
|     GameWorld.DebugLog("Íæ¼Ò¿ç·þPK×¼±¸Íê±Ï: accID=%s,playerID=%s,vsRoomID=%s" % (accID, playerID, vsRoomID))  | 
|     return  | 
|   | 
| def __ReadyOKRoomPlayerProcess(tick):  | 
|     ## Íæ¼Ò¿ç·þPKÒÑ×¼±¸ºÃµÄ·¿¼ä´¦Àí  | 
|       | 
|     #GameWorld.Log("===ÒÑ×¼±¸ºÃµÄ¶ÔÕ½·¿¼ä´¦Àí===")  | 
|     serverGroupIDList = []  | 
|     sendReadyOKRoomList = []  | 
|     for roomID, vsRoom in PyGameData.g_crossPKRoomDict.items():  | 
|           | 
|         # ·ÇµÈ´ý״̬µÄ·¿¼ä²»´¦Àí  | 
|         if vsRoom.roomState != ShareDefine.Def_VsRoom_State_WaitPlayer:  | 
|             continue  | 
|           | 
|         if not vsRoom.roomPlayerIDList:  | 
|             continue  | 
|           | 
|         pkZoneID = 0  | 
|         isAllReady = True  | 
|         roomGroupIDList = []  | 
|         readyMemberDict = {} # ÒÑ×¼±¸ºÃµÄÍæ¼ÒÐÅÏ¢  | 
|         for num, roomPlayerID in enumerate(vsRoom.roomPlayerIDList, 1):  | 
|             if roomPlayerID not in vsRoom.readyPlayerIDList or roomPlayerID not in PyGameData.g_crossPKPlayerDict:  | 
|                 isAllReady = False  | 
|                 break  | 
|             roomPlayer = PyGameData.g_crossPKPlayerDict[roomPlayerID]  | 
|             pkZoneID = roomPlayer.pkZoneID  | 
|             roomGroupIDList.append(roomPlayer.serverGroupID)  | 
|             readyMemberDict[roomPlayerID] = {"ServerGroupID":roomPlayer.serverGroupID, "Name":roomPlayer.playerName, "Number":num,  | 
|                                              "Job":roomPlayer.playerJob, "LV":roomPlayer.playerLV, "MaxHP":roomPlayer.maxHP, "MaxProDef":roomPlayer.maxProDef}  | 
|                       | 
|         if not isAllReady:  | 
|             continue  | 
|         vsRoom.roomState = ShareDefine.Def_VsRoom_State_PrepareFight  | 
|         vsRoom.readyTick = tick  | 
|         GameWorld.DebugLog("    ×¼±¸ºÃµÄ·¿¼ä: pkZoneID=%s,roomID=%s,mapID=%s,readyMemberDict=%s" % (pkZoneID, roomID, vsRoom.mapID, str(readyMemberDict)))  | 
|           | 
|         sendReadyOKRoomList.append([roomID, readyMemberDict])  | 
|         serverGroupIDList += roomGroupIDList  | 
|           | 
|     # ½«ÒÑ×¼±¸ºÃµÄ·¿¼ä¹ã²¥µ½×Ó·þ  | 
|     if sendReadyOKRoomList:  | 
|         GameWorld.DebugLog("    ÒÑ×¼±¸ºÃµÄ¶ÔÕ½·¿¼äÊý: %s" % len(sendReadyOKRoomList))  | 
|         CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKReadyOKRoomList, sendReadyOKRoomList, serverGroupIDList)  | 
|           | 
|     return  | 
| #  | 
| #def TestAddMatch(tick, addCount, maxDanLV=None, isClear=False):  | 
| #    if isClear:  | 
| #        PyGameData.g_crossPKPlayerDict = {}  | 
| #        PyGameData.g_crossPKZoneMatchPlayerDict = {}  | 
| #        PyGameData.g_crossPKRoomDict = {}  | 
| #        PyGameData.g_crossPKRoomID = 0  | 
| #          | 
| #    ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
| #    if maxDanLV == None:  | 
| #        maxDanLV = ipyDataMgr.GetCrossRealmPKDanCount() - 1  | 
| #    crossZoneName = GameWorld.GetCrossZoneName()  | 
| #    crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)  | 
| #    if not crossZoneList:  | 
| #        return  | 
| #    for zoneIpyData in crossZoneList:  | 
| #        pkZoneID = zoneIpyData.GetZoneID()  | 
| #          | 
| #        addPlayerList = []  | 
| #        zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])  | 
| #        maxPlayerID = pkZoneID * 1000 if not zoneMatchPlayerList else max(zoneMatchPlayerList)  | 
| #        for i in xrange(1, addCount + 1):  | 
| #            playerID = maxPlayerID + i  | 
| #              | 
| #            pkPlayer = CrossPKPlayer()  | 
| #            pkPlayer.playerID = playerID  | 
| #            danLV = random.randint(0, maxDanLV)  | 
| #            pkPlayer.danLV = danLV  | 
| #            pkPlayer.matchTick = tick  | 
| #            pkPlayer.pkScore = danLV * 1000 + random.randint(0, 999)  | 
| #            pkPlayer.pkZoneID = pkZoneID  | 
| #            pkPlayer.seasonID = 1  | 
| #              | 
| #            PyGameData.g_crossPKPlayerDict[playerID] = pkPlayer  | 
| #            addPlayerList.append([playerID, danLV])  | 
| #            # ¼ÓÈëÈüÇøÆ¥ÅäÁÐ±í  | 
| #            zoneMatchPlayerList.append(playerID)  | 
| #        PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList  | 
| #        GameWorld.Log("Add zoneID=%s,addPlayerList=%s" % (pkZoneID, addPlayerList))  | 
| #          | 
| #    #GameWorld.Log("PyGameData.g_crossPKPlayerDict=%s" % PyGameData.g_crossPKPlayerDict)  | 
| #    return  | 
|   | 
| def OnPKMatchProcess(tick):  | 
|     ## Íæ¼Ò¿ç·þPKÆ¥Å䶨ʱ´¦ÀíÂß¼  | 
|       | 
|     # ·Ç¿ç·þ·þÎñÆ÷²»´¦Àí¿ç·þPKÆ¥ÅäÂß¼  | 
|     if not GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     if not IsCrossRealmPKMatchState():  | 
|         return  | 
|       | 
|     # ¶¨Ê±¸üÐÂÅÅÐаñ  | 
|     crossPKBillboardMgr = PyDataManager.GetCrossPKBillboardManager()  | 
|     crossPKBillboardMgr.PKBillboardSortByTime(tick)  | 
|       | 
|     processTick = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 1) * 1000  | 
|     processTickKey = "PKMatchLastTick"  | 
|     lastProcessTick = GameWorld.GetGameWorld().GetDictByKey(processTickKey)  | 
|     if tick - lastProcessTick < processTick:  | 
|         return  | 
|     GameWorld.GetGameWorld().SetDict(processTickKey, tick)  | 
|       | 
|     # ´¦Àí³¬Ê±µÄ·¿¼ä  | 
|     __DoCheckRoomTimeout(tick)  | 
|     # Í¨ÖªÒÑ×¼±¸ºÃµÄ·¿¼äÍæ¼Ò¿É½øÈë¿ç·þ  | 
|     __ReadyOKRoomPlayerProcess(tick)  | 
|       | 
|     maxGroupCnt = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 2)  | 
|     outTimeTick = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 3) * 1000  | 
|       | 
|     # Ã¿¸öÈüÇøµ¥¶ÀÆ¥Åä  | 
|     for pkZoneID, matchPlayerIDList in PyGameData.g_crossPKZoneMatchPlayerDict.items():  | 
|         matchPlayerCount = len(matchPlayerIDList)  | 
|         if matchPlayerCount < 2:  | 
|             #GameWorld.Log("Æ¥ÅäPKÈËÊý²»×㣬²»´¦Àí£¡pkZoneID=%s, ×ÜÈËÊý:%s" % (pkZoneID, matchPlayerCount))  | 
|             continue  | 
|           | 
|         GameWorld.DebugLog("¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¿ªÊ¼¿ç·þPKÆ¥Åä(pkZoneID=%s, ×ÜÈËÊý:%s)¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï" % (pkZoneID, matchPlayerCount))  | 
|           | 
|         matchPlayerList = []  | 
|         for matchPlayerID in matchPlayerIDList:  | 
|             if matchPlayerID not in PyGameData.g_crossPKPlayerDict:  | 
|                 continue  | 
|             matchPlayerList.append(PyGameData.g_crossPKPlayerDict[matchPlayerID])  | 
|         # °´Æ¥Åäʱ¼ä¡¢»ý·ÖÉýÐòÅÅÐò  | 
|         matchTickSortList = sorted(matchPlayerList, key=operator.attrgetter("matchTick"))  | 
|         scoreSortList = sorted(matchPlayerList, key=operator.attrgetter("pkScore"))  | 
|           | 
|         matchPlayerVSList = [] # ³É¹¦Æ¥ÅäÍæ¼Ò¶ÔÕ½ÁÐ±í  | 
|           | 
|         # ÓÅÏÈÆ¥ÅäµÈ´ý³¬Ê±Íæ¼Ò  | 
|         __DoMatch_OutTimePlayer(matchTickSortList, scoreSortList, outTimeTick, matchPlayerVSList, tick)  | 
|           | 
|         if len(matchPlayerVSList) < maxGroupCnt:  | 
|             # ÔÙ°´»ý·Ö¶ÎÆ¥ÅäÍæ¼Ò  | 
|             __DoMatch_DanScorePlayer(scoreSortList, maxGroupCnt, matchPlayerVSList)  | 
|               | 
|         # ¸ø³É¹¦Æ¥ÅäµÄÍæ¼Ò·ÇÅä¶ÔÕ½·¿¼ä  | 
|         matchPlayerVSList = matchPlayerVSList[:maxGroupCnt]  | 
|         __DoSetVSRoom(pkZoneID, matchPlayerVSList, tick)  | 
|         GameWorld.DebugLog("==========Æ¥Åä½áÊø(×ÜÆ¥Åä¶ÓÎé:%s)==========" % len(matchPlayerVSList))  | 
|         #GameWorld.DebugLog("crossPlayerIDList=%s" % PyGameData.g_crossPKPlayerDict.keys())  | 
|         #GameWorld.DebugLog("matchPlayerIDList=%s" % PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID])  | 
|     return  | 
|   | 
|   | 
| def __DoMatch_OutTimePlayer(matchTickSortList, scoreSortList, outTimeTick, matchPlayerVSList, tick):  | 
|     '''Æ¥Åä³¬Ê±Íæ¼Ò  | 
|         Æ¥ÅäÖеÄÍæ¼Ò°´»ý·ÖÅÅÐò£¬×îºóÒ»¸öĬÈÏÆ¥ÅäÉÏÒ»¸ö£¬µÚÒ»¸öĬÈÏÆ¥ÅäÏÂÒ»¸ö£¬ÆäËûÆ¥Åäǰºó»ý·Ö²î¾ø¶ÔÖµ½ÏСµÄÒ»¸ö  | 
|     '''  | 
|     GameWorld.DebugLog(" ==ÓÅÏÈÆ¥Å䳬ʱµÈ´ýÍæ¼Ò==×î´óµÈ´ýʱ¼ä:%s, tick=%s" % (outTimeTick, tick))  | 
|     GameWorld.DebugLog(" scoreSortListLen=%s" % len(scoreSortList))  | 
|     for i, matchPlayer in enumerate(matchTickSortList):          | 
|         # Ö»ÓÐÒ»¸öÍæ¼Ò  | 
|         if len(scoreSortList) <= 1:  | 
|             #GameWorld.DebugLog("    µ±Ç°Íæ¼ÒÊý%s<=1£¬²»ÔÙÆ¥Å䣡" % len(scoreSortList))  | 
|             break  | 
|           | 
|         if tick - matchPlayer.matchTick < outTimeTick:  | 
|             #GameWorld.DebugLog("    i=%s,Íæ¼Òδ³¬Ê±£¬²»ÔÙÆ¥Å䣡" % (i))  | 
|             break  | 
|           | 
|         GameWorld.DebugLog("    i=%s,³¬Ê±Íæ¼Ò, %s-%s=%s >= outTimeTick(%s)"   | 
|                            % (i, tick, matchPlayer.matchTick, tick - matchPlayer.matchTick, outTimeTick))  | 
|         # ÒѾ±»Æ¥Åä×ßÁË  | 
|         if matchPlayer not in scoreSortList:  | 
|             GameWorld.DebugLog("        ÒѾ±»Æ¥Åä×ßÁË£¡")  | 
|             continue  | 
|           | 
|         outTimeIndex = scoreSortList.index(matchPlayer)  | 
|         # ×îºóÒ»¸öĬÈÏÆ¥ÅäÉÏÒ»¸ö  | 
|         if outTimeIndex == len(scoreSortList) - 1:   | 
|             vsIndex = outTimeIndex - 1  | 
|             GameWorld.DebugLog("        ³¬Ê±Íæ¼Ò»ý·ÖÅÅÐòË÷Òý%s,×îºóÒ»¸ö,ĬÈÏÆ¥ÅäÉÏÒ»¸öË÷Òý%s£¡" % (outTimeIndex, vsIndex))  | 
|         # µÚÒ»¸öĬÈÏÆ¥ÅäÏÂÒ»¸ö  | 
|         elif outTimeIndex == 0:  | 
|             vsIndex = outTimeIndex + 1  | 
|             GameWorld.DebugLog("        ³¬Ê±Íæ¼Ò»ý·ÖÅÅÐòË÷Òý%s,µÚÒ»¸ö,ĬÈÏÆ¥ÅäÏÂÒ»¸öË÷Òý%s£¡" % (outTimeIndex, vsIndex))  | 
|         # ÆäËûÇé¿öÆ¥Åä»ý·Ö½Ï½üµÄÒ»¸ö  | 
|         else:  | 
|             preIndex = outTimeIndex - 1  | 
|             nextIndex = outTimeIndex + 1  | 
|             prePlayer = scoreSortList[preIndex]  | 
|             nextPlayer = scoreSortList[nextIndex]  | 
|             preDiff = abs(prePlayer.pkScore - matchPlayer.pkScore)  | 
|             nextDiff = abs(matchPlayer.pkScore - nextPlayer.pkScore)  | 
|             vsIndex = preIndex if preDiff <= nextDiff else nextIndex  | 
|             GameWorld.DebugLog("        ³¬Ê±Íæ¼Ò»ý·ÖÅÅÐòË÷Òý-»ý·Ö(%s-%s),ÉÏÒ»¸ö(%s-%s),ÏÂÒ»¸ö(%s-%s),preDiff=%s,nextDiff=%s,vsIndex=%s"   | 
|                                % (outTimeIndex, matchPlayer.pkScore, preIndex, prePlayer.pkScore,   | 
|                                   nextIndex, nextPlayer.pkScore, preDiff, nextDiff, vsIndex))  | 
|               | 
|         if outTimeIndex > vsIndex:   | 
|             scoreSortList.pop(outTimeIndex)  | 
|             vsPlayer = scoreSortList.pop(vsIndex)  | 
|         elif outTimeIndex < vsIndex:  | 
|             vsPlayer = scoreSortList.pop(vsIndex)  | 
|             scoreSortList.pop(outTimeIndex)  | 
|         else:  | 
|             continue  | 
|           | 
|         # ¼ÓÈë³É¹¦Æ¥ÅäÁÐ±í  | 
|         matchPlayerVSList.append([matchPlayer, vsPlayer])  | 
|           | 
|     return  | 
|   | 
| def __DoMatch_DanScorePlayer(scoreSortList, maxGroupCnt, matchPlayerVSList):  | 
|     ''' Æ¥Åä»ý·Ö·Ö¶ÎÍæ¼Ò  | 
|             Æ¥ÅäÖеÄÍæ¼Ò°´¶Îλ»ý·Ö¹é×飬¹é×éºó£¬Ëæ»ú¶Îλ˳Ðò£¬Ã¿¸ö¶Îλ×éÖеÄÍæ¼ÒËæ»úÁ½Á½PK  | 
|     '''  | 
|     GameWorld.DebugLog(" ==Æ¥Åä»ý·Ö·Ö¶ÎÍæ¼Ò== maxGroupCnt=%s,scoreSortListLen=%s" % (maxGroupCnt, len(scoreSortList)))  | 
|     danPlayerListDict = {} # °´»ý·Ö·Ö¶ÎÁбí·ÖÉ¢Íæ¼Ò  | 
|     for matchPlayer in scoreSortList:  | 
|         danLV = matchPlayer.danLV  | 
|         danPlayerList = danPlayerListDict.get(danLV, [])  | 
|         danPlayerList.append(matchPlayer)  | 
|         danPlayerListDict[danLV] = danPlayerList  | 
|           | 
|     # °´·Ö¶ÎÍæ¼ÒËæ»úÆ¥Åä  | 
|     danList = danPlayerListDict.keys()  | 
|     random.shuffle(danList) # ´òÂÒ¶Îλ˳Ðò  | 
|       | 
|     GameWorld.DebugLog("    »ý·Ö·Ö¶Î¸öÊý: %s, %s" % (len(danList), danList))  | 
|       | 
|     # ÓÅÏÈÆ¥ÅäÏàͬ¶Îλ  | 
|     doCount = 0  | 
|     while len(matchPlayerVSList) < maxGroupCnt and doCount < maxGroupCnt:  | 
|         doCount += 1  | 
|         isMatchOK = False  | 
| #        # ÈÕÖ¾Êä³ö·Ö×éÃ÷ϸ  | 
| #        GameWorld.DebugLog("    -------------")  | 
| #        for danLV in danList:  | 
| #            strList = []  | 
| #            for player in danPlayerListDict[danLV]:  | 
| #                strList.append((player.playerID, player.pkScore, player.fightPower))  | 
| #            GameWorld.DebugLog("    »ý·Ö¶Î×é, danLV=%s, %s" % (danLV, str(strList)))  | 
| #        # -------------------------------  | 
|           | 
|         for danLV in danList:  | 
|             danPlayerList = danPlayerListDict[danLV]  | 
|             danPlayerCount = len(danPlayerList)  | 
|             if danPlayerCount < 2:  | 
|                 #GameWorld.DebugLog("    ¶ÎλÈËÊýÉÙÓÚ2¸ö£¬²»´¦Àí£¡doCount=%s,danLV=%s" % (doCount, danLV))  | 
|                 continue  | 
|               | 
|             vsIndexList = random.sample(xrange(danPlayerCount), 2) # Ëæ»úÈ¡Á½¸öË÷Òý¶ÔÕ½  | 
|             vsIndexList.sort()  | 
|             aPlayer = danPlayerList.pop(vsIndexList[1])  | 
|             bPlayer = danPlayerList.pop(vsIndexList[0])  | 
|               | 
|             matchPlayerVSList.append([aPlayer, bPlayer])  | 
|             isMatchOK = True  | 
|             GameWorld.DebugLog("    ³É¹¦Æ¥ÅäÏàͬ¶ÎÎ»Íæ¼Ò: aPlayerID=%s,aDanLV=%s VS bPlayerID=%s,bDanLV=%s" % (aPlayer.playerID, aPlayer.danLV, bPlayer.playerID, bPlayer.danLV))  | 
|               | 
|             if len(matchPlayerVSList) >= maxGroupCnt:  | 
|                 GameWorld.DebugLog("    ÒѾ´ïµ½×î´óÆ¥ÅäÊý! ÒÑÆ¥Åä¶ÔÕ½Êý=%s, ²»ÔÙÆ¥Å䣡doCount=%s" % (len(matchPlayerVSList), doCount))  | 
|                 break  | 
|               | 
|         if not isMatchOK:  | 
|             GameWorld.DebugLog("    ÒѾûÓÐÂú×ãÆ¥ÅäÌõ¼þµÄÍæ¼Ò! ²»ÔÙÆ¥Å䣡doCount=%s" % (doCount))  | 
|             break  | 
|           | 
|     # ²»×ãÔÙÆ¥Å䷶Χ¶Îλ  | 
|     doCount = 0  | 
|     while len(matchPlayerVSList) < maxGroupCnt and doCount < maxGroupCnt:  | 
|         doCount += 1  | 
|         isMatchOK = False  | 
| #        # ÈÕÖ¾Êä³ö·Ö×éÃ÷ϸ  | 
| #        GameWorld.DebugLog("    -------------")  | 
| #        for danLV in danList:  | 
| #            strList = []  | 
| #            for player in danPlayerListDict[danLV]:  | 
| #                strList.append((player.playerID, player.pkScore, player.fightPower))  | 
| #            GameWorld.DebugLog("    »ý·Ö¶Î×é, danLV=%s, %s" % (danLV, str(strList)))  | 
| #        # -------------------------------  | 
|           | 
|         for danLV in danList:  | 
|             danMatchRange = []  | 
|             danMatchPlayerList = []  | 
|             danIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", danLV)  | 
|             matchDanRange = [] if not danIpyData else danIpyData.GetMatchRange()  | 
|             if matchDanRange and len(matchDanRange) == 2:  | 
|                 danMatchRange = range(matchDanRange[0], matchDanRange[1] + 1)  | 
|                   | 
|             if danLV not in danMatchRange:  | 
|                 danMatchRange.append(danLV)  | 
|                   | 
|             for matchDanLV in danMatchRange:  | 
|                 if matchDanLV not in danPlayerListDict:  | 
|                     continue  | 
|                 danMatchPlayerList += danPlayerListDict[matchDanLV]  | 
|                   | 
|             #matchPlayerIDList = [matchPlayer.playerID for matchPlayer in danMatchPlayerList]  | 
|             #GameWorld.DebugLog("danLV=%s,danMatchRange=%s,matchPlayerIDList=%s" % (danLV, danMatchRange, matchPlayerIDList))  | 
|             matchPlayerCount = len(danMatchPlayerList)  | 
|             if matchPlayerCount < 2:  | 
|                 #GameWorld.DebugLog("    ¶Îλ·¶Î§ÈËÊýÉÙÓÚ2¸ö£¬²»´¦Àí£¡doCount=%s,danLV=%s,danMatchRange=%s" % (doCount, danLV, danMatchRange))  | 
|                 continue  | 
|               | 
|             vsIndexList = random.sample(xrange(matchPlayerCount), 2) # Ëæ»úÈ¡Á½¸öË÷Òý¶ÔÕ½  | 
|             aPlayer, bPlayer = danMatchPlayerList[vsIndexList[0]], danMatchPlayerList[vsIndexList[1]]  | 
|               | 
|             aDanPlayerList = danPlayerListDict.get(aPlayer.danLV, [])  | 
|             bDanPlayerList = danPlayerListDict.get(bPlayer.danLV, [])  | 
|             if aPlayer in aDanPlayerList and bPlayer in bDanPlayerList:  | 
|                 aDanPlayerList.remove(aPlayer)  | 
|                 bDanPlayerList.remove(bPlayer)  | 
|             else:  | 
|                 continue  | 
|               | 
|             matchPlayerVSList.append([aPlayer, bPlayer])  | 
|             isMatchOK = True  | 
|             GameWorld.DebugLog("    ³É¹¦Æ¥Å䷶Χ¶ÎÎ»Íæ¼Ò: aPlayerID=%s,aDanLV=%s VS bPlayerID=%s,bDanLV=%s | danLV=%s,danMatchRange=%s"   | 
|                                % (aPlayer.playerID, aPlayer.danLV, bPlayer.playerID, bPlayer.danLV, danLV, danMatchRange))  | 
|               | 
|             if len(matchPlayerVSList) >= maxGroupCnt:  | 
|                 GameWorld.DebugLog("    ÒѾ´ïµ½×î´óÆ¥ÅäÊý! ÒÑÆ¥Åä¶ÔÕ½Êý=%s, ²»ÔÙÆ¥Å䣡doCount=%s" % (len(matchPlayerVSList), doCount))  | 
|                 break  | 
|               | 
|         if not isMatchOK:  | 
|             GameWorld.DebugLog("    ÒѾûÓÐÂú×ãÆ¥ÅäÌõ¼þµÄÍæ¼Ò! ²»ÔÙÆ¥Åä! doCount=%s" % (doCount))  | 
|             break  | 
|           | 
|     return  | 
|   | 
| def __DoSetVSRoom(pkZoneID, matchPlayerVSList, tick):  | 
|     ## ÉèÖöÔÕ½·¿¼ä  | 
|       | 
|     if not matchPlayerVSList:  | 
|         return  | 
|       | 
|     vsRoomDict = {}  | 
|     serverGroupIDList = []  | 
|     zoneMatchPlayerList = PyGameData.g_crossPKZoneMatchPlayerDict.get(pkZoneID, [])  | 
|       | 
|     mapIDList = IpyGameDataPY.GetFuncCfg("CrossRealmPKMatch", 4)  | 
|     GameWorld.DebugLog("===¸øÅä¶ÔµÄÍæ¼Ò¿ª·¿¼ä(pkZoneID=%s,Åä¶ÔÊý:%s)===" % (pkZoneID, len(matchPlayerVSList)))  | 
|     for aPlayer, bPlayer in matchPlayerVSList:  | 
|           | 
|         if not aPlayer or not bPlayer:  | 
|             continue  | 
|           | 
|         aPlayerID = aPlayer.playerID  | 
|         bPlayerID = bPlayer.playerID  | 
|         if aPlayerID not in PyGameData.g_crossPKPlayerDict or bPlayerID not in PyGameData.g_crossPKPlayerDict:  | 
|             GameWorld.ErrLog("Íæ¼ÒÆ¥ÅäÊý¾ÝÒì³££¡aPlayerID=%s,bPlayerID=%s" % (aPlayerID, bPlayerID))  | 
|             continue  | 
|           | 
|         roomID = __GetNewRoomID()  | 
|         if not roomID:  | 
|             GameWorld.ErrLog("ÎÞ·¨´´½¨·¿¼ä£¡¸Ã·¿¼äÒѾ´æÔÚ£¡PyGameData.g_crossPKRoomID=%s" % PyGameData.g_crossPKRoomID)  | 
|             continue  | 
|         mapID = random.choice(mapIDList)  | 
|           | 
|         newRoom = CrossPKRoom()  | 
|         newRoom.pkZoneID = pkZoneID  | 
|         newRoom.seasonID = aPlayer.seasonID # ÒòΪƥÔÚÒ»ÆðµÄÍæ¼ÒÒ»¶¨ÊÇͬһÈüÇøÍ¬Ò»Èü¼¾µÄ£¬ËùÒÔËæ±ãȡһ¸öÍæ¼ÒµÄÈü¼¾IDÐÅÏ¢¼´¿É  | 
|         newRoom.roomID = roomID  | 
|         newRoom.mapID = mapID  | 
|         newRoom.openTick = tick  | 
|         newRoom.roomPlayerIDList = [aPlayerID, bPlayerID]  | 
|         PyGameData.g_crossPKRoomDict[roomID] = newRoom  | 
|           | 
|         aServerGroupID, bServerGroupID = aPlayer.serverGroupID, bPlayer.serverGroupID  | 
|         GameWorld.DebugLog("    ¿ª·¿:pkZoneID=%s,mapID=%s,roomID=%s,aPlayerID=%s,bPlayerID=%s" % (pkZoneID, mapID, roomID, aPlayerID, bPlayerID))  | 
|         vsRoomDict[roomID] = [mapID, [[aServerGroupID, aPlayerID], [bServerGroupID, bPlayerID]]]  | 
|           | 
|         # ¼Ç¼Á÷Ïò  | 
|         dataDict = {"aPlayer":aPlayer.GetDRInfo(), "bPlayer":bPlayer.GetDRInfo()}  | 
|         dataDict.update(newRoom.GetDRInfo())  | 
|         DR_CrossReamlPK("OpenRoom", dataDict)  | 
|           | 
|         serverGroupIDList.append(aServerGroupID)  | 
|         serverGroupIDList.append(bServerGroupID)  | 
|           | 
|         # ÒƳýÆ¥Åä¶ÓÁÐ  | 
|         if aPlayerID in zoneMatchPlayerList:  | 
|             zoneMatchPlayerList.remove(aPlayerID)  | 
|         if bPlayerID in zoneMatchPlayerList:  | 
|             zoneMatchPlayerList.remove(bPlayerID)  | 
|         PyGameData.g_crossPKZoneMatchPlayerDict[pkZoneID] = zoneMatchPlayerList  | 
|           | 
|     # ½«Æ¥Åä½á¹û¹ã²¥µ½×Ó·þ  | 
|     if vsRoomDict:  | 
|         CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchResult, vsRoomDict, serverGroupIDList)  | 
|           | 
|     return  | 
|   | 
| def __GetNewRoomID():  | 
|     ## »ñȡз¿¼äID, ·¿¼äºÅÖ±½Ó×ÔÔö£¬Ò»¶¨²»»áÖØ¸´£¬³ý·Ç×ÔÔöÒ»ÂÖºó·¿¼äID»¹Ã»ÓÐÊÍ·Å  | 
|     for _ in xrange(100):  | 
|         newRoomID = PyGameData.g_crossPKRoomID + 1  | 
|         if newRoomID > 65530:  | 
|             newRoomID = 1  | 
|         PyGameData.g_crossPKRoomID = newRoomID  | 
|         if newRoomID not in PyGameData.g_crossPKRoomDict:  | 
|             return newRoomID  | 
|     return 0  | 
|   | 
| def __DoCheckRoomTimeout(tick):  | 
|     ## ´¦Àí³¬Ê±µÄ·¿¼ä  | 
|       | 
|     timeoutRoomDict = {}  | 
|     serverGroupIDList = []  | 
|     roomTimeout = IpyGameDataPY.GetFuncCfg("CrossRealmPKCfg", 2) * 1000 # Õâ¸öʱ¼ä¾¡Á¿³¤µã£¬Ä¿Ç°ÔÝʱ²»È·¶¨Íæ¼Ò´Ó×¼±¸µ½½øÈëµ½µØÍ¼µÄʱ³¤  | 
|     for roomID, pkRoom in PyGameData.g_crossPKRoomDict.items():  | 
|         if pkRoom.mapFBOpenTick or not pkRoom.readyTick:  | 
|             continue  | 
|         if tick - pkRoom.readyTick <= roomTimeout:  | 
|             continue  | 
|         pkZoneID = pkRoom.pkZoneID  | 
|         GameWorld.Log("PK·¿¼äµÈ´ýÍæ¼Ò½øÀ´³¬Ê±£¬Ã»ÓÐÍæ¼Ò½øÀ´£¬¹Ø±Õ¸Ã·¿¼ä£¡pkZoneID=%s,roomID=%s,openTick=%s,readyTick=%s,tick=%s"   | 
|                       % (pkZoneID, roomID, pkRoom.openTick, pkRoom.readyTick, tick))  | 
|         roomPlayerInfo = []  | 
|         for roomPlayerID in pkRoom.roomPlayerIDList:  | 
|             pkPlayer = PyGameData.g_crossPKPlayerDict.pop(roomPlayerID, None)  | 
|             if not pkPlayer:  | 
|                 continue  | 
|             serverGroupID = pkPlayer.serverGroupID  | 
|             GameWorld.Log("    ÒƳýÍæ¼Ò£¬Íæ¼ÒÐèÖØÐÂÊÖ¶¯Æ¥Å䣬serverGroupID=%s,roomPlayerID=%s" % (serverGroupID, roomPlayerID))  | 
|             serverGroupIDList.append(serverGroupID)  | 
|             roomPlayerInfo.append([serverGroupID, roomPlayerID])  | 
|         timeoutRoomDict[roomID] = roomPlayerInfo  | 
|         PyGameData.g_crossPKRoomDict.pop(roomID)  | 
|           | 
|         # ¼Ç¼Á÷Ïò  | 
|         DR_CrossReamlPK("TimeoutRoom", pkRoom.GetDRInfo())  | 
|           | 
|     # ½«³¬Ê±·¿¼ä¹ã²¥µ½×Ó·þ  | 
|     if timeoutRoomDict:  | 
|         CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKTimeoutRoomList, timeoutRoomDict, serverGroupIDList)  | 
|     return  | 
|   | 
| def MapServer_CrossPKRoomOpen(msgList, tick):  | 
|     roomID = msgList[0]  | 
|     if roomID not in PyGameData.g_crossPKRoomDict:  | 
|         GameWorld.ErrLog("MapServer_CrossPKRoomOpen => PK·¿¼ä²»´æÔÚ£¡roomID=%s" % roomID)  | 
|         return  | 
|     pkRoom = PyGameData.g_crossPKRoomDict[roomID]  | 
|     pkRoom.mapFBOpenTick = tick  | 
|     GameWorld.Log("MapServer_CrossPKRoomOpen => roomID=%s" % roomID)  | 
|     return  | 
|   | 
| def MapServer_CrossPKOver(infoList, tick):  | 
|     ## ÊÕµ½MapServer¸±±¾¿ç·þPK½á¹ûͬ²½  | 
|       | 
|     GameWorld.DebugLog("ÊÕµ½MapServer_¿ç·þPKÕ½¶·½á¹û: %s" % str(infoList))  | 
|       | 
|     roomID, winnerID, loserID, roundWinnerIDList, overType = infoList  | 
|       | 
|     if roomID not in PyGameData.g_crossPKRoomDict:  | 
|         GameWorld.ErrLog("¿ç·þPK·¿¼äÊý¾Ý²»´æÔÚ£¡roomID=%s" % roomID)  | 
|         return  | 
|     vsRoom = PyGameData.g_crossPKRoomDict.pop(roomID)  | 
|     #vsRoom = PyGameData.g_crossPKRoomDict[roomID]  | 
|     roomPlayerIDList = vsRoom.roomPlayerIDList  | 
|     if not winnerID and not loserID:  | 
|         GameWorld.ErrLog("µØÍ¼Ã»ÓнáËã¿ç·þPKʤ¸ºÍæ¼Ò£¬Ëæ»úÍæ¼Ò»ñʤ!")  | 
|         if not roomPlayerIDList or len(roomPlayerIDList) != 2:  | 
|             return  | 
|         winnerID, loserID = roomPlayerIDList  | 
|     elif not loserID:  | 
|         for roomPlayerID in roomPlayerIDList:  | 
|             if roomPlayerID != winnerID:  | 
|                 loserID = roomPlayerID  | 
|                 break  | 
|               | 
|     if winnerID not in roomPlayerIDList or loserID not in roomPlayerIDList:  | 
|         GameWorld.ErrLog("¿ç·þPK·¿¼ä¼°Íæ¼Ò²»Æ¥Å䣬²»½áË㣡roomID=%s,winnerID=%s,loserID=%s,roomPlayerIDList=%s"   | 
|                          % (roomID, winnerID, loserID, vsRoom.roomPlayerIDList))  | 
|         return  | 
|       | 
|     if winnerID not in PyGameData.g_crossPKPlayerDict:  | 
|         GameWorld.ErrLog("¿ç·þPK·¿¼ä»ñÈ¡²»µ½Íæ¼ÒPKÊý¾Ý, roomID=%s,winnerID=%s" % (roomID, winnerID))  | 
|         return  | 
|     if loserID not in PyGameData.g_crossPKPlayerDict:  | 
|         GameWorld.ErrLog("¿ç·þPK·¿¼ä»ñÈ¡²»µ½Íæ¼ÒPKÊý¾Ý, roomID=%s,loserID=%s" % (roomID, loserID))  | 
|         return  | 
|       | 
|     winner = PyGameData.g_crossPKPlayerDict.pop(winnerID)  | 
|     loser = PyGameData.g_crossPKPlayerDict.pop(loserID)  | 
|     #winner = PyGameData.g_crossPKPlayerDict[winnerID]  | 
|     #loser = PyGameData.g_crossPKPlayerDict[loserID]  | 
|     zoneID = vsRoom.pkZoneID  | 
|     seasonID = vsRoom.seasonID  | 
|       | 
|     cWinCount = winner.cWinCount  | 
|     winnerScore, loserScore = winner.pkScore, loser.pkScore  | 
|     winnerDanLV, loserDanLV = winner.danLV, loser.danLV  | 
|     winnerDayScore, loserDayScore = max(0, winnerScore - winner.ondayScore), max(0, loserScore - loser.ondayScore) # ½ñÈÕÒÑ»ñµÃ»ý·Ö£¬Õý»ý·Ö  | 
|       | 
|     GameWorld.DebugLog("winnerDayScore=%s,winnerScore=%s,winnerDanLV=%s,cWinCount=%s" % (winnerDayScore, winnerScore, winnerDanLV, cWinCount))  | 
|     GameWorld.DebugLog("loserDayScore=%s,loserScore=%s,loserDanLV=%s" % (loserDayScore, loserScore, loserDanLV))  | 
|       | 
|     winIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", winnerDanLV)  | 
|     loseIpyData = IpyGameDataPY.GetIpyGameData("CrossRealmPKDan", loserDanLV)  | 
|     if not winIpyData or not loseIpyData:  | 
|         GameWorld.ErrLog("¿ç·þPK·¿¼ä¶ÎλÊý¾ÝÒì³£! roomID=%s,winnerDanLV=%s,loserDanLV=%s" % (roomID, winnerDanLV, loserDanLV))  | 
|           | 
|     baseScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKScore", 2) # Ê¤¸º±£µ×·Ö  | 
|     wBaseScore = baseScoreList[0] if len(baseScoreList) > 0 else 0  | 
|     lBaseScore = baseScoreList[1] if len(baseScoreList) > 1 else 0  | 
|     wExScore = eval(IpyGameDataPY.GetFuncCompileCfg("CrossRealmPKScore", 3)) # Ê¤·½¸½¼Ó·Ö  | 
|     lExScore = 0  | 
|       | 
|     winnerAddScore = wBaseScore + wExScore  | 
|     loserAddScore = lBaseScore + lExScore  | 
|       | 
|     dayMaxScore = IpyGameDataPY.GetFuncCfg("CrossRealmPKScore", 1) # Ã¿ÈÕ»ñµÃ»ý·ÖÉÏÏÞ£¬0Ϊ²»ÏÞÖÆ  | 
|     if dayMaxScore:  | 
|         if winnerAddScore > 0:  | 
|             winnerAddScore = min(dayMaxScore - winnerDayScore, winnerAddScore)  | 
|         if loserAddScore > 0:  | 
|             loserAddScore = min(dayMaxScore - loserDayScore, loserAddScore)  | 
|       | 
|     winner.pkScore += winnerAddScore  | 
|     loser.pkScore += loserAddScore  | 
|       | 
|     winner.cWinCount += 1  | 
|     loser.cWinCount = 0  | 
|       | 
|     if winIpyData and winIpyData.GetLVUpScore() and winner.pkScore >= winIpyData.GetLVUpScore():  | 
|         winner.danLV += 1  | 
|               | 
|     if loseIpyData and loseIpyData.GetLVUpScore() and loser.pkScore >= loseIpyData.GetLVUpScore():  | 
|         loser.danLV += 1  | 
|           | 
|     GameWorld.DebugLog("wBaseScore=%s,wExScore=%s,winnerAddScore=%s,updScore=%s,updDanLV=%s,updCWinCount=%s" % (wBaseScore, wExScore, winnerAddScore, winner.pkScore, winner.danLV, winner.cWinCount))  | 
|     GameWorld.DebugLog("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 = {}  | 
|     # Í¨Öª¿Í»§¶ËÕ½¶·½á¹û  | 
|     for playerID in [winnerID, loserID]:  | 
|         if playerID == winnerID:  | 
|             serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName = \  | 
|                 winner.serverGroupID, winner.pkScore, winner.danLV, winner.cWinCount, winnerAddScore, loser.playerID, loser.playerName  | 
|         else:  | 
|             serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName = \  | 
|                 loser.serverGroupID, loser.pkScore, loser.danLV, loser.cWinCount, loserAddScore, winner.playerID, winner.playerName  | 
|                   | 
|         player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|         notifyState = True if player else False  | 
|           | 
|         playerOverDict[playerID] = [roomID, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList] \  | 
|                                     + [serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]  | 
|         if not player:  | 
|             continue  | 
|           | 
|         overPack = ChPyNetSendPack.tagGCCrossRealmPKOverInfo()  | 
|         overPack.TimeStr = timeStr  | 
|         overPack.OverType = overType  | 
|         overPack.WinnerID = winnerID  | 
|         overPack.RoundWinnerID = roundWinnerIDList  | 
|         overPack.RoundCount = len(overPack.RoundWinnerID)  | 
|         overPack.AddScore = addScore  | 
|         overPack.Score = pkScore  | 
|         overPack.DanLV = danLV  | 
|         overPack.CWinCnt = cWinCount  | 
|         overPack.TagName = tagPlayerName  | 
|         overPack.TagNameLen = len(overPack.TagName)  | 
|         NetPackCommon.SendFakePack(player, overPack)  | 
|           | 
|         GameWorld.DebugLog("ͬ²½Íæ¼ÒPK½á¹û: serverGroupID=%s,roomID=%s,addScore=%s,pkScore=%s,danLV=%s,cWinCount=%s,tagPlayerID=%s"   | 
|                            % (serverGroupID, roomID, addScore, pkScore, danLV, cWinCount, tagPlayerID), playerID)  | 
|           | 
|     serverGroupIDList = [winner.serverGroupID, loser.serverGroupID]  | 
|     GameWorld.DebugLog("ͬ²½×Ó·þÕ½¶·½á¹û: seasonID=%s,timeStr=%s,roomID=%s,overType=%s,winnerID=%s,roundWinnerIDList=%s"   | 
|                        % (seasonID, timeStr, roomID, overType, winnerID, roundWinnerIDList))  | 
|     # Í¬²½×Ó·þ  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKOverInfo, playerOverDict, serverGroupIDList)  | 
|       | 
|     # ¼Ç¼Á÷Ïò  | 
|     dataDict = {"roundWinnerIDList":roundWinnerIDList, "overType":overType, "winner":winner.GetDRInfo(), "loser":loser.GetDRInfo()}  | 
|     dataDict.update(vsRoom.GetDRInfo())  | 
|     DR_CrossReamlPK("PKOverRoom", dataDict)  | 
|     return  | 
|   | 
| ##================================== ÒÔÏÂÊÇ×Ó·þÂß¼ ==========================================  | 
|   | 
| def OnGameServerInitOK():  | 
|       | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     dbZoneID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)  | 
|     dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)  | 
|     dbSeasonState = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)  | 
|     GameWorld.Log("OnGameServerInitOK dbZoneID=%s,dbSeasonID=%s,dbSeasonState=%s" % (dbZoneID, dbSeasonID, dbSeasonState))  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     zoneID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)  | 
|     if not zoneID:  | 
|         gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID, dbZoneID)  | 
|         gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID, dbSeasonID)  | 
|         gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState, dbSeasonState)  | 
|         GameWorld.Log("    ·þÎñÆ÷Æô¶¯È¡DBÖµÉèÖñ¾·þÈüÇøÈü¼¾ÐÅÏ¢: ")  | 
|           | 
|     return  | 
|   | 
| def OnMapServerInitOK():  | 
|     # Í¨ÖªµØÍ¼·þÎñÆ÷״̬  | 
|       | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     zoneID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)  | 
|     seasonID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)  | 
|     seasonState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)  | 
|     matchState = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK)  | 
|       | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID, zoneID)  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID, seasonID)  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState, seasonState)  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK, matchState)  | 
|     return  | 
|   | 
| def CrossServerMsg_PKSeasonInfo(seasonInfo):  | 
|     ## ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄÈü¼¾ÐÅÏ¢  | 
|     #seasonInfo = {"ZoneID":zoneID, "SeasonID":seasonID, "SeasonState":seasonState, "MatchState":matchState}  | 
|     GameWorld.Log("ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄÈü¼¾ÐÅÏ¢...")  | 
|     if not seasonInfo:  | 
|         return  | 
|     zoneID = seasonInfo.get("ZoneID", 0)  | 
|     seasonID = seasonInfo.get("SeasonID", 0)  | 
|     seasonState = seasonInfo.get("SeasonState", 0)  | 
|     matchState = seasonInfo.get("MatchState", 0)  | 
|     GameWorld.Log("    zoneID=%s,seasonID=%s,seasonState=%s,matchState=%s" % (zoneID, seasonID, seasonState, matchState))  | 
|     if not zoneID:  | 
|         return  | 
|     if not seasonID:  | 
|         dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)  | 
|         if dbSeasonID:  | 
|             GameWorld.ErrLog("    ÒѾÓзÖÅäÈü¼¾IDµÄÔݶ¨²»Äܱ»ÖÃΪ0! dbSeasonID=%s" % dbSeasonID)  | 
|             return  | 
|           | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     curSeasonState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)  | 
|       | 
|     gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID, zoneID)  | 
|     gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID, seasonID)  | 
|     gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState, seasonState)  | 
|     gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK, matchState)  | 
|       | 
|     # Ç¿ÖƸ²¸Ç´æDB  | 
|     dbZoneID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)  | 
|     dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)  | 
|     dbSeasonState = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)  | 
|     GameWorld.Log("    before dbZoneID=%s,dbSeasonID=%s,dbSeasonState=%s" % (dbZoneID, dbSeasonID, dbSeasonState))  | 
|       | 
|     PlayerDBGSEvent.SetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID, zoneID)  | 
|     PlayerDBGSEvent.SetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID, seasonID)  | 
|     PlayerDBGSEvent.SetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState, seasonState)  | 
|     dbZoneID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)  | 
|     dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID)  | 
|     dbSeasonState = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)  | 
|     GameWorld.Log("    update dbZoneID=%s,dbSeasonID=%s,dbSeasonState=%s" % (dbZoneID, dbSeasonID, dbSeasonState))  | 
|       | 
|     if curSeasonState == 1 and seasonState == 2:  | 
|         pass  | 
|         #PlayerControl.WorldNotify(0, "NotifySeasonOver")  | 
|           | 
|     # Í¨ÖªµØÍ¼·þÎñÆ÷״̬  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID, zoneID)  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID, seasonID)  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState, seasonState)  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.DailyActionID_CrossReamPK, matchState)  | 
|       | 
|     # ¹ã²¥Íæ¼ÒÈü¼¾Ïà¹Ø×´Ì¬±ä¸ü  | 
|     seasonStatePack = ChPyNetSendPack.tagGCCrossRealmPKSeasonState()  | 
|     seasonStatePack.ZoneID = zoneID  | 
|     seasonStatePack.SeasonID = seasonID  | 
|     seasonStatePack.SeasonState = seasonState  | 
|     seasonStatePack.MatchState = matchState  | 
|     seasonStatePack.CrossZoneName = GameWorld.GetCrossZoneName()  | 
|     seasonStatePack.CrossZoneNameLen = len(seasonStatePack.CrossZoneName)  | 
|     playerManager = GameWorld.GetPlayerManager()  | 
|     for i in xrange(playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(i)  | 
|         if curPlayer == None or not curPlayer.GetInitOK():  | 
|             continue  | 
|         NetPackCommon.SendFakePack(curPlayer, seasonStatePack)  | 
|     return  | 
|   | 
| def CrossServerMsg_PKMatchReqRet(retInfo):  | 
|     ## ¿ç·þPKÆ¥ÅäÇëÇó½á¹û  | 
|     playerID, result = retInfo  | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|     if not curPlayer:  | 
|         return  | 
|       | 
|     if result == -2:  | 
|         PlayerControl.NotifyCode(curPlayer, "CrossMatching17")  | 
|         return  | 
|       | 
|     if result == 1:  | 
|         SetIsCrossPKMatching(curPlayer, 1)  | 
|         NetPackCommon.SendFakePack(curPlayer, ChPyNetSendPack.tagGCCrossRealmPKStartMatch())  | 
|           | 
|     return  | 
|   | 
| ## ¿ç·þÆ¥Åä״̬  | 
| def SetIsCrossPKMatching(curPlayer, isMatching):  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_IsCrossPKMatching, isMatching)  | 
|     sysMsg = str(isMatching)  | 
|     curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossPKMatching", sysMsg, len(sysMsg))  | 
|     return  | 
| def GetIsCrossPKMatching(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_IsCrossPKMatching)  | 
|   | 
| def CrossServerMsg_PKMatchResult(vsRoomDict):  | 
|     ## ¿ç·þPKÆ¥Åä½á¹û  | 
|     curServerGroupID = GameWorld.GetServerGroupID()  | 
|     mapPosList = IpyGameDataPY.GetFuncEvalCfg("CrossRealmPKMatch", 5)  | 
|     GameWorld.DebugLog("=== ÊÕµ½PKÆ¥Åä½á¹û´¦Àí  === curServerGroupID=%s" % curServerGroupID)  | 
|     if not mapPosList:  | 
|         GameWorld.ErrLog("ûÓÐÅäÖöÔÕ½µØÍ¼½øÈë×ø±ê£¡")  | 
|         return  | 
|       | 
|     for roomID, roomInfo in vsRoomDict.items():  | 
|         mapID, playerList = roomInfo  | 
|         GameWorld.DebugLog("    roomID=%s,playerList=%s" % (roomID, playerList))  | 
|         for i, playerInfo in enumerate(playerList):  | 
|             serverGroupID, playerID = playerInfo  | 
|             if serverGroupID != curServerGroupID:  | 
|                 GameWorld.DebugLog("        ²»ÊDZ¾·þÍæ¼Ò£¬²»´¦Àí!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))  | 
|                 continue  | 
|             player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|             if not player:  | 
|                 GameWorld.DebugLog("        Íæ¼Ò²»ÔÚÏß, playerID=%s" % (playerID))  | 
|                 continue  | 
|             if PlayerControl.GetIsTJG(player):  | 
|                 GameWorld.DebugLog("        Íæ¼ÒÍÑ»úÖÐ, playerID=%s" % (playerID))  | 
|                 continue  | 
|             PlayerControl.SetVsRoomId(player, roomID, True)  | 
|             # Í¨ÖªµØÍ¼Íæ¼ÒÆ¥Åä³É¹¦, ÉÏ´«Êý¾Ý, ×¼±¸½øÈë¿ç·þ·þÎñÆ÷  | 
|             posX, posY = mapPosList[i] if len(mapPosList) > i else mapPosList[0]  | 
|             CrossRealmPlayer.SendCrossRealmReg(player, ChConfig.Def_FBMapID_CrossRealmPK, mapID, mapID, 0, posX, posY)  | 
|               | 
|     return  | 
|   | 
| def CrossServerMsg_PKReadyOKRoomList(readyOKRoomList):  | 
|     ## ×Ó·þ½ÓÊÕÍæ¼ÒÒÑ×¼±¸ºÃµÄPK·¿¼äÐÅÏ¢, ´Ë·¿¼äÀïµÄÍæ¼Ò¿É´«ËͽøÈë¿ç·þ  | 
|       | 
|     curServerGroupID = GameWorld.GetServerGroupID()  | 
|     GameWorld.DebugLog("===ÊÕµ½¿ç·þ·þÎñÆ÷֪ͨÒÑ×¼±¸ºÃµÄ¶ÔÕ½PK·¿¼äÐÅÏ¢´¦Àí=== curServerGroupID=%s" % curServerGroupID)  | 
|     # serverGroupID, playerName, playerJob  | 
|       | 
|     if not CrossRealmPlayer.IsCrossServerOpen():  | 
|         GameWorld.Log("¿ç·þ·þÎñÆ÷ά»¤ÖУ¬²»´¦Àí!")  | 
|         return  | 
|       | 
|     for roomID, readyMemberDict in readyOKRoomList:  | 
|         for playerID, playerInfo in readyMemberDict.items():  | 
|             serverGroupID = playerInfo["ServerGroupID"]  | 
|             playerName = playerInfo["Name"]  | 
|             number = playerInfo["Number"]  | 
|               | 
|             if serverGroupID != curServerGroupID:  | 
|                 GameWorld.DebugLog("    ²»ÊDZ¾·þÍæ¼Ò£¬²»´¦Àí!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))  | 
|                 continue  | 
|               | 
|             player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|             if not player:  | 
|                 GameWorld.DebugLog("    Íæ¼Ò²»ÔÚÏß , playerID=%s" % (playerID))  | 
|                 continue  | 
|             if PlayerControl.GetIsTJG(player):  | 
|                 GameWorld.DebugLog("    Íæ¼ÒÍÑ»úÖÐ, playerID=%s" % (playerID))  | 
|                 continue  | 
|             player.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 1)  | 
|               | 
|             matchPlayer = ChPyNetSendPack.tagGCCrossRealmPKMatchPlayer()  | 
|             for readyPlayerID, readyPlayerInfo in readyMemberDict.items():  | 
|                 if readyPlayerID != playerID:  | 
|                     matchPlayer.PlayerID = readyPlayerID  | 
|                     matchPlayer.PlayerName = readyPlayerInfo["Name"]  | 
|                     matchPlayer.NameLen = len(matchPlayer.PlayerName)  | 
|                     matchPlayer.Job = readyPlayerInfo["Job"]  | 
|                     matchPlayer.LV = readyPlayerInfo["LV"]  | 
|                     matchPlayer.MaxHP = readyPlayerInfo["MaxHP"]  | 
|                     matchPlayer.MaxProDef = readyPlayerInfo["MaxProDef"]  | 
|                     break  | 
|                   | 
|             PlayerControl.SetCrossMapID(player, ChConfig.Def_FBMapID_CrossRealmPK)  | 
|             SetIsCrossPKMatching(player, 0)  | 
|               | 
|             # Í¨ÖªÆ¥Åä³É¹¦£¬¿É½øÈë¿ç·þ  | 
|             matchOKPack = ChPyNetSendPack.tagGCCrossRealmPKMatchOK()  | 
|             matchOKPack.RoomID = roomID  | 
|             matchOKPack.PlayerName = playerName  | 
|             matchOKPack.NameLen = len(matchOKPack.PlayerName)  | 
|             matchOKPack.Number = number  | 
|             matchOKPack.MatchPlayer = [matchPlayer]  | 
|             matchOKPack.MatchPlayerCount = len(matchOKPack.MatchPlayer)  | 
|             NetPackCommon.SendFakePack(player, matchOKPack)  | 
|             GameWorld.DebugLog("    Í¨ÖªÍæ¼Ò½øÈë¿ç·þPK¶ÔÕ½·¿¼ä! roomID=%s,playerID=%s,matchPlayerID=%s" % (roomID, playerID, matchPlayer.PlayerID))  | 
|               | 
|     return  | 
|   | 
| def CrossServerMsg_PKTimeoutRoomList(timeoutRoomDict):  | 
|     ## ×Ó·þ½ÓÊÕÒѳ¬Ê±µÄPK·¿¼äÐÅÏ¢, ´Ë·¿¼äÀïµÄÍæ¼ÒÖØÖÿç·þ״̬  | 
|       | 
|     curServerGroupID = GameWorld.GetServerGroupID()  | 
|     GameWorld.DebugLog("===ÊÕµ½¿ç·þ·þÎñÆ÷֪ͨÒѳ¬Ê±µÄ¶ÔÕ½PK·¿¼äÐÅÏ¢´¦Àí=== curServerGroupID=%s" % curServerGroupID)  | 
|       | 
|     for roomID, roomPlayerInfo in timeoutRoomDict.items():  | 
|         if not roomPlayerInfo:  | 
|             continue  | 
|         serverGroupID, playerID = roomPlayerInfo  | 
|           | 
|         if serverGroupID != curServerGroupID:  | 
|             GameWorld.DebugLog("    ²»ÊDZ¾·þÍæ¼Ò£¬²»´¦Àí!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))  | 
|             continue  | 
|           | 
|         player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|         if not player:  | 
|             GameWorld.DebugLog("    Íæ¼Ò²»ÔÚÏß , playerID=%s" % (playerID))  | 
|             continue  | 
|         if PlayerControl.GetIsTJG(player):  | 
|             GameWorld.DebugLog("    Íæ¼ÒÍÑ»úÖÐ, playerID=%s" % (playerID))  | 
|             continue  | 
|         playerVSRoomID = player.GetVsRoomId()  | 
|         if playerVSRoomID and playerVSRoomID != roomID:  | 
|             GameWorld.DebugLog("    ·¿¼äID²»Í¬, playerID=%s" % (playerID))  | 
|             continue  | 
|         player.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 0)  | 
|         PlayerControl.SetCrossMapID(player, 0)  | 
|           | 
|     return  | 
|   | 
| #¿ç·þ¾º¼¼³¡Î´Í¨ÖªÍæ¼ÒµÄ±ÈÈü½á¹û£¬×¢Òâ¸ÃÀàÖ»´¦ÀíÊý¾ÝÂß¼£¬¹¦ÄÜÏà¹ØÂß¼²»ÒªÐ´ÔÚ¸ÃÀ࣬²»È»ÖضÁ½Å±¾²»»áÉúЧ  | 
| class CrossPKUnNotifyOverInfoManager(object):  | 
|       | 
|     def __init__(self):  | 
|         self.__unNotifyOverInfoDict = {} # {playerID:tagDBCrossPKUnNotifyOverInfo, ...}  | 
|         return  | 
|       | 
|     def AddUnNotifyOverInfo(self, playerID, overInfoData):  | 
|         self.__unNotifyOverInfoDict[playerID] = overInfoData  | 
|         return  | 
|       | 
|     def GetPlayerUnNotifyOverInfo(self, playerID): return self.__unNotifyOverInfoDict.pop(playerID, None)  | 
|       | 
|     # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  | 
|     def GetSaveData(self):  | 
|         savaData = ""  | 
|         cntData = ""  | 
|         cnt = 0  | 
|         for overInfoData in self.__unNotifyOverInfoDict.values():  | 
|             cnt += 1  | 
|             savaData += overInfoData.getBuffer()  | 
|                   | 
|         GameWorld.Log("SaveDBCrossPKUnNotifyOverInfo cnt :%s" % cnt)  | 
|         return CommFunc.WriteDWORD(cntData, cnt) + savaData  | 
|       | 
|     # ´ÓÊý¾Ý¿âÔØÈëÊý¾Ý  | 
|     def LoadPyGameData(self, datas, pos, dataslen):  | 
|         cnt, pos = CommFunc.ReadDWORD(datas, pos)  | 
|         GameWorld.Log("LoadDBCrossPKUnNotifyOverInfo cnt :%s" % cnt)  | 
|           | 
|         for _ in xrange(cnt):  | 
|             overInfoData = PyGameDataStruct.tagDBCrossPKUnNotifyOverInfo()  | 
|             overInfoData.clear()  | 
|             pos += overInfoData.readData(datas, pos, dataslen)  | 
|             self.__unNotifyOverInfoDict[overInfoData.PlayerID] = overInfoData  | 
|               | 
|         return pos  | 
|       | 
| def CrossServerMsg_PKOverInfo(playerOverDict):  | 
|     ## ×Ó·þ½ÓÊÕ¿ç·þPK½á¹ûÐÅÏ¢  | 
|       | 
|     curServerGroupID = GameWorld.GetServerGroupID()  | 
|     GameWorld.DebugLog("===ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄ¿ç·þPK½á¹û=== curServerGroupID=%s" % curServerGroupID)  | 
|       | 
|     for playerID, overInfo in playerOverDict.items():  | 
|         roomID, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, \  | 
|             serverGroupID, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState = overInfo  | 
|         if serverGroupID != curServerGroupID:  | 
|             GameWorld.DebugLog("    ²»ÊDZ¾·þÍæ¼Ò£¬²»´¦Àí!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID))  | 
|             continue  | 
|           | 
|         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.DebugLog("    Íæ¼Ò²»ÔÚÏß »òÍÑ»úÖУ¬ÏÈ»º´æ£¬Íæ¼ÒÉÏÏߺóÔÙͬ²½£¬playerID=%s" % (playerID))  | 
|             overInfoData = PyGameDataStruct.tagDBCrossPKUnNotifyOverInfo()  | 
|             overInfoData.clear()  | 
|             overInfoData.ZoneID = zoneID  | 
|             overInfoData.SeasonID = seasonID  | 
|             overInfoData.RoomID = roomID  | 
|             overInfoData.TimeStr = timeStr  | 
|             overInfoData.OverType = overType  | 
|             overInfoData.PlayerID = playerID  | 
|             overInfoData.WinnerID = winnerID  | 
|             overInfoData.RoundWinnerInfo = str(roundWinnerIDList)  | 
|             overInfoData.RoundWinnerLen = len(overInfoData.RoundWinnerInfo)  | 
|             overInfoData.PKScore = pkScore  | 
|             overInfoData.DanLV = danLV  | 
|             overInfoData.CWinCount = cWinCount  | 
|             overInfoData.AddScore = addScore  | 
|             overInfoData.TagPlayerID = tagPlayerID  | 
|             overInfoData.TagPlayerName = tagPlayerName  | 
|             PyDataManager.GetCrossPKUnNotifyOverInfoManager().AddUnNotifyOverInfo(playerID, overInfoData)  | 
|             continue  | 
|           | 
|         PlayerControl.SetVsRoomId(player, 0)  | 
|         sysMsg = str(sendMapOverInfo)  | 
|         player.MapServer_QueryPlayerResult(0, 0, "CrossPKOverInfo", sysMsg, len(sysMsg))  | 
|         GameWorld.DebugLog("֪ͨµØÍ¼¿ç·þ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):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     overInfoData = PyDataManager.GetCrossPKUnNotifyOverInfoManager().GetPlayerUnNotifyOverInfo(playerID)  | 
|     if not overInfoData:  | 
|         return  | 
|     PlayerControl.SetCrossMapID(curPlayer, 0)  | 
|     PlayerControl.SetVsRoomId(curPlayer, 0)  | 
|       | 
|     zoneID = overInfoData.ZoneID  | 
|     seasonID = overInfoData.SeasonID  | 
|     roomID = overInfoData.RoomID  | 
|     timeStr = overInfoData.TimeStr  | 
|     overType = overInfoData.OverType  | 
|     #playerID = overInfoData.PlayerID  | 
|     winnerID = overInfoData.WinnerID  | 
|     roundWinnerIDList = []  | 
|     try:  | 
|         roundWinnerIDList = eval(overInfoData.RoundWinnerInfo)  | 
|     except:  | 
|         GameWorld.ErrLog("__OnLoginNotifyPKOverInfo roundWinnerIDList eval error! RoundWinnerInfo=%s" % overInfoData.RoundWinnerInfo, playerID)  | 
|     pkScore = overInfoData.PKScore  | 
|     danLV = overInfoData.DanLV  | 
|     cWinCount = overInfoData.CWinCount  | 
|     addScore = overInfoData.AddScore  | 
|     tagPlayerID = overInfoData.TagPlayerID  | 
|     tagPlayerName = overInfoData.TagPlayerName  | 
|     notifyState = 0 # µÇ¼²Å֪ͨµÄĬÈÏδ֪ͨ  | 
|     sendMapOverInfo = [roomID, zoneID, seasonID, timeStr, overType, winnerID, roundWinnerIDList, pkScore, danLV, cWinCount, addScore, tagPlayerID, tagPlayerName, notifyState]  | 
|     sysMsg = str(sendMapOverInfo)  | 
|     curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossPKOverInfo", sysMsg, len(sysMsg))  | 
|     GameWorld.DebugLog("Íæ¼ÒÉÏÏß֪ͨµØÍ¼Î´½áËãµÄ¿ç·þ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, curPlayer.GetMapID()), playerID)  | 
|     return  | 
|   | 
| def DR_CrossReamlPK(eventName, dataDict={}):  | 
|     drDataDict = {}  | 
|     drDataDict.update(dataDict)  | 
|     DataRecordPack.SendEventPack("CrossPK_%s" % eventName, drDataDict)  | 
|     return  | 
|   |