| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package CrossBattlefield  | 
| #  | 
| # @todo:¿ç·þÕ½³¡/¹ÅÉñÕ½³¡  | 
| # @author hxp  | 
| # @date 2022-01-06  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ¿ç·þÕ½³¡/¹ÅÉñÕ½³¡  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2022-01-06 20:30"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import datetime  | 
| import PyGameData  | 
| import CrossRealmMsg  | 
| import PlayerControl  | 
| import PyDataManager  | 
| import ChPyNetSendPack  | 
| import CrossRealmPlayer  | 
| import PlayerCompensation  | 
| import PlayerViewCache  | 
| import PlayerFuncTeam  | 
| import CrossBillboard  | 
| import IpyGameDataPY  | 
| import NetPackCommon  | 
| import ShareDefine  | 
| import GameWorld  | 
| import PlayerFB  | 
| import ChConfig  | 
|   | 
| import operator  | 
| import time  | 
|   | 
| '''  | 
| ÈȸüÅäÖà  | 
| Ð޸ĿªÆôʱ¼ä£¬Ö»Äܵȵ±Ìì¶¼½áÊøÁ˲ÅÄܸüУ¬¼´¸ôÌìÉúЧ£¬²»È»¿ÉÄܵ¼ÖÂÒѹºÂò³¡´ÎµÄÍæ¼Ò¹ºÂòÊý¾Ý¶ªÊ§  | 
| ÆäËûÅäÖÃÔÝÎÞÓ°Ï죬¿ÉÖ±½ÓÈȸü  | 
|   | 
| ºÏ·þ  | 
| ¿ª·Åʱ¼äͬ¿ç·þPKÒ»Ñù£¬Èü¼¾½áÊøÆÚ¼ä²»¿É¹ºÂò£¬²»¿É¿ªÆô£¬¸ø·ÖÇøµ÷ÕûÌÚ³ö¿Õ¼ä£¬¹¦Äܲ»¿¼ÂÇ·ÖÇø±ä¸ü´øÀ´µÄÎÊÌâ  | 
| '''  | 
|   | 
| Def_RecType_CrossBattlefieldBuy = ShareDefine.Def_UniversalGameRecType_CrossBattlefieldBuy  | 
| '''  | 
| Íæ¼Ò¿ªÆôµÄ¿ç·þÕ½³¡  | 
| ShareDefine.Def_UniversalGameRecType_CrossBattlefieldBuy  | 
| time:time                ¹ºÂòʱ¼ä  | 
| value1:zoneID            ·ÖÇøID  | 
| value2:hmNum            Ê±·Ö³¡´Î±àºÅ  | 
| value3:playerID        ¹ºÂòµÄÍæ¼ÒID  | 
| value4:factionID        ËùÑ¡ÔñµÄÕóÓªID  | 
| value5:serverOnly        ÊÇ·ñ½ö±¾·þÍæ¼Ò¿É¼ÓÈ룬0-·ñ£¬1-ÊÇ  | 
|   | 
| StrValue3:[callPlayerID,...]    ÕÙ¼¯À´µÄÍæ¼ÒID£¬°üº¬×Ô¼º  | 
| '''  | 
|   | 
| class CrossBattlefieldBuy():  | 
|     ''' ¿ç·þÕ½³¡¹ºÂò¼Ç¼  | 
|     '''  | 
|     def __init__(self):  | 
|         self.Clear()  | 
|         return  | 
|       | 
|     def Clear(self):  | 
|         self.buyTime = 0  | 
|         self.hmNum = 0  | 
|         self.zoneID = 0  | 
|         self.playerID = 0  | 
|         self.factionID = 0  | 
|         self.serverOnly = 0  | 
|         self.callPlayerIDList = []  | 
|           | 
|         # ×Ó·þÓ㬿ç·þ·þÎñÆ÷ͬ²½Êý¾Ýʱ¸ºÖµ£» ²»´æ¿â£¬Íæ¼ÒÊôÐÔ»º´æÐÅÏ¢£¬±¾·þÍæ¼ÒÈ¡×Ô¼º·þÎñÆ÷×îлº´æ  | 
|         self.callPlayerDict = {} # {playerID:{attrName:value, ...}, ...}  | 
|         return  | 
|       | 
|     def GetSyncClientServerString(self):  | 
|         self.callPlayerDict = {}  | 
|         for playerID in self.callPlayerIDList:  | 
|             curCache = PlayerViewCache.FindViewCache(playerID)  | 
|             if not curCache:  | 
|                 continue  | 
|             cacheDict = PlayerViewCache.GetCachePropDataDict(curCache)  | 
|             self.callPlayerDict[playerID] = {"Name":cacheDict["Name"], "Job":cacheDict["Job"], "LV":cacheDict["LV"],   | 
|                                              "RealmLV":cacheDict["RealmLV"], "FightPower":cacheDict["FightPower"]}  | 
|               | 
|         return {"buyTime":self.buyTime, "hmNum":self.hmNum, "zoneID":self.zoneID, "playerID":self.playerID, "factionID":self.factionID,  | 
|                 "serverOnly":self.serverOnly, "callPlayerIDList":self.callPlayerIDList, "callPlayerDict":self.callPlayerDict}  | 
|           | 
|     def SetAttr(self, attrDict):  | 
|         for k, v in attrDict.items():  | 
|             setattr(self, k, v)  | 
|         return  | 
|   | 
| def OnServerStart():  | 
|       | 
|     if not GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     PyGameData.g_crossBattlefieldBuyInfo = {}  | 
|       | 
|     universalRecMgr = GameWorld.GetUniversalRecMgr()  | 
|     recDataList = universalRecMgr.GetTypeList(Def_RecType_CrossBattlefieldBuy)  | 
|     GameWorld.Log("¼ÓÔØ¿ç·þÕ½³¡¹ºÂò¼Ç¼! %s" % recDataList.Count())  | 
|       | 
|     for index in xrange(recDataList.Count()):  | 
|         recData = recDataList.At(index)  | 
|         zoneID = recData.GetValue1()  | 
|         hmNum = recData.GetValue2()  | 
|         playerID = recData.GetValue3()  | 
|         factionID = recData.GetValue4()  | 
|         serverOnly = recData.GetValue5()  | 
|           | 
|         strValue3 = recData.GetStrValue3()  | 
|               | 
|         buyRec = CrossBattlefieldBuy()  | 
|         buyRec.buyTime = recData.GetTime()  | 
|         buyRec.zoneID = zoneID  | 
|         buyRec.hmNum = hmNum  | 
|         buyRec.playerID = playerID  | 
|         buyRec.factionID = factionID  | 
|         buyRec.serverOnly = serverOnly  | 
|         buyRec.callPlayerIDList = eval(strValue3) if strValue3 else []  | 
|           | 
|         buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)  | 
|         buyPlayerInfo[playerID] = buyRec  | 
|           | 
|         GameWorld.Log("    %s" % buyRec.GetSyncClientServerString())  | 
|           | 
|     return  | 
|   | 
| def OnServerClose():  | 
|     if not GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     universalRecMgr = GameWorld.GetUniversalRecMgr()  | 
|     universalRecMgr.Delete(Def_RecType_CrossBattlefieldBuy)  | 
|       | 
|     GameWorld.Log("±£´æ¿ç·þÕ½³¡¹ºÂò¼Ç¼!")  | 
|       | 
|     recDataList = universalRecMgr.GetTypeList(Def_RecType_CrossBattlefieldBuy)  | 
|     for _, buyHMInfo in PyGameData.g_crossBattlefieldBuyInfo.items():  | 
|         for _, buyPlayerInfo in buyHMInfo.items():  | 
|             for buyRec in buyPlayerInfo.values():  | 
|                 GameWorld.Log("    %s" % buyRec.GetSyncClientServerString())  | 
|                   | 
|                 recData = recDataList.AddRec()  | 
|                 recData.SetTime(buyRec.buyTime)  | 
|                   | 
|                 recData.SetValue1(buyRec.zoneID)  | 
|                 recData.SetValue2(buyRec.hmNum)  | 
|                 recData.SetValue3(buyRec.playerID)  | 
|                 recData.SetValue4(buyRec.factionID)  | 
|                 recData.SetValue5(buyRec.serverOnly)  | 
|                   | 
|                 recData.SetStrValue3(str(buyRec.callPlayerIDList).replace(" ", ""))  | 
|                   | 
|     return  | 
|   | 
| def GetHMNum(openHour, openMinute): return openHour * 100 + openMinute  | 
| def GetHMByNum(hmNum): return hmNum / 100, hmNum % 100  | 
|   | 
| def GetCrossBattlefieldZoneIpyDataList(serverGroupID=0):  | 
|     ## »ñÈ¡ËùÓзÖÇøÅäÖÃÁÐ±í  | 
|     ipyDataList = CrossRealmPlayer.GetCrossZoneIpyDataListByServerGroupID(ChConfig.Def_FBMapID_CrossBattlefield, serverGroupID)  | 
|     if not ipyDataList:  | 
|         return []  | 
|     return ipyDataList  | 
|   | 
| def GetCrossBattlefieldZoneIpyData(serverGroupID):  | 
|     ## »ñÈ¡·þÎñÆ÷ËùÊô·ÖÇøÅäÖà  | 
|     return CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(ChConfig.Def_FBMapID_CrossBattlefield, serverGroupID)  | 
|   | 
| def GetCrossBattlefieldZoneID(serverGroupID):  | 
|     ## »ñÈ¡·þÎñÆ÷ËùÊô·ÖÇøID  | 
|     zoneIpyData = GetCrossBattlefieldZoneIpyData(serverGroupID)  | 
|     if not zoneIpyData:  | 
|         return 0  | 
|     return zoneIpyData.GetZoneID()  | 
|   | 
| def OnPlayerLogin(curPlayer):  | 
|     zoneIpyData = GetCrossBattlefieldZoneIpyData(GameWorld.GetServerGroupID())  | 
|     if not zoneIpyData:  | 
|         return  | 
|     zoneID = zoneIpyData.GetZoneID()  | 
|     SyncCrossBattlefieldBuyInfo(curPlayer, zoneID)  | 
|     return  | 
|   | 
| def DoOnDayEx():  | 
|     if not GameWorld.IsCrossServer():  | 
|         return  | 
|     PyGameData.g_crossBattlefieldBuyInfo = {}  | 
|     Sync_CrossBattlefieldDataToClientServer()  | 
|     return  | 
|   | 
| def DoOnWeekEx():  | 
|     if not GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     enterWeekMoneyItemID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboardJoin", 3) # ÖܲÎÓë°ñ¶îÍâ½±Àø»õ±ÒÎïÆ·ID  | 
|     enterWeekMoneyMultiDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboardJoin", 4, {}) # ÖܲÎÓë°ñ¶îÍâ½±Àø»õ±ÒÃû´Î¶ÔÓ¦±¶Öµ  | 
|     enterWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboardJoin", 2, {}) # ÖܲÎÓë°ñÃû´Î¶ÔÓ¦½±ÀøÎïÆ·Áбí {"Ãû´Î":[[ÎïÆ·ID,¸öÊý,ÊÇ·ñÅÄÆ·], ...], ...} , Ãû´ÎÅäÖÃÖ§³Ö¶ÎÅäÖà  | 
|     callWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboard", 2, {}) # ÖÜÕÙ¼¯°ñÃû´Î¶ÔÓ¦½±ÀøÎïÆ·Áбí {"Ãû´Î":[[ÎïÆ·ID,¸öÊý,ÊÇ·ñÅÄÆ·], ...], ...} , Ãû´ÎÅäÖÃÖ§³Ö¶ÎÅäÖà  | 
|     scoreWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboard", 3, {}) # ÖÜ»ý·Ö°ñÃû´Î¶ÔÓ¦½±ÀøÎïÆ·Áбí {"Ãû´Î":[[ÎïÆ·ID,¸öÊý,ÊÇ·ñÅÄÆ·], ...], ...} , Ãû´ÎÅäÖÃÖ§³Ö¶ÎÅäÖà  | 
|       | 
|     enterWeekMoneyMultiIntDict = {int(k):v for k, v in enterWeekMoneyMultiDict.items()}  | 
|     enterWeekOrderIntAwardDict = {int(k):v for k, v in enterWeekOrderAwardDict.items()}  | 
|     callWeekOrderIntAwardDict = {int(k):v for k, v in callWeekOrderAwardDict.items()}  | 
|     scoreWeekOrderIntAwardDict = {int(k):v for k, v in scoreWeekOrderAwardDict.items()}  | 
|       | 
|     billboardDict = {  | 
|                      ShareDefine.Def_CBT_BattlefieldWJoin:[enterWeekOrderIntAwardDict, "CrossBattlefieldEnterOrderWeek"],  | 
|                      ShareDefine.Def_CBT_BattlefieldWCall:[callWeekOrderIntAwardDict, "CrossBattlefieldCallOrderWeek"],  | 
|                      ShareDefine.Def_CBT_BattlefieldWScore:[scoreWeekOrderIntAwardDict, "CrossBattlefieldScoreOrderWeek"],  | 
|                      }  | 
|     # ½áËãÖܰñ  | 
|     billboardMgr = PyDataManager.GetCrossBillboardManager()  | 
|     for billboardType, doInfo in billboardDict.items():  | 
|         awardDict, mailKey = doInfo  | 
|         groupList = billboardMgr.GetBillboardGroupList(billboardType)  | 
|         GameWorld.Log("¹ýÖܽáËã¿ç·þÕ½³¡Öܰñ½±Àø: billboardType=%s,groupList=%s" % (billboardType, groupList))  | 
|         for billboardType, groupValue1, groupValue2 in groupList:  | 
|             billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)  | 
|             if not billboardObj:  | 
|                 continue  | 
|             billboardObj.SortData()  | 
|             for i in xrange(billboardObj.GetCount()):  | 
|                 billboardData = billboardObj.At(i)  | 
|                 if not billboardData:  | 
|                     continue  | 
|                 playerID = billboardData.ID  | 
|                 cmpValue = billboardData.CmpValue  | 
|                 rank = i + 1  | 
|                 awardItemList = []  | 
|                 rankAwardItemList = GameWorld.GetOrderValueByDict(awardDict, rank, False, [])  | 
|                 if rankAwardItemList:  | 
|                     awardItemList.extend(rankAwardItemList)  | 
|                 paramList = [rank]  | 
|                 if billboardType == ShareDefine.Def_CBT_BattlefieldWJoin and enterWeekMoneyItemID:  | 
|                     moneyBaseCount, multiValue = GameWorld.GetOrderValueByDict(enterWeekMoneyMultiIntDict, rank, False, [0, 0]) # ½±Àø»õ±Ò±¶Öµ  | 
|                     #»ù´¡±£µ×Öµ£¨²»Í¬Ãû´Î¿ÉÄܲ»Ò»Ñù£© + Ãû´Î±¶ÂÊ*´ÎÊý  | 
|                     awardMoneyCount = int(moneyBaseCount + multiValue * cmpValue)  | 
|                     awardItemList.append([enterWeekMoneyItemID, awardMoneyCount, 0])  | 
|                 GameWorld.Log("    billboardType=%s,rank=%s,playerID=%s,cmpValue=%s,awardItemList=%s"   | 
|                               % (billboardType, rank, playerID, cmpValue, awardItemList))  | 
|                 if awardItemList:  | 
|                     PlayerCompensation.SendMailByKey(mailKey, [playerID], awardItemList, paramList, crossMail=True)  | 
|                   | 
|             billboardObj.ClearData()  | 
|               | 
|     return  | 
|   | 
| def GetCrossBattlefieldState():  | 
|     return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield)  | 
|   | 
| def IsBattlefieldCallPlayer(playerID):  | 
|     ## ÊÇ·ñÕ½³¡ÕÙ¼¯Íæ¼Ò£¬°üº¬±»ÕÙ¼¯Íæ¼Ò  | 
|     for buyHMInfo in PyGameData.g_crossBattlefieldBuyInfo.values():  | 
|         for buyPlayerInfo in buyHMInfo.values():  | 
|             for buyRec in buyPlayerInfo.values():  | 
|                 if playerID in buyRec.callPlayerIDList:  | 
|                     return True  | 
|     return False  | 
|   | 
| def GetBuyPlayerInfo(zoneID, hmNum):  | 
|     ## »ñȡս³¡¹ºÂòÕÙ¼¯³¡´ÎÍæ¼ÒÐÅÏ¢  | 
|     ## @return: buyPlayerInfo={playerID:CrossBattlefieldBuy, ...}  | 
|     if zoneID not in PyGameData.g_crossBattlefieldBuyInfo:  | 
|         PyGameData.g_crossBattlefieldBuyInfo[zoneID] = {}  | 
|     buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo[zoneID]  | 
|     if hmNum not in buyHMInfo:  | 
|         buyHMInfo[hmNum] = {}  | 
|     buyPlayerInfo = buyHMInfo[hmNum]  | 
|     return buyPlayerInfo  | 
|   | 
| def Sync_CrossBattlefieldDataToClientServer(serverGroupID=0):  | 
|     ''' Í¬²½¿ç·þÕ½³¡Êý¾Ýµ½×Ó·þÎñÆ÷  | 
|     @param serverGroupID: Îª0ʱͬ²½ËùÓÐ×Ó·þ  | 
|     '''  | 
|       | 
|     GameWorld.Log("ͬ²½¸ø×Ó·þ¿ç·þÕ½³¡Êý¾Ý: syncServerGroupID=%s" % (serverGroupID))  | 
|     crossZoneList = GetCrossBattlefieldZoneIpyDataList(serverGroupID)  | 
|     if not crossZoneList:  | 
|         return  | 
|       | 
|     # Í¨Öª×´Ì¬ - È«ÇøÒ»Ö  | 
|     battlefieldState = GetCrossBattlefieldState()  | 
|     dataMsg = {"battlefieldState":battlefieldState}  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_BattlefieldState, dataMsg)  | 
|       | 
|     for zoneIpyData in crossZoneList:  | 
|         zoneID = zoneIpyData.GetZoneID()  | 
|         serverGroupIDList = [serverGroupID] if serverGroupID else zoneIpyData.GetServerGroupIDList()  | 
|           | 
|         # Í¨Öª¹ºÂòÐÅÏ¢  | 
|         Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList)  | 
|                   | 
|     return  | 
|   | 
| def Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, opData=None):  | 
|     # Í¨Öª×Ó·þ¹ºÂòÐÅÏ¢  | 
|       | 
|     buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo.get(zoneID, {})  | 
|     if opData:  | 
|         hmNum = GetHMNum(opData["openHour"], opData["openMinute"])  | 
|         hmNumList = [hmNum]  | 
|     else:  | 
|         hmNumList = buyHMInfo.keys()  | 
|           | 
|     syncBuyHMInfo = {}  | 
|     for hmNum in hmNumList:  | 
|         if hmNum not in buyHMInfo:  | 
|             continue  | 
|         buyPlayerInfo = buyHMInfo[hmNum]  | 
|           | 
|         syncBuyPlayerInfo = {}  | 
|         for playerID, buyRec in buyPlayerInfo.items():  | 
|             syncBuyPlayerInfo[playerID] = buyRec.GetSyncClientServerString()  | 
|         syncBuyHMInfo[hmNum] = syncBuyPlayerInfo  | 
|           | 
|     sendMsg = {"zoneID":zoneID, "syncBuyHMInfo":syncBuyHMInfo, "opData":opData}  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_BattlefieldBuy, sendMsg, serverGroupIDList)  | 
|     return  | 
|   | 
| def OnMapServerInitOK():  | 
|     # Í¨ÖªµØÍ¼·þÎñÆ÷״̬  | 
|     SyncMapServerCrossBattlefieldBuyInfo()  | 
|     SyncMapServerCrossBattlefieldSysCallBuyInfo()  | 
|     return  | 
|   | 
| def SyncMapServerCrossBattlefieldBuyInfo():  | 
|     #if not GameWorld.IsCrossServer():  | 
|     #    return  | 
|     syncMapBuyInfo = {}  | 
|     for zoneID, buyHMInfo in PyGameData.g_crossBattlefieldBuyInfo.items():  | 
|         syncMapBuyInfo[zoneID] = {}  | 
|         for hmNum, buyPlayerInfo in buyHMInfo.items():  | 
|             buyInfo = {}  | 
|             for playerID, buyRec in buyPlayerInfo.items():  | 
|                 buyInfo[playerID] = {"callPlayerIDList":buyRec.callPlayerIDList, "factionID":buyRec.factionID}  | 
|             syncMapBuyInfo[zoneID][hmNum] = buyInfo  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossBattlefieldCallTeamInfo, syncMapBuyInfo)  | 
|     return  | 
|   | 
| def SyncMapServerCrossBattlefieldSysCallBuyInfo():  | 
|     syncMapBuyInfo = PyGameData.g_crossBattlefieldSysCallBuyList  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossBattlefieldSysCallBuyInfo, syncMapBuyInfo)  | 
|     return  | 
|   | 
| def OnMinuteProcess():  | 
|     if not GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     Dispose_CrossBattlefieldState()  | 
|     return  | 
|   | 
| def __GetCrossBattlefieldTime(isRefreshState=True):  | 
|       | 
|     key = "CrossBattlefieldTimeInfo"  | 
|     CrossBattlefieldTimeInfo = IpyGameDataPY.GetConfigEx(key)  | 
|     serverTime = GameWorld.GetServerTime()  | 
|     reloadSign = "%d-%d-%d" % (serverTime.year, serverTime.month, serverTime.day)  | 
|     if CrossBattlefieldTimeInfo and CrossBattlefieldTimeInfo[0] == reloadSign:  | 
|         GameWorld.DebugLog("ÒѾ¼ÓÔØ¹ý±¾ÈÕ¿ç·þÕ½³¡Ê±¼ä״̬ÐÅÏ¢£¡reloadSign=%s" % reloadSign)  | 
|         return False, CrossBattlefieldTimeInfo[1]  | 
|       | 
|     sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)  | 
|     callOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 2)  | 
|     allOpenHMList = sysOpenHMList + callOpenHMList  | 
|     dailyIpyData = IpyGameDataPY.GetIpyGameData("DailyAction", ShareDefine.DailyActionID_CrossBattlefield)  | 
|     fbTotalMinutes = dailyIpyData.GetDuration() if dailyIpyData else 10  | 
|       | 
|     openNotifyMinuteList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 3)  | 
|       | 
|     battleTimeInfoList = []  | 
|       | 
|     startDateStr = "%d-%d-%d" % (serverTime.year, serverTime.month, serverTime.day)  | 
|     for openHour, openMinute in allOpenHMList:  | 
|           | 
|         openDateTime = datetime.datetime.strptime("%s %02d:%02d:00" % (startDateStr, openHour, openMinute), ChConfig.TYPE_Time_Format)  | 
|         closeDateTime = openDateTime + datetime.timedelta(minutes=fbTotalMinutes)  | 
|           | 
|         notifyOpenTimeDict = {}  | 
|         for notifyOpenMinute in openNotifyMinuteList:  | 
|             notifyOpenDateTime = openDateTime + datetime.timedelta(minutes=-notifyOpenMinute)  | 
|             notifyOpenTimeDict[notifyOpenDateTime] = notifyOpenMinute  | 
|               | 
|         battleTimeInfoList.append([openHour, openMinute, openDateTime, closeDateTime, notifyOpenTimeDict])  | 
|           | 
|     CrossBattlefieldTimeInfo = IpyGameDataPY.SetConfigEx(key, [reloadSign, battleTimeInfoList])  | 
|       | 
|     GameWorld.Log("±¾ÈÕ¿ç·þÕ½³¡Ê±¼ä״̬ÐÅÏ¢¼ÓÔØÍê±Ï!reloadSign=%s,isRefreshState=%s" % (reloadSign, isRefreshState))  | 
|     GameWorld.Log("    allOpenHMList=%s,fbTotalMinutes=%s" % (allOpenHMList, fbTotalMinutes))  | 
|     GameWorld.Log("=============================================================")  | 
|     if isRefreshState:  | 
|         Dispose_CrossBattlefieldState(True)  | 
|           | 
|     return True, CrossBattlefieldTimeInfo[1]  | 
|   | 
| def Dispose_CrossBattlefieldState(reloadRefresh=False):  | 
|       | 
|     isReload, battlefieldTimeList = __GetCrossBattlefieldTime(False)  | 
|     isReload = isReload or reloadRefresh  | 
|       | 
|     # ÕâÀïʱ¼äÐ辫ȷµ½·ÖÖÓ£¬²»È»ºóÃæµÄ±È½Ï»áÆ¥Åä²»µ½  | 
|     curDateTime = GameWorld.GetServerTime()  | 
|     curDateTime = datetime.datetime.strptime("%d-%d-%d %d:%d:00" % (curDateTime.year, curDateTime.month, curDateTime.day,  | 
|                                                                     curDateTime.hour, curDateTime.minute), ChConfig.TYPE_Time_Format)  | 
|       | 
|     battlefieldState = 0  | 
|     for openHour, openMinute, openDateTime, closeDateTime, notifyOpenTimeDict in battlefieldTimeList:  | 
|           | 
|         # È«·þ¹ã²¥ÌáʾÐÅÏ¢  | 
|         if curDateTime in notifyOpenTimeDict:  | 
|             notifyOpenMinute = notifyOpenTimeDict[curDateTime]  | 
|             __DoBattlefieldOpenNotify(openHour, openMinute, notifyOpenMinute)  | 
|               | 
|         if openDateTime <= curDateTime < closeDateTime:  | 
|             battlefieldState = openHour * 100 + openMinute  | 
|             PyGameData.g_openDateTime = openDateTime  | 
|               | 
|     stateKey = ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     beforeState = gameWorld.GetDictByKey(stateKey)  | 
|       | 
|     if not isReload and beforeState == battlefieldState:  | 
|         #ÒѾÊÇÕâ¸ö״̬ÁË  | 
|         return  | 
|       | 
|     GameWorld.SendMapServerMsgEx(stateKey, battlefieldState) #֪ͨMapserver,ÉèÖÃ×Öµä  | 
|     gameWorld.SetDict(stateKey, battlefieldState) #¸üÐÂ×ÖµäÖµ  | 
|     GameWorld.Log("¿ç·þÕ½³¡×´Ì¬±ä¸ü: beforeState=%s,battlefieldState=%s" % (beforeState, battlefieldState))  | 
|       | 
|     # ¿ªÆô¸±±¾  | 
|     if battlefieldState and beforeState != battlefieldState:  | 
|         # ÒƳýÒѾ´æÔڵĸ±±¾Ïß·  | 
|         PyGameData.g_crossDynamicLineInfo.pop(ChConfig.Def_FBMapID_CrossBattlefield, None)  | 
|           | 
|         PyGameData.g_overPlayerIDList = []  | 
|         PyGameData.g_crossBattlefieldSysCallBuyList = []  | 
|           | 
|         hmNum = battlefieldState  | 
|         openHour, openMinute = GetHMByNum(hmNum)  | 
|         sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)  | 
|                   | 
|         crossZoneList = GetCrossBattlefieldZoneIpyDataList()  | 
|         for zoneIpyData in crossZoneList:  | 
|             zoneID = zoneIpyData.GetZoneID()  | 
|               | 
|             # ÏµÍ³¾ÖÈ·±£Ã¿¸öµÈ¼¶¶Î¶¼ÓÐÒ»³¡  | 
|             if [openHour, openMinute] in sysOpenHMList:  | 
|                 dynamicLineLVRangeDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 4, {})  | 
|                 lvRangeInfoList = dynamicLineLVRangeDict.get(ChConfig.Def_FBMapID_CrossBattlefield, [])  | 
|                 GameWorld.Log("    ¿ªÆôÕ½³¡ÏµÍ³¾Ö£¬È·±£Ã¿¸öµÈ¼¶¶Î¶¼ÓÐÒ»³¡: zoneID=%s,lvRangeInfoList=%s" % (zoneID, lvRangeInfoList))  | 
|                 if lvRangeInfoList:  | 
|                     funcLineIDList = range(len(lvRangeInfoList))  | 
|                     PlayerFB.OpenCrossDynamicLineBySys(zoneID, ChConfig.Def_FBMapID_CrossBattlefield, funcLineIDList, True)  | 
|                       | 
|             # ÓйºÂòµÄ³¡´ÎĬÈÏÖ»¿ªÒ»³¡  | 
|             else:  | 
|                 buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo.get(zoneID, {})  | 
|                 if hmNum in buyHMInfo and len(buyHMInfo[hmNum]) > 0:  | 
|                     GameWorld.Log("    ÓÐÕÙ¼¯µÄ³¡´Î¿ªÆô·ÖÇøÕ½³¡! zoneID=%s" % (zoneID))  | 
|                     funcLineIDList = [0]  | 
|                     PlayerFB.OpenCrossDynamicLineBySys(zoneID, ChConfig.Def_FBMapID_CrossBattlefield, funcLineIDList, True)  | 
|                 else:  | 
|                     GameWorld.Log("    ÎÞÕÙ¼¯µÄ³¡´Î²»¿ª·ÖÇøÕ½³¡! zoneID=%s" % (zoneID))  | 
|                    | 
|     # ¹Ø±Õ  | 
|     if not battlefieldState and beforeState != battlefieldState:  | 
|         # »î¶¯½áÊøÇå¿Õ¶ÓÎé  | 
|         PlayerFuncTeam.DelTeamByFunc(ChConfig.Def_FBMapID_CrossBattlefield)  | 
|           | 
|     # Í¬²½×Ó·þÎñÆ÷  | 
|     dataMsg = {"battlefieldState":battlefieldState}  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_BattlefieldState, dataMsg)  | 
|     return  | 
|   | 
| def __DoBattlefieldOpenNotify(openHour, openMinute, notifyOpenMinute):  | 
|     ''' Ö´Ðпç·þÕ½³¡¿ªÆô¹ã²¥  | 
|                     »¹ÒªÏÞÖÆ¿ª·þÌ쿪Æô  | 
|     '''  | 
|       | 
|     sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)  | 
|     if [openHour, openMinute] in sysOpenHMList:  | 
|           | 
|         crossZoneList = GetCrossBattlefieldZoneIpyDataList()  | 
|         if not crossZoneList:  | 
|             return  | 
|           | 
|         for zoneIpyData in crossZoneList:  | 
|             zoneID = zoneIpyData.GetZoneID()  | 
|               | 
|             serverGroupIDList = zoneIpyData.GetServerGroupIDList()  | 
|             PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "CrossBattlefieldOpenSys", [notifyOpenMinute])  | 
|               | 
|         return  | 
|       | 
|     curHMNum = GetHMNum(openHour, openMinute)  | 
|       | 
|     for zoneID, buyHMInfo in PyGameData.g_crossBattlefieldBuyInfo.items():  | 
|           | 
|         zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByZoneID(ChConfig.Def_FBMapID_CrossBattlefield, zoneID)  | 
|         if not zoneIpyData:  | 
|             continue  | 
|         serverGroupIDList = zoneIpyData.GetServerGroupIDList()  | 
|           | 
|         if curHMNum not in buyHMInfo:  | 
|             continue  | 
|           | 
|         PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "CrossBattlefieldOpenSys", [notifyOpenMinute])  | 
|           | 
|     return  | 
|   | 
| def GetCrossBattlefieldOpenTime(serverGroupID, zoneID, playerID):  | 
|     ## »ñÈ¡¿ç·þÕ½³¡¸±±¾µ±Ç°ÊÇ·ñ¿ª·ÅµÄʱ¼äµã  | 
|     #  @return: None-µ±Ç°Î´¿ª·Å£»  | 
|     #  @return: isCallBattle, openHour, openMinute  -  µ±Ç°¿ª·ÅÖеÄʱ¼äʱ·Ö£¬¿É½øÈë  | 
|       | 
|     hmNum = GetCrossBattlefieldState()  | 
|     if not hmNum:  | 
|         GameWorld.Log("µ±Ç°Ê±¼äÕ½³¡Î´¿ªÆô!", playerID)  | 
|         PlayerControl.NotifyCodeCross(serverGroupID, playerID, "FBIsNotOpen")  | 
|         return  | 
|       | 
|     if playerID in PyGameData.g_overPlayerIDList:  | 
|         # ÄúÒѾ²Î¼Ó¹ý¸Ã³¡´Î£¬ÎÞ·¨ÔÙ½øÈë!  | 
|         PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossBattlefieldAlreadyJoin")  | 
|         return  | 
|       | 
|     openHour, openMinute = GetHMByNum(hmNum)  | 
|     sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)  | 
|     isCallBattle = [openHour, openMinute] not in sysOpenHMList  | 
|     if isCallBattle:  | 
|         if zoneID not in PyGameData.g_crossBattlefieldBuyInfo:  | 
|             GameWorld.Log("¸Ã·ÖÇøÃ»ÓÐʹÓÃÕÙ¼¯Á zoneID=%s" % zoneID, playerID)  | 
|             PlayerControl.NotifyCodeCross(serverGroupID, playerID, "FBIsNotOpen")  | 
|             return  | 
|         buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo[zoneID]  | 
|         if hmNum not in buyHMInfo:  | 
|             GameWorld.Log("¸Ãʱ¶Î»¹Î´Ê¹ÓÃÕÙ¼¯Á zoneID=%s,hmNum=%s" % (zoneID, hmNum), playerID)  | 
|             PlayerControl.NotifyCodeCross(serverGroupID, playerID, "FBIsNotOpen")  | 
|             return  | 
|           | 
|         # ÕÙ¼¯³¡Ö»ÓÐÒ»ÌõÏߣ¬Èç¹ûÓÐÈ˽áËãÔò´ú±íÒѾ½áÊøÁË  | 
|         if PyGameData.g_overPlayerIDList:  | 
|             # ¸ÃÕÙ¼¯³¡´ÎÒѽáË㣬ÎÞ·¨½øÈë!  | 
|             PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossBattlefieldCallOver")  | 
|             return  | 
|           | 
|     if PyGameData.g_openDateTime:  | 
|         serverTime = GameWorld.GetServerTime()  | 
|         passSeconds = (serverTime - PyGameData.g_openDateTime).seconds  | 
|         closeEnterMinutes = IpyGameDataPY.GetFuncCfg("CrossBattlefieldOpen", 5) # ¿ªÆôX·ÖÖӺ󲻿ɽøÈ룬²»°üº¬ÒѽøÈëÍæ¼Ò¼°ÕÙ¼¯¶ÓÎéÖеÄÍæ¼Ò  | 
|         closeSeconds = closeEnterMinutes * 60  | 
|         if passSeconds > closeSeconds:  | 
|             GameWorld.DebugLog("³Ùµ½ÁË! passSeconds=%s > %s" % (passSeconds, closeSeconds), playerID)  | 
|             isBelate = True  | 
|             #È¥³ýжÓÔ±½øÈë²»ÊÜʱ¼äÏÞÖÆÉ趨  | 
|             for _, copyMapObj in PyGameData.g_crossDynamicLineCopyMapInfo.items():  | 
|                 if copyMapObj.IsMustCopyMapPlayer(playerID, False):  | 
|                     isBelate = False  | 
|                     GameWorld.DebugLog("ÒѽøÈëµÄÖØ¸´½øÈë²»ÏÞÖÆÊ±¼ä!  playerID=%s" % playerID)  | 
|                     break  | 
|                   | 
|             if isCallBattle:  | 
|                 buyPlayerInfo = buyHMInfo[hmNum]  | 
|                 for buyRec in buyPlayerInfo.values():  | 
|                     if playerID in buyRec.callPlayerIDList:  | 
|                         isBelate = False  | 
|                         GameWorld.DebugLog("ÕÙ¼¯Áî³ÉÔ±²»ÊÜÈËʱ¼äÏÞÖÆ!  playerID=%s" % playerID)  | 
|                         break  | 
|                       | 
|             if isBelate:  | 
|                 PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossBattlefieldBelate", [closeEnterMinutes])  | 
|                 return  | 
|         #else:  | 
|         #    GameWorld.DebugLog("ûÓгٵ½£¡passSeconds=%s <= %s" % (passSeconds, closeSeconds), playerID)  | 
|           | 
|     return isCallBattle, openHour, openMinute  | 
|   | 
| def GetCallPlayerCopymapObj(playerID, serverGroupID, mapID, funcLineID, zoneID, copyMapPlayerMax, includeOffline, tick):  | 
|     ## »ñÈ¡Íæ¼ÒÕÙ¼¯Áî¶ÓÎé¶ÔÓ¦µÄ¸±±¾·ÖÏß  | 
|     ## @return tagCopyMapObj  | 
|       | 
|     hmNum = GetCrossBattlefieldState()  | 
|     if not hmNum:  | 
|         return  | 
|       | 
|     if mapID not in PyGameData.g_crossDynamicLineInfo:  | 
|         PyGameData.g_crossDynamicLineInfo[mapID] = {}  | 
|     zoneLineDict = PyGameData.g_crossDynamicLineInfo[mapID] # ¿ç·þ¶¯Ì¬Ïß·ÐÅÏ¢ {dataMapID:{(zoneID, funcLineID):[CrossFuncLineInfo, CrossFuncLineInfo, ...], ...}, ...}  | 
|     zoneLineKey = (zoneID, funcLineID)  | 
|     if zoneLineKey not in zoneLineDict:  | 
|         zoneLineDict[zoneLineKey] = []  | 
|     funcLineObjList = zoneLineDict[zoneLineKey]  | 
|     if not funcLineObjList:  | 
|         return  | 
|       | 
|     # ÕÙ¼¯Á´Î£¬Ã¿¸ö·ÖÇø¹Ì¶¨Ö»ÓÐÒ»³¡  | 
|     for _, funcLineObj in enumerate(funcLineObjList, 1):  | 
|         realMapID, copyMapID = funcLineObj.realMapID, funcLineObj.copyMapID  | 
|         if not realMapID:  | 
|             continue  | 
|         key = (realMapID, copyMapID)  | 
|         if key not in PyGameData.g_crossDynamicLineCopyMapInfo:  | 
|             continue  | 
|         copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key]  | 
|           | 
|         if copyMapObj.zoneID != zoneID:  | 
|             continue  | 
|           | 
|         # ÕÙ¼¯Áî³ÉÔ±²»ÊÜÈËÊýÏÞÖÆ  | 
|         buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo.get(zoneID, {})  | 
|         if hmNum not in buyHMInfo:  | 
|             continue  | 
|         buyPlayerInfo = buyHMInfo[hmNum]  | 
|         for buyRec in buyPlayerInfo.values():  | 
|             if playerID in buyRec.callPlayerIDList:  | 
|                 GameWorld.DebugLog("ÕÙ¼¯Áî³ÉÔ±²»ÊÜÈËÊýÏÞÖÆ£¬¿É½øÈ룡 playerID=%s" % playerID)  | 
|                 return copyMapObj  | 
|           | 
|         canEnter = copyMapObj.OnRequestEnterCrossCopyMap(playerID, tick, copyMapPlayerMax, includeOffline)  | 
|         if canEnter:  | 
|             return copyMapObj  | 
|           | 
|     return  | 
|   | 
| def ClientServerMsg_BattlefieldBuyOpen(serverGroupID, msgData):  | 
|       | 
|     if not GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     zoneIpyData = GetCrossBattlefieldZoneIpyData(serverGroupID)  | 
|     if not zoneIpyData:  | 
|         return  | 
|     zoneID = zoneIpyData.GetZoneID()  | 
|       | 
|     playerID = msgData["playerID"] # ½ÇÉ«ID  | 
|     playerName = msgData["playerName"] # Íæ¼ÒÃû  | 
|     job = msgData["playerJob"] # Ö°Òµ  | 
|     playerLV = msgData["playerLV"] # Ö°Òµ  | 
|     realmLV = msgData["realmLV"] # ¾³½ç  | 
|     fightPower = msgData["fightPower"] # Õ½¶·Á¦  | 
|     buyOpenCountWeek = msgData["buyOpenCountWeek"] # ±¾ÖÜÒѹºÂòÕÙ¼¯³¡´Î  | 
|       | 
|     openHour = msgData["openHour"]  | 
|     openMinute = msgData["openMinute"]  | 
|     faction = msgData["faction"]  | 
|     serverOnly = msgData.get("serverOnly", 0)  | 
|     face = msgData.get("face", 0)  | 
|     facePic = msgData.get("facePic", 0)  | 
|       | 
|     hmNum = GetHMNum(openHour, openMinute)  | 
|       | 
|     # ¸üлº´æ  | 
|     curCache = PlayerViewCache.FindViewCache(playerID, True)  | 
|     if curCache:  | 
|         cacheDict = PlayerViewCache.GetCachePropDataDict(curCache)  | 
|         cacheDict["Name"] = playerName  | 
|         cacheDict["Job"] = job  | 
|         cacheDict["LV"] = playerLV  | 
|         cacheDict["RealmLV"] = realmLV  | 
|         cacheDict["FightPower"] = fightPower      | 
|           | 
|     sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)  | 
|     if [openHour, openMinute] in sysOpenHMList:  | 
|         if playerID in PyGameData.g_crossBattlefieldSysCallBuyList:  | 
|             GameWorld.Log("Íæ¼ÒÒѾ¹ºÂò¹ý¸Ãϵͳ³¡´Î£¡ zoneID=%s,openHour=%s,openMinute=%s" % (zoneID, openHour, openMinute), playerID)  | 
|             return  | 
|         PyGameData.g_crossBattlefieldSysCallBuyList.append(playerID)  | 
|           | 
|         buyTime = int(time.time())  | 
|         GameWorld.DebugLog("Íæ¼Ò¹ºÂòϵͳÕÙ¼¯³¡´Î£¡ zoneID=%s,openHour=%s,openMinute=%s" % (zoneID, openHour, openMinute), playerID)  | 
|           | 
|         # Éϰñ  | 
|         billboardCallCountLimit = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboard", 1) # ÖÜÕÙ¼¯°ñÉϰñÖÁÉÙ´ÎÊý  | 
|         groupValue1, dataID, name1, name2 = zoneID, playerID, playerName, ""  | 
|         type2, value1, value2 = job, realmLV, 0  | 
|         cmpValue = buyOpenCountWeek + 1  | 
|         if cmpValue >= billboardCallCountLimit:  | 
|             CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BattlefieldWCall, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue, value3=face, value4=facePic)              | 
|           | 
|         # Í¨Öª×Ó·þ  | 
|         serverGroupIDList = [serverGroupID]  | 
|         msgData.update({"opType":"SysCallBuy", "buyTime":buyTime})  | 
|         sendMsg = {"zoneID":zoneID, "SysCallBuyPlayerID":playerID, "opData":msgData}  | 
|         CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_BattlefieldBuy, sendMsg, serverGroupIDList)  | 
|           | 
|         SyncMapServerCrossBattlefieldSysCallBuyInfo()  | 
|           | 
|         buyPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|         if buyPlayer:  | 
|             sendCMD = str(["SysCallBuy", PyGameData.g_crossBattlefieldSysCallBuyList])  | 
|             GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, buyPlayer.GetPlayerID(), buyPlayer.GetRealMapID(),   | 
|                                                                "CrossBattlefield", sendCMD, len(sendCMD), buyPlayer.GetRouteServerIndex())  | 
|         return  | 
|       | 
|     if zoneID not in PyGameData.g_crossBattlefieldBuyInfo:  | 
|         PyGameData.g_crossBattlefieldBuyInfo[zoneID] = {}  | 
|     buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo[zoneID]  | 
|     if hmNum not in buyHMInfo:  | 
|         buyHMInfo[hmNum] = {}  | 
|     buyPlayerInfo = buyHMInfo[hmNum]  | 
|       | 
|     if playerID in buyPlayerInfo:  | 
|         GameWorld.Log("Íæ¼ÒÒѾ¹ºÂò¹ý¸ÃÕÙ¼¯³¡´Î£¡ zoneID=%s,openHour=%s,openMinute=%s" % (zoneID, openHour, openMinute), playerID)  | 
|         return  | 
|       | 
|     curFactionCount, othFactionCount = 0, 0  | 
|     for _, buyRec in buyPlayerInfo.items():  | 
|         if buyRec.factionID == faction:  | 
|             curFactionCount += 1  | 
|         else:  | 
|             othFactionCount += 1  | 
|               | 
| #        if playerID in buyRec.callPlayerIDList:  | 
| #            GameWorld.Log("Íæ¼ÒÒѾÔÚ¸ÃÕÙ¼¯³¡´ÎÕóÓªÀ zoneID=%s,openHour=%s,openMinute=%s,callPlayerID=%s,callPlayerIDList=%s"   | 
| #                          % (zoneID, openHour, openMinute, callPlayerID, buyRec.callPlayerIDList), playerID)  | 
| #            return  | 
|           | 
|     if curFactionCount > othFactionCount:  | 
|         GameWorld.Log("ÕóӪƽºâÏÞÖÆ£¬²»¿ÉÔÙ¹ºÂò¸Ã¿ç·þÕ½³¡ÕóÓª£¡ zoneID=%s,openHour=%s,openMinute=%s,faction=%s,curFactionCount(%s) > othFactionCount(%s)"   | 
|                       % (zoneID, openHour, openMinute, faction, curFactionCount, othFactionCount), playerID)  | 
|         return  | 
|       | 
|     # ================ ¿ÉÒÔ¹ºÂò£¬ÒÔÏÂÖ´ÐÐÌí¼Ó¹ºÂò³¡´ÎÕóÓªÂß¼  ================  | 
|       | 
|     # ÐÂÔö³¡´Î¹ºÂò¼Ç¼  | 
|     buyTime = int(time.time())  | 
|     buyRec = CrossBattlefieldBuy()  | 
|     buyRec.buyTime = buyTime  | 
|     buyRec.zoneID = zoneID  | 
|     buyRec.hmNum = hmNum  | 
|     buyRec.playerID = playerID  | 
|     buyRec.factionID = faction  | 
|     buyRec.callPlayerIDList = [playerID]  | 
|     buyRec.serverOnly = serverOnly  | 
|     buyPlayerInfo[playerID] = buyRec  | 
|       | 
|     GameWorld.DebugLog("Íæ¼Ò¹ºÂò¿ªÆôÕÙ¼¯³¡´Î£¡ zoneID=%s,openHour=%s,openMinute=%s,faction=%s,serverOnly=%s"   | 
|                        % (zoneID, openHour, openMinute, faction, serverOnly), playerID)  | 
|       | 
|     # Éϰñ  | 
|     billboardCallCountLimit = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboard", 1) # ÖÜÕÙ¼¯°ñÉϰñÖÁÉÙ´ÎÊý  | 
|     groupValue1, dataID, name1, name2 = zoneID, playerID, playerName, ""  | 
|     type2, value1, value2 = job, realmLV, 0  | 
|     cmpValue = buyOpenCountWeek + 1  | 
|     if cmpValue >= billboardCallCountLimit:  | 
|         CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BattlefieldWCall, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue, value3=face, value4=facePic)  | 
|           | 
|     for otherBuyPlayerID, otherRec in buyPlayerInfo.items():  | 
|         if otherBuyPlayerID == playerID:  | 
|             continue  | 
|         if playerID in otherRec.callPlayerIDList:  | 
|             otherRec.callPlayerIDList.remove(playerID)  | 
|             GameWorld.DebugLog("    ´ÓÒѼÓÈëµÄÆäËûÕÙ¼¯¶ÓÎéÒÆ³ý: otherBuyPlayerID=%s,playerID=%s" % (otherBuyPlayerID, playerID), playerID)  | 
|               | 
|     SyncMapServerCrossBattlefieldBuyInfo()  | 
|       | 
|     # Í¨Öª×Ó·þ  | 
|     serverGroupIDList = zoneIpyData.GetServerGroupIDList()  | 
|     msgData.update({"opType":"BuyOpen", "buyTime":buyTime})  | 
|     Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, msgData)  | 
|     return  | 
|   | 
| def ClientServerMsg_BattlefieldCallJoin(serverGroupID, msgData):  | 
|     # "openHour":openHour, "openMinute":openMinute, "buyPlayerID":buyPlayerID, "tagPlayerID":tagPlayerID, "playerID":playerID  | 
|       | 
|     openHour = msgData["openHour"]  | 
|     openMinute = msgData["openMinute"]  | 
|     buyPlayerID = msgData["buyPlayerID"]  | 
|     tagPlayerID = msgData["tagPlayerID"]  | 
|     playerID = msgData["playerID"]  | 
|       | 
|     zoneIpyData = GetCrossBattlefieldZoneIpyData(serverGroupID)  | 
|     if not zoneIpyData:  | 
|         return  | 
|     zoneID = zoneIpyData.GetZoneID()  | 
|       | 
|     hmNum = GetHMNum(openHour, openMinute)  | 
|     buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)  | 
|     if tagPlayerID in buyPlayerInfo:  | 
|         GameWorld.ErrLog("Íæ¼ÒÒѹºÂò¸Ã³¡´ÎÕÙ¼¯¶ÓÎ飬ÎÞ·¨¼ÓÈëÆäËûÕÙ¼¯¶ÓÎé! hmNum=%s,tagPlayerID=%s in %s" % (hmNum, tagPlayerID, buyPlayerInfo.keys()), playerID)  | 
|         return  | 
|     if buyPlayerID not in buyPlayerInfo:  | 
|         GameWorld.ErrLog("¿ç·þÕ½³¡²»´æÔÚ¸ÃÍæ¼ÒµÄÕÙ¼¯¶ÓÎé! hmNum=%s,buyPlayerID=%s" % (hmNum, buyPlayerID), playerID)  | 
|         return  | 
|     buyRec = buyPlayerInfo[buyPlayerID]  | 
|       | 
|     callTeamMemMax = IpyGameDataPY.GetFuncCfg("CrossBattlefieldCall", 1)  | 
|     if len(buyRec.callPlayerIDList) >= callTeamMemMax:  | 
|         GameWorld.ErrLog("¿ç·þÕ½³¡ÕÙ¼¯ÈËÊýÒÑÂú! hmNum=%s,buyPlayerID=%s,callPlayerIDList=%s" % (hmNum, buyPlayerID, buyRec.callPlayerIDList), playerID)  | 
|         return  | 
|       | 
|     GameWorld.DebugLog("Íæ¼Ò¼ÓÈëÕÙ¼¯¶ÓÎ飡 zoneID=%s,openHour=%s,openMinute=%s,buyPlayerID=%s,tagPlayerID=%s"   | 
|                        % (zoneID, openHour, openMinute, buyPlayerID, tagPlayerID), playerID)  | 
|       | 
|     if tagPlayerID not in buyRec.callPlayerIDList:  | 
|         buyRec.callPlayerIDList.append(tagPlayerID)  | 
|           | 
|     for otherBuyPlayerID, otherRec in buyPlayerInfo.items():  | 
|         if otherBuyPlayerID == buyPlayerID:  | 
|             continue  | 
|         if tagPlayerID in otherRec.callPlayerIDList:  | 
|             otherRec.callPlayerIDList.remove(tagPlayerID)  | 
|             GameWorld.DebugLog("    ´ÓÒѼÓÈëµÄÆäËûÕÙ¼¯¶ÓÎéÒÆ³ý: otherBuyPlayerID=%s,tagPlayerID=%s" % (otherBuyPlayerID, tagPlayerID), playerID)  | 
|               | 
|     SyncMapServerCrossBattlefieldBuyInfo()  | 
|       | 
|     serverGroupIDList = zoneIpyData.GetServerGroupIDList()  | 
|     msgData.update({"opType":"CallJoin"})  | 
|     Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, msgData)  | 
|     return  | 
|   | 
| def ClientServerMsg_BattlefieldCallKick(serverGroupID, msgData):  | 
|     # "openHour":openHour, "openMinute":openMinute, "buyPlayerID":buyPlayerID, "tagPlayerID":tagPlayerID, "playerID":playerID  | 
|       | 
|     openHour = msgData["openHour"]  | 
|     openMinute = msgData["openMinute"]  | 
|     buyPlayerID = msgData["buyPlayerID"]  | 
|     tagPlayerID = msgData["tagPlayerID"]  | 
|     playerID = msgData["playerID"]  | 
|       | 
|     zoneIpyData = GetCrossBattlefieldZoneIpyData(serverGroupID)  | 
|     if not zoneIpyData:  | 
|         return  | 
|     zoneID = zoneIpyData.GetZoneID()  | 
|       | 
|     hmNum = GetHMNum(openHour, openMinute)  | 
|     buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)  | 
|     if buyPlayerID not in buyPlayerInfo:  | 
|         GameWorld.ErrLog("¿ç·þÕ½³¡²»´æÔÚ¸ÃÍæ¼ÒµÄÕÙ¼¯¶ÓÎé! hmNum=%s,buyPlayerID=%s" % (hmNum, buyPlayerID), playerID)  | 
|         return  | 
|     buyRec = buyPlayerInfo[buyPlayerID]  | 
|       | 
|     if tagPlayerID not in buyRec.callPlayerIDList:  | 
|         GameWorld.ErrLog("¿ç·þÕ½³¡ÕÙ¼¯¶ÓÎéûÓиÃÍæ¼Ò! hmNum=%s,buyPlayerID=%s,tagPlayerID=%s not in callPlayerIDList=%s"   | 
|                            % (hmNum, buyPlayerID, tagPlayerID, buyRec.callPlayerIDList), playerID)  | 
|         return  | 
|     buyRec.callPlayerIDList.remove(tagPlayerID)  | 
|       | 
|     GameWorld.DebugLog("Íæ¼ÒÕÙ¼¯¶ÓÎéÌßÈË£¡ zoneID=%s,openHour=%s,openMinute=%s,buyPlayerID=%s,tagPlayerID=%s"   | 
|                        % (zoneID, openHour, openMinute, buyPlayerID, tagPlayerID), playerID)  | 
|       | 
|     SyncMapServerCrossBattlefieldBuyInfo()  | 
|       | 
|     serverGroupIDList = zoneIpyData.GetServerGroupIDList()  | 
|     msgData.update({"opType":"CallKick"})  | 
|     Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, msgData)  | 
|     return  | 
|   | 
| def ClientServerMsg_BattlefieldCallChange(serverGroupID, msgData):  | 
|       | 
|     openHour = msgData["openHour"]  | 
|     openMinute = msgData["openMinute"]  | 
|     serverOnly = msgData["serverOnly"]  | 
|     playerID = msgData["playerID"]  | 
|       | 
|     zoneIpyData = GetCrossBattlefieldZoneIpyData(serverGroupID)  | 
|     if not zoneIpyData:  | 
|         return  | 
|     zoneID = zoneIpyData.GetZoneID()  | 
|       | 
|     hmNum = GetHMNum(openHour, openMinute)  | 
|     buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)  | 
|     if playerID not in buyPlayerInfo:  | 
|         GameWorld.ErrLog("¿ç·þÕ½³¡²»´æÔÚ¸ÃÍæ¼ÒµÄÕÙ¼¯¶ÓÎé! hmNum=%s,playerID=%s" % (hmNum, playerID), playerID)  | 
|         return  | 
|     buyRec = buyPlayerInfo[playerID]  | 
|     buyRec.serverOnly = 1 if serverOnly else 0  | 
|       | 
|     GameWorld.DebugLog("Íæ¼ÒÕÙ¼¯¶ÓÎéÐ޸ģ¡ zoneID=%s,openHour=%s,openMinute=%s,serverOnly=%s"   | 
|                        % (zoneID, openHour, openMinute, serverOnly), playerID)  | 
|       | 
|     #SyncMapServerCrossBattlefieldBuyInfo()  | 
|       | 
|     serverGroupIDList = zoneIpyData.GetServerGroupIDList()  | 
|     msgData.update({"opType":"CallChange"})  | 
|     Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, msgData)  | 
|     return  | 
|   | 
| def MapServer_CrossBattlefieldOver(msgList):  | 
|     ## ¿ç·þÕ½³¡µØÍ¼½áËã  | 
|     overTime = int(time.time())  | 
|     hmNum, fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, finalSuperItemPlayerID, finalSuperItemPlayerName, superItemPlayerIDList, scoreKingID, scoreKingName, battlePlayerList = msgList  | 
|     GameWorld.Log("¿ç·þÕ½³¡µØÍ¼Í¬²½½á¹û: hmNum=%s,zoneID=%s,funcLineID=%s,winnerFaction=%s,superItemInfo=%s,finalSuperItemPlayerID=%s,superItemPlayerIDList=%s,scoreKingID=%s,battlePlayerCount=%s"   | 
|                   % (hmNum, zoneID, funcLineID, winnerFaction, superItemInfo, finalSuperItemPlayerID, superItemPlayerIDList, scoreKingID, len(battlePlayerList)), fbPropertyID)  | 
|       | 
|     winnerOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAward", 2, {}) # Ê¤Àû·½Ãû´Î¶ÔÓ¦½±ÀøÎïÆ·Áбí {"Ãû´Î":[[ÎïÆ·ID,¸öÊý,ÊÇ·ñÅÄÆ·], ...], ...} , Ãû´ÎÅäÖÃÖ§³Ö¶ÎÅäÖà  | 
|     loserOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAward", 3, {}) # Ê§°Ü·½Ãû´Î¶ÔÓ¦½±ÀøÎïÆ·Áбí {"Ãû´Î":[[ÎïÆ·ID,¸öÊý,ÊÇ·ñÅÄÆ·], ...], ...} , Ãû´ÎÅäÖÃÖ§³Ö¶ÎÅäÖà  | 
|     winnerAwardList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAward", 4) # Ê¤Àû·½¹Ì¶¨½áËã½±ÀøÁбí [[ÎïÆ·ID,¸öÊý,ÊÇ·ñÅÄÆ·], ...]  | 
|     loserAwardList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAward", 5) # Ê§°Ü·½¹Ì¶¨½áËã½±ÀøÁбí [[ÎïÆ·ID,¸öÊý,ÊÇ·ñÅÄÆ·], ...]  | 
|       | 
|     winnerOrderIntAwardDict = {int(k):v for k, v in winnerOrderAwardDict.items()}  | 
|     loserOrderIntAwardDict = {int(k):v for k, v in loserOrderAwardDict.items()}  | 
|       | 
|     billboardEnterCountLimit = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboardJoin", 1) # ÖܲÎÓë°ñÉϰñÖÁÉÙ´ÎÊý  | 
|       | 
|     syncPlayerDataInfo = {}  | 
|     winnerPlayerIDList, loserPlayerIDList = [], []  | 
|     for playerInfo in battlePlayerList:  | 
|         playerID, job, face, facePic, realmLV, name, \  | 
|             isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, teamID, \  | 
|             isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt, \  | 
|             factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt \  | 
|                 = playerInfo  | 
|               | 
|         PyGameData.g_overPlayerIDList.append(playerID)  | 
|           | 
|         paramList = [rank]  | 
|         if faction == winnerFaction:  | 
|             winnerPlayerIDList.append(playerID)  | 
|             orderAwardMailKey = "CrossBattlefieldOrderWin"  | 
|             orderAwardItemList = GameWorld.GetOrderValueByDict(winnerOrderIntAwardDict, rank, False)  | 
|             GameWorld.Log("    »ñʤÕóÓªÍæ¼Ò: faction=%s,rank=%s,playerID=%s" % (faction, rank, playerID), fbPropertyID)  | 
|         else:  | 
|             loserPlayerIDList.append(playerID)  | 
|             orderAwardMailKey = "CrossBattlefieldOrderLose"  | 
|             orderAwardItemList = GameWorld.GetOrderValueByDict(loserOrderIntAwardDict, rank, False)  | 
|             GameWorld.Log("    Ê§°ÜÕóÓªÍæ¼Ò: faction=%s,rank=%s,playerID=%s" % (faction, rank, playerID), fbPropertyID)  | 
|               | 
|         # ÅÅÃû½±ÀøÓʼþ  | 
|         if orderAwardItemList:  | 
|             PlayerCompensation.SendMailByKey(orderAwardMailKey, [playerID], orderAwardItemList, paramList, crossMail=True)  | 
|           | 
|         # ¸üÐÂÖܲÎÓë°ñµ¥  | 
|         groupValue1, dataID, name1, name2 = zoneID, playerID, name, ""  | 
|         type2, value1, value2 = job, realmLV, 0  | 
|         enterCountWeek += 1  | 
|         cmpValue = enterCountWeek  | 
|         if cmpValue >= billboardEnterCountLimit:  | 
|             CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BattlefieldWJoin, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue, value3=face, value4=facePic)  | 
|               | 
|         # ¸üÐÂÖܸ߷ְñµ¥  | 
|         if score > highScoreToday:  | 
|             highScoreWeekTotal += (score - highScoreToday)  | 
|             highScoreToday = score  | 
|             cmpValue = highScoreWeekTotal  | 
|             CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BattlefieldWScore, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue, value3=face, value4=facePic)  | 
|               | 
|         GameWorld.Log("    Õ½³¡ÕóÓªÍæ¼Ò: faction=%s,isWinner=%s,rank=%s,playerID=%s,score=%s,highScoreToday=%s,highScoreWeekTotal=%s,enterCountWeek=%s,teamID=%s,isCallOpen=%s,isCalled=%s"   | 
|                       % (faction, isWinner, rank, playerID, score, highScoreToday, highScoreWeekTotal, enterCountWeek, teamID, isCallOpen, isCalled), fbPropertyID)  | 
|           | 
|         syncPlayerDataInfo[playerID] = [isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, teamID,  | 
|                                         isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt,   | 
|                                         factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt]  | 
|           | 
|     # ²ÎÓë½±ÀøÓʼþ  | 
|     if winnerPlayerIDList:  | 
|         PlayerCompensation.SendMailByKey("CrossBattlefieldJoinWin", winnerPlayerIDList, winnerAwardList, crossMail=True)  | 
|     if loserPlayerIDList:  | 
|         PlayerCompensation.SendMailByKey("CrossBattlefieldJoinLose", loserPlayerIDList, loserAwardList, crossMail=True)  | 
|       | 
|     # ´ó½±»ñµÃÕßÓʼþ  | 
|     superItemID, superItemCount = 0, 0  | 
|     if superItemPlayerIDList and superItemInfo and len(superItemInfo) == 3:  | 
|         superItemID, superItemCount = superItemInfo[0], superItemInfo[1]  | 
|         for superItemPlayerID in superItemPlayerIDList:  | 
|             PlayerCompensation.SendMailByKey("CrossBattlefieldSuperAward", [superItemPlayerID], [superItemInfo], crossMail=True)  | 
|           | 
|     zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByZoneID(ChConfig.Def_FBMapID_CrossBattlefield, zoneID)  | 
|     serverGroupIDList = zoneIpyData.GetServerGroupIDList() if zoneIpyData else []  | 
|       | 
|     # Í¨Öª×Ó·þ¸üвÎÓëÍæ¼ÒÊý¾Ý  | 
|     sendMsg = {"zoneID":zoneID, "overTime":overTime, "syncPlayerDataInfo":syncPlayerDataInfo}  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_BattlefieldOver, sendMsg, serverGroupIDList)  | 
|       | 
|     # ½áËã¹ã²¥  | 
|     nextBattleTimeStr = ""  | 
|     openHour, openMinute = GetHMByNum(hmNum)  | 
|     sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)  | 
|     callOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 2)  | 
|     allOpenHMList = sysOpenHMList + callOpenHMList  | 
|     allOpenHMList.sort()  | 
|     if [openHour, openMinute] in allOpenHMList:  | 
|         nextOpenIndex = allOpenHMList.index([openHour, openMinute]) + 1  | 
|         nextOpenHour, nextOpenMinute = allOpenHMList[nextOpenIndex] if len(allOpenHMList) > nextOpenIndex else allOpenHMList[0]  | 
|         nextBattleTimeStr = "%02d:%02d" % (nextOpenHour, nextOpenMinute)  | 
|           | 
|     # ±¾·ÖÇøÈ«·þ£ºXXÕóӪʤÀû£¬xxxΪ±¾³¡»ý·ÖÍõ£¬xxx»ñµÃÁ˹ÅÉñ´ó½±XXX£¬Ï¸ö³¡´ÎÔ¤¼Æ½«ÔÚXXµã¿ª·Å¡£  | 
|     if finalSuperItemPlayerName:  | 
|         msgParamList = [winnerFaction, scoreKingName, finalSuperItemPlayerName, superItemID, superItemCount, nextBattleTimeStr]  | 
|         PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "CrossBattlefieldOver", msgParamList)  | 
|     return  | 
|   | 
| ####################################################################################################  | 
|   | 
| def CrossServerMsg_BattlefieldState(msgData):  | 
|     battlefieldState = msgData["battlefieldState"]  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|       | 
|     beforeState = GetCrossBattlefieldState()  | 
|       | 
|     GameWorld.DebugLog("ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄÕ½³¡×´Ì¬: battlefieldState=%s,beforeState=%s" % (battlefieldState, beforeState))  | 
|       | 
|     key = ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield  | 
|     gameWorld.SetDict(key, battlefieldState)  | 
|     GameWorld.SendMapServerMsgEx(key, battlefieldState)  | 
|     return  | 
|   | 
| def CrossServerMsg_BattlefieldOver(msgData):  | 
|     GameWorld.DebugLog("ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄÕ½³¡½áËãÐÅÏ¢: %s" % msgData)  | 
|       | 
|     zoneID = msgData["zoneID"]  | 
|     overTime = msgData["overTime"]  | 
|     syncPlayerDataInfo = msgData["syncPlayerDataInfo"]  | 
|       | 
|     curZoneID = GetCrossBattlefieldZoneID(GameWorld.GetServerGroupID())  | 
|     if zoneID != curZoneID:  | 
|         GameWorld.ErrLog("·Ç±¾·þËùÊô·ÖÇøµÄ¿ç·þÕ½³¡¹ºÂòÐÅÏ¢! curZoneID(%s) != zoneID(%s) %s" % (curZoneID, zoneID, str(msgData)))  | 
|         return  | 
|       | 
|     for playerID, playerData in syncPlayerDataInfo.items():  | 
|         if PlayerControl.GetDBPlayerAccIDByID(playerID):  | 
|             msgInfo = ["BattlefieldOver", [overTime] + playerData]  | 
|             CrossRealmPlayer.MapServer_QueryCrossPlayerResult(playerID, "CrossBattlefield", msgInfo, True)  | 
|               | 
|     return  | 
|   | 
| def CrossServerMsg_BattlefieldBuy(msgData):  | 
|     GameWorld.DebugLog("ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄÕ½³¡¹ºÂòÐÅÏ¢: %s" % msgData)  | 
|       | 
|     zoneID = msgData["zoneID"]  | 
|     opData = msgData.get("opData", {})  | 
|       | 
|     curZoneID = GetCrossBattlefieldZoneID(GameWorld.GetServerGroupID())  | 
|     if zoneID != curZoneID:  | 
|         GameWorld.ErrLog("·Ç±¾·þËùÊô·ÖÇøµÄ¿ç·þÕ½³¡¹ºÂòÐÅÏ¢! curZoneID(%s) != zoneID(%s) %s" % (curZoneID, zoneID, str(msgData)))  | 
|         return  | 
|       | 
|     if "SysCallBuyPlayerID" in msgData:  | 
|         playerID = msgData["SysCallBuyPlayerID"]  | 
|         if PlayerControl.GetDBPlayerAccIDByID(playerID):  | 
|             openHour = opData["openHour"]  | 
|             openMinute = opData["openMinute"]  | 
|             faction = opData["faction"]  | 
|             buyTime = opData["buyTime"]  | 
|             todayBuyOpenCount = opData["todayBuyOpenCount"]  | 
|             msgInfo = ["BattlefieldBuy", [openHour, openMinute, faction, todayBuyOpenCount, buyTime]]  | 
|             CrossRealmPlayer.MapServer_QueryCrossPlayerResult(playerID, "CrossBattlefield", msgInfo)  | 
|         return  | 
|       | 
|     syncBuyHMInfo = msgData["syncBuyHMInfo"]  | 
|     if not syncBuyHMInfo:  | 
|         PyGameData.g_crossBattlefieldBuyInfo.pop(zoneID, None)  | 
|           | 
|     # ¸üÐÂÊý¾Ý  | 
|     for hmNum, syncBuyPlayerInfo in syncBuyHMInfo.items():  | 
|         buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)  | 
|         for buyPlayerID, attrDict in syncBuyPlayerInfo.items():  | 
|             buyRec = CrossBattlefieldBuy()  | 
|             buyRec.SetAttr(attrDict)  | 
|             buyPlayerInfo[buyPlayerID] = buyRec  | 
|               | 
|     SyncMapServerCrossBattlefieldBuyInfo()  | 
|       | 
|     if not opData or "opType" not in opData:  | 
|         SyncCrossBattlefieldBuyInfo(None, zoneID)  | 
|         return  | 
|     opType = opData["opType"]  | 
|     openHour = opData["openHour"]  | 
|     openMinute = opData["openMinute"]  | 
|     hmNum = GetHMNum(openHour, openMinute)  | 
|     SyncCrossBattlefieldBuyInfo(None, zoneID, hmNum)  | 
|       | 
|     if opType == "BuyOpen":  | 
|         playerID = opData["playerID"]  | 
|         playerName = opData["playerName"]  | 
|         PlayerControl.WorldNotify(0, "CrossBattlefieldBuyOpen", [playerName, "%d:%02d" % (openHour, openMinute)])  | 
|           | 
|         if PlayerControl.GetDBPlayerAccIDByID(playerID):  | 
|             faction = opData["faction"]  | 
|             buyTime = opData["buyTime"]  | 
|             todayBuyOpenCount = opData["todayBuyOpenCount"]  | 
|             msgInfo = ["BattlefieldBuy", [openHour, openMinute, faction, todayBuyOpenCount, buyTime]]  | 
|             CrossRealmPlayer.MapServer_QueryCrossPlayerResult(playerID, "CrossBattlefield", msgInfo)  | 
|               | 
|     elif opType == "CallJoin":  | 
|         pass  | 
|       | 
|     elif opType == "CallKick":  | 
|         pass  | 
|       | 
|     elif opType == "CallChange":  | 
|         pass  | 
|       | 
|     return  | 
|   | 
| def SyncCrossBattlefieldBuyInfo(curPlayer, zoneID, hmNum=None):  | 
|     ## Í¨ÖªÕ½³¡ÕÙ¼¯³¡´Î¹ºÂòÐÅÏ¢  | 
|       | 
|     buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo.get(zoneID, {})  | 
|     hmNumList = [hmNum] if hmNum != None else buyHMInfo.keys()  | 
|       | 
|     clientPack = ChPyNetSendPack.tagGCCrossBattlefieldBuyInfo()  | 
|     clientPack.HMBuyList = []  | 
|     for hmNum in hmNumList:  | 
|         h, m = GetHMByNum(hmNum)  | 
|         hmPack = ChPyNetSendPack.tagGCCrossBattlefieldBuyHM()  | 
|         hmPack.Hour = h  | 
|         hmPack.Minute = m  | 
|         hmPack.BuyPlayerList = []  | 
|           | 
|         buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)  | 
|         for buyPlayerID, buyRec in buyPlayerInfo.items():  | 
|             buyPlayerPack = ChPyNetSendPack.tagGCCrossBattlefieldBuyPlayer()  | 
|             buyPlayerPack.BuyPlayerID = buyPlayerID  | 
|             buyPlayerPack.Faction = buyRec.factionID  | 
|             buyPlayerPack.ServerOnly = buyRec.serverOnly  | 
|             buyPlayerPack.FactionPlayerList = []  | 
|               | 
|             for callPlayerID in buyRec.callPlayerIDList:  | 
|                 playerPack = ChPyNetSendPack.tagGCCrossBattlefieldPlayer()  | 
|                 playerPack.PlayerID = callPlayerID  | 
|                 if callPlayerID in buyRec.callPlayerDict:  | 
|                     factionPlayerInfo = buyRec.callPlayerDict[callPlayerID]  | 
|                     fightPower = factionPlayerInfo["FightPower"]  | 
|                     playerPack.PlayerName = factionPlayerInfo["Name"]  | 
|                     playerPack.Job = factionPlayerInfo["Job"]  | 
|                     playerPack.LV = factionPlayerInfo["LV"]  | 
|                     playerPack.RealmLV = factionPlayerInfo["RealmLV"]  | 
|                     playerPack.FightPower = fightPower % ShareDefine.Def_PerPointValue  | 
|                     playerPack.FightPowerEx = fightPower / ShareDefine.Def_PerPointValue  | 
|                 buyPlayerPack.FactionPlayerList.append(playerPack)  | 
|             buyPlayerPack.FactionPlayerCount = len(buyPlayerPack.FactionPlayerList)  | 
|               | 
|             hmPack.BuyPlayerList.append(buyPlayerPack)  | 
|         hmPack.BuyPlayerCount = len(hmPack.BuyPlayerList)  | 
|           | 
|         clientPack.HMBuyList.append(hmPack)  | 
|     clientPack.HMCount = len(clientPack.HMBuyList)  | 
|       | 
|     if curPlayer:  | 
|         NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     else:  | 
|         # ¹ã²¥È«·þÍæ¼Ò  | 
|         playerManager = GameWorld.GetPlayerManager()  | 
|         for i in xrange(playerManager.GetPlayerCount()):  | 
|             curPlayer = playerManager.GetPlayerByIndex(i)  | 
|             if curPlayer == None or not curPlayer.GetInitOK() or PlayerControl.GetIsTJG(curPlayer):  | 
|                 continue  | 
|             NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  | 
|   | 
| #// C0 07 ¿ç·þÕ½³¡¼ÓÈëÕÙ¼¯³¡´Î #tagCGCrossBattlefieldJoinByCall  | 
| #  | 
| #struct    tagCGCrossBattlefieldJoinByCall  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE    Hour;        //Õ½³¡¿ªÆôʱ  | 
| #    BYTE    Minute;        //Õ½³¡¿ªÆô·Ö  | 
| #    DWORD    BuyPlayerID;    //¼ÓÈëÄ¿±êÍæ¼ÒµÄÕÙ¼¯¶ÓÎ飬¼´¹ºÂòÕÙ¼¯³¡µÄÍæ¼ÒID  | 
| #};  | 
| def OnCrossBattlefieldJoinByCall(index, clientData, tick):  | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     openHour = clientData.Hour  | 
|     openMinute = clientData.Minute  | 
|     buyPlayerID = clientData.BuyPlayerID  | 
|     tagPlayerID = playerID  | 
|       | 
|     closeBuyMinute = IpyGameDataPY.GetFuncCfg("CrossBattlefieldOpen", 4) # ¿ªÆôǰX·ÖÖÓºó¹Ø±Õ¹ºÂò  | 
|     crossServerTimeStr = GameWorld.GetCrossServerTimeStr()  | 
|     crossServerDateTime = GameWorld.ChangeStrToDatetime(crossServerTimeStr)  | 
|       | 
|     startTimeStr = "%s-%s-%s %s:%s:00" % (crossServerDateTime.year, crossServerDateTime.month, crossServerDateTime.day, openHour, openMinute)  | 
|     startDateTime = GameWorld.ChangeStrToDatetime(startTimeStr)  | 
|     endBuyDateTime = startDateTime + datetime.timedelta(minutes=-closeBuyMinute)  | 
|     if crossServerDateTime >= endBuyDateTime:  | 
|         GameWorld.Log("¸Ãʱ¼äµãÕ½³¡ÒѹرÕÕÙ¼¯£¬²»ÄÜÔÙÕÙ¼¯¼ÓÈë! openHour=%s,openMinute=%s,crossServerDateTime(%s) >= endBuyDateTime(%s)"   | 
|                       % (openHour, openMinute, crossServerDateTime, endBuyDateTime), playerID)  | 
|         return  | 
|       | 
|     zoneID = GetCrossBattlefieldZoneID(GameWorld.GetServerGroupID())  | 
|     if not zoneID:  | 
|         return  | 
|       | 
|     hmNum = GetHMNum(openHour, openMinute)  | 
|     buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)  | 
|     if buyPlayerID not in buyPlayerInfo:  | 
|         GameWorld.ErrLog("²»´æÔÚ¸ÃÍæ¼ÒµÄ¿ç·þÕ½³¡ÕÙ¼¯¶ÓÎé! hmNum=%s,buyPlayerID=%s" % (hmNum, buyPlayerID), playerID)  | 
|         return  | 
|     buyRec = buyPlayerInfo[buyPlayerID]  | 
|       | 
|     callTeamMemMax = IpyGameDataPY.GetFuncCfg("CrossBattlefieldCall", 1)  | 
|     if len(buyRec.callPlayerIDList) >= callTeamMemMax:  | 
|         GameWorld.DebugLog("ÕÙ¼¯ÈËÊýÒÑÂú! hmNum=%s,buyPlayerID=%s,callPlayerIDList=%s" % (hmNum, buyPlayerID, buyRec.callPlayerIDList), playerID)  | 
|         return  | 
|       | 
|     if buyRec.serverOnly and not PlayerControl.GetDBPlayerAccIDByID(buyPlayerID):  | 
|         PlayerControl.NotifyCode(curPlayer, "CrossBattlefieldCallServerOnly")  | 
|         #GameWorld.DebugLog("·Ç±¾·þÍæ¼Ò£¬ÎÞ·¨¼ÓÈëÆä¹ºÂòµÄÕÙ¼¯¶ÓÎé! hmNum=%s,buyPlayerID=%s,serverOnly=%s" % (hmNum, buyPlayerID, buyRec.serverOnly), playerID)  | 
|         return  | 
|       | 
|     # ÇëÇó²éѯ¿ç·þ·þÎñÆ÷  | 
|     dataMsg = {"openHour":openHour, "openMinute":openMinute, "buyPlayerID":buyPlayerID, "tagPlayerID":tagPlayerID, "playerID":playerID}  | 
|     CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BattlefieldCallJoin, dataMsg)  | 
|     return  | 
|   | 
|   | 
| #// C0 08 ¿ç·þÕ½³¡ÕÙ¼¯³¡´ÎÌßÈË #tagCGCrossBattlefieldCallKick  | 
| #  | 
| #struct    tagCGCrossBattlefieldCallKick  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE    Hour;        //Õ½³¡¿ªÆôʱ  | 
| #    BYTE    Minute;        //Õ½³¡¿ªÆô·Ö  | 
| #    DWORD    TagPlayerID;    //Ä¿±êÍæ¼ÒID£¬¼´Òª±»Ìß³öÈ¥µÄÍæ¼ÒID  | 
| #};  | 
| def OnCrossBattlefieldCallKick(index, clientData, tick):  | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     openHour = clientData.Hour  | 
|     openMinute = clientData.Minute  | 
|     tagPlayerID = clientData.TagPlayerID  | 
|     buyPlayerID = playerID  | 
|     GameWorld.DebugLog("ÕÙ¼¯³¡´ÎÌßÈË: tagPlayerID=%s,openHour=%s,openMinute=%s" % (tagPlayerID, openHour, openMinute), playerID)  | 
|     if buyPlayerID == tagPlayerID:  | 
|         return  | 
|       | 
|     closeBuyMinute = IpyGameDataPY.GetFuncCfg("CrossBattlefieldOpen", 4) # ¿ªÆôǰX·ÖÖÓºó¹Ø±Õ¹ºÂò  | 
|     crossServerTimeStr = GameWorld.GetCrossServerTimeStr()  | 
|     crossServerDateTime = GameWorld.ChangeStrToDatetime(crossServerTimeStr)  | 
|       | 
|     startTimeStr = "%s-%s-%s %s:%s:00" % (crossServerDateTime.year, crossServerDateTime.month, crossServerDateTime.day, openHour, openMinute)  | 
|     startDateTime = GameWorld.ChangeStrToDatetime(startTimeStr)  | 
|     endBuyDateTime = startDateTime + datetime.timedelta(minutes= -closeBuyMinute)  | 
|     if crossServerDateTime >= endBuyDateTime:  | 
|         GameWorld.Log("¸Ãʱ¼äµãÕ½³¡ÒѹرÕÕÙ¼¯£¬²»ÄÜÔÙÕÙ¼¯ÌßÈË! openHour=%s,openMinute=%s,crossServerDateTime(%s) >= endBuyDateTime(%s)"   | 
|                       % (openHour, openMinute, crossServerDateTime, endBuyDateTime), playerID)  | 
|         return  | 
|       | 
|     zoneID = GetCrossBattlefieldZoneID(GameWorld.GetServerGroupID())  | 
|     if not zoneID:  | 
|         return  | 
|       | 
|     hmNum = GetHMNum(openHour, openMinute)  | 
|     buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)  | 
|     if buyPlayerID not in buyPlayerInfo:  | 
|         GameWorld.ErrLog("²»´æÔÚ¸ÃÍæ¼ÒµÄ¿ç·þÕ½³¡ÕÙ¼¯¶ÓÎé! hmNum=%s,buyPlayerID=%s" % (hmNum, buyPlayerID), playerID)  | 
|         return  | 
|     buyRec = buyPlayerInfo[buyPlayerID]  | 
|       | 
|     if tagPlayerID not in buyRec.callPlayerIDList:  | 
|         GameWorld.DebugLog("¸ÃÕÙ¼¯¶ÓÎéûÓиÃÍæ¼Ò! hmNum=%s,buyPlayerID=%s,tagPlayerID=%s not in callPlayerIDList=%s"   | 
|                            % (hmNum, buyPlayerID, tagPlayerID, buyRec.callPlayerIDList), playerID)  | 
|         return  | 
|       | 
|     # ÇëÇó²éѯ¿ç·þ·þÎñÆ÷  | 
|     dataMsg = {"openHour":openHour, "openMinute":openMinute, "buyPlayerID":buyPlayerID, "tagPlayerID":tagPlayerID, "playerID":playerID}  | 
|     CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BattlefieldCallKick, dataMsg)  | 
|     return  | 
|   | 
| #// C0 09 ¿ç·þÕ½³¡ÕÙ¼¯³¡´ÎÐ޸Ġ#tagCGCrossBattlefieldCallChange  | 
| #  | 
| #struct    tagCGCrossBattlefieldCallChange  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE    Hour;        //Õ½³¡¿ªÆôʱ  | 
| #    BYTE    Minute;        //Õ½³¡¿ªÆô·Ö  | 
| #    BYTE    ServerOnly;    //ÊÇ·ñ½ö±¾·þÍæ¼Ò¿É¼ÓÈ룬0-·ñ£¬1-ÊÇ  | 
| #};  | 
| def OnCrossBattlefieldCallChange(index, clientData, tick):  | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     openHour = clientData.Hour  | 
|     openMinute = clientData.Minute  | 
|     serverOnly = clientData.ServerOnly  | 
|       | 
|     # ÇëÇó²éѯ¿ç·þ·þÎñÆ÷  | 
|     dataMsg = {"openHour":openHour, "openMinute":openMinute, "serverOnly":serverOnly, "playerID":playerID}  | 
|     CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BattlefieldCallChange, dataMsg)  | 
|     return  |