| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldMergePK  | 
| #  | 
| # @todo:¿ç·þPK  | 
| # @author hxp  | 
| # @date 2015-10-22  | 
| # @version 1.7  | 
| #  | 
| # @change: "2015-11-05 18:00" hxp Ôö¼ÓÁ¬Ê¤¹ã²¥£»¹ºÂò»Ö¸´Á¬Ê¤£»¶ÔÊÖÐÅϢͬ²½; Ôö¼ÓÿÈÕ»ý·Ö½±Àø  | 
| # @change: "2015-11-19 15:00" hxp Ôö¼ÓÍõÕßÕù°Ô; ÐÞ¸´Å¼·¢Öظ´¼ÓÈëµÈ´ýÆ¥Åä¶ÓÁе¼ÖÂÆ¥Å䱨´íÎÊÌâ  | 
| # @change: "2015-12-04 16:00" hxp ÐÞ¸´·ÇÆ¥Åäʱ¼ä¶ÎÄÚ»Ö¸´Á¬Ê¤µ¼Öµ±Èջ½áÊøºóÎÞ·¨·¢·ÅÆ¥Åä½áËã½±Àøbug  | 
| # @change: "2015-12-22 17:00" hxp Ôö¼ÓÐøÊ¤³É¹¦Í¨Öª  | 
| # @change: "2015-12-28 17:00" hxp Õ½¶·½á¹û¸ÄΪGameServer֪ͨ¿Í»§¶Ë; ÓÅ»¯È¡ÏûÆ¥ÅäÂß¼  | 
| # @change: "2016-01-11 16:00" hxp Õ½¶·½á¹ûδͬ²½µÄÖ±½Óͬ²½µ½×Ó·þ£¬ÓÉ×Ó·þͬ²½¸øÍæ¼Ò  | 
| # @change: "2016-12-20 17:30" hxp Ð°æ¿ç·þPKÈüÐ޸ģ¬ÒÔplayerIDΪΨһkeyµÄģʽ  | 
| # ÏêϸÃèÊö: ¿ç·þPKÆ¥Åä  | 
| #  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2016-12-20 17:30"""  | 
| #---------------------------------------------------------------------  | 
| import GameWorld  | 
| import PlayerControl  | 
| import MergeChildMsg  | 
| import MergeBroadcast  | 
| import PlayerCompensation  | 
| import PlayerMergeRegister  | 
| import PlayerUniversalGameRec  | 
| #import GameWorldMergeKing  | 
| import ChPyNetSendPack  | 
| import PlayerBillboard  | 
| import PlayerDBGSEvent  | 
| import DataRecordPack  | 
| import NetPackCommon  | 
| import ReadChConfig  | 
| import ShareDefine  | 
| import ChConfig  | 
|   | 
| import operator  | 
| import random  | 
| import copy  | 
| import time  | 
|   | 
| Def_RoomMemberCnt = 2 # Ã¿¸ö·¿¼ä¶ÔÕ½Íæ¼ÒÊý  | 
|   | 
| g_matchPlayerDict = {} # µÈ´ýÆ¥ÅäÍæ¼Ò×Öµä{playerID:matchPlayerObj, ...}  | 
| g_matchPlayerList = [] # µÈ´ýÆ¥ÅäÍæ¼Ò¶ÓÁÐ[matchPlayerObj, ...]  | 
| g_preparePlayerDict = {} # Æ¥ÅäºÃºó×¼±¸Íæ¼Ò×Öµä{playerID:preparePlayerObj, ...}  | 
| g_prepareRoomDict = {} # Íæ¼Ò×¼±¸Öеķ¿¼ä×Öµä{roomID:[preparePlayerObjA,preparePlayerObjB], ...}  | 
| g_roomMemberExtendInfoDict = {} # ·¿¼äÍæ¼ÒÀ©Õ¹ÐÅÏ¢ {playerID:PlayerExtendInfoObj, ...}   | 
| g_playerEquipViewDict = {} # ²ÎÈüÍæ¼Ò×°±¸Ô¤ÀÀÐÅÏ¢ {playerID:[equipeId, equipPlace, startLV, elemLv], ...}  | 
|   | 
| g_recoverMergePKWinPlayerIDList = [] # ÇëÇó»Ö¸´PKÁ¬Ê¤µÄÍæ¼ÒIDÁÐ±í  | 
|   | 
| #g_unNotifyPKOverDict = {} # Î´Í¨ÖªµÄPK½á¹û{accID:[½á¹ûÐÅÏ¢,...], ...}  | 
|   | 
| Def_MergePKAwardRecordType = ShareDefine.Def_UniversalGameRecType_MergePKAwardRecord  | 
| Def_MergePKTopPlayerEquipRecordType = ShareDefine.Def_UniversalGameRecType_MergePKTopPlayerEquip  | 
| Def_MergePKUnNotifyOverRecordType = ShareDefine.Def_UniversalGameRecType_MergePKUnNotifyOver  | 
|   | 
| Def_TopPlayerViewTypeList = (  | 
| Def_TopPlayerView_Yesterday, # ×òÈÕ¸ßÊÖ°ñ  | 
| Def_TopPlayerView_Week, # ½ØÖ¹µ½×òÈÕ£¬±¾ÖܸßÊÖ°ñ  | 
| Def_TopPlayerView_LastWeek, # ÉÏÒ»ÖܸßÊÖ°ñ  | 
| ) = range(3)  | 
|   | 
| (  | 
| Def_Match_ProcessTick, # Æ¥Åä´¦ÀíÆµÂÊ, ºÁÃë  | 
| Def_Match_MaxGroupCnt, # Ã¿´Î´¦Àí×î´óÆ¥Åä¶ÔÕ½×éÊý  | 
| Def_Match_OutTimeTick, # ×µÈ´ýÆ¥Åäʱ¼ä, ºÁÃë, ¼´µÈ´ýÆ¥Å䳬¹ý¸Ãʱ¼äºóÓÅÏȰïÍæ¼ÒÆ¥Åä  | 
| Def_Match_StepScoreList, # »ý·ÖÆ¥Åä¶ÎÁÐ±í  | 
| Def_Match_MapIDList, # ¶ÔÕ½µØÍ¼ÁÐ±í  | 
| Def_Match_SyncBillboardTick, # Í¬²½¶ÔÕ½»ý·Ö°ñµ¥µ½×Ó·þµÄƵÂÊ  | 
| ) = range(6)  | 
|   | 
| ## Íæ¼ÒÀëÏß´¦Àí  | 
| def OnLeaveServer(curPlayer):      | 
|     # ·¢ËÍÈ¡ÏûÆ¥Åä  | 
|     SendCancelMergePKMatch(curPlayer, "PlayerDisconnect")  | 
|     return  | 
|   | 
| #Def_BT_MergePKDay,                        #¿ç·þPKÿÈÕ»ý·Ö°ñ91  | 
| #Def_BT_MergePKWeek,                       #¿ç·þPKÈü¼¾»ý·Ö°ñ92    | 
|   | 
| #################################ÅÅÐаñ##########################################  | 
| #ĿǰÒÑÈ·±£playerIDËùÓÐÆ½Ì¨Î¨Ò»ÐÔ£¬¹Ê¿ÉÖ±½ÓÓÃplayID×÷ΪΨһ±êʶ  | 
| #ÓÉÓÚÌÚѶƽ̨Õ˺Źý³¤ÖÁÉÙÊÇ43£¬¹ÊÔname2´æ´¢Õ˺ÅÒѲ»ÊÊÓã¬È¥³ý¸ÃÉ趨 331bab61500d491151d0e198f6f300fa@tencent@s7  | 
| #def SetType(self, *args): ÅÅÐаñindex BYTE  | 
| #def SetID(self, *args): ¿ç·þplayerID/×Ó·þplayerID Ä¿Ç°ÒÑÈ·±£Î¨Ò»  | 
| #def SetID2(self, *args):  µ±Ç°¶Îλ*100 + ÀúÊ·×î¸ß¶Îλ  | 
| #def SetName1(self, *args): Íæ¼ÒÃû  | 
| #def SetName2(self, *args): ÔÝÎÞ  | 
| #def SetType2(self, *args): Ö°Òµ  BYTE  | 
| #def SetValue1(self, *args): Õ½¶·Á¦  | 
| #def SetValue2(self, *args): ÔÝÎÞ  | 
| #def SetCmpValue(self, *args): ×Ü»ý·Ö   | 
| #def SetCmpValue2(self, *args): ÀÛ¼ÆÊ¤Àû³¡´Î * 100000 + ÀÛ¼ÆPK³¡´Î, µ¥Èü¼¾×î¸ßÖ§³Ö³¡´Î20000  | 
| #def SetCmpValue3(self, *args): µ±Ç°Á¬Ê¤³¡´Î * 100000 + ×î´óÁ¬Ê¤³¡´Î, µ¥Èü¼¾×î¸ßÖ§³Ö³¡´Î20000  | 
| def GetBBPlayerAccID(bbData): return bbData.GetName2() # Íæ¼ÒÕ˺Š | 
| def GetBBMergePlayerID(bbData): return bbData.GetID() # ¿ç·þplayerID  | 
|   | 
| def GetBBPlayerID(bbData): return bbData.GetID() # playerID  | 
| def SetBBPlayerID(bbData, playerID): return bbData.SetID(playerID) # playerID  | 
| # ¶Îλ: °Ùλǧλ´æµ±Ç°¶Îλ£» ¸öλʮλ´æÀúÊ·×î¸ß¶Îλ  | 
| def GetBBPlayerGrade(bbData): return bbData.GetID2() / 100 # µ±Ç°¶Îλ  | 
| def GetBBPlayerMaxGrade(bbData): return bbData.GetID2() % 100 # ÀúÊ·×î¸ß¶Îλ  | 
| def SetBBPlayerGrade(bbData, grade):  | 
|     maxGrade = max(GetBBPlayerMaxGrade(bbData), grade)  | 
|     return bbData.SetID2(grade * 100 + maxGrade)  | 
| def GetBBPlayerName(bbData): return bbData.GetName1() # Íæ¼ÒÃû  | 
| def SetBBPlayerName(bbData, name): return bbData.SetName1(name) # Íæ¼ÒÃû  | 
| def GetBBPlayerJob(bbData): return bbData.GetType2() # Ö°Òµ  | 
| def SetBBPlayerJob(bbData, job): return bbData.SetType2(job) # Ö°Òµ  | 
| def GetBBFightPower(bbData): return bbData.GetValue1() # Íæ¼ÒÕ½¶·Á¦  | 
| def SetBBFightPower(bbData, fightPower): return bbData.SetValue1(fightPower) # Íæ¼ÒÕ½¶·Á¦  | 
| def GetBBMergePKScore(bbData): return bbData.GetCmpValue() # ×Ü»ý·Ö  | 
| def SetBBMergePKScore(bbData, score): # ×Ü»ý·Ö  | 
|     bbData.SetCmpValue(score)  | 
|     # »ý·Ö±ä¸üͬ²½¸üжÎλ  | 
|     matchCfg = ReadChConfig.GetEvalChConfig("MergePK_Match")  | 
|     for grade, sScore in enumerate(matchCfg[Def_Match_StepScoreList]):  | 
|         if score <= sScore:  | 
|             SetBBPlayerGrade(bbData, grade)  | 
|             return  | 
|     # ÕÒ²»µ½Ä¬ÈÏÈ¡×îºóÒ»¸ö¶Îλ  | 
|     maxGrade = max(0, len(matchCfg[Def_Match_StepScoreList]) - 1)  | 
|     SetBBPlayerGrade(bbData, maxGrade)  | 
|     GameWorld.ErrLog("¿ç·þPKÕÒ²»µ½·ÖÖµ¶ÔÓ¦¶Îλ, Ä¬ÈÏÉèÖÃΪ×î´ó¶Îλ!score=%s,maxGrade=%s" % (score, maxGrade))  | 
|     return  | 
| PKCnt_CalcValue = 100000 # PK´ÎÊý×éºÏ´æ´¢¼ÆËã²Î¿¼Öµ  | 
| PKCnt_MaxValue = 20000 # µ¥Èü¼¾¿É´æ´¢×î´óPK³¡´Î  | 
| # CmpValue2 ÀÛ¼ÆÊ¤Àû³¡´Î * PKCnt_CalcValue + ÀÛ¼ÆPK³¡´Î  | 
| def GetBBMergePKWinCnt(bbData): return bbData.GetCmpValue2() / PKCnt_CalcValue # ÀÛ¼ÆÊ¤Àû³¡´Î  | 
| def SetBBMergePKWinCnt(bbData, totalWinCnt):  | 
|     totalWinCnt = min(PKCnt_MaxValue, totalWinCnt)  | 
|     return bbData.SetCmpValue2(totalWinCnt * PKCnt_CalcValue + GetBBMergePKCnt(bbData)) # ÀÛ¼ÆÊ¤Àû³¡´Î  | 
| def GetBBMergePKCnt(bbData): return bbData.GetCmpValue2() % PKCnt_CalcValue # ÀÛ¼ÆPK³¡´Î  | 
| def SetBBMergePKCnt(bbData, pkCnt):  | 
|     pkCnt = min(PKCnt_MaxValue, pkCnt)  | 
|     return bbData.SetCmpValue2(GetBBMergePKWinCnt(bbData) * PKCnt_CalcValue + pkCnt) # ÀÛ¼ÆPK³¡´Î  | 
|   | 
| # CmpValue3 µ±Ç°Á¬Ê¤³¡´Î * 100000 + ×î´óÁ¬Ê¤³¡´Î, µ¥Èü¼¾×î¸ßÖ§³Ö³¡´Î20000  | 
| def GetBBMergePKCWinCnt(bbData): return bbData.GetCmpValue3() / PKCnt_CalcValue # µ±Ç°Á¬Ê¤³¡´Î  | 
| def SetBBMergePKCWinCnt(bbData, cWinCnt):  | 
|     cWinCnt = min(PKCnt_MaxValue, cWinCnt)  | 
|     return bbData.SetCmpValue3(cWinCnt * PKCnt_CalcValue + GetBBMergePKMaxCWinCnt(bbData)) # µ±Ç°Á¬Ê¤³¡´Î  | 
| def GetBBMergePKMaxCWinCnt(bbData): return bbData.GetCmpValue3() % PKCnt_CalcValue # ×î´óÁ¬Ê¤³¡´Î  | 
| def SetBBMergePKMaxCWinCnt(bbData, maxCWinCnt):  | 
|     maxCWinCnt = min(PKCnt_MaxValue, maxCWinCnt)  | 
|     return bbData.SetCmpValue3(GetBBMergePKCWinCnt(bbData) * PKCnt_CalcValue + maxCWinCnt) # ×î´óÁ¬Ê¤³¡´Î  | 
|   | 
| def GetMatchPlayerBillboardData(billboardIndex, playerID, isAdd=False):  | 
|     ''''  | 
|     ¸ù¾ÝÕ˺ŻñÈ¡¶ÔÕ½Íæ¼ÒÊý¾ÝÐÅÏ¢  | 
|     @param billboardIndex: ÅÅÐаñË÷Òý  | 
|     @param playerID: Íæ¼ÒID,  | 
|     @param isAdd: ÕÒ²»µ½Êý¾ÝʱÊÇ·ñÌí¼ÓÐÂÊý¾Ý  | 
|     @return: [billBoard, bbData]  | 
|     '''  | 
|       | 
|     billBoard = GameWorld.GetBillboard().FindBillboard(billboardIndex)  | 
|     if not billBoard:  | 
|         return [billBoard, None]  | 
|       | 
|     bbData = billBoard.FindByID(playerID)  | 
|     if bbData != None:  | 
|         return [billBoard, bbData]  | 
|       | 
| #    for index in xrange(billBoard.GetCount()):  | 
| #          | 
| #        bbData = billBoard.At(index)  | 
| #        if not bbData:  | 
| #            continue  | 
| #          | 
| #        if GetBBPlayerID(bbData) == playerID:  | 
| #            return [billBoard, bbData]  | 
|           | 
|     if billBoard.IsFull():  | 
|         GameWorld.ErrLog("¿ç·þPK»ý·Ö°ñµ¥ÒÑÂú£¡billboardIndex=%s" % billboardIndex)  | 
|         return [billBoard, None]  | 
|       | 
|     if not isAdd:  | 
|         return [billBoard, None]  | 
|       | 
|     #²åÈëÒ»ÌõÊý¾Ý  | 
|     bbData = billBoard.AddToBillboard(playerID)  | 
|     bbData.SetType(billboardIndex)  | 
|     return [billBoard, bbData]  | 
|   | 
| def __SyncBillboardToClientServer(isForce, tick, isStateChange=False):  | 
|       | 
|     actionState = int(IsMergePKMatchOpen())  | 
|     processTickKey = "PKMatchSyncBBToClientServer"  | 
|     if not isForce:  | 
|         matchCfg = ReadChConfig.GetEvalChConfig("MergePK_Match")  | 
|         processTick = matchCfg[Def_Match_SyncBillboardTick]  | 
|           | 
|         lastProcessTick = GameWorld.GetGameWorld().GetDictByKey(processTickKey)  | 
|         if tick - lastProcessTick < processTick:  | 
|             return  | 
|     GameWorld.GetGameWorld().SetDict(processTickKey, tick)  | 
|       | 
|     GameWorld.Log("¿ªÊ¼Í¬²½¿ç·þ»ý·Ö°ñµ¥µ½×Ó·þÎñÆ÷¡£¡£¡£isForce=%s,actionState=%s,isStateChange=%s" % (isForce, actionState, isStateChange))  | 
|     for bbType in [ShareDefine.Def_BT_MergePKDay, ShareDefine.Def_BT_MergePKWeek]:  | 
|         billBoard = GameWorld.GetBillboard().FindBillboard(bbType)  | 
|         if not billBoard:  | 
|             continue  | 
|           | 
|         bbDataList = []  | 
|         # Èç¹ûÊÇÖܰñ£¬ÏȽøÐÐÒ»´ÎÅÅÐò, ÈÕ°ñÔÚ½á¹û¸üÐÂʱÒÑÅÅÐò  | 
|         if bbType == ShareDefine.Def_BT_MergePKWeek:  | 
|             billBoard.Sort()  | 
|               | 
|         for index in xrange(billBoard.GetCount()):  | 
|             bbData = billBoard.At(index)  | 
|             #playerID, id2, name1, name2, type2, value1, value2, cmpValue, cmpValue2, cmpValue3  | 
|             bbDataList.append([bbData.GetID(), bbData.GetID2(), bbData.GetName1(), bbData.GetName2(),  | 
|                                bbData.GetType2(), bbData.GetValue1(), bbData.GetValue2(),  | 
|                                bbData.GetCmpValue(), bbData.GetCmpValue2(), bbData.GetCmpValue3()])  | 
|               | 
|         syncList = [isStateChange, actionState, bbType, bbDataList]  | 
|         GameWorld.Log("    Í¬²½¿ç·þPK»ý·Ö°ñµ¥µ½×Ó·þÎñÆ÷: isStateChange=%s,actionState=%s,bbType=%s,bbDataListLen=%s,dataStrLen=%s"   | 
|                       % (isStateChange, actionState, bbType, len(bbDataList), len(str(bbDataList))))  | 
|         MergeBroadcast.SendBroadcastMerge(ChConfig.Def_MergePKSyncBillboard, 0, syncList, False)  | 
|     return  | 
|   | 
| ################################################################################  | 
|   | 
| class PlayerExtendInfo():  | 
|     ## ¶ÔÕ½·¿¼äÍæ¼ÒÀ©Õ¹ÐÅÏ¢  | 
|       | 
|     def __init__(self):  | 
|         self.accID = ""  | 
|         self.playerID = 0  | 
|         self.playerName = ""  | 
|         self.fightPower = 0  | 
|         self.playerLV = 0  | 
|         self.maxHP = 0  | 
|         return  | 
|       | 
| class MatchPlayer():  | 
|     ## Æ¥ÅäÍæ¼ÒÀà  | 
|       | 
|     ## ¹¹Ô캯Êý  | 
|     def __init__(self, accID, playerID, playerName, pkScore, fightPower, tick):  | 
|         self.accID = accID  | 
|         self.playerID = playerID  | 
|         self.playerName = playerName  | 
|         self.pkScore = pkScore  | 
|         self.fightPower = fightPower  | 
|         self.matchTick = tick  | 
|         return  | 
|   | 
| def OnMapServerInitOK():  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|       | 
|     # PK״̬  | 
|     pkStateKey = ShareDefine.Def_Notify_WorldKey_MergePKState  | 
|     GameWorld.SendMapServerMsgEx(pkStateKey, gameWorld.GetDictByKey(pkStateKey))  | 
|       | 
|     for idKey in [ShareDefine.Def_Notify_WorldKey_MergePKDayID, ShareDefine.Def_Notify_WorldKey_MergePKSeasonID,   | 
|                   ShareDefine.Def_Notify_WorldKey_MergePKSeasonStartTime]:  | 
|           | 
|         actionID = gameWorld.GetDictByKey(idKey)  | 
|         # Èç¹ûûÓÐÖµ£¬ÔòÈ¡DB¼Ç¼ÖеÄÖµ  | 
|         if actionID <= 0:  | 
|             actionID = PlayerDBGSEvent.GetDBGSTrig_ByKey(idKey)  | 
|             gameWorld.SetDict(idKey, actionID)  | 
|               | 
|         GameWorld.SendMapServerMsgEx(idKey, actionID)  | 
|     return  | 
|   | 
| def OnMergePKMatchStateChange(state):  | 
|     ''' ¿ç·þPKÈü״̬±ä¸ü´¦Àí£¬ ½ö¿ç·þÖ÷·þÎñÆ÷ÓÐЧ£¬ ´¦Àí״̬ͬ²½¸ø×Ó·þÎñÆ÷½øÐÐÏàÓ¦µÄ´¦Àí '''  | 
|     global g_matchPlayerDict  | 
|     global g_matchPlayerList  | 
|     global g_preparePlayerDict  | 
|     global g_prepareRoomDict  | 
|   | 
|     if not GameWorld.IsMergeServer():  | 
|         return  | 
|     # Ã¿¸öÈü¼¾ÖÜÆÚ, ±ØÐëΪһ¸öÐÇÆÚ7ÌìµÄÕû±¶Êý, Èç7, 14, 21, 28µÈ  | 
|     seasonCycle = ReadChConfig.GetEvalChConfig("MergePK_Season") # Èü¼¾ÅäÖà  | 
|       | 
|     if seasonCycle % 7 != 0:  | 
|         GameWorld.ErrLog("¿ç·þPKÈü¼¾Ñ»·ÖÜÆÚÅäÖôíÎó, ±ØÐëΪ7µÄ±¶Êý! seasonCycle=%s" % seasonCycle)  | 
|         return  | 
|       | 
|     dayIDKey = ShareDefine.Def_Notify_WorldKey_MergePKDayID  | 
|     seasonIDKey = ShareDefine.Def_Notify_WorldKey_MergePKSeasonID  | 
|     seasonStartTimeKey = ShareDefine.Def_Notify_WorldKey_MergePKSeasonStartTime  | 
|     isSeasonEndKey = ShareDefine.Def_Notify_WorldKey_IsSeasonEnd  | 
|       | 
|     dbDayID = PlayerDBGSEvent.GetDBGSTrig_ByKey(dayIDKey)  | 
|     dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(seasonIDKey)  | 
|     dbStartTime = PlayerDBGSEvent.GetDBGSTrig_ByKey(seasonStartTimeKey)  | 
|     dbIsSeasonEnd = PlayerDBGSEvent.GetDBGSTrig_ByKey(isSeasonEndKey)  | 
|     if state == ChConfig.Def_Action_Close and dbSeasonID == 0:  | 
|         # Î´¿ªÆô¹ýÈü¼¾µÄ£¬¸ÕºÃÊÇʱ¼ä½áÊø£¬Ö±½Ó·µ»Ø£¬µ±×öû¿ª¹ý  | 
|         return  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|       | 
|     # Çå¿ÕÆ¥Åä¶ÓÁÐ  | 
|     g_matchPlayerDict = {}  | 
|     g_matchPlayerList = []  | 
|     g_preparePlayerDict = {}  | 
|     g_prepareRoomDict = {}  | 
|     GameWorld.GetVSRoomManager().DeleteAllVsRooms()  | 
|       | 
|     # ÊÇ·ñ¿ªÆôÐÂÈü¼¾, ÊÇ·ñ¿ªÆôÈÕÈü, ÊÇ·ñ½áÊøÈü¼¾  | 
|     #isSeasonStart, isDayStart, isSeasonEnd = False, False, False  | 
|     isSeasonEnd = dbIsSeasonEnd  | 
|     dayTime = GameWorld.GetServerTime()  | 
|     weekDay = dayTime.weekday()  | 
|     curTime = int(time.time())  | 
|     curDateStr = GameWorld.ChangeTimeNumToStr(curTime, ChConfig.TYPE_Time_YmdFormat) # µ±ÌìÈÕÆÚ  | 
|     dbStartDateStr = GameWorld.ChangeTimeNumToStr(dbStartTime, ChConfig.TYPE_Time_YmdFormat) # db¼Ç¼µÄÈü¼¾¿ªÆôÈÕÆÚ  | 
|     endTime = dbStartTime + seasonCycle * 24 * 3600 # ÕæÊµÈü¼¾½áÊøÊ±¼ä£¬½øÈëÏÂÒ»Èü¼¾µÄÁÙ½çµã  | 
|     endDateStr = GameWorld.ChangeTimeNumToStr(endTime, ChConfig.TYPE_Time_YmdFormat) # Èü¼¾½áËãÈÕÆÚ£¬½øÈëÏÂÒ»Èü¼¾µÄ½áËãÈÕ  | 
|       | 
|     # ¿ªÆô´¦Àí  | 
|     if state == ChConfig.Def_Action_Open:  | 
|         # Î´¿ªÆô¹ý or Ã¿ÖÜÒ» ¿ªÆôÐÂÈü¼¾ £¨Ðè·ÀÖ¹ÖÜÒ»ÖØ¸´¿ª·þÎñÆ÷µ¼ÖÂÖØ¸´¿ªÈü¼¾ÎÊÌ⣩  | 
|         if dbSeasonID == 0 or curDateStr >= endDateStr:  | 
|             dbSeasonID += 1  | 
|             newSeasonStartTime = curTime - weekDay * 24 * 3600 # É趨Ϊ±¾ÖÜÒ»¿ªÆôµÄ  | 
|             newSeasonStartDateStr = GameWorld.ChangeTimeNumToStr(newSeasonStartTime, ChConfig.TYPE_Time_YmdFormat)  | 
|             dbStartTime = newSeasonStartTime  | 
|             __SetMergePKActionKeyValue(gameWorld, seasonIDKey, dbSeasonID)  | 
|             __SetMergePKActionKeyValue(gameWorld, seasonStartTimeKey, newSeasonStartTime)  | 
|             PlayerBillboard.ClearBillboardByIndex(ShareDefine.Def_BT_MergePKWeek) # ÖØÖÃÈü¼¾°ñµ¥  | 
|             #isSeasonStart = True  | 
|             GameWorld.Log("¿ç·þPKÐÂÈü¼¾¿ªÆô: newSeasonID=%s,newSeasonStartTime=%s(%s),curTime=%s(%s),oldSesonEndTime=%s(%s)"   | 
|                           % (dbSeasonID, newSeasonStartTime, newSeasonStartDateStr, curTime, curDateStr, endTime, endDateStr))  | 
|         else:  | 
|             GameWorld.Log("¿ç·þPK±¾Èü¼¾ÒѾ¿ªÆôÁË: seasonID=%s,seasonStartTime=%s(%s),curTime=%s(%s),endTime=%s(%s)"   | 
|                           % (dbSeasonID, dbStartTime, dbStartDateStr, curTime, curDateStr, endTime, endDateStr))  | 
|               | 
|         dayID = GameWorld.ChangeTimeStrToNum("%s 00:00:00" % curDateStr, ChConfig.TYPE_Time_Format)  | 
|         curDayIDDateStr = GameWorld.ChangeTimeNumToStr(dayID, ChConfig.TYPE_Time_Format)  | 
|         dbDayIDDateStr = GameWorld.ChangeTimeNumToStr(dbDayID, ChConfig.TYPE_Time_Format)  | 
|         # ÈÕ°ñÖØÖÃ  | 
|         if dbSeasonID > 0 and dayID != dbDayID:  | 
|             PlayerBillboard.ClearBillboardByIndex(ShareDefine.Def_BT_MergePKDay)  | 
|             __SetMergePKActionKeyValue(gameWorld, dayIDKey, dayID)  | 
|             GameWorld.Log("¿ç·þPKÐÂÈÕÈü¿ªÆô: seasonID=%s,dbDayID=%s(%s),curDayID=%s(%s)"   | 
|                           % (dbSeasonID, dbDayID, dbDayIDDateStr, dayID, curDayIDDateStr))  | 
|             dbDayID = dayID  | 
|             #isDayStart = True  | 
|         else:  | 
|             GameWorld.Log("¿ç·þPK±¾ÈÕÈüÒѾ¿ªÆôÁË: seasonID=%s,dbDayID=%s(%s),curDayID=%s(%s)"   | 
|                           % (dbSeasonID, dbDayID, dbDayIDDateStr, dayID, curDayIDDateStr))  | 
|               | 
|         isSeasonEnd = 0 # Ö»Òª»î¶¯ÓпªÆô, ´ú±íÈü¼¾·Ç½áÊø×´Ì¬        | 
|                | 
|     # ¹Ø±Õ´¦Àí  | 
|     elif state == ChConfig.Def_Action_Close:  | 
|         setSeasonEndTime = dbStartTime + (seasonCycle - 1) * 24 * 3600 # ÉèÖÃÈü¼¾½áÊøÊ±¼ä£¬Ò»°ãÎªÕæÊµ½áÊøÊ±¼äµÄǰһÌì  | 
|         setSeasonEndDateStr = GameWorld.ChangeTimeNumToStr(setSeasonEndTime, ChConfig.TYPE_Time_YmdFormat) # ÉèÖÃÈü¼¾½áÊøÈÕÆÚ  | 
|         isSeasonEndDate = curDateStr >= setSeasonEndDateStr  | 
|         if isSeasonEndDate:  | 
|             isSeasonEnd = 1  | 
|             GameWorld.Log("¿ç·þPKÈü¼¾½áÊø: seasonID=%s,startTime=%s(%s),endTime=%s(%s),setSeasonEndDateStr=%s(%s),curTime=%s(%s)"   | 
|                           % (dbSeasonID, dbStartTime, dbStartDateStr, endTime, endDateStr,   | 
|                              setSeasonEndTime, setSeasonEndDateStr, curTime, curDateStr))  | 
|         else:  | 
|             GameWorld.Log("¿ç·þPKÈü¼¾Î´½áÊø, ½ö¹Ø±Õµ±ÈÕPK״̬!: seasonID=%s,startTime=%s(%s),endTime=%s(%s),setSeasonEndDateStr=%s(%s),curTime=%s(%s)"   | 
|                           % (dbSeasonID, dbStartTime, dbStartDateStr, endTime, endDateStr,   | 
|                              setSeasonEndTime, setSeasonEndDateStr, curTime, curDateStr))  | 
|               | 
|         # ±£´æÍæ¼Ò×°±¸Ô¤ÀÀÐÅÏ¢  | 
|         __SaveTopPlayerEquipView(isSeasonEndDate)  | 
|         # ±¸·ÝÅÅÐаñ  | 
|         GameWorld.Log("±¸·ÝÈÕ»ý·Ö°ñ...")  | 
|         DataRecordPack.DR_BillboardDataByDay(ShareDefine.Def_BT_MergePKDay)  | 
|         GameWorld.Log("±¸·ÝÖÜ»ý·Ö°ñ...")  | 
|         DataRecordPack.DR_BillboardDataByDay(ShareDefine.Def_BT_MergePKWeek)  | 
|         #if isWeekEnd:  | 
|         #    # Õù°ÔÈü32Ç¿·Ö×é  | 
|         #    GameWorldMergeKing.DoMergeKingBattleGrouping32()  | 
|       | 
|     # ÔÝÍ£  | 
|     elif state == ChConfig.Def_Action_Pause:  | 
|         GameWorld.Log("¿ç·þÆ¥ÅäPK»î¶¯ÔÝÍ£...")  | 
|       | 
|     # ´¥·¢¸üÐÂPKState  | 
|     __SetMergePKActionKeyValue(gameWorld, ShareDefine.Def_Notify_WorldKey_MergePKState, state, False)  | 
|       | 
|     if isSeasonEnd != dbIsSeasonEnd:  | 
|         __SetMergePKActionKeyValue(gameWorld, isSeasonEndKey, isSeasonEnd)  | 
|         | 
|     # ¹ã²¥×Ó·þ ¿ç·þPK»î¶¯×´Ì¬±ä¸ü  | 
|     actionStateInfo = [state, dbSeasonID, dbStartTime, dbDayID, isSeasonEnd]  | 
|     MergeBroadcast.SendBroadcastMerge(ChConfig.Def_MergePKActionState, 0, actionStateInfo, False)  | 
|           | 
|     # »î¶¯¿ª¹Ø±ä¸ü¶¼ÒªÍ¬²½ÅÅÐаñ, ÐèÔÚͬ²½×îÐÂ״̬֮ºó  | 
|     # Èç¹ûÏÈͬ²½ÅÅÐаñÔÙͬ²½»î¶¯×´Ì¬£¬ÔòÔÚÈü¼¾ÖØÖûòÈÕÈüÖØÖÃʱÎÞ·¨×öδÁìÈ¡½±Àø²¹·¢Âß¼£¬ÒòΪÏÈͬ²½ÅÅÐаñµÄ»°¾ÉÈü¼¾ÅÅÐаñÒѱ»¸²¸Ç  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     __SyncBillboardToClientServer(True, tick, True)  | 
|     return  | 
|   | 
| def OnClientServerInitOK(tick):  | 
|     ''' ×Ó·þÆô¶¯³É¹¦Í¨Öª»î¶¯×´Ì¬¼°Êý¾Ý '''  | 
|     __SyncBillboardToClientServer(True, tick)  | 
|       | 
|     state = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_MergePKState)  | 
|     dbDayID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_MergePKDayID)  | 
|     dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_MergePKSeasonID)  | 
|     dbStartTime = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_MergePKSeasonStartTime)  | 
|     dbIsSeasonEnd = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_IsSeasonEnd)  | 
|       | 
|     actionStateInfo = [state, dbSeasonID, dbStartTime, dbDayID, dbIsSeasonEnd]  | 
|     MergeBroadcast.SendBroadcastMerge(ChConfig.Def_MergePKActionState, 0, actionStateInfo, False)  | 
|     return  | 
|   | 
| def __SetMergePKActionKeyValue(gameWorld, key, value, isSaveDB=True):  | 
|     # ÉèÖÿç·þPK»î¶¯Ïà¹ØKeyµÄÖµ  | 
|     gameWorld.SetDict(key, value)  | 
|     if isSaveDB:  | 
|         PlayerDBGSEvent.SetDBGSTrig_ByKey(key, value)  | 
|     GameWorld.SendMapServerMsgEx(key, value)  | 
|     GameWorld.Log("    ¿ç·þPK״̬ID±ä¸ü key=%s,value=%s" % (key, value))  | 
|     return  | 
|   | 
| def __SaveTopPlayerEquipView(isSeasonEndDate):  | 
|     ## »î¶¯½áÊøºó±£´æ¸ßÊÖÍæ¼Ò×°±¸Ô¤ÀÀÐÅÏ¢  | 
|     global g_playerEquipViewDict  | 
|       | 
|     #g_playerEquipViewDict = {'937701@s999': [[30071, 0, 15, 0], [18258, 1, 15, 0], [18058, 2, 15, 0], [18458, 3, 15, 0], [18858, 4, 15, 0], [15258, 20, 15, 0], [18658, 21, 15, 0],   | 
|     #                [26020, 22, 0, 0]],   | 
|     #                'ale2': [[13058, 0, 15, 0], [16258, 1, 15, 0], [16058, 2, 15, 0], [16458, 3, 15, 0], [16858, 4, 15, 0], [19803, 14, 0, 0], [13258, 20, 15, 0],   | 
|     #                [16658, 21, 15, 0], [26080, 22, 0, 0], [31001, 25, 15, 0], [31002, 26, 15, 0], [31003, 27, 15, 0], [31004, 28, 15, 0], [31005, 29, 15, 0]]}  | 
|     GameWorld.Log("¿ªÊ¼±£´æ¸ßÊÖÍæ¼ÒÄ£ÐÍÔ¤ÀÀÐÅÏ¢...")  | 
|     universalRecMgr = GameWorld.GetUniversalRecMgr()  | 
|     recordList = universalRecMgr.GetTypeList(Def_MergePKTopPlayerEquipRecordType)  | 
|     lastTopPlayerDict = __GetAllTopPlayerViewInfoDict(recordList) # {dataType:{accID:playerInfoList, ...}}  | 
|     GameWorld.Log("    ÀúÊ·¼Ç¼: %s" % str(lastTopPlayerDict))  | 
|       | 
|     # Çå¿Õ¼Ç¼, ÖØÐ¸ù¾Ý±¾ÆÚ½áËãµÄÅÅÐаñÌí¼Ó¼Ç¼  | 
|     GameWorld.GetUniversalRecMgr().Delete(Def_MergePKTopPlayerEquipRecordType)  | 
|       | 
|     recordList = universalRecMgr.GetTypeList(Def_MergePKTopPlayerEquipRecordType)  | 
|     # ´æ´¢×òÈÕ¸ßÊÖ°ñ  | 
|     GameWorld.Log("    ==´æ´¢×òÈÕ¸ßÊÖ°ñ==")  | 
|     dayBillBoard = GameWorld.GetBillboard().FindBillboard(ShareDefine.Def_BT_MergePKDay)  | 
|     __SavePlayerViewInfoByBBData(dayBillBoard, recordList, Def_TopPlayerView_Yesterday)  | 
|               | 
|     # ´æ´¢×òÈÕÈü¼¾¸ßÊÖ°ñ  | 
|     GameWorld.Log("    ==´æ´¢×òÈÕÈü¼¾¸ßÊÖ°ñ==")  | 
|     weekBillBoard = GameWorld.GetBillboard().FindBillboard(ShareDefine.Def_BT_MergePKWeek)  | 
|     __SavePlayerViewInfoByBBData(weekBillBoard, recordList, Def_TopPlayerView_Week)  | 
|       | 
|     # ´æ´¢ÉÏÈü¼¾¸ßÊÖ°ñ, Èç¹ûÊÇ×îºóÒ»ÌìÔò¸üÐÂÈü¼¾¸ßÊÖ°ñ£¬·ñÔò½öÈ¡ÉÏÈü¼¾µÄÔÙ´æ½øÈ¥  | 
|     GameWorld.Log("    ==´æ´¢×òÈÕÈü¼¾¸ßÊÖ°ñ==isSeasonEndDate(%s)" % isSeasonEndDate)  | 
|     if isSeasonEndDate:  | 
|         __SavePlayerViewInfoByBBData(weekBillBoard, recordList, Def_TopPlayerView_LastWeek)  | 
|     else:  | 
|         lastWeekTopPlayerDict = lastTopPlayerDict.get(Def_TopPlayerView_LastWeek, {})  | 
|         for playerID, viewInfo in lastWeekTopPlayerDict.items():  | 
|             playerName, equipViewInfoList, job, order = viewInfo  | 
|             __SaveEquipViewRecData(recordList, Def_TopPlayerView_LastWeek, job, order, playerID, playerName, equipViewInfoList)  | 
|   | 
|     # ½«×îÐÂÇé¿ö¹ã²¥×Ó·þ  | 
|     syncClientServerInfo = __GetAllTopPlayerViewInfoDict(recordList, False)  | 
|     GameWorld.Log("    ¹ã²¥×Ó·þ¸ßÊÖ°ñÍæ¼ÒÄ£ÐÍÔ¤ÀÀÐÅÏ¢: %s" % str(syncClientServerInfo))    | 
|     MergeBroadcast.SendBroadcastMerge(ChConfig.Def_MergePKTopPlayerView, 0, syncClientServerInfo, False)  | 
|     return  | 
|   | 
| def __GetAllTopPlayerViewInfoDict(recordList, isUpdPlayerEquipView=True):  | 
|     ## »ñÈ¡ËùÓиßÊÖÍæ¼Ò×°±¸Ô¤ÀÀÐÅÏ¢×Öµä  | 
|     global g_playerEquipViewDict  | 
|     allTopPlayerDict = {}  | 
|     for i in xrange(recordList.Count()):  | 
|         recData = recordList.At(i)  | 
|         dataType, job, order, playerID, playerName, equipViewInfo = __GetPlayerModelViewInfo(recData)  | 
|         # È¡³öÀúÊ·¼Ç¼  | 
|         viewInfoDict = allTopPlayerDict.get(dataType, {})  | 
|         playerInfoList = viewInfoDict.get(playerID, [])  | 
|         equipViewInfoList = [] if not playerInfoList else playerInfoList[1]  | 
|         equipViewInfoList.append(equipViewInfo)  | 
|         viewInfoDict[playerID] = [playerName, equipViewInfoList, job, order]  | 
|         allTopPlayerDict[dataType] = viewInfoDict  | 
|               | 
|         # °ÑÉÏÒ»ÆÚµÄ²»ÔÚ±¾ÆÚ»º´æÀïµÄ´æÆðÀ´, ·ÀÖ¹ÖØ¶Áʱ¶ªÊ§  | 
|         if isUpdPlayerEquipView and playerID not in g_playerEquipViewDict:  | 
|             g_playerEquipViewDict[playerID] = equipViewInfoList  | 
|     return allTopPlayerDict  | 
|   | 
| def __SavePlayerViewInfoByBBData(billBoard, recordList, dataType):  | 
|     ## ¸ù¾ÝÅÅÐаñ±£´æÔ¤ÀÀÐÅÏ¢  | 
|     if not billBoard:  | 
|         return  | 
|     maxIndex = min(3, billBoard.GetCount()) # Ö»È¡Ç°3  | 
|     for index in xrange(maxIndex):  | 
|         bbData = billBoard.At(index)  | 
|         playerID = GetBBPlayerID(bbData)  | 
|         equipViewInfoList = g_playerEquipViewDict.get(playerID, [])  | 
|         __SaveEquipViewRecData(recordList, dataType, GetBBPlayerJob(bbData), index + 1,   | 
|                                playerID, GetBBPlayerName(bbData), equipViewInfoList)  | 
|     return  | 
|   | 
| def __SaveEquipViewRecData(recordList, dataType, job, order, playerID, playerName, equipViewInfoList):  | 
|     ## ¸ù¾Ý×°±¸ÁÐ±í±£´æÔ¤ÀÀÐÅÏ¢  | 
|     # Ò»¼þ×°±¸´æÒ»Ìõ¼Ç¼£¬ÓÉÓÚ255³¤¶ÈÏÞÖÆ  | 
|     for equipViewInfo in equipViewInfoList:  | 
|         recData = recordList.AddRec()  | 
|         __SetPlayerModelViewInfo(recData, dataType, job, order, playerID, playerName, equipViewInfo)  | 
|     return  | 
|   | 
| def __GetPlayerModelViewInfo(recData):  | 
|     dataType = recData.GetValue1()  | 
|     job = recData.GetValue2()  | 
|     order = recData.GetValue3()  | 
|     playerID = recData.GetValue4()  | 
|     #accID = recData.GetStrValue1()  | 
|     playerName = recData.GetStrValue2()  | 
|     equipViewInfo = recData.GetStrValue3()  | 
|     return dataType, job, order, playerID, playerName, equipViewInfo  | 
|   | 
| def __SetPlayerModelViewInfo(recData, dataType, job, order, playerID, playerName, equipViewInfo):  | 
|     GameWorld.Log("    ±£´æ¼Í¼ dataType=%s,job=%s,order=%s,playerID=%s,name=%s,equipViewInfo=%s"   | 
|                   % (dataType, job, order, playerID, playerName, equipViewInfo))  | 
|     equipViewInfo = str(equipViewInfo)  | 
|     recData.SetValue1(dataType)  | 
|     recData.SetValue2(job)  | 
|     recData.SetValue3(order)  | 
|     recData.SetValue4(playerID)  | 
|     #recData.SetStrValue1(accID)  | 
|     recData.SetStrValue2(playerName)  | 
|     recData.SetStrValue3(equipViewInfo)  | 
|     return  | 
|   | 
| def IsMergePKMatchOpen():  | 
|     ## ¿ç·þPKÆ¥ÅäÈüÊÇ·ñ¿ªÆô  | 
|     return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_MergePKState) == ChConfig.Def_Action_Open  | 
|   | 
| def ClientServer_RecoverMergePKWin(playerInfoDict, tick):  | 
|     # ¿ç·þPK»Ö¸´Á¬Ê¤  | 
|     accID = playerInfoDict["accID"] # ½ÇÉ«Õ˺Š | 
|     playerID = playerInfoDict["playerID"] # Íæ¼ÒID  | 
|     recoverType = playerInfoDict["type"] # 1-ÇëÇó¿Û·Ñ£»2-¿Û·Ñ³É¹¦ºóÈ·Èϻָ´  | 
|       | 
|     bbData = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKWeek, playerID)[1]  | 
|       | 
|     if not bbData:  | 
|         GameWorld.ErrLog("ClientServer_RecoverMergePKWin Íæ¼Ò²»ÔÚÖܰñÀïÃæ£¡accID=%s,playerID=%s" % (accID, playerID))  | 
|         return  | 
|       | 
|     cWin = GetBBMergePKCWinCnt(bbData) # µ±Ç°Á¬Ê¤  | 
|     maxCWin = GetBBMergePKMaxCWinCnt(bbData) # ÀúÊ·×î´óÁ¬Ê¤  | 
|     if cWin == maxCWin:  | 
|         GameWorld.Log("ClientServer_RecoverMergePKWin ²»ÐèÒª»Ö¸´Á¬Ê¤£¡accID=%s,playerID=%s,cWin=%s,maxCWin=%s"   | 
|                              % (accID, playerID, cWin, maxCWin))  | 
|         return  | 
|       | 
|     # ÇëÇó¿Û·Ñ  | 
|     if recoverType == 1:  | 
|         moneyType, costFormat = ReadChConfig.GetEvalChConfig("MergePKWinRecoverCost")  | 
|         costMoney = eval(costFormat)  | 
|         if costMoney <= 0:  | 
|             GameWorld.ErrLog("ClientServer_RecoverMergePKWin ÏûºÄ¼ÆËãÒì³££¡accID=%s,playerID=%s,cWin=%s,maxCWin=%s,costMoney=%s"   | 
|                              % (accID, playerID, cWin, maxCWin, costMoney))  | 
|             return  | 
|           | 
|         costInfoList = [accID, moneyType, costMoney, cWin, maxCWin]  | 
|         MergeBroadcast.SendBroadcastMerge(ChConfig.Def_RecoverMergePKWinCost, 0, costInfoList, False)   | 
|         GameWorld.Log("ÇëÇó»Ö¸´Á¬Ê¤£ºaccID=%s,playerID=%s,cWin=%s,maxCWin=%s,costMoney=%s"   | 
|                       % (accID, playerID, cWin, maxCWin, costMoney))  | 
|       | 
|     # ¿Û·Ñ³É¹¦ºóÈ·Èϻָ´  | 
|     elif recoverType == 2:  | 
|         SetBBMergePKCWinCnt(bbData, maxCWin)  | 
|         DataRecordPack.DR_RecoverMergePKWin(accID, cWin, maxCWin)  | 
|         __SyncBillboardToClientServer(True, tick) # Õë¶Ô´ËÇé¿ö£¬Ç¿ÖÆÍ¬²½Ò»´ÎÅÅÐаñ  | 
|         GameWorld.Log("¿Û·Ñ³É¹¦È·Èϻָ´Á¬Ê¤£ºaccID=%s,playerID=%s,cWin=%s,maxCWin=%s" % (accID, playerID, cWin, maxCWin))  | 
|     return  | 
|   | 
| def ClientServer_RequestMergePKMatch(playerInfoDict, tick):  | 
|     ## ÇëÇóÆ¥Åä  | 
|     global g_matchPlayerDict  | 
|     global g_matchPlayerList  | 
|       | 
|     if not GameWorld.IsMergeServer():  | 
|         GameWorld.ErrLog("·Ç¿ç·þ·þÎñÆ÷²»´¦Àí¿ç·þPKÆ¥ÅäÇëÇó£¡")  | 
|         return  | 
|       | 
|     if not IsMergePKMatchOpen():  | 
|         GameWorld.Log("¿ç·þÆ¥ÅäPK»î¶¯Î´¿ªÆô£¬²»ÔÊÐíÇëÇóÆ¥Å䣡")  | 
|         return  | 
|       | 
|     accID = playerInfoDict["accID"] # ½ÇÉ«Õ˺Š | 
|     playerID = playerInfoDict["playerID"] # ½ÇÉ«ID  | 
|     playerName = playerInfoDict["playerName"] # ¿ç·þ×Ó·þÍæ¼ÒÃû  | 
|     fightPower = playerInfoDict["fightPower"] # Õ½¶·Á¦  | 
|       | 
|     # ÕâÀïֻҪȡÀúÊ·Êý¾Ý£¬ÔÝʱ²»ÐèÒª´´½¨°ñµ¥Êý¾Ý£¬ÇÒ×Ó·þÎñÆ÷ÔÚÇëÇóÆ¥ÅäµÄʱºò²»Ò»¶¨ÉÏ´«¹ýÊý¾Ý  | 
|     # ¹Ì´ËʱµÄmergePlayerIDÀíÂÛÉÏ¿ÉÄÜ»ñÈ¡²»µ½£¬ÇÒ´Ë´¦Ò²²»ÐèÒª£¬¹ÌĬÈÏ´«0  | 
|     bbData = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKWeek, playerID)[1]  | 
|     pkScore = 0 if not bbData else GetBBMergePKScore(bbData)  | 
|       | 
|     if playerID in g_matchPlayerDict:  | 
|         GameWorld.Log("ÖØ¸´Ìá½»¿ç·þPKÆ¥ÅäÇëÇó£¡ÒѾÔÚÆ¥Åä¶ÓÁÐÀplayerID=%s,accID=%s" % (playerID, accID))  | 
|         return  | 
|       | 
|     if playerID in g_preparePlayerDict:  | 
|         GameWorld.Log("ÖØ¸´Ìá½»¿ç·þPKÆ¥ÅäÇëÇó£¡ÒѾÔÚ×¼±¸¶ÓÁÐÀplayerID=%s,accID=%s" % (playerID, accID))  | 
|         return  | 
|       | 
|     # ¼ÓÈëµÈ´ýÆ¥ÅäÁÐ±í  | 
|     matchPlayer = MatchPlayer(accID, playerID, playerName, pkScore, fightPower, tick)  | 
|     g_matchPlayerDict[playerID] = matchPlayer  | 
|     if matchPlayer not in g_matchPlayerList:  | 
|         g_matchPlayerList.append(matchPlayer)  | 
|     GameWorld.Log("Íæ¼Ò¼ÓÈëÆ¥Åä: accID=%s,playerID=%s,playerName=%s,pkScore=%s,fightPower=%s,playerCnt=%s,dictÈËÊý=%s"   | 
|                   % (accID, playerID, playerName, pkScore, fightPower, len(g_matchPlayerList), len(g_matchPlayerDict)))  | 
|     return  | 
|   | 
| def SendCancelMergePKMatch(curPlayer, reason):     | 
|     ## ·¢ËÍÈ¡ÏûÆ¥Åä  | 
|     # ¿ç·þ·þÎñÆ÷²»´¦Àí  | 
|     if GameWorld.IsMergeServer():  | 
|         return  | 
|       | 
|     # ·Ç»î¶¯Öв»´¦Àí  | 
|     if not IsMergePKMatchOpen():  | 
|         return  | 
|       | 
|     # Èç¹ûÊÇÒªµÇ½µ½¿ç·þ·þÎñÆ÷µÄ£¬²»·¢ËÍÈ¡Ïû  | 
|     if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_IsLoginToMergeServer):  | 
|         GameWorld.DebugLog("±¾´ÎÀëÏßΪҪµÇ½¿ç·þ·þÎñÆ÷µÄ×Ô¶¯ÀëÏßÐÐΪ£¬²»·¢ËÍÈ¡ÏûÆ¥Å䣡", curPlayer.GetPlayerID())  | 
|         curPlayer.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 0)  | 
|         return  | 
|       | 
|     dataMsg = {"accID":curPlayer.GetAccID(), # Õ˺Š | 
|                "playerID":curPlayer.GetPlayerID(), # Íæ¼ÒID  | 
|                "playerName":curPlayer.GetName(), # ¿ç·þ×Ó·þÍæ¼ÒÃû  | 
|                "reason":reason, # È¡ÏûÔÒò  | 
|                "vsRoomID":curPlayer.GetVsRoomId(), # ¶ÔÕ½·¿¼äID  | 
|                }  | 
|     MergeChildMsg.SendMergerChildToCenterStringData(ChConfig.Def_CancelMergePKMatch, dataMsg)  | 
|     PlayerControl.SetVsRoomId(curPlayer, 0)  | 
|     GameWorld.Log("·¢ËÍÈ¡Ïû¿ç·þPKÆ¥Åäµ½¿ç·þ·þÎñÆ÷£ºdataMsg=%s" % str(dataMsg), curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def ClientServer_CancelMergePKMatch(playerInfoDict, tick):  | 
|     ## È¡ÏûÆ¥Åä  | 
|     global g_matchPlayerDict  | 
|     global g_matchPlayerList  | 
|     global g_preparePlayerDict  | 
|     global g_prepareRoomDict  | 
|       | 
|     if not GameWorld.IsMergeServer():  | 
|         GameWorld.ErrLog("·Ç¿ç·þ·þÎñÆ÷²»´¦ÀíÈ¡Ïû¿ç·þPKÆ¥Å䣡")  | 
|         return  | 
|       | 
|     # ·Ç»î¶¯Öв»´¦Àí  | 
|     if not IsMergePKMatchOpen():  | 
|         return  | 
|       | 
|     accID = playerInfoDict["accID"] # ½ÇÉ«Õ˺Š | 
|     playerID = playerInfoDict["playerID"] # Íæ¼ÒID  | 
|     playerName = playerInfoDict["playerName"] # ¿ç·þ×Ó·þÍæ¼ÒÃû  | 
|     reason = playerInfoDict["reason"] # È¡ÏûÔÒò  | 
|     vsRoomID = playerInfoDict["vsRoomID"] # ËùÊô¶ÔÕ½·¿¼äID  | 
|       | 
|     GameWorld.Log("Íæ¼ÒÈ¡ÏûÆ¥Åä: reason=%s,accID=%s,playerID=%s,playerName=%s,playerCnt=%s,vsRoomID=%s"   | 
|                   % (reason, accID, playerID,playerName, len(g_matchPlayerList), vsRoomID))  | 
|       | 
|     # ´ÓÆ¥Åä¶ÓÁÐÖÐÒÆ³ý  | 
|     if playerID in g_matchPlayerDict:  | 
|         matchPlayer = g_matchPlayerDict.pop(playerID)  | 
|         if matchPlayer in g_matchPlayerList:  | 
|             g_matchPlayerList.pop(g_matchPlayerList.index(matchPlayer))  | 
|         GameWorld.Log("    ´ÓÆ¥Åä¶ÓÁÐÖÐɾ³ý: accID=%s,playerID=%s,Æ¥Åä¶ÓÁÐÊ£ÓàÈËÊý=%s" % (accID, playerID, len(g_matchPlayerList)))  | 
|           | 
|     # ´Ó×¼±¸¶ÓÁÐÖÐÒÆ³ý  | 
|     if playerID in g_preparePlayerDict:  | 
|         g_preparePlayerDict.pop(playerID)  | 
|         GameWorld.Log("    ´Ó×¼±¸¶ÓÁÐÖÐɾ³ý: accID=%s,playerID=%s" % (accID, playerID))  | 
|   | 
|     #È¡ÏûËùÓдæÔÚ¸ÃÍæ¼ÒµÄ·¿¼ä£¬×Ó·þ²»Ò»¶¨ÖªµÀÍæ¼Òµ±Ç°×îÐÂËùÊô·¿¼äID£¬ ¹ÊÖ»ÄÜͨ¹ý±éÀúɾ³ýÒÑ¾ÎªÍæ¼Ò´´½¨µÄ·¿¼ä  | 
|     delRoomIDList = []  | 
|     for roomID, playerList in g_prepareRoomDict.items():  | 
|         isInRoom = False # ÊÇ·ñÔÚÕâ¸ö·¿¼äÀïÃæ  | 
|         for player in playerList:  | 
|             if player.playerID == playerID:  | 
|                 isInRoom = True  | 
|                 break  | 
|               | 
|         if not isInRoom:  | 
|             continue  | 
|           | 
|         delRoomIDList.append(roomID)  | 
|         for player in playerList:  | 
|             rpAccID = player.accID  | 
|             rpPlayerID = player.playerID  | 
|             if rpPlayerID == playerID:  | 
|                 #GameWorld.Log("    ×Ô¼º²»´¦Àí roomID=%s,player=%s" % (roomID, player))  | 
|                 continue  | 
|   | 
|             if rpPlayerID in g_preparePlayerDict:  | 
|                 g_preparePlayerDict.pop(rpPlayerID)  | 
|                 GameWorld.Log("    ½«Ö®Ç°Æ¥ÅäµÄ¶ÔÊÖ´Ó×¼±¸¶ÓÁÐÖÐɾ³ý rpAccID=%s,rpPlayerID=%s,roomID=%s" % (rpAccID, rpPlayerID, roomID))  | 
|           | 
|             # ½«·Ç¸ÃÍæ¼ÒÖØÐ¼ÓÈëÆ¥Åä¶ÓÁÐ, ²åÈë×îÇ°Ãæ£¬Ï´ÎÓÅÏÈÆ¥Åä  | 
|             if player not in g_matchPlayerList:  | 
|                 g_matchPlayerList.insert(0, player)  | 
|             g_matchPlayerDict[rpPlayerID] = player  | 
|             GameWorld.Log("    ½«Ö®Ç°Æ¥ÅäµÄ¶ÔÊÖÖØÐ¼ÓÈëÆ¥Åä¶ÓÁÐÍ· rpAccID=%s,rpPlayerID=%s,roomID=%s,Æ¥ÅäÈËÊý±ä¸ü=%s,dictÈËÊý=%s"   | 
|                           % (rpAccID, rpPlayerID, roomID, len(g_matchPlayerList), len(g_matchPlayerDict)))  | 
|           | 
|     if delRoomIDList:  | 
|         GameWorld.Log("    É¾³ý·¿¼äIDÁбí, delRoomCnt=%s, %s" % (len(delRoomIDList), str(delRoomIDList)))  | 
|         vsRoomMgr = GameWorld.GetVSRoomManager()  | 
|         for delRoomID in delRoomIDList:  | 
|               | 
|             if delRoomID in g_prepareRoomDict:  | 
|                 g_prepareRoomDict.pop(delRoomID)  | 
|                 GameWorld.Log("        g_prepareRoomDict ÒƳý·¿¼ä: delRoomID=%s" % (delRoomID))  | 
|                   | 
|             delVSRoom = vsRoomMgr.FindVsRoom(delRoomID)  | 
|             if not delVSRoom:  | 
|                 GameWorld.Log("        È¡ÏûÆ¥ÅäGetVSRoomManagerÕÒ²»µ½¶ÔÕ½·¿¼ä: delRoomID=%s" % delRoomID)  | 
|             else:  | 
|                 GameWorld.GetVSRoomManager().DeleteVsRoomById(delRoomID)  | 
|                 GameWorld.Log("        GetVSRoomManagerɾ³ýÒѾ´´½¨µÄ¶ÔÕ½·¿¼ä: delRoomID=%s" % delRoomID)  | 
|     return  | 
|   | 
| def ClientServer_MergePKPrepareOK(playerInfoDict, tick):  | 
|     ## Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK  | 
|     global g_roomMemberExtendInfoDict  | 
|       | 
|     if not GameWorld.IsMergeServer():  | 
|         GameWorld.ErrLog("·Ç¿ç·þ·þÎñÆ÷²»´¦ÀíÈ¡Ïû¿ç·þPKÆ¥Å䣡")  | 
|         return  | 
|       | 
|     playerAccID = playerInfoDict["playerAccID"] # ×Ó·þÍæ¼ÒÕ˺Š | 
|     playerID = playerInfoDict["playerID"] # ×Ó·þÍæ¼ÒID  | 
|     playerName = playerInfoDict["playerName"] # ×Ó·þÍæ¼ÒÃû  | 
|     playerJob = playerInfoDict["playerJob"] # ×Ó·þÍæ¼ÒÖ°Òµ  | 
|     vsRoomID = playerInfoDict["vsRoomID"] # ËùÊô¶ÔÕ½·¿¼äID  | 
|     fightPower = playerInfoDict["fightPower"] # Õ½¶·Á¦  | 
|     playerLV = playerInfoDict["playerLV"] # Íæ¼ÒµÈ¼¶  | 
|     maxHP = playerInfoDict["maxHP"] # ×î´óѪÁ¿  | 
|       | 
|     vsRoom = GameWorld.GetVSRoomManager().FindVsRoom(vsRoomID)  | 
|       | 
|     if not vsRoom:  | 
|         GameWorld.ErrLog("Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK, µ«ÕÒ²»µ½¸Ã¶ÔÕ½·¿¼ä(%s)£¡¿ÉÄܶÔÊÖÒÑÈ¡Ïû£¡" % vsRoomID)  | 
|         return  | 
|       | 
|     if vsRoom.GetRoomState() != ShareDefine.Def_VsRoom_State_WaitPlayer:  | 
|         GameWorld.ErrLog("Íæ¼Ò¿ç·þ¶ÔÕ½Êý¾Ý×¼±¸OK, µ«·¿¼ä״̬·ÇµÈ´ý״̬, state=%s£¡" % vsRoom.GetRoomState())  | 
|         return  | 
|           | 
|     # Ã»ÓжÓÎéÔòÏÈ´´½¨  | 
|     roomTeam = vsRoom.AddVsTeam() if vsRoom.GetVsTeamCount() <= 0 else vsRoom.GetVSTeam(0)  | 
|   | 
|     if not roomTeam:  | 
|         return  | 
|       | 
|     member = roomTeam.GetMemberById(playerID)  | 
|     if not member:  | 
|         member = roomTeam.AddMember(playerID)  | 
|     member.SetIsReady(1) # ÉèÖøÃÍæ¼Ò×¼±¸×´Ì¬  | 
|     member.SetPlayerName(playerName) # ÉèÖøÃÍæ¼ÒÃû  | 
|     member.SetJob(playerJob) # ÉèÖøÃÍæ¼ÒÖ°Òµ  | 
|     extendInfo = g_roomMemberExtendInfoDict.get(playerID, PlayerExtendInfo())  | 
|     extendInfo.accID = playerAccID  | 
|     extendInfo.playerID = playerID  | 
|     extendInfo.playerName = playerName  | 
|     extendInfo.fightPower = fightPower  | 
|     extendInfo.playerLV = playerLV  | 
|     extendInfo.maxHP = maxHP  | 
|     g_roomMemberExtendInfoDict[playerID] = extendInfo  | 
|     GameWorld.Log("Íæ¼Ò¿ç·þPK×¼±¸Íê±Ï: playerAccID=%s,playerID=%s,playerName=%s,fightPower=%s,vsRoomID=%s"   | 
|                   % (playerAccID, playerID, playerName, fightPower, vsRoomID))  | 
|     return  | 
|   | 
| def __ReadyOKRoomPlayerProcess(tick):  | 
|     ## Íæ¼Ò¿ç·þPKÒÑ×¼±¸ºÃµÄ·¿¼ä´¦Àí  | 
|     global g_preparePlayerDict  | 
|     global g_prepareRoomDict  | 
|   | 
|     GameWorld.Log("===ÒÑ×¼±¸ºÃµÄ¶ÔÕ½·¿¼ä´¦Àí===")  | 
|     sendReadyOKRoomList = []  | 
|     vsRoomMgr = GameWorld.GetVSRoomManager()  | 
|     for vsRoomIndex in xrange(vsRoomMgr.GetVsRoomCount()):  | 
|         vsRoom = vsRoomMgr.GetVsRoom(vsRoomIndex)  | 
|         if not vsRoom:  | 
|             continue  | 
|           | 
|         roomState = vsRoom.GetRoomState()  | 
|         # ·ÇµÈ´ý״̬µÄ·¿¼ä²»´¦Àí  | 
|         if roomState != ShareDefine.Def_VsRoom_State_WaitPlayer:  | 
|             continue  | 
|           | 
|         # »¹Ã»ÓÐÍæ¼Ò½øÈë·¿¼ä  | 
|         if vsRoom.GetVsTeamCount() <= 0:  | 
|             continue  | 
|           | 
|         roomID = vsRoom.GetCreaterID()  | 
|         roomMapID = GameWorld.ToIntDef(vsRoom.GetPws())  | 
|         if roomMapID <= 0:  | 
|             continue  | 
|           | 
|         roomTeam = vsRoom.GetVSTeam(0)  | 
|         readyMemberDict = {} # ÒÑ×¼±¸ºÃµÄÍæ¼ÒÐÅÏ¢  | 
|         for mIndex in range(roomTeam.GetMemberCount()):  | 
|               | 
|             member = roomTeam.GetMember(mIndex)  | 
|             if not member:  | 
|                 break  | 
|             # »¹Ã»×¼±¸ºÃ  | 
|             if not member.GetIsReady():  | 
|                 break  | 
|               | 
|             memPlayerID = member.GetPlayerID()  | 
|             extendInfo = g_roomMemberExtendInfoDict.get(memPlayerID)  | 
|             exAccID = "" if not extendInfo else extendInfo.accID  | 
|             fightPower = 0 if not extendInfo else extendInfo.fightPower  | 
|             playerLV = 0 if not extendInfo else extendInfo.playerLV  | 
|             maxHP = 0 if not extendInfo else extendInfo.maxHP  | 
|             dayBBData = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKDay, memPlayerID)[1]  | 
|             dayScore = 0 if not dayBBData else GetBBMergePKScore(dayBBData) # µ±ÈÕÒÑ»ñµÃ»ý·Ö  | 
|             bbData = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKWeek, memPlayerID)[1]  | 
|             if not bbData:  | 
|                 readyMemberDict[memPlayerID] = [exAccID,  | 
|                                                 member.GetPlayerName(),  | 
|                                                 member.GetJob(),  | 
|                                                 0,0,0,0,0,0,fightPower, playerLV, maxHP, dayScore,  | 
|                                                 ]  | 
|             else:  | 
|                 readyMemberDict[memPlayerID] = [exAccID,  | 
|                                                 GetBBPlayerName(bbData),  | 
|                                                 GetBBPlayerJob(bbData),  | 
|                                                 GetBBMergePKCnt(bbData),  | 
|                                                 GetBBMergePKCWinCnt(bbData),  | 
|                                                 GetBBMergePKScore(bbData),  | 
|                                                 GetBBMergePKWinCnt(bbData),  | 
|                                                 GetBBMergePKMaxCWinCnt(bbData),  | 
|                                                 GetBBPlayerGrade(bbData),  | 
|                                                 fightPower, playerLV, maxHP,   | 
|                                                 dayScore,  | 
|                                                 ]  | 
|               | 
|         if len(readyMemberDict) != Def_RoomMemberCnt:  | 
|             continue  | 
|           | 
|         sendReadyOKRoomList.append([roomMapID, roomID, readyMemberDict])  | 
|         vsRoom.SetRoomState(ShareDefine.Def_VsRoom_State_PrepareFight)  | 
|         GameWorld.Log("    ×¼±¸ºÃµÄ·¿¼ä: MapID=%s,roomID=%s,readyMemberDict=%s"   | 
|                       % (roomMapID, roomID, str(readyMemberDict)))  | 
|           | 
|         # É¾³ý×¼±¸·¿¼äÏà¹Ø»º´æ  | 
|         if roomID in g_prepareRoomDict:  | 
|             preparePlayerList = g_prepareRoomDict.pop(roomID)  | 
|             GameWorld.Log("        ×¼±¸·¿¼ä×ֵ仺´æ g_prepareRoomDict pop ÒƳýroomID=%s" % roomID)  | 
|             for prePlayer in preparePlayerList:  | 
|                 playerID = prePlayer.playerID  | 
|                 if playerID in g_preparePlayerDict:  | 
|                     g_preparePlayerDict.pop(playerID)  | 
|                     GameWorld.Log("            ×¼±¸Íæ¼Ò×ֵ仺´æ g_preparePlayerDict pop ÒƳýaccID=%s,playerID=%s"   | 
|                                   % (prePlayer.accID, playerID))  | 
|           | 
|     # ½«ÒÑ×¼±¸ºÃµÄ·¿¼ä¹ã²¥µ½×Ó·þ  | 
|     GameWorld.Log("    ÒÑ×¼±¸ºÃµÄ¶ÔÕ½·¿¼äÊý: %s" % len(sendReadyOKRoomList))  | 
|     if sendReadyOKRoomList:  | 
|         MergeBroadcast.SendBroadcastMerge(ChConfig.Def_MergePKReadyOKRoomList, 0, sendReadyOKRoomList, False)   | 
|               | 
|     return  | 
|   | 
| def OnPKMatchProcess(tick):  | 
|     ## Íæ¼Ò¿ç·þPKÆ¥Å䶨ʱ´¦ÀíÂß¼  | 
|       | 
|     # ·Ç¿ç·þ·þÎñÆ÷²»´¦Àí¿ç·þPKÆ¥ÅäÂß¼  | 
|     if not GameWorld.IsMergeServer():  | 
|         return  | 
|       | 
|     if not IsMergePKMatchOpen():  | 
|         return  | 
|       | 
|     # Í¬²½×Ó·þÅÅÐаñ  | 
|     __SyncBillboardToClientServer(False, tick)  | 
|       | 
|     matchCfg = ReadChConfig.GetEvalChConfig("MergePK_Match")  | 
|     processTick = matchCfg[Def_Match_ProcessTick]  | 
|   | 
|     processTickKey = "PKMatchLastTick"  | 
|     lastProcessTick = GameWorld.GetGameWorld().GetDictByKey(processTickKey)  | 
|     if tick - lastProcessTick < processTick:  | 
|         return  | 
|     GameWorld.GetGameWorld().SetDict(processTickKey, tick)  | 
|       | 
|     # Í¨ÖªÒÑ×¼±¸ºÃµÄ·¿¼äÍæ¼Ò¿É½øÈë¿ç·þ  | 
|     __ReadyOKRoomPlayerProcess(tick)  | 
|       | 
|     if len(g_matchPlayerList) < 2:  | 
|         GameWorld.Log("Æ¥ÅäPKÈËÊý(%s) < 2¸ö£¬²»´¦Àí£¡" % len(g_matchPlayerList))  | 
|         return  | 
|       | 
|     GameWorld.Log("¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¿ªÊ¼¿ç·þPKÆ¥Åä(×ÜÈËÊý:%s)¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï¡ï" % len(g_matchPlayerList))  | 
|     maxGroupCnt = matchCfg[Def_Match_MaxGroupCnt]  | 
|     outTimeTick = matchCfg[Def_Match_OutTimeTick]  | 
|     stepScoreList = matchCfg[Def_Match_StepScoreList]  | 
|       | 
|     # °´»ý·ÖÉýÐòÅÅÐò  | 
|     scoreSortList = sorted(g_matchPlayerList, key=operator.attrgetter('pkScore'))  | 
|       | 
|     matchPlayerVSList = [] # ³É¹¦Æ¥ÅäÍæ¼Ò¶ÔÕ½ÁÐ±í  | 
|       | 
|     # ÓÅÏÈÆ¥ÅäµÈ´ý³¬Ê±Íæ¼Ò  | 
|     __DoMatch_OutTimePlayer(scoreSortList, outTimeTick, matchPlayerVSList, tick)  | 
|       | 
|     if len(matchPlayerVSList) < maxGroupCnt:  | 
|         # ÔÙ°´»ý·Ö¶ÎÆ¥ÅäÍæ¼Ò  | 
|         __DoMatch_StepScorePlayer(scoreSortList, stepScoreList, maxGroupCnt, matchPlayerVSList)  | 
|       | 
|     # ¸ø³É¹¦Æ¥ÅäµÄÍæ¼Ò·ÇÅä¶ÔÕ½·¿¼ä  | 
|     matchPlayerVSList = matchPlayerVSList[:maxGroupCnt]  | 
|     __DoSetVSRoom(matchPlayerVSList, tick)  | 
|     GameWorld.Log("==========Æ¥Åä½áÊø(×ÜÆ¥Åä¶ÓÎé:%s)==========" % len(matchPlayerVSList))  | 
|     return  | 
|   | 
| def __DoMatch_OutTimePlayer(scoreSortList, outTimeTick, matchPlayerVSList, tick):  | 
|     ## Æ¥Åä³¬Ê±Íæ¼Ò  | 
|     GameWorld.Log(" ==ÓÅÏÈÆ¥Å䳬ʱµÈ´ýÍæ¼Ò==×î´óµÈ´ýʱ¼ä:%s, tick=%s" % (outTimeTick, tick))  | 
|     for matchPlayer in g_matchPlayerList:          | 
|         # Ö»ÓÐÒ»¸öÍæ¼Ò  | 
|         if len(scoreSortList) <= 1:  | 
|             GameWorld.Log("    µ±Ç°Íæ¼ÒÊý%s<=1£¬²»ÔÙÆ¥Å䣡" % len(scoreSortList))  | 
|             break  | 
|           | 
|         if tick - matchPlayer.matchTick < outTimeTick:  | 
|             continue  | 
|           | 
|         GameWorld.Log("    ³¬Ê±Íæ¼Ò, %s-%s=%s >= outTimeTick(%s)"   | 
|                       % (tick, matchPlayer.matchTick, tick - matchPlayer.matchTick, outTimeTick))  | 
|         # ÒѾ±»Æ¥Åä×ßÁË  | 
|         if matchPlayer not in scoreSortList:  | 
|             GameWorld.Log("        ÒѾ±»Æ¥Åä×ßÁË£¡")  | 
|             continue  | 
|           | 
|         outTimeIndex = scoreSortList.index(matchPlayer)  | 
|         # ×îºóÒ»¸öĬÈÏÆ¥ÅäÉÏÒ»¸ö  | 
|         if outTimeIndex == len(scoreSortList) - 1:   | 
|             vsIndex = outTimeIndex - 1  | 
|             GameWorld.Log("        ³¬Ê±Íæ¼ÒË÷Òý%s,×îºóÒ»¸ö,ĬÈÏÆ¥ÅäÉÏÒ»¸öË÷Òý%s£¡" % (outTimeIndex, vsIndex))  | 
|         # µÚÒ»¸öĬÈÏÆ¥ÅäÏÂÒ»¸ö  | 
|         elif outTimeIndex == 0:  | 
|             vsIndex = outTimeIndex + 1  | 
|             GameWorld.Log("        ³¬Ê±Íæ¼ÒË÷Òý%s,µÚÒ»¸ö,ĬÈÏÆ¥ÅäÏÂÒ»¸öË÷Òý%s£¡" % (outTimeIndex, vsIndex))  | 
|         # ÆäËûÇé¿öÆ¥Åä»ý·Ö½Ï½üµÄÒ»¸ö  | 
|         else:  | 
|             preIndex = outTimeIndex - 1  | 
|             nextIndex = outTimeIndex + 1  | 
|             prePlayer = scoreSortList[preIndex]  | 
|             nextPlayer = scoreSortList[nextIndex]  | 
|             preDiff = abs(prePlayer.pkScore - matchPlayer.pkScore)  | 
|             nextDiff = abs(matchPlayer.pkScore - nextPlayer.pkScore)  | 
|             vsIndex = preIndex if preDiff <= nextDiff else nextIndex  | 
|             GameWorld.Log("        ³¬Ê±Íæ¼ÒË÷Òý-»ý·Ö(%s-%s),ÉÏÒ»¸ö(%s-%s),ÏÂÒ»¸ö(%s-%s),preDiff=%s,nextDiff=%s,vsIndex=%s"   | 
|                           % (outTimeIndex, matchPlayer.pkScore, preIndex, prePlayer.pkScore,  | 
|                              nextIndex, nextPlayer.pkScore, preDiff, nextDiff, vsIndex))  | 
|               | 
|         if outTimeIndex > vsIndex:   | 
|             scoreSortList.pop(outTimeIndex)  | 
|             vsPlayer = scoreSortList.pop(vsIndex)  | 
|         elif outTimeIndex < vsIndex:  | 
|             vsPlayer = scoreSortList.pop(vsIndex)  | 
|             scoreSortList.pop(outTimeIndex)  | 
|         else:  | 
|             continue  | 
|           | 
|         # ¼ÓÈë³É¹¦Æ¥ÅäÁÐ±í  | 
|         matchPlayerVSList.append([matchPlayer, vsPlayer])  | 
|           | 
|     return  | 
|   | 
| def __DoMatch_StepScorePlayer(scoreSortList, stepScoreList, maxGroupCnt, matchPlayerVSList):  | 
|     ## Æ¥Åä»ý·Ö·Ö¶ÎÍæ¼Ò  | 
|     GameWorld.Log(" ==Æ¥Åä»ý·Ö·Ö¶ÎÍæ¼Ò== maxGroupCnt=%s,scoreSortListLen=%s" % (maxGroupCnt, len(scoreSortList)))  | 
|     splitPlayerList = [] # °´»ý·Ö·Ö¶ÎÁбí·ÖÉ¢Íæ¼Ò  | 
|     tempPlayerList = copy.deepcopy(scoreSortList)  | 
|     for stepScore in stepScoreList:  | 
|           | 
|         if not tempPlayerList:  | 
|             break  | 
|           | 
|         stepIndex = -1  | 
|         for i, matchPlayer in enumerate(tempPlayerList):  | 
|             pkScore = matchPlayer.pkScore  | 
|             if pkScore > stepScore:  | 
|                 break  | 
|               | 
|             stepIndex = i  | 
|               | 
|         if stepIndex == -1:  | 
|             continue  | 
|           | 
|         splitPlayerList.append(tempPlayerList[:stepIndex+1])  | 
|         tempPlayerList = tempPlayerList[stepIndex+1:]  | 
|           | 
|     # °´·Ö¶ÎÍæ¼ÒËæ»úÆ¥Åä  | 
|     random.shuffle(splitPlayerList) # ´òÂÒ¶Îλ˳Ðò  | 
|       | 
|     GameWorld.Log("    »ý·Ö·Ö¶Î¸öÊý: %s" % len(splitPlayerList))  | 
|       | 
|     # ÈÕÖ¾Êä³ö·Ö×éÃ÷ϸ  | 
|     for i, sPlayerList in enumerate(splitPlayerList):  | 
|         strList = []  | 
|         for player in sPlayerList:  | 
|             strList.append((player.pkScore, player.fightPower))  | 
|               | 
|         GameWorld.Log("        »ý·Ö¶Î×é %s: %s" % (i, str(strList)))  | 
|               | 
|     # ÕâÀïÓÃmaxGroupCnt×÷Ϊ×î´ó±éÀú´ÎÊý£¬Êµ¼ÊÉϱéÀú´ÎÊýÒ»°ãСÓÚ¸ÃÖµ£¬³ý·Çÿ´ÎֻƥÅäÒ»×é  | 
|     for i in xrange(maxGroupCnt):  | 
|         isMatchOK = False  | 
|         for sPlayerList in splitPlayerList:  | 
|               | 
|             # ¸Ã¶Îλ²»×ã2ÈË£¬±¾ÂÖÂÖ¿Õ  | 
|             if len(sPlayerList) < 2:  | 
|                 #GameWorld.Log("    ¶ÎλÈËÊýÉÙÓÚ2¸ö£¬´Ë¶Îλ±¾ÂÖÂÖ¿Õ£¡")  | 
|                 continue  | 
|               | 
|             vsIndexList = random.sample(xrange(len(sPlayerList)), 2) # Ëæ»úÈ¡Á½¸öË÷Òý¶ÔÕ½  | 
|             vsIndexList.sort()  | 
|             aPlayer = sPlayerList.pop(vsIndexList[1])  | 
|             bPlayer = sPlayerList.pop(vsIndexList[0])  | 
|               | 
|             aAccID = aPlayer.accID  | 
|             bAccID = bPlayer.accID  | 
|             aPlayerID = aPlayer.playerID  | 
|             bPlayerID = bPlayer.playerID  | 
|               | 
|             amPlayer = g_matchPlayerDict.get(aPlayerID)  | 
|             if not amPlayer:  | 
|                 GameWorld.ErrLog("    µÈ´ý¶ÓÁÐÕÒ²»µ½Íæ¼Ò£¬accID=%s,playerID=%s" % (aAccID, aPlayerID))  | 
|                 continue  | 
|               | 
|             bmPlayer = g_matchPlayerDict.get(bPlayerID)  | 
|             if not bmPlayer:  | 
|                 GameWorld.ErrLog("    µÈ´ý¶ÓÁÐÕÒ²»µ½Íæ¼Ò£¬accID=%s,playerID=%s" % (bAccID, bPlayerID))  | 
|                 continue  | 
|               | 
|             matchPlayerVSList.append([amPlayer, bmPlayer])  | 
|             isMatchOK = True  | 
|             GameWorld.Log("    ³É¹¦Æ¥ÅäÍæ¼Ò:aAccID=%s,aPlayerID=%s,aName=%s,aScore=%s,aFP=%s VS bAccID=%s,bPlayerID=%s,bName=%s,bScore=%s,bFP=%s"   | 
|                           % (aPlayer.accID, aPlayer.playerID, aPlayer.playerName, aPlayer.pkScore, aPlayer.fightPower,  | 
|                              bPlayer.accID, bPlayer.playerID, bPlayer.playerName, bPlayer.pkScore, bPlayer.fightPower))  | 
|           | 
|         if not isMatchOK:  | 
|             GameWorld.Log("    ÒѾûÓÐÂú×ãÆ¥ÅäÌõ¼þµÄÍæ¼Ò! isMatchOK=%s, ²»ÔÙÆ¥Å䣡" % isMatchOK)  | 
|             break  | 
|         if len(matchPlayerVSList) >= maxGroupCnt:  | 
|             GameWorld.Log("    ÒѾ´ïµ½×î´óÆ¥ÅäÊý! ÒÑÆ¥Åä¶ÔÕ½Êý=%s, ²»ÔÙÆ¥Å䣡" % len(matchPlayerVSList))  | 
|             break  | 
|     return  | 
|   | 
| def __DoSetVSRoom(matchPlayerVSList, tick):  | 
|     ## ÉèÖöÔÕ½·¿¼ä  | 
|     global g_matchPlayerList  | 
|     global g_matchPlayerDict  | 
|       | 
|     if not matchPlayerVSList:  | 
|         return  | 
|       | 
|     sendMatchResultList = []  | 
|     vsRoomMgr = GameWorld.GetVSRoomManager()  | 
|       | 
|     GameWorld.Log("===¸øÅä¶ÔµÄÍæ¼Ò¿ª·¿¼ä(Åä¶ÔÊý:%s)===" % len(matchPlayerVSList))  | 
|     for aPlayer, bPlayer in matchPlayerVSList:  | 
|           | 
|         if not aPlayer or not bPlayer:  | 
|             continue  | 
|           | 
|         if aPlayer not in g_matchPlayerList or bPlayer not in g_matchPlayerList:  | 
|             GameWorld.Log("    Íæ¼Ò²»ÔڵȴýÆ¥Åä¶ÓÁÐÀ¿ÉÄÜÒѾ±»Æ¥Åä×ߣ¡aAccID=%s,bAccID=%s"   | 
|                           % (aPlayer.accID, bPlayer.accID))  | 
|             continue  | 
|           | 
|         roomID = 0  | 
|         for _ in xrange(20):  | 
|             # ÓÉÓÚ¿Í»§¶Ë·¢ËͽøÈ븱±¾·â°üÐèÒª´øroomID£¬ÔÝʱÓÃlineID´úÌæ£¬Ö»Ö§³ÖWORD  | 
|             ranRoomID = random.randint(1, 65535)  | 
|             if not vsRoomMgr.FindVsRoom(ranRoomID):  | 
|                 roomID = ranRoomID  | 
|                 break  | 
|               | 
|         if not roomID:  | 
|             continue  | 
|   | 
|         newRoom = vsRoomMgr.AddVsRoom(roomID)  | 
|         if not newRoom:  | 
|             continue  | 
|   | 
|         mapIDList = ReadChConfig.GetEvalChConfig("MergePK_Match")[Def_Match_MapIDList]  | 
|         mapID = random.choice(mapIDList)  | 
|           | 
|         newRoom.SetOpenTick(tick)  | 
|         newRoom.SetRoomState(ShareDefine.Def_VsRoom_State_WaitPlayer)  | 
|         newRoom.SetPws(str(mapID)) # ´Ë´¦ÓÃpwsÀ´´æ´¢Ëæ»úmapID£¬µÈÍæ¼Ò½øÈëʱ½øÐзÖÁ÷´«ËÍ  | 
|           | 
|         aAccID = aPlayer.accID  | 
|         bAccID = bPlayer.accID  | 
|         aPlayerID = aPlayer.playerID  | 
|         bPlayerID = bPlayer.playerID  | 
|           | 
|         GameWorld.Log("    ¿ª·¿:mapID=%s,roomID=%s,aAccID=%s,aPlayerID=%s,bAccID=%s,bPlayerID=%s"   | 
|                       % (mapID, roomID, aAccID, aPlayerID, bAccID, bPlayerID))  | 
|         sendMatchResultList.append([roomID, [aPlayerID, bPlayerID]])  | 
|         __PopMatchPlayerToPrepare(aPlayer, roomID)  | 
|         __PopMatchPlayerToPrepare(bPlayer, roomID)  | 
|           | 
|     # ½«Æ¥Åä½á¹û¹ã²¥µ½×Ó·þ  | 
|     if sendMatchResultList:  | 
|         MergeBroadcast.SendBroadcastMerge(ChConfig.Def_MergePKMatchResult, 0, sendMatchResultList, False)   | 
|     return  | 
|   | 
| def __PopMatchPlayerToPrepare(matchPlayer, roomID):  | 
|     global g_matchPlayerList  | 
|     global g_matchPlayerDict  | 
|     global g_preparePlayerDict  | 
|     global g_prepareRoomDict  | 
|       | 
|     accID = matchPlayer.accID  | 
|     playerID = matchPlayer.playerID  | 
|     mPlayer = g_matchPlayerList.pop(g_matchPlayerList.index(matchPlayer))  | 
|     if playerID in g_matchPlayerDict:  | 
|         g_matchPlayerDict.pop(playerID)  | 
|           | 
|     g_preparePlayerDict[playerID] = mPlayer  | 
|     roomPlayerList = g_prepareRoomDict.get(roomID, [])  | 
|     roomPlayerList.append(mPlayer)  | 
|     g_prepareRoomDict[roomID] = roomPlayerList  | 
|       | 
|     GameWorld.Log("        ½«Æ¥ÅäÍæ¼Ò×ªÒÆµ½µÈ´ý¶ÓÁУ¡roomID=%s,accID=%s,playerID=%s" % (roomID, accID, playerID))  | 
|     return  | 
|   | 
| def DR_MergePKOver(roomID, winnerID, loserID, winnerWinCnt, loserWinCnt, overType, exDict={}):  | 
|     dataDict = {"roomID":roomID, "winnerID":winnerID, "loserID":loserID, "winnerWinCnt":winnerWinCnt,   | 
|                 "loserWinCnt":loserWinCnt, "overType":overType}  | 
|     dataDict.update(exDict)  | 
|     DataRecordPack.SendEventPack("MergePKOver", dataDict)  | 
|     return  | 
|       | 
| def MapServer_MergePKOver(infoList):  | 
|     ## ÊÕµ½MapServer¸±±¾¿ç·þPK½á¹ûͬ²½  | 
|     #global g_unNotifyPKOverDict  | 
|     global g_playerEquipViewDict  | 
|       | 
|     GameWorld.Log("ÊÕµ½MapServer_¿ç·þPKÕ½¶·½á¹û %s" % str(infoList))  | 
|       | 
|     roomID, winnerID, loserID, winnerWinCnt, loserWinCnt, winnerEquipViewList, loserEquipViewList, overType = infoList  | 
|     luckyItemList = []  | 
|     #roomID, winnerID, loserID, winnerAddScore, loserAddScore, luckyItemList, \  | 
|     #        winnerEquipViewList, loserEquipViewList, overType, remainTime = infoList  | 
|       | 
|     if not winnerID or not loserID:  | 
|         GameWorld.Log("    Ã»ÓжÔÊÖÐÅÏ¢, ¸Ã³¡Õ½¶·ÊÓΪÎÞЧ!winnerID=%s,loserID=%s" % (winnerID, loserID))  | 
|         GameWorld.GetVSRoomManager().DeleteVsRoomById(roomID)  | 
|         timeStr = GameWorld.GetCurrentDataTimeStr()  | 
|         for playerID in [winnerID, loserID]:  | 
|             player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|             if not player:  | 
|                 continue  | 
|             __NotifyPKOverInfo(player, [[timeStr, roomID, overType, 0, "", "", winnerID, loserID, "", "", 0, 0, 0,   | 
|                                         winnerWinCnt, loserWinCnt, luckyItemList]])  | 
|         DR_MergePKOver(roomID, winnerID, loserID, winnerWinCnt, loserWinCnt, overType)  | 
|         return  | 
|       | 
|     vsRoom = GameWorld.GetVSRoomManager().FindVsRoom(roomID)  | 
|     if not vsRoom:  | 
|         return  | 
|       | 
|     billBoardDay, winnerBBDataDay = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKDay, winnerID, True)  | 
|     billBoardWeek, winnerBBDataSeason = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKWeek, winnerID, True)  | 
|     billBoardDay, loserBBDataDay = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKDay, loserID, True)  | 
|     billBoardWeek, loserBBDataSeason = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKWeek, loserID, True)  | 
|       | 
|     winnerDayScore = GetBBMergePKScore(winnerBBDataDay) # Ê¤Àû·½½ñÈÕÀۼƻñµÃ»ý·Ö  | 
|     winnerScore = GetBBMergePKScore(winnerBBDataSeason) # Ê¤Àû·½µ±Ç°×Ü»ý·Ö  | 
|     winnerGrade = GetBBPlayerGrade(winnerBBDataSeason) # Ê¤Àû·½µ±Ç°¶Îλ  | 
|       | 
|     loserDayScore = GetBBMergePKScore(loserBBDataDay) # Ê§°Ü·½½ñÈÕÀۼƻñµÃ»ý·Ö  | 
|     loserScore = GetBBMergePKScore(loserBBDataSeason) # Ê§°Ü·½µ±Ç°×Ü»ý·Ö  | 
|     loserGrade = GetBBPlayerGrade(loserBBDataSeason) # Ê§°Ü·½µ±Ç°¶Îλ  | 
|       | 
|     scoreCfg = ReadChConfig.GetEvalChConfig("MergePK_Score")  | 
|     dayMaxScore, wBaseScoreList, wExScoreFormat, lBaseScoreList, lExScoreFormat  = scoreCfg  | 
|     wBaseScore = wBaseScoreList[winnerGrade] if winnerGrade < len(wBaseScoreList) else wBaseScoreList[-1]  | 
|     wExScore = eval(wExScoreFormat)  | 
|     lBaseScore = lBaseScoreList[loserGrade] if loserGrade < len(lBaseScoreList) else lBaseScoreList[-1]  | 
|     lExScore = eval(lExScoreFormat)  | 
|       | 
|     winnerAddScore = max(0, min(dayMaxScore - winnerDayScore, wBaseScore + wExScore)) # Ê¤ÕßÖÁÉÙ0·Ö  | 
|     loserAddScore = min(dayMaxScore - loserDayScore, lBaseScore + lExScore) # Ê§°ÜµÄÖ§³Ö¸º·Ö  | 
|       | 
|     GameWorld.DebugLog("winnerDayScore=%s,winnerScore=%s,winnerGrade=%s" % (winnerDayScore, winnerScore, winnerGrade))  | 
|     GameWorld.DebugLog("loserDayScore=%s,loserScore=%s,loserGrade=%s" % (loserDayScore, loserScore, loserGrade))  | 
|     GameWorld.DebugLog("wBaseScore=%s,wExScore=%s,winnerAddScore=%s" % (wBaseScore, wExScore, winnerAddScore))  | 
|     GameWorld.DebugLog("lBaseScore=%s,lExScore=%s,loserAddScore=%s" % (lBaseScore, lExScore, loserAddScore))  | 
|       | 
|     playerIDList = [] # ÓÃÓÚͬ²½×îÐÂÅÅÐаñ  | 
|     #billBoardDay = None  | 
|     #billBoardWeek = None  | 
|     winnerName = ""  | 
|     loserName = ""  | 
|     notifyCWin = 0  | 
|     notifyStopCWin = 0  | 
|     winnerCWinCnt = 0 # Ê¤ÕßÁ¬Ê¤Êý  | 
|     winerAccID = ""  | 
|     loserAccID = ""  | 
|     loserID = 0  | 
|     for teamIndex in xrange(vsRoom.GetVsTeamCount()):  | 
|         roomTeam = vsRoom.GetVSTeam(teamIndex)  | 
|         for mIndex in xrange(roomTeam.GetMemberCount()):  | 
|             member = roomTeam.GetMember(mIndex)  | 
|             memPlayerID = member.GetPlayerID()  | 
|             playerName = member.GetPlayerName()  | 
|             job = member.GetJob()  | 
|               | 
|             if memPlayerID not in g_roomMemberExtendInfoDict:  | 
|                 continue  | 
|               | 
|             extendInfo = g_roomMemberExtendInfoDict[memPlayerID]  | 
|             accID = extendInfo.accID  | 
|             fightPower = extendInfo.fightPower  | 
|             isWin = (memPlayerID == winnerID)  | 
|             equipViewInfo = winnerEquipViewList if isWin else loserEquipViewList  | 
|             # ÓÐеÄ×°±¸ÐÅÏ¢²Å¸üР | 
|             if equipViewInfo:  | 
|                 g_playerEquipViewDict[memPlayerID] = equipViewInfo  | 
|             addScore = winnerAddScore if isWin else loserAddScore  | 
|             # ¸üÐÂÈÕ°ñ  | 
|             #billBoardDay, bbDataDay = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKDay, memPlayerID, True)  | 
|             bbDataDay = winnerBBDataDay if isWin else loserBBDataDay  | 
|             __UpdateMatchPKBillboardData(bbDataDay, accID, memPlayerID, playerName, job, fightPower, addScore, isWin)  | 
|               | 
|             # ¸üÐÂÖܰñ  | 
|             #billBoardWeek, bbDataWeek = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKWeek, memPlayerID, True)  | 
|             bbDataSeason = winnerBBDataSeason if isWin else loserBBDataSeason  | 
|             notifyCnt = __UpdateMatchPKBillboardData(bbDataSeason, accID, memPlayerID, playerName, job, fightPower, addScore, isWin, True)  | 
|             if isWin:  | 
|                 notifyCWin = notifyCnt  | 
|                 winnerName = playerName  | 
|                 winnerCWinCnt = GetBBMergePKCWinCnt(bbDataSeason)  | 
|                 winerAccID = accID  | 
|             else:  | 
|                 notifyStopCWin = notifyCnt  | 
|                 loserName = playerName  | 
|                 loserAccID = accID  | 
|                 loserID = memPlayerID  | 
|               | 
|             playerIDList.append(memPlayerID)  | 
|       | 
|     GameWorld.DebugLog("×°±¸»º´æ: %s" % str(g_playerEquipViewDict))              | 
|     # É¾³ý·¿¼ä  | 
|     GameWorld.GetVSRoomManager().DeleteVsRoomById(roomID)  | 
|   | 
|     # Ë«·½¸üкúó½øÐÐÒ»´ÎÅÅÐò  | 
|     if billBoardDay:  | 
|         billBoardDay.Sort()  | 
|     #Öܰñͬ²½µÄʱºòÔÙÅÅÐò  | 
|     if billBoardWeek:  | 
|         pass  | 
|         #billBoardWeek.Sort()  | 
|           | 
|     # Í¨Öª¿Í»§¶ËÕ½¶·½á¹û  | 
|     remainTime = 0  | 
|     timeStr = GameWorld.GetCurrentDataTimeStr()  | 
|     overInfo = [timeStr, roomID, overType, winnerCWinCnt, winerAccID, loserAccID, winnerID, loserID, winnerName, loserName,   | 
|                 remainTime, winnerAddScore, loserAddScore, winnerWinCnt, loserWinCnt, luckyItemList]  | 
|     GameWorld.Log("Õ½¶·½á¹û: %s" % str(overInfo))  | 
|     # Í¬²½¶ÔÕ½Íæ¼Òǰºó×îаñµ¥Êý¾Ý¸øÍæ¼Ò£¬ÔÝʱֻͬ²½¸Ã°ñµ¥£¬ÆäËû°ñµ¥ÔÚ×Ó·þ×Ô¼º²éѯ  | 
|     for playerID in playerIDList:  | 
|         player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|         if not player:  | 
|             MergeBroadcast.SendBroadcastMerge(ChConfig.Def_MergePKUnNotifyOverInfo, 0, [playerID, overInfo], False)  | 
|             GameWorld.Log("Íæ¼Ò²»ÔÚÏß, PK½á¹ûͬ²½¸ø×Ó·þ!roomID=%s,playerID=%s" % (roomID, playerID))  | 
|             continue  | 
|         PlayerBillboard.Sync_BillboardEx(player, ShareDefine.Def_BT_MergePKDay, True)  | 
|         __NotifyPKOverInfo(player, [overInfo])  | 
|       | 
|     # Èç¹ûÓеõ½ÐÒÔËÎïÆ·£¬¹ã²¥×Ó·þ·¢·ÅÍæ¼ÒÎïÆ·  | 
|     if luckyItemList:  | 
|         syncLuckyItemDict = {"playerIDList":playerIDList, "luckyItemList":luckyItemList}  | 
|         GameWorld.Log("¹ã²¥×Ó·þ·¢·ÅÍæ¼ÒÎïÆ· %s" % str(syncLuckyItemDict))  | 
|         MergeBroadcast.SendBroadcastMerge(ChConfig.Def_MergePKLuckyItem, 0, syncLuckyItemDict, False)  | 
|           | 
|     # Á¬Ê¤¿çÈ«·þ¹ã²¥  | 
|     if notifyCWin > 0:  | 
|         PlayerControl.MergeWorldNotify(0, "PK_liubo_160510", [winnerName, notifyCWin])  | 
|     if notifyStopCWin > 0:  | 
|         PlayerControl.MergeWorldNotify(0, "PK_liubo_46483", [winnerName, loserName, notifyStopCWin])  | 
|       | 
|     # Õ½¶·½á¹ûÁ÷Ïò  | 
|     exDict = {"winerAccID":winerAccID, "loserAccID":loserAccID, "winnerWinCnt":winnerWinCnt, "loserWinCnt":loserWinCnt,   | 
|               "winnerAddScore":winnerAddScore, "loserAddScore":loserAddScore  | 
|               }  | 
|     # Á÷Ïò°ñµ¥ÏêϸÐÅÏ¢  | 
|     drBillboardDataDict = {"winnerBBDataDay":winnerBBDataDay, "winnerBBDataSeason":winnerBBDataSeason,  | 
|                            "loserBBDataDay":loserBBDataDay, "loserBBDataSeason":loserBBDataSeason,  | 
|                            }  | 
|     for drKey, bbData in drBillboardDataDict.items():  | 
|         exDict[drKey] = [GetBBPlayerID(bbData), GetBBPlayerJob(bbData), GetBBFightPower(bbData),   | 
|                          GetBBPlayerGrade(bbData), GetBBPlayerMaxGrade(bbData), GetBBMergePKScore(bbData),   | 
|                          GetBBMergePKCnt(bbData), GetBBMergePKWinCnt(bbData),  | 
|                          GetBBMergePKCWinCnt(bbData), GetBBMergePKMaxCWinCnt(bbData)]  | 
|     DR_MergePKOver(roomID, winnerID, loserID, winnerWinCnt, loserWinCnt, overType, exDict)  | 
|     return  | 
|   | 
| def __UpdateMatchPKBillboardData(bbData, accID, playerID, playerName, job, fightPower, addScore, isWin, isNotifyCWin=False):  | 
|     ## ¸üпç·þPKÅÅÐаñÄÚÈÝ  | 
|     if not bbData:  | 
|         return 0  | 
|       | 
|     bbType = bbData.GetType()  | 
|     bbData.SetType(bbType)  | 
|     SetBBPlayerJob(bbData, job) # Ö±½ÓÌæ»»¸üР | 
|     SetBBPlayerID(bbData, playerID) # Ö±½ÓÌæ»»¸üР | 
|     SetBBPlayerName(bbData, playerName) # Ö±½ÓÌæ»»¸üР | 
|     SetBBFightPower(bbData, fightPower) # Ö±½ÓÌæ»»¸üР | 
|       | 
|     # ÀÛ¼ÆPK´ÎÊý, Ã¿´Î+1  | 
|     pkCnt = GetBBMergePKCnt(bbData)  | 
|     updPKCnt = pkCnt + 1  | 
|     SetBBMergePKCnt(bbData, updPKCnt)  | 
|       | 
|     # µ±Ç°Á¬Ê¤³¡´Î, Ê§°ÜÖØÖ㬻ñʤ+1  | 
|     cWin = GetBBMergePKCWinCnt(bbData)  | 
|     updCWin = 0 if not isWin else (cWin + 1)  | 
|     SetBBMergePKCWinCnt(bbData, updCWin)  | 
|       | 
|     # »ý·Ö£¬Ö±½ÓÀÛ¼Ó  | 
|     score = GetBBMergePKScore(bbData)  | 
|     updScore = max(0, score + addScore) # ¿ÉÄÜ»áÓиºÖµ£¬×ö¸ö·À·¶  | 
|     SetBBMergePKScore(bbData, updScore)  | 
|       | 
|     # ÀۼƻñʤÊý, Ê§°Ü²»±ä£¬»ñʤ+1  | 
|     winCnt = GetBBMergePKWinCnt(bbData)  | 
|     updWinCnt = winCnt if not isWin else (winCnt + 1)  | 
|     SetBBMergePKWinCnt(bbData, updWinCnt)  | 
|       | 
|     # ×î´óÁ¬Ê¤³¡´Î  | 
|     maxCWin = GetBBMergePKMaxCWinCnt(bbData)  | 
|     updMaxCWin = updCWin if updCWin > maxCWin else maxCWin  | 
|     SetBBMergePKMaxCWinCnt(bbData, updMaxCWin)  | 
|     GameWorld.Log("¸üпç·þPK»ý·Ö°ñ: type=%s,accID=%s,playerID=%s,name=%s,job=%s,addScore=%s,isWin=%s,pkCnt=(%s-%s),score=(%s-%s),winCnt=(%s-%s),cWin=(%s-%s),maxCWin=(%s-%s)"   | 
|                   % (bbType, accID, playerID, playerName, job, addScore, isWin, pkCnt, updPKCnt, score, updScore, winCnt, updWinCnt, cWin, updCWin, maxCWin, updMaxCWin))  | 
|       | 
|     if not isNotifyCWin:  | 
|         return 0  | 
|       | 
|     # Á¬Ê¤Ïà¹Ø¹ã²¥  | 
|     cWinCntList, stopCWinCnt = ReadChConfig.GetEvalChConfig("MergePK_WinNotify")  | 
|     # ·µ»ØÁ¬Ê¤¹ã²¥´ÎÊý  | 
|     if isWin and updCWin in cWinCntList:  | 
|         return updCWin  | 
|       | 
|     # ·µ»ØÖÕÖ¹Á¬Ê¤¹ã²¥´ÎÊý  | 
|     if not isWin and cWin >= stopCWinCnt:  | 
|         return cWin  | 
|       | 
|     return 0  | 
|   | 
| def __NotifyPKOverInfo(curPlayer, playerPKOverList):  | 
|     ## Í¬²½PK½á¹û¸øÍæ¼Ò  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     # D1 27 Í¨Öª¿ç·þPKÕ½¶·½á¹û #tagMergePKOverInfo  | 
|     pkOverInfoPack = ChPyNetSendPack.tagMergePKOverInfo()  | 
|     pkOverInfoPack.Clear()  | 
|     pkOverInfoPack.PKOverList = []  | 
|       | 
|     for overInfo in playerPKOverList:  | 
|         timeStr, roomID, overType, winnerCWinCnt, winerAccID, loserAccID, winnerID, loserID, winnerName, loserName, \  | 
|                 remainTime, winnerAddScore, loserAddScore, winnerWinCnt, loserWinCnt, luckyItemList = overInfo  | 
|         luckyItemID = 0  | 
|         if len(luckyItemList) > 0 and len(luckyItemList[0]) > 0:  | 
|             luckyItemID = luckyItemList[0][0]  | 
|               | 
|         pkOverInfo = ChPyNetSendPack.tagMergePKOver()  | 
|         pkOverInfo.Clear()  | 
|         pkOverInfo.TimeStr = timeStr  | 
|         pkOverInfo.TimeLen = len(pkOverInfo.TimeStr)  | 
|         pkOverInfo.RoomID = roomID  | 
|         pkOverInfo.OverType = overType  | 
|         pkOverInfo.RemainTime = remainTime  | 
|         pkOverInfo.WinnerAccID = winerAccID  | 
|         pkOverInfo.WinnerAccIDLen = len(pkOverInfo.WinnerAccID)  | 
|         pkOverInfo.LoserAccID = loserAccID  | 
|         pkOverInfo.LoserAccIDLen = len(pkOverInfo.LoserAccID)  | 
|         pkOverInfo.WinnerID = winnerID  | 
|         pkOverInfo.LoserID = loserID  | 
|         pkOverInfo.WinnerName = winnerName  | 
|         pkOverInfo.WinnerNameLen = len(pkOverInfo.WinnerName)  | 
|         pkOverInfo.LoserName = loserName  | 
|         pkOverInfo.LoserNameLen = len(pkOverInfo.LoserName)  | 
|         pkOverInfo.WinnerAddScore = winnerAddScore  | 
|         pkOverInfo.LoserAddScore = str(loserAddScore)  | 
|         pkOverInfo.LoserAddScoreLen = len(pkOverInfo.LoserAddScore)         | 
|         pkOverInfo.WinnerWinCnt = winnerWinCnt  | 
|         pkOverInfo.LoserWinCnt = loserWinCnt  | 
|         pkOverInfo.WinnerCWinCnt = winnerCWinCnt  | 
|         pkOverInfo.LuckyItemID = luckyItemID  | 
|         pkOverInfoPack.PKOverList.append(pkOverInfo)  | 
|           | 
|         GameWorld.Log("ͬ²½Íæ¼ÒÕ½¶·½á¹û: roomID=%s,luckyItemID=%s" % (roomID, luckyItemID), playerID)  | 
|           | 
|     pkOverInfoPack.Count = len(pkOverInfoPack.PKOverList)  | 
|     NetPackCommon.SendFakePack(curPlayer, pkOverInfoPack)  | 
|     return  | 
|   | 
| ######################################### ÒÔÏÂÊÇ×Ó·þÏà¹Ø´¦Àí #########################################  | 
|   | 
| def OnRecvMergePKActionState(actionStateInfo):  | 
|     ## ×Ó·þ½ÓÊÕPK»î¶¯×´Ì¬±ä¸ü state, dbSeasonID, dbStartTime, dbDayID, isSeasonEnd  | 
|     if not actionStateInfo:  | 
|         return  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     state, seasonID, startTime, dayID, isSeasonEnd = actionStateInfo      | 
|     GameWorld.Log("×Ó·þÊÕµ½¿ç·þPKÈü״̬ͬ²½ actionStateInfo=%s" % (actionStateInfo))  | 
|       | 
|     if state != GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_MergePKState):  | 
|         __SetMergePKActionKeyValue(gameWorld, ShareDefine.Def_Notify_WorldKey_MergePKState, state, False)  | 
|     else:  | 
|         GameWorld.Log("    ×Ó·þ¿ç·þPK״̬Ïàͬ, ²»´¦Àí! MergePKState=%s" % state)  | 
|       | 
|     if isSeasonEnd != PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_IsSeasonEnd):  | 
|         __SetMergePKActionKeyValue(gameWorld, ShareDefine.Def_Notify_WorldKey_IsSeasonEnd, isSeasonEnd)  | 
|         if isSeasonEnd:  | 
|             Sync_MergePKSeasonInfo(None)  | 
|     else:  | 
|         GameWorld.Log("    ×Ó·þ¿ç·þPKÈü¼¾½áÊø×´Ì¬Ïàͬ, ²»´¦Àí! isSeasonEnd=%s" % isSeasonEnd)  | 
|   | 
|     if state == ChConfig.Def_Action_Open:  | 
|         dayIDKey = ShareDefine.Def_Notify_WorldKey_MergePKDayID  | 
|         seasonIDKey = ShareDefine.Def_Notify_WorldKey_MergePKSeasonID  | 
|         seasonStartTimeKey = ShareDefine.Def_Notify_WorldKey_MergePKSeasonStartTime  | 
|           | 
|         dbDayID = PlayerDBGSEvent.GetDBGSTrig_ByKey(dayIDKey)  | 
|         dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(seasonIDKey)  | 
|         dbSeasonStartTime = PlayerDBGSEvent.GetDBGSTrig_ByKey(seasonStartTimeKey)  | 
|         GameWorld.Log("    seasonID=%s,dbSeasonID=%s,startTime=%s,dbSeasonStartTime=%s,dayID=%s,dbDayID=%s,"   | 
|                       % (seasonID, dbSeasonID, startTime, dbSeasonStartTime, dayID, dbDayID))  | 
|           | 
|         # ÈÕÖØÖÃ  | 
|         if dayID != dbDayID:  | 
|             GameWorld.Log("    ×Ó·þ¿ç·þPKÈÕÈüÖØÖÃ!")  | 
|             __GiveMergePKAwardByMail_Day(dbDayID) # ²¹·¢×òÈÕδÁìÈ¡½±Àø  | 
|             __ResetMergePKDayAwardRecord() # ÐèÔÚ²¹·¢½±ÀøÖ®ºó  | 
|             __SetMergePKActionKeyValue(gameWorld, dayIDKey, dayID)  | 
|         else:  | 
|             GameWorld.Log("    ×Ó·þ¿ç·þPKÈÕÈüÒѾ¿ªÆôÁË!")  | 
|               | 
|               | 
|         # Èü¼¾ÖØÖÃ  | 
|         if seasonID != dbSeasonID:  | 
|             GameWorld.Log("    ×Ó·þ¿ç·þPKÈü¼¾ÖØÖÃ!")  | 
|             __GiveMergePKAwardByMail_Season(dbSeasonID) # ²¹·¢Èü¼¾Î´ÁìÈ¡½±Àø  | 
|             GameWorld.GetUniversalRecMgr().Delete(Def_MergePKAwardRecordType) # ÔÚ¿ªÊ¼µÄʱºò²ÅÇå, ÐèÔÚ²¹·¢½±ÀøÖ®ºó  | 
|             __SetMergePKActionKeyValue(gameWorld, seasonIDKey, seasonID)  | 
|             __SetMergePKActionKeyValue(gameWorld, seasonStartTimeKey, startTime)  | 
|             Sync_MergePKSeasonInfo(None)  | 
|         else:  | 
|             GameWorld.Log("    ×Ó·þ¿ç·þPKÈü¼¾ÒѾ¿ªÆôÁË!")  | 
|               | 
|               | 
|     return  | 
|   | 
| def OnRecvMergePKMatchInfo(vsPlayerList):  | 
|     ## ×Ó·þ½ÓÊÕPKÆ¥ÅäÐÅÏ¢  | 
|     actionType = ShareDefine.Def_MergeAction_MergePK  | 
|     mapID = ChConfig.Def_MergeTransMapID # Ä¬ÈÏÏÈÉÏ´«µ½ÖÐתµØÍ¼  | 
|     posX, posY = ChConfig.Def_MergeTransMapPos  | 
|       | 
|     GameWorld.Log("=== ÊÕµ½PKÆ¥Åä½á¹û´¦Àí ===")  | 
|       | 
|     for roomID, playerList in vsPlayerList:  | 
|           | 
|         for playerID in playerList:  | 
|               | 
|             player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|             if not player:  | 
|                 GameWorld.DebugLog("    Íæ¼Ò²»ÔÚÏß»ò²»ÊDZ¾·þÍæ¼Ò!playerID=%s" % (playerID))  | 
|                 continue  | 
|               | 
|             PlayerControl.SetVsRoomId(player, roomID, True)  | 
|             # Í¨ÖªµØÍ¼Íæ¼ÒÆ¥Åä³É¹¦, ÉÏ´«Êý¾Ý, ×¼±¸½øÈë¿ç·þ·þÎñÆ÷  | 
|             PlayerMergeRegister.SendMergeActionReg(player, actionType, [mapID, mapID, 0, posX, posY])  | 
|     return  | 
|   | 
| def OnRecvMergePKReadyOKRoom(readyOKRoomList):  | 
|     ## ×Ó·þ½ÓÊÕÍæ¼ÒÒÑ×¼±¸ºÃµÄPK·¿¼äÐÅÏ¢, ´Ë·¿¼äÀïµÄÍæ¼Ò¿É´«ËͽøÈë¿ç·þ  | 
|     GameWorld.Log("===ÊÕµ½¿ç·þ·þÎñÆ÷֪ͨÒÑ×¼±¸ºÃµÄ¶ÔÕ½PK·¿¼äÐÅÏ¢´¦Àí===")  | 
|     for roomMapID, roomID, readyMemberDict in readyOKRoomList:  | 
|           | 
|         for readyOKPlayerID in readyMemberDict.keys():  | 
|               | 
|             regRecData = PlayerMergeRegister.GetRegisterPlayerRec(readyOKPlayerID)  | 
|             # ²»ÊDZ¾·þÍæ¼Ò  | 
|             if not regRecData:  | 
|                 GameWorld.DebugLog("    ²»ÊDZ¾·þÍæ¼Ò readyOKPlayerID=%s" % readyOKPlayerID)  | 
|                 continue  | 
|               | 
|             player = GameWorld.GetPlayerManager().FindPlayerByID(readyOKPlayerID)  | 
|             if not player:  | 
|                 GameWorld.DebugLog("    Íæ¼Ò²»ÔÚÏß readyOKPlayerID=%s" % readyOKPlayerID)  | 
|                 continue  | 
|             player.SetDict(ChConfig.Def_PlayerKey_IsLoginToMergeServer, 1)   | 
|             # Í¨ÖªÍæ¼Ò¿É½øÈë¿ç·þPK  | 
|             enterPack = ChPyNetSendPack.tagCanEnterMergePK()  | 
|             enterPack.Clear()  | 
|             enterPack.MapID = roomMapID  | 
|             enterPack.RoomID = roomID  | 
|             enterPack.MemberList = []  | 
|             for memberInfo in readyMemberDict.values():  | 
|                 accID, name, job, pkCnt, pkCWinCnt, score, pkWinCnt, maxCWInCnt, grade, \  | 
|                     fightPower, playerLV, maxHP, dayScore = memberInfo  | 
|                 member = ChPyNetSendPack.tagCanEnterMergePKMember()  | 
|                 member.Clear()  | 
|                 member.AccID = accID  | 
|                 member.AccIDLen = len(accID)  | 
|                 member.PlayerName = name  | 
|                 member.NameLen = len(name)  | 
|                 member.Job = job  | 
|                 member.PKCnt = pkCnt  | 
|                 member.PKCWinCnt = pkCWinCnt  | 
|                 member.Score = score  | 
|                 member.DayScore = dayScore  | 
|                 member.PKWinCnt = pkWinCnt  | 
|                 member.MaxCWinCnt = maxCWInCnt  | 
|                 member.Grade = grade  | 
|                 member.FightPower = fightPower  | 
|                 member.PlayerLV = playerLV  | 
|                 member.MaxHP = maxHP  | 
|                 enterPack.MemberList.append(member)  | 
|             enterPack.MemberCnt = len(enterPack.MemberList)  | 
|             NetPackCommon.SendFakePack(player, enterPack)  | 
|             GameWorld.Log("    Í¨ÖªÍæ¼Ò½øÈë¿ç·þPK¶ÔÕ½·¿¼ä!roomMapID=%s,roomID=%s" % (roomMapID, roomID), readyOKPlayerID)  | 
|               | 
|             # µ½ÕâÀïĬÈÏÈÏΪһ¶¨»áÓнá¹ûµÄ£¬ËùÒÔ±¾·þÖ±½ÓÔö¼Ó´ÎÊý  | 
|             #player.MapServer_QueryPlayerResult(0, 0, 'MergePKAddCnt', "", 0)  | 
|     return  | 
|   | 
| def OnRecvMergePKLuckyItem(luckyItemInfoDict):  | 
|     ## ×Ó·þ½ÓÊÕÍæ¼Ò»ñµÃ¿ç·þPKÐÒÔËÎïÆ·  | 
|     playerIDList = luckyItemInfoDict.get("playerIDList", [])  | 
|     luckyItemList = luckyItemInfoDict.get("luckyItemList", [])  | 
|   | 
|     title, contentTemple, getDays = ReadChConfig.GetEvalChConfig("MergePK_LuckyItemMail")  | 
|     curTimeStr = GameWorld.GetCurrentDataTimeStr()  | 
|     for playerID in playerIDList:  | 
|         regRecData = PlayerMergeRegister.GetRegisterPlayerRec(playerID)  | 
|         # ²»ÊDZ¾·þÍæ¼Ò  | 
|         if not regRecData:  | 
|             GameWorld.DebugLog("¿ç·þPK»ñµÃÐÒÔËÎïÆ·£¬²»ÊDZ¾·þÍæ¼Ò playerID=%s" % playerID)  | 
|             continue  | 
|       | 
|         content = contentTemple % (curTimeStr)  | 
|         PlayerCompensation.SendPersonalItemMailEx(title, content, getDays, [playerID], luckyItemList)  | 
|     return  | 
|   | 
| def OnRecvMergePKSyncBillboard(syncBBDataInfo):  | 
|     ## ×Ó·þÊÕµ½»ý·Ö°ñµ¥Í¬²½  | 
|     isStateChange, actionState, bbType, bbDataList = syncBBDataInfo  | 
|     billBoard = GameWorld.GetBillboard().FindBillboard(bbType)  | 
|     if not billBoard:  | 
|         GameWorld.ErrLog("OnRecvMergePKSyncBillboard °ñµ¥Î´³õʼ»¯! bbType=%s" % bbType)  | 
|         return  | 
|       | 
|     billBoard.Clear() # ÏÈÇå¿Õ£¬ÔÙÌæ»»  | 
|                                  | 
|     for playerID, id2, name1, name2, type2, value1, value2, cmpValue, cmpValue2, cmpValue3 in bbDataList:  | 
|         bbData = billBoard.AddToBillboard(playerID)  | 
|         bbData.SetType(bbType)  | 
|         bbData.SetID2(id2)  | 
|         bbData.SetName1(name1)  | 
|         bbData.SetName2(name2)  | 
|         bbData.SetType2(type2)  | 
|         bbData.SetValue1(value1)  | 
|         bbData.SetValue2(value2)  | 
|         bbData.SetCmpValue(cmpValue)  | 
|         bbData.SetCmpValue2(cmpValue2)  | 
|         bbData.SetCmpValue3(cmpValue3)  | 
|           | 
|     GameWorld.Log("×Ó·þ¸üпç·þPK»ý·Ö°ñµ¥³É¹¦: bbType=%s,ÌõÊý=%s,isStateChange=%s,actionState=%s"   | 
|                   % (bbType, len(bbDataList), isStateChange, actionState))  | 
|       | 
|     # Èç¹ûÊǻ½áÊøµÄ£¬Ö´Ðз¢·Å½±Àø´¦Àí  | 
|     if isStateChange and actionState == ChConfig.Def_Action_Close:  | 
|         pass  | 
|         # ¸ÄΪÔڻID±ä¸üʱ²¹·¢½±Àø  | 
|       | 
|     if bbType == ShareDefine.Def_BT_MergePKWeek:  | 
|         __Sync_RecoverMergePKWinPlayer()  | 
|     return  | 
|   | 
| def __Sync_RecoverMergePKWinPlayer():  | 
|     ## Í¬²½¸øÇëÇó»Ö¸´Á¬Ê¤µÄС»ï°é×îÐÂÅÅÐаñ  | 
|     global g_recoverMergePKWinPlayerIDList  | 
|       | 
|     if not g_recoverMergePKWinPlayerIDList:  | 
|         return  | 
|       | 
|     bbType = ShareDefine.Def_BT_MergePKWeek  | 
|     billBoard = GameWorld.GetBillboard().FindBillboard(bbType)  | 
|     if not billBoard:  | 
|         return  | 
|           | 
|     GameWorld.Log("    ¼ì²éδͬ²½ÐøÊ¤Íæ¼Òid£¡%s" % str(g_recoverMergePKWinPlayerIDList))  | 
|     syncPlayerIDList = []  | 
|     for playerID in g_recoverMergePKWinPlayerIDList:  | 
|         player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|         if not player:  | 
|             continue  | 
|         bbData = billBoard.FindByID(playerID)  | 
|         if not bbData:  | 
|             continue  | 
|           | 
|         # µ±Ç°Á¬Ê¤Óë×î´óÁ¬Ê¤ÏàµÈʱ²Åͬ²½  | 
|         if GetBBMergePKCWinCnt(bbData) != GetBBMergePKMaxCWinCnt(bbData):  | 
|             GameWorld.Log("        µ±Ç°Á¬Ê¤ != ×î´óÁ¬Ê¤ ²»Í¬²½£¡playerID=%s" % playerID)  | 
|             continue  | 
|           | 
|         PlayerBillboard.Sync_BillboardEx(player, bbType, True)  | 
|         GameWorld.Log("        Í¬²½×ÔÉíÖܰñ¸ø»Ö¸´Á¬Ê¤Íæ¼Ò£¡playerID=%s" % playerID)  | 
|           | 
|         # Í¬²½ÅÅÐаñºóÍ¨ÖªÐøÊ¤OK  | 
|         recoverOKPack = ChPyNetSendPack.tagRecoverMergePKWinOK()  | 
|         recoverOKPack.Clear()  | 
|         NetPackCommon.SendFakePack(player, recoverOKPack)  | 
|         syncPlayerIDList.append(playerID)  | 
|           | 
|     for sPlayerID in syncPlayerIDList:  | 
|         if sPlayerID in g_recoverMergePKWinPlayerIDList:  | 
|             g_recoverMergePKWinPlayerIDList.pop(g_recoverMergePKWinPlayerIDList.index(sPlayerID))  | 
|     GameWorld.Log("    Ê£Óàδͬ²½ÐøÊ¤Íæ¼Òid£¡%s" % str(g_recoverMergePKWinPlayerIDList))  | 
|     return  | 
|   | 
| def Add_RecoverMergePKWinPlayer(playerID):  | 
|     ## Ìí¼ÓÇëÇó»Ö¸´Á¬Ê¤µÄÍæ¼ÒID£¬ÓÃÓÚ×îÐÂÅÅÐаñͬ²½ºóÖ÷¶¯Í¬²½Ò»´Î¸ø¿Í»§¶Ë  | 
|     global g_recoverMergePKWinPlayerIDList  | 
|     if playerID > 0 and playerID not in g_recoverMergePKWinPlayerIDList:  | 
|         g_recoverMergePKWinPlayerIDList.append(playerID)  | 
|         GameWorld.Log("Ìí¼Ó»Ö¸´Á¬Ê¤Íæ¼ÒID: playerID=%s, %s" % (playerID, str(g_recoverMergePKWinPlayerIDList)))  | 
|     return  | 
|   | 
| def OnRecvMergePKTopPlayerView(infoDict):  | 
|     ## ×Ó·þÊÕµ½¸ßÊÖ°ñÍæ¼ÒÔ¤ÀÀÐÅÏ¢  | 
|     universalRecMgr = GameWorld.GetUniversalRecMgr()  | 
|     # Çå¿Õ¼Ç¼, ÖØÐ¸ù¾Ý±¾ÆÚ½áËãµÄÅÅÐаñÌí¼Ó¼Ç¼  | 
|     universalRecMgr.Delete(Def_MergePKTopPlayerEquipRecordType)  | 
|     GameWorld.Log("×Ó·þ¸üпç·þPK¸ßÊÖ°ñÔ¤ÀÀÐÅÏ¢¡£¡£¡£")  | 
|     recordList = universalRecMgr.GetTypeList(Def_MergePKTopPlayerEquipRecordType)  | 
|     for dataType, viewInfoDict in infoDict.items():  | 
|         GameWorld.Log("    Ô¤ÀÀÀàÐÍ£ºdataType=%s" % dataType)  | 
|         for playerID, viewInfo in viewInfoDict.items():  | 
|             playerName, equipViewInfoList, job, order = viewInfo  | 
|             __SaveEquipViewRecData(recordList, dataType, job, order, playerID, playerName, equipViewInfoList)  | 
|               | 
|     # Í¬²½ÔÚÏßÍæ¼Ò  | 
|     playerManager = GameWorld.GetPlayerManager()  | 
|     for index in xrange(0, playerManager.GetPlayerCount()):  | 
|         player = playerManager.GetPlayerByIndex(index)  | 
|         if player == None or not player.GetInitOK():  | 
|             continue  | 
|         PlayerUniversalGameRec.SendUniversalGameRecInfo(player, Def_MergePKTopPlayerEquipRecordType)  | 
|            | 
|     GameWorld.Log("    ×Ó·þ¸üпç·þPK¸ßÊÖ°ñÔ¤ÀÀÐÅÏ¢OK!")  | 
|     return  | 
|   | 
| def OnRecvRecoverMergePKWinCost(costInfoList):  | 
|     ## ¿ç·þPK»Ö¸´Á¬Ê¤¿Û·ÑÐÅÏ¢20  | 
|     accID, moneyType, costMoney, cWin, maxCWin = costInfoList      | 
|     player = GameWorld.GetPlayerManager().FindPlayerByAccID(accID)  | 
|     if not player:  | 
|         GameWorld.DebugLog("ÊÕµ½»Ö¸´Á¬Ê¤¿Û·ÑÐÅÏ¢, Íæ¼Ò²»ÔÚÏß »ò ·Ç±¾·þÍæ¼Ò£¡ accID=%s" % accID)  | 
|         return  | 
|       | 
|     # Í¨ÖªMapServer½øÐÐ¿Û·Ñ  | 
|     playerMsg = str([moneyType, costMoney, cWin, maxCWin])  | 
|     player.MapServer_QueryPlayerResult(0, 0, 'MergePKRecoverWinCost', playerMsg, len(playerMsg))  | 
|     return  | 
|   | 
| def OnRecvMergePKUnNotifyOverInfo(unNotifyPKOverInfo):  | 
|     ## ¿ç·þPKδͬ²½µÄPK½á¹û24  | 
|     playerID, overInfo = unNotifyPKOverInfo      | 
|     recData = PlayerMergeRegister.GetRegisterPlayerRec(playerID)  | 
|     GameWorld.Log("×Ó·þÊÕµ½¿ç·þPKδͬ²½µÄ½á¹û playerID=%s, %s" % (playerID, str(unNotifyPKOverInfo)), playerID)  | 
|       | 
|     # ²»ÊDZ¾·þÍæ¼Ò  | 
|     if not recData:  | 
|         GameWorld.Log("    ²»ÊDZ¾·þÍæ¼Ò playerID=%s" % playerID)  | 
|         return  | 
|       | 
|     # Èç¹û×Ó·þÍæ¼ÒÔÚÏßÖ±½Óͬ²½¸øÍæ¼Ò  | 
|     player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|     if player:  | 
|         __NotifyPKOverInfo(player, [overInfo])  | 
|         return  | 
|       | 
|     # ²»ÔÚÏßÔò¼ÓÈëͨÓüǼ£¬Ï´ÎÍæ¼ÒÉÏÏߺóͬ²½¸øÍæ¼Ò  | 
|     universalRecMgr = GameWorld.GetUniversalRecMgr()  | 
|     recordList = universalRecMgr.GetTypeList(Def_MergePKUnNotifyOverRecordType)  | 
|     recordRec = recordList.AddRec()    | 
|     recordRec.SetValue1(playerID)  | 
|     recordRec.SetStrValue3(str(overInfo))  | 
|     GameWorld.Log("    Íæ¼Ò²»ÔÚÏß, ²åÈëδͬ²½µÄ¿ç·þPK½á¹ûͨÓüǼ£¡playerID=%s" % playerID, playerID)  | 
|     return  | 
|   | 
| def OnMergePKLogin(curPlayer):  | 
|     ## ÉÏÏßͬ²½Î´Í¬²½µÄPK½á¹û¸øÍæ¼Ò  | 
|     # ½ö×Ó·þ´¦Àí  | 
|     if GameWorld.IsMergeServer():  | 
|         return  | 
|       | 
|     Sync_MergePKSeasonInfo(curPlayer)  | 
|     PlayerUniversalGameRec.SendUniversalGameRecInfo(curPlayer, Def_MergePKAwardRecordType)  | 
|       | 
|     playerPKOverList = []  | 
|     accID = curPlayer.GetAccID()  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     universalRecMgr = GameWorld.GetUniversalRecMgr()  | 
|     recordList = universalRecMgr.GetTypeList(Def_MergePKUnNotifyOverRecordType)  | 
|     recordCnt = recordList.Count()  | 
|     delCnt = 0  | 
|     GameWorld.Log("OnMergePKLogin recordCnt=%s" % recordCnt)  | 
|     #for i in xrange(recordCnt):  | 
|     #    recData = recordList.At(i)  | 
|     #    GameWorld.DebugLog("i=%s,strValue1=%s,strValue3=%s" % (i, recData.GetStrValue1(), recData.GetStrValue3()))  | 
|           | 
|     for i in xrange(recordCnt):  | 
|         dataIndex = i - delCnt  | 
|         recData = recordList.At(dataIndex)  | 
|         if not recData:  | 
|             continue  | 
|           | 
|         if recData.GetValue1() != playerID:  | 
|             continue  | 
|         overStr = recData.GetStrValue3()  | 
|         try:  | 
|             overInfo = eval(overStr)  | 
|             playerPKOverList.append(overInfo)  | 
|             recordList.Delete(dataIndex)  | 
|             delCnt += 1  | 
|         except:  | 
|             GameWorld.ErrLog("OnMergePKLogin eval(%s) error!" % overStr, curPlayer.GetPlayerID())  | 
|       | 
|     if playerPKOverList:  | 
|         GameWorld.Log("Íæ¼ÒÉÏÏßͬ²½¿ç·þPK½á¹û: accID=%s, %s" % (accID, str(playerPKOverList)), playerID)  | 
|         __NotifyPKOverInfo(curPlayer, playerPKOverList)  | 
|     return  | 
|   | 
| def OnRequestEnterMergePKMap(curPlayer, mapID, roomID):  | 
|     ## ÇëÇó½øÈë¿ç·þÆ¥ÅäPKµØÍ¼  | 
|     if mapID not in ReadChConfig.GetEvalChConfig("MergePK_Match")[Def_Match_MapIDList]:  | 
|         return False  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     vsRoom = GameWorld.GetVSRoomManager().FindVsRoom(roomID)  | 
|     if not vsRoom:  | 
|         GameWorld.ErrLog("ÕÒ²»µ½¿ç·þPK·¿¼ä, roomID=%s" % roomID, playerID)  | 
|         return True  | 
|       | 
|     for teamIndex in xrange(vsRoom.GetVsTeamCount()):  | 
|         roomTeam = vsRoom.GetVSTeam(teamIndex)  | 
|         for mIndex in xrange(roomTeam.GetMemberCount()):  | 
|             member = roomTeam.GetMember(mIndex)  | 
|             if member.GetPlayerID() == playerID:  | 
|                 factionID = ShareDefine.CampType_Evil if mIndex % 2 else ShareDefine.CampType_Justice  | 
|                 playerMsg = str([mapID, 0, factionID])  | 
|                 curPlayer.MapServer_QueryPlayerResult(0, 0, 'EnterFBSetFaction', playerMsg, len(playerMsg))  | 
|                 return True  | 
|               | 
|     GameWorld.ErrLog("¿ç·þPK·¿¼äÕÒ²»µ½¶ÔÓ¦Íæ¼Ò, roomID=%s" % roomID, playerID)    | 
|     return True  | 
|   | 
|   | 
| ################################### ½±Àø ############################################  | 
|   | 
| def __GiveMergePKAwardByMail_Day(preDayID):  | 
|     ''' Óʼþ²¹·¢¿ç·þPKµ±ÈÕδÁìÈ¡½±Àø   | 
|         @param preDayID: ²¹·¢µÄÉÏÒ»¸öÈÕÈüID, µ±ÈÕ0µãµÄtimeÖµ  | 
|     '''  | 
|     dateStr = GameWorld.ChangeTimeNumToStr(preDayID, ChConfig.TYPE_Time_YmdFormat)  | 
|     GameWorld.Log("    ÈÕÈü±ä¸ü, Óʼþ²¹·¢×òÈÕδÁìÈ¡½±Àø, preDayID=%s,dateStr=%s" % (preDayID, dateStr))  | 
|     if not preDayID:  | 
|         return  | 
|     bbType = ShareDefine.Def_BT_MergePKDay  | 
|     billboard = GameWorld.GetBillboard().FindBillboard(bbType)  | 
|     if not billboard:  | 
|         GameWorld.ErrLog("        ÕÒ²»µ½ÅÅÐаñ(%s)" % bbType)  | 
|         return  | 
|     dayPKCntInfo = ReadChConfig.GetEvalChConfig("MergePKAward_DayPKCnt")  | 
|     pkMailTempNum, pkDays, pkCntAwardDict = dayPKCntInfo  | 
|     pkCntKeyList = pkCntAwardDict.keys()  | 
|     pkCntKeyList.sort()  | 
|     sendPKCntMailDict = {} # ²¹·¢Ã¿ÈÕPK´ÎÊý½±ÀøÍæ¼Ò×ÖµäÐÅÏ¢ {pkCnt:[Ðè²¹·¢µÄÍæ¼ÒIDÁбí], ...}  | 
|       | 
|     dayWinCntInfo = ReadChConfig.GetEvalChConfig("MergePKAward_DayWinCnt")  | 
|     winMailTempNum, winDays, winCntAwardDict = dayWinCntInfo  | 
|     winCntKeyList = winCntAwardDict.keys()  | 
|     winCntKeyList.sort()  | 
|     sendWinCntMailDict = {} # ²¹·¢Ã¿ÈÕʤÀû´ÎÊý½±ÀøÍæ¼Ò×ÖµäÐÅÏ¢ {winCnt:[Ðè²¹·¢µÄÍæ¼ÒIDÁбí], ...}  | 
|   | 
|     # ±éÀúÐèÒª²¹·¢½±ÀøµÄÍæ¼Ò  | 
|     for i in xrange(billboard.GetCount()):  | 
|         bbData = billboard.At(i)  | 
|         curPlayerID = GetBBPlayerID(bbData) # Íæ¼ÒID  | 
|           | 
|         regRec = PlayerMergeRegister.GetRegisterPlayerRec(curPlayerID)  | 
|         # ²»ÊDZ¾·þÍæ¼Ò  | 
|         if not regRec:  | 
|             GameWorld.DebugLog("        ²»ÊDZ¾·þÍæ¼Ò, playerID=%s" % curPlayerID)  | 
|             continue  | 
|           | 
|         recordRec = __GetMergePKAwardRecordRec(curPlayerID)  | 
|   | 
|         curPKCnt = GetBBMergePKCnt(bbData) # PK´ÎÊý  | 
|         for pkIndex, pkCnt in enumerate(pkCntKeyList):  | 
|             if curPKCnt < pkCnt:  | 
|                 GameWorld.DebugLog("        µ±ÈÕPK´ÎÊý²»×ã²»¿É²¹·¢, playerID=%s,curPKCnt=%s < pkCnt=%s"   | 
|                                    % (curPlayerID, curPKCnt, pkCnt))  | 
|                 continue  | 
|             pkCntAwardRecord = __GetMergePKAwardRecord(recordRec, ShareDefine.Def_MergePKAward_DayPKCnt)  | 
|             if pkCntAwardRecord&pow(2, pkIndex):  | 
|                 GameWorld.DebugLog("        ÒÑÁìÈ¡µÄPK´ÎÊý²»²¹·¢, playerID=%s,pkCnt=%s,pkCntAwardRecord=%s,pkIndex=%s"   | 
|                                    % (curPlayerID, pkCnt, pkCntAwardRecord, pkIndex))  | 
|                 continue  | 
|             pkPlayerIDList = sendPKCntMailDict.get(pkCnt, [])  | 
|             if curPlayerID in pkPlayerIDList:  | 
|                 continue  | 
|             GameWorld.DebugLog("        ¼ÓÈëPK´ÎÊý²¹·¢½±ÀøÁбí, playerID=%s,pkCnt=%s,pkCntAwardRecord=%s,pkIndex=%s"   | 
|                                % (curPlayerID, pkCnt, pkCntAwardRecord, pkIndex))  | 
|             pkPlayerIDList.append(curPlayerID)  | 
|             sendPKCntMailDict[pkCnt] = pkPlayerIDList  | 
|             __SetMergePKAwardRecord(curPlayerID, recordRec, ShareDefine.Def_MergePKAward_DayPKCnt, pkCntAwardRecord|pow(2,pkIndex))  | 
|           | 
|         curWinCnt = GetBBMergePKWinCnt(bbData) # Ê¤Àû´ÎÊý  | 
|         for winIndex, winCnt in enumerate(winCntKeyList):  | 
|             if curWinCnt < winCnt:  | 
|                 GameWorld.DebugLog("        µ±ÈÕʤÀû´ÎÊý²»×ã²»¿É²¹·¢, playerID=%s,curWinCnt=%s < winCnt=%s"   | 
|                                    % (curPlayerID, curWinCnt, winCnt))  | 
|                 continue  | 
|             winCntAwardRecord = __GetMergePKAwardRecord(recordRec, ShareDefine.Def_MergePKAward_DayWinCnt)  | 
|             if winCntAwardRecord&pow(2, winIndex):  | 
|                 GameWorld.DebugLog("        ÒÑÁìÈ¡µÄʤÀû´ÎÊý²»²¹·¢, playerID=%s,winCnt=%s,winCntAwardRecord=%s,winIndex=%s"   | 
|                                    % (curPlayerID, winCnt, winCntAwardRecord, winIndex))  | 
|                 continue  | 
|             winCntPlayerIDList = sendWinCntMailDict.get(winCnt, [])  | 
|             if curPlayerID in winCntPlayerIDList:  | 
|                 continue  | 
|             GameWorld.DebugLog("        ¼ÓÈëʤÀû´ÎÊý²¹·¢½±ÀøÁбí, playerID=%s,winCnt=%s,winCntAwardRecord=%s,winIndex=%s"   | 
|                                % (curPlayerID, winCnt, winCntAwardRecord, winIndex))  | 
|             winCntPlayerIDList.append(curPlayerID)  | 
|             sendWinCntMailDict[winCnt] = winCntPlayerIDList  | 
|             __SetMergePKAwardRecord(curPlayerID, recordRec, ShareDefine.Def_MergePKAward_DayWinCnt, winCntAwardRecord|pow(2,winIndex))  | 
|               | 
|     GameWorld.Log("    ²¹·¢×òÈÕδÁìÈ¡PK´ÎÊý½±Àø: sendPKCntMailDict=%s" % sendPKCntMailDict)  | 
|     for pkCnt, pkPlayerIDList in sendPKCntMailDict.items():  | 
|         pkAwardItemList = pkCntAwardDict[pkCnt]  | 
|         pkMailContent = ShareDefine.Def_MailFormat % (pkMailTempNum, "'%s',%s" % (dateStr, pkCnt))  | 
|         guid = PlayerCompensation.SendPersonalItemMailEx("", pkMailContent, pkDays, pkPlayerIDList, pkAwardItemList)  | 
|         DataRecordPack.DR_SendMergePKRewardMail(pkPlayerIDList, guid, "DayPKCnt", pkAwardItemList, {"PKCnt":pkCnt})  | 
|   | 
|     GameWorld.Log("    ²¹·¢×òÈÕδÁìȡʤÀû´ÎÊý½±Àø: sendWinCntMailDict=%s" % sendWinCntMailDict)  | 
|     for winCnt, winPlayerIDList in sendWinCntMailDict.items():  | 
|         winAwardItemList = winCntAwardDict[winCnt]  | 
|         winMailContent = ShareDefine.Def_MailFormat % (winMailTempNum, "'%s',%s" % (dateStr, winCnt))  | 
|         guid = PlayerCompensation.SendPersonalItemMailEx("", winMailContent, winDays, winPlayerIDList, winAwardItemList)  | 
|         DataRecordPack.DR_SendMergePKRewardMail(winPlayerIDList, guid, "DayWinCnt", winAwardItemList, {"WinCnt":winCnt})  | 
|           | 
|     return  | 
|   | 
| def __GiveMergePKAwardByMail_Season(preSeasonID):  | 
|     ''' Óʼþ²¹·¢¿ç·þPKÈü¼¾Î´ÁìÈ¡½±Àø  | 
|         @param preSeasonID: ²¹·¢µÄÉÏÒ»¸öÈü¼¾ID  | 
|     '''  | 
|     GameWorld.Log("    Èü¼¾±ä¸ü, Óʼþ²¹·¢ÉϸöÈü¼¾Î´ÁìÈ¡½±Àø preSeasonID=%s" % (preSeasonID))  | 
|     if not preSeasonID:  | 
|         return  | 
|     bbType = ShareDefine.Def_BT_MergePKWeek  | 
|     billboard = GameWorld.GetBillboard().FindBillboard(bbType)  | 
|     if not billboard:  | 
|         GameWorld.ErrLog("        ÕÒ²»µ½ÅÅÐаñ(%s)" % bbType)  | 
|         return  | 
|       | 
|     rankAwardInfo = ReadChConfig.GetEvalChConfig("MergePKAward_SeasonRank")  | 
|     rankMailTempNum, rankDays, rankAwardDict = rankAwardInfo  | 
|     sendRankMailDict = {} # ²¹·¢Èü¼¾Ãû´Î½±ÀøÍæ¼ÒÐÅÏ¢ {Ãû´Î:Íæ¼ÒID, ...}  | 
|           | 
|     gradeAwardInfo = ReadChConfig.GetEvalChConfig("MergePKAward_SeasonGrade")  | 
|     gradeMailTempNum, gradeDays, gradeAwardDict = gradeAwardInfo  | 
|     gradeKeyList = gradeAwardDict.keys()  | 
|     gradeKeyList.sort()  | 
|     sendGradeMailDict = {} # ²¹·¢Èü¼¾¶Îλ½ú¼¶½±ÀøÍæ¼Ò×ÖµäÐÅÏ¢ {¶Îλ:[Ðè²¹·¢µÄÍæ¼ÒIDÁбí], ...}  | 
|       | 
|     # ±éÀúÐèÒª²¹·¢½±ÀøµÄÍæ¼Ò  | 
|     for order in xrange(1, billboard.GetCount() + 1):  | 
|         bbData = billboard.At(order - 1)  | 
|         curPlayerID = GetBBPlayerID(bbData) # Íæ¼ÒID  | 
|         regRec = PlayerMergeRegister.GetRegisterPlayerRec(curPlayerID)  | 
|         # ²»ÊDZ¾·þÍæ¼Ò  | 
|         if not regRec:  | 
|             GameWorld.DebugLog("        ²»ÊDZ¾·þÍæ¼Ò, playerID=%s" % curPlayerID)  | 
|             continue  | 
|           | 
|         curMaxGrade = GetBBPlayerMaxGrade(bbData) # ÀúÊ·×î¸ß¶Îλ  | 
|         recordRec = __GetMergePKAwardRecordRec(curPlayerID)  | 
|           | 
|         for i, grade in enumerate(gradeKeyList):  | 
|             if curMaxGrade < grade:  | 
|                 GameWorld.DebugLog("        Èü¼¾×î¸ß¶Îλ²»×ã²»¿É²¹·¢, playerID=%s,curMaxGrade=%s < grade=%s"   | 
|                                    % (curPlayerID, curMaxGrade, grade))  | 
|                 continue  | 
|             gradeAwardRecord = __GetMergePKAwardRecord(recordRec, ShareDefine.Def_MergePKAward_SeasonGrade)  | 
|             if gradeAwardRecord&pow(2, i):  | 
|                 GameWorld.DebugLog("        ÒÑÁìÈ¡µÄ¶Îλ²»²¹·¢, playerID=%s,grade=%s,gradeAwardRecord=%s,i=%s"   | 
|                                    % (curPlayerID, grade, gradeAwardRecord, i))  | 
|                 continue  | 
|             playerIDList = sendGradeMailDict.get(grade, [])  | 
|             if curPlayerID in playerIDList:  | 
|                 continue  | 
|             playerIDList.append(curPlayerID)  | 
|             sendGradeMailDict[grade] = playerIDList  | 
|             __SetMergePKAwardRecord(curPlayerID, recordRec, ShareDefine.Def_MergePKAward_SeasonGrade, gradeAwardRecord|pow(2,i))  | 
|             GameWorld.DebugLog("        ¼ÓÈë¶Îλ²¹·¢½±ÀøÍæ¼Ò, playerID=%s,grade=%s,gradeAwardRecord=%s,i=%s"   | 
|                                % (curPlayerID, grade, gradeAwardRecord, i))  | 
|               | 
|         rankAwardRecord = __GetMergePKAwardRecord(recordRec, ShareDefine.Def_MergePKAward_SeasonRank)  | 
|         if order > 0 and not rankAwardRecord:  | 
|             sendRankMailDict[order] = curPlayerID  | 
|             __SetMergePKAwardRecord(curPlayerID, recordRec, ShareDefine.Def_MergePKAward_SeasonRank, 1)  | 
|             GameWorld.DebugLog("        ¼ÓÈëÃû´Î²¹·¢½±ÀøÍæ¼Ò, playerID=%s,order=%s,rankAwardRecord=%s"   | 
|                                % (curPlayerID, order, rankAwardRecord))  | 
|         else:  | 
|             GameWorld.DebugLog("        ÒÑÁìÈ¡µÄÅÅÃû²»²¹·¢, playerID=%s,order=%s,rankAwardRecord=%s"   | 
|                                % (curPlayerID, order, rankAwardRecord))  | 
|               | 
|     GameWorld.Log("    ²¹·¢Èü¼¾Î´ÁìÈ¡¶Îλ½ú¼¶½±Àø: sendGradeMailDict=%s" % sendGradeMailDict)  | 
|     for mGrade, mPlayerIDList in sendGradeMailDict.items():  | 
|         awardItemList = gradeAwardDict[mGrade]  | 
|         gradeMailContent = ShareDefine.Def_MailFormat % (gradeMailTempNum, "%s,%s" % (preSeasonID, mGrade))  | 
|         guid = PlayerCompensation.SendPersonalItemMailEx("", gradeMailContent, gradeDays, mPlayerIDList, awardItemList)  | 
|         DataRecordPack.DR_SendMergePKRewardMail(mPlayerIDList, guid, "SeasonGrade", awardItemList, {"SeasonID":preSeasonID, "Grade":mGrade})  | 
|               | 
|     GameWorld.Log("    ²¹·¢Èü¼¾Î´ÁìÈ¡Ãû´Î½±Àø: sendRankMailDict=%s" % sendRankMailDict)  | 
|     for mOrder, mPlayerID in sendRankMailDict.items():  | 
|         rankAwardItemList = GameWorld.GetDictValueByRangeKey(rankAwardDict, mOrder)  | 
|         if not rankAwardItemList:  | 
|             continue  | 
|         rankMailContent = ShareDefine.Def_MailFormat % (rankMailTempNum, "%s,%s" % (preSeasonID, mOrder))  | 
|         guid = PlayerCompensation.SendPersonalItemMailEx("", rankMailContent, rankDays, [mPlayerID], rankAwardItemList)  | 
|         DataRecordPack.DR_SendMergePKRewardMail([mPlayerID], guid, "SeasonRank", rankAwardItemList, {"SeasonID":preSeasonID, "Rank":mOrder})  | 
|           | 
|     return  | 
|   | 
| def MapServer_QueryMergePKAward(curPlayer, msgList):  | 
|     ''' µØÍ¼Íæ¼ÒÇëÇóÁìÈ¡¿ç·þPKÏà¹Ø½±Àø '''  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     awardType, index, packSpaceNum = msgList  | 
|     GameWorld.Log("ÁìÈ¡¿ç·þPK½±Àø: awardType=%s,index=%s,packSpaceNum=%s" % (awardType, index, packSpaceNum), playerID)  | 
|       | 
|     if awardType not in ShareDefine.Def_MergePKAwardTypeList:  | 
|         GameWorld.Log("    Ã»Óиý±ÀøÀàÐÍ!")  | 
|         return ""  | 
|       | 
|     # ÅÅÃû½±ÀøÖ»ÓÐÒ»¸ö½±Àø£¬Ä¬ÈϼǼΪ0Ë÷Òý  | 
|     if awardType == ShareDefine.Def_MergePKAward_SeasonRank:  | 
|         # Èü¼¾½áËã½öÈü¼¾½áÊøºó¿ÉÁì  | 
|         if not PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_IsSeasonEnd):  | 
|             GameWorld.Log("    Èü¼¾Î´½áÊø£¬²»¿ÉÁìÈ¡¸Ã½±Àø!awardType=%s" % awardType, playerID)  | 
|             return ""  | 
|         index = 0  | 
|       | 
|     # Ê×ʤÁ콱״̬MapServerÅÐ¶Ï  | 
|     if awardType != ShareDefine.Def_MergePKAward_FirstWinCnt:  | 
|         recordRec = __GetMergePKAwardRecordRec(playerID)  | 
|         getRecord = __GetMergePKAwardRecord(recordRec, awardType)  | 
|         if getRecord&pow(2, index):  | 
|             GameWorld.Log("    ÒÑÁìÈ¡¹ý¸Ã½±Àø£¡awardType=%s,getRecord=%s,index=%s" % (awardType, getRecord, index), playerID)  | 
|             return ""  | 
|       | 
|     if awardType == ShareDefine.Def_MergePKAward_DayPKCnt:  | 
|         awardItemList = __GetMergePKAwardItemList_DayPKCnt(curPlayer, index)  | 
|     elif awardType == ShareDefine.Def_MergePKAward_DayWinCnt:  | 
|         awardItemList = __GetMergePKAwardItemList_DayWinCnt(curPlayer, index)  | 
|     elif awardType == ShareDefine.Def_MergePKAward_SeasonGrade:  | 
|         awardItemList = __GetMergePKAwardItemList_SeasonGrade(curPlayer, index)  | 
|     elif awardType == ShareDefine.Def_MergePKAward_SeasonRank:  | 
|         awardItemList = __GetMergePKAwardItemList_SeasonRank(curPlayer)  | 
|     elif awardType == ShareDefine.Def_MergePKAward_FirstWinCnt:  | 
|         awardItemList = __GetMergePKAwardItemList_FirstWinCnt(curPlayer, index)  | 
|     else:  | 
|         return ""  | 
|           | 
|     if not awardItemList:  | 
|         return ""  | 
|       | 
|     if packSpaceNum < len(awardItemList):  | 
|         GameWorld.Log("    ÁìÈ¡Á¬Ê¤½±Àø£¬±³°ü¿Õ¼ä²»×㣡awardType=%s, index=%s, packSpaceNum=%s"   | 
|                       % (awardType, index, packSpaceNum), playerID)  | 
|         return ""  | 
|       | 
|     if awardType != ShareDefine.Def_MergePKAward_FirstWinCnt:  | 
|         __SetMergePKAwardRecord(playerID, recordRec, awardType, getRecord|pow(2, index))  | 
|         PlayerUniversalGameRec.SendUniversalGameRecInfo(curPlayer, Def_MergePKAwardRecordType)  | 
|           | 
|     # ·µ»ØÁìÈ¡µÄË÷Òý£¬¼°»ñµÃµÄ½±ÀøÎïÆ·ÐÅÏ¢ÁÐ±í  | 
|     return [awardType, index, awardItemList]  | 
|   | 
| def __GetMergePKAwardRecordRec(playerID):  | 
|     ''' »ñÈ¡Íæ¼Ò¿ç·þPK½±ÀøÁìÈ¡¼Ç¼ '''  | 
|     recordList = GameWorld.GetUniversalRecMgr().GetTypeList(Def_MergePKAwardRecordType)  | 
|     recordRec = None  | 
|     for i in xrange(recordList.Count()):  | 
|         recData = recordList.At(i)  | 
|         if recData.GetValue1() != playerID:  | 
|             continue  | 
|         recordRec = recData  | 
|         break  | 
|     if not recordRec:  | 
|         recordRec = recordList.AddRec()    | 
|         recordRec.SetValue1(playerID)  | 
|     return recordRec  | 
|   | 
| def __ResetMergePKDayAwardRecord():  | 
|     ''' ÖØÖÿç·þPKÍæ¼ÒÈÕ½±ÀøÁìÈ¡¼Ç¼ '''  | 
|     recordList = GameWorld.GetUniversalRecMgr().GetTypeList(Def_MergePKAwardRecordType)  | 
|     for i in xrange(recordList.Count()):  | 
|         recordRec = recordList.At(i)  | 
|         recordRec.SetValue2(0) # Ã¿ÈÕPK´ÎÊý  | 
|         recordRec.SetValue3(0) # Ã¿ÈÕʤÀû´ÎÊý  | 
|     return  | 
|   | 
| def __GetMergePKAwardRecord(recordRec, awardType):  | 
|     ''' »ñÈ¡¿ç·þPK½±ÀøÁìÈ¡¼Ç¼ '''  | 
|     if awardType == ShareDefine.Def_MergePKAward_DayPKCnt:  | 
|         return recordRec.GetValue2()  | 
|     elif awardType == ShareDefine.Def_MergePKAward_DayWinCnt:  | 
|         return recordRec.GetValue3()  | 
|     elif awardType == ShareDefine.Def_MergePKAward_SeasonGrade:  | 
|         return recordRec.GetValue4()  | 
|     elif awardType == ShareDefine.Def_MergePKAward_SeasonRank:  | 
|         return recordRec.GetValue5()  | 
|     return 0  | 
|   | 
| def __SetMergePKAwardRecord(playerID, recordRec, awardType, record):  | 
|     ''' ÉèÖÿç·þPK½±ÀøÁìÈ¡¼Ç¼ '''  | 
|     if awardType == ShareDefine.Def_MergePKAward_DayPKCnt:  | 
|         recordRec.SetValue2(record)  | 
|     elif awardType == ShareDefine.Def_MergePKAward_DayWinCnt:  | 
|         recordRec.SetValue3(record)  | 
|     elif awardType == ShareDefine.Def_MergePKAward_SeasonGrade:  | 
|         recordRec.SetValue4(record)  | 
|     elif awardType == ShareDefine.Def_MergePKAward_SeasonRank:  | 
|         recordRec.SetValue5(record)  | 
|     GameWorld.Log("        ¸üпç·þPK½±ÀøÁìÈ¡¼Ç¼: playerID=%s,awardType=%s,record=%s" % (playerID, awardType, record))  | 
|     return  | 
|   | 
| def __GetMergePKAwardItemList_DayPKCnt(curPlayer, index):  | 
|     ''' »ñÈ¡¿ç·þPKµ±ÈÕPK´ÎÊý½±ÀøÎïÆ·ÐÅÏ¢Áбí '''  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     bbData = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKDay, playerID)[1]  | 
|     if not bbData:  | 
|         return []  | 
|       | 
|     dayPKCntInfo = ReadChConfig.GetEvalChConfig("MergePKAward_DayPKCnt")  | 
|     pkCntAwardDict = dayPKCntInfo[2]  | 
|     pkCntKeyList = pkCntAwardDict.keys()  | 
|     pkCntKeyList.sort()  | 
|     maxLen = len(pkCntKeyList)  | 
|     if index >= maxLen or index < 0:  | 
|         GameWorld.Log("    ÁìȡÿÈÕPK´ÎÊý½±ÀøË÷ÒýÔ½½ç£¡index=%s,maxLen=%s" % (index, maxLen), playerID)  | 
|         return []  | 
|       | 
|     needPKCnt = pkCntKeyList[index]  | 
|     curPKCnt = GetBBMergePKCnt(bbData)  | 
|     if needPKCnt > curPKCnt:  | 
|         GameWorld.Log("    ÁìȡÿÈÕPK´ÎÊý½±Àø´ÎÊý²»×ã, needPKCnt=%s > curPKCnt=%s" % (needPKCnt, curPKCnt), playerID)  | 
|         return []  | 
|     return pkCntAwardDict[needPKCnt]  | 
|   | 
| def __GetMergePKAwardItemList_DayWinCnt(curPlayer, index):  | 
|     ''' »ñÈ¡¿ç·þPKµ±ÈÕʤÀû´ÎÊý½±ÀøÎïÆ·ÐÅÏ¢Áбí '''  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     bbData = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKDay, playerID)[1]  | 
|     if not bbData:  | 
|         return []  | 
|       | 
|     dayWinCntInfo = ReadChConfig.GetEvalChConfig("MergePKAward_DayWinCnt")  | 
|     winCntAwardDict = dayWinCntInfo[2]  | 
|     winCntKeyList = winCntAwardDict.keys()  | 
|     winCntKeyList.sort()  | 
|     maxLen = len(winCntKeyList)  | 
|     if index >= maxLen or index < 0:  | 
|         GameWorld.Log("    ÁìȡÿÈÕʤÀû´ÎÊý½±ÀøË÷ÒýÔ½½ç£¡index=%s,maxLen=%s" % (index, maxLen), playerID)  | 
|         return []  | 
|       | 
|     needWinCnt = winCntKeyList[index]  | 
|     curWinCnt = GetBBMergePKWinCnt(bbData)  | 
|     if needWinCnt > curWinCnt:  | 
|         GameWorld.Log("    ÁìȡÿÈÕʤÀû´ÎÊý½±Àø´ÎÊý²»×ã, needWinCnt=%s > curWinCnt=%s" % (needWinCnt, curWinCnt), playerID)  | 
|         return []  | 
|     return winCntAwardDict[needWinCnt]  | 
|   | 
| def __GetMergePKAwardItemList_FirstWinCnt(curPlayer, index):  | 
|     ''' »ñÈ¡¿ç·þPKÊ×´ÎʤÀû´ÎÊý½±ÀøÎïÆ·ÐÅÏ¢ÁÐ±í   | 
|          Ê¤Àû´ÎÊýȡÿ¸öÈü¼¾µÄʤÀû´ÎÊý, Èü¼¾ÖØÖúó, Ê¤Àû´ÎÊýÖØÐÂͳ¼Æ, Á콱״̬²»ÖØÖà  | 
|     '''  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     bbData = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKWeek, playerID)[1]  | 
|     if not bbData:  | 
|         return []  | 
|       | 
|     firstWinCntAwardDict = ReadChConfig.GetEvalChConfig("MergePKAward_FirstWinCnt")  | 
|     firstWinCntKeyList = firstWinCntAwardDict.keys()  | 
|     firstWinCntKeyList.sort()  | 
|     maxLen = len(firstWinCntKeyList)  | 
|     if index >= maxLen or index < 0:  | 
|         GameWorld.Log("    ÁìÈ¡Ê×´ÎʤÀû´ÎÊý½±ÀøË÷ÒýÔ½½ç£¡index=%s,maxLen=%s" % (index, maxLen), playerID)  | 
|         return []  | 
|       | 
|     needWinCnt = firstWinCntKeyList[index]  | 
|     curWinCnt = GetBBMergePKWinCnt(bbData)  | 
|     if needWinCnt > curWinCnt:  | 
|         GameWorld.Log("    ÁìÈ¡Ê×´ÎʤÀû´ÎÊý½±Àø´ÎÊý²»×ã, needWinCnt=%s > curWinCnt=%s" % (needWinCnt, curWinCnt), playerID)  | 
|         return []  | 
|     return firstWinCntAwardDict[needWinCnt]  | 
|   | 
| def __GetMergePKAwardItemList_SeasonGrade(curPlayer, index):  | 
|     ''' »ñÈ¡¿ç·þPKÈü¼¾¶Îλ½ú¼¶½±ÀøÎïÆ·ÐÅÏ¢Áбí '''  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     bbData = GetMatchPlayerBillboardData(ShareDefine.Def_BT_MergePKWeek, playerID)[1]  | 
|     if not bbData:  | 
|         return []  | 
|       | 
|     seasonGradeInfo = ReadChConfig.GetEvalChConfig("MergePKAward_SeasonGrade")  | 
|     gradeAwardDict = seasonGradeInfo[2]  | 
|     gradeKeyList = gradeAwardDict.keys()  | 
|     gradeKeyList.sort()  | 
|     maxLen = len(gradeKeyList)  | 
|     if index >= maxLen or index < 0:  | 
|         GameWorld.Log("    ÁìÈ¡Èü¼¾½ú¼¶½±ÀøË÷ÒýÔ½½ç£¡index=%s,maxLen=%s" % (index, maxLen), playerID)  | 
|         return []  | 
|       | 
|     needGrade = gradeKeyList[index]  | 
|     curMaxGrade = GetBBPlayerMaxGrade(bbData) # ÕâÀïÈ¡ÀúÊ·×î´ó¶Îλ  | 
|     if needGrade > curMaxGrade:  | 
|         GameWorld.Log("    ÁìÈ¡Èü¼¾½ú¼¶½±Àø¶Îλ²»×ã, needGrade=%s > curMaxGrade=%s" % (needGrade, curMaxGrade), playerID)  | 
|         return []  | 
|     return gradeAwardDict[needGrade]  | 
|   | 
| def __GetMergePKAwardItemList_SeasonRank(curPlayer):  | 
|     ''' »ñÈ¡¿ç·þPKÈü¼¾ÅÅÃû½±ÀøÎïÆ·ÐÅÏ¢Áбí '''  | 
|     billBoard = GameWorld.GetBillboard().FindBillboard(ShareDefine.Def_BT_MergePKWeek)  | 
|     if not billBoard:  | 
|         GameWorld.ErrLog("    ÕÒ²»µ½Èü¼¾ÅÅÐаñ...")  | 
|         return []  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     seasonOrder = billBoard.IndexOfByID(playerID) + 1  # Íæ¼ÒÔÚÅÅÐаñÖеÄÃû´Î  | 
|     if seasonOrder <= 0:  | 
|         GameWorld.Log("    »ñÈ¡Èü¼¾ÅÅÃû½±ÀøÎ´Éϰñ, seasonOrder=%s" % seasonOrder, playerID)  | 
|         return []  | 
|       | 
|     seasonRankInfo = ReadChConfig.GetEvalChConfig("MergePKAward_SeasonRank")  | 
|     rankAwardDict = seasonRankInfo[2]  | 
|     rankAwardItemList = GameWorld.GetDictValueByRangeKey(rankAwardDict, seasonOrder, [])  | 
|     if not rankAwardItemList:  | 
|         GameWorld.ErrLog("    ÕÒ²»µ½Èü¼¾ÅÅÃû½±ÀøÅäÖÃ: seasonOrder=%s" % seasonOrder, playerID)  | 
|     return rankAwardItemList  | 
|   | 
|   | 
| def Sync_MergePKSeasonInfo(curPlayer):  | 
|     # Í¨ÖªÈü¼¾ÐÅÏ¢, curPlayer ÎªNoneʱ֪ͨȫ·þÍæ¼Ò  | 
|     dbSeasonID = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_MergePKSeasonID)  | 
|     dbStartTime = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_MergePKSeasonStartTime)  | 
|     if not dbSeasonID or not dbStartTime:  | 
|         return  | 
|       | 
|     seasonInfo = ChPyNetSendPack.tagGCMergePKSeasonInfo()  | 
|     seasonInfo.Clear()  | 
|     seasonInfo.SeasonID = dbSeasonID  | 
|     seasonInfo.SeasonStartTime = dbStartTime  | 
|     seasonInfo.SeasonCycle = ReadChConfig.GetEvalChConfig("MergePK_Season")  | 
|     seasonInfo.IsSeasonEnd = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_IsSeasonEnd)  | 
|       | 
|     if not curPlayer:  | 
|         # È«·þ¹ã²¥ÔÚÏßÍæ¼Ò  | 
|         playerManager = GameWorld.GetPlayerManager()  | 
|         for i in xrange(playerManager.GetPlayerCount()):  | 
|             curPlayer = playerManager.GetPlayerByIndex(i)  | 
|             if curPlayer == None or not curPlayer.GetInitOK():  | 
|                 continue  | 
|             NetPackCommon.SendFakePack(curPlayer, seasonInfo)  | 
|     else:  | 
|         NetPackCommon.SendFakePack(curPlayer, seasonInfo)  | 
|     return  | 
|   |