| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package CrossBoss  | 
| #  | 
| # @todo:¿ç·þboss  | 
| # @author hxp  | 
| # @date 2019-01-09  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ¿ç·þboss  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2019-01-09 15:30"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import ChConfig  | 
| import GameWorld  | 
| import IpyGameDataPY  | 
| import ChPyNetSendPack  | 
| import CrossRealmPlayer  | 
| #import DataRecordPack  | 
| import PlayerControl  | 
| import NetPackCommon  | 
| import CrossRealmMsg  | 
| import ShareDefine  | 
| import PyGameData  | 
| import PlayerFB  | 
|   | 
| import time  | 
|   | 
| '''  | 
| ShareDefine.Def_UniversalGameRecType_CrossBossInfo  | 
| value1:bossID  | 
| value2:killedTime  | 
| value4:refreshTime  | 
| value5:zoneID  | 
| StrValue3:"ʱ¼ä_Íæ¼ÒÃû|..."  | 
| '''  | 
|   | 
| def GetRecBossID(recData): return recData.GetValue1()  | 
| def SetRecBossID(recData, value): return recData.SetValue1(value)  | 
| def GetRecKilledTime(recData): return recData.GetValue2()  | 
| def SetRecKilledTime(recData, value): return recData.SetValue2(value)  | 
| def GetRecRefreshTime(recData): return recData.GetValue4()  | 
| def SetRecRefreshTime(recData, value): return recData.SetValue4(value)  | 
| def GetRecZoneID(recData): return recData.GetValue5()  | 
| def SetRecZoneID(recData, value): return recData.SetValue5(value)  | 
| def GetRecKilledRecord(recData): return recData.GetStrValue3()  | 
| def SetRecKilledRecord(recData, value): return recData.SetStrValue3(value)  | 
|   | 
| g_bossRecDataDict = {} # boss¶ÔÓ¦rec¼Ç¼»º´æ {(zoneID, bossID):recData, ...}  | 
|   | 
| def GetCrossBossZoneID(mapID, realMapID, copyMapID):  | 
|     ## »ñÈ¡µØÍ¼¿ç·þbossËùÊô·ÖÇø  | 
|     if mapID not in ChConfig.Def_CrossMapIDList:  | 
|         return 0  | 
|     # ¹Ì¶¨Ïß··ÖÅäµÄ  | 
|     if mapID in ChConfig.Def_CrossZoneMapTableName:  | 
|         tableName = ChConfig.Def_CrossZoneMapTableName[mapID]  | 
|         zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, mapID, copyMapID)  | 
|         if not zoneIpyData:  | 
|             return 0  | 
|         return zoneIpyData.GetZoneID()  | 
|       | 
|     # ¶¯Ì¬Ïß··ÖÅäµÄ  | 
|     elif mapID in ChConfig.Def_CrossDynamicLineMap:  | 
|         return PlayerFB.GetCrossDynamicLineZoneID(mapID, realMapID, copyMapID)  | 
|     return 0  | 
|   | 
| def __GetCrossBossRecData(zoneID, bossID):  | 
|     ## »ñÈ¡¿ç·þBoss RecÊý¾Ý  | 
|     #  @param zoneID: ·ÖÇøID  | 
|     #  @param bossID: bossID  | 
|       | 
|     global g_bossRecDataDict  | 
|     key = (zoneID, bossID)  | 
|     if key in g_bossRecDataDict:  | 
|         return g_bossRecDataDict[key]  | 
|       | 
|     recTypeListData = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_CrossBossInfo)  | 
|       | 
|     # ²éÕÒÊÇ·ñÒÑÓмǼ  | 
|     bossRec = None  | 
|     for index in xrange(recTypeListData.Count()):  | 
|         recData = recTypeListData.At(index)  | 
|         if GetRecBossID(recData) == bossID and GetRecZoneID(recData) == zoneID:  | 
|             bossRec = recData  | 
|             break  | 
|           | 
|     if bossRec == None:  | 
|         #»¹Î´¼Ç¼£¬ÔòÌí¼ÓÒ»¸ö¼Ç¼¶ÔÏó  | 
|         bossRec = recTypeListData.AddRec()  | 
|         SetRecBossID(bossRec, bossID)  | 
|         SetRecZoneID(bossRec, zoneID)  | 
|           | 
|     g_bossRecDataDict[key] = bossRec  | 
|     return bossRec  | 
|   | 
| def __SetCrossBossIsAlive(zoneID, bossID, isAlive):  | 
|     ## ÉèÖÿç·þÊÀ½çbossÊÇ·ñ»î×Å  | 
|     GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_CrossBossIsAlive % (zoneID, bossID), isAlive)  | 
|     return  | 
|   | 
| def __GetCrossBossIsAlive(zoneID, bossID):  | 
|     ## »ñÈ¡¿ç·þÊÀ½çbossÊÇ·ñ»î×Å  | 
|     return GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_CrossBossIsAlive % (zoneID, bossID))  | 
|   | 
| def Sync_CrossBossInitDataToClientServer(serverGroupID=0):  | 
|     ''' Í¬²½¿ç·þBoss»î¶¯Êý¾Ýµ½×Ó·þÎñÆ÷  | 
|     @param serverGroupID: Îª0ʱͬ²½ËùÓÐ×Ó·þ  | 
|     '''  | 
|       | 
|     crossMapBossIDListDict = {}  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetBOSSInfoCount()):  | 
|         ipyData = ipyDataMgr.GetBOSSInfoByIndex(i)  | 
|         mapID = ipyData.GetMapID()  | 
|         bossID = ipyData.GetNPCID()  | 
|         if mapID not in ChConfig.Def_CrossZoneTypeName:  | 
|             continue  | 
|         if mapID not in crossMapBossIDListDict:  | 
|             crossMapBossIDListDict[mapID] = []  | 
|         bossIDList = crossMapBossIDListDict[mapID]  | 
|         bossIDList.append(bossID)  | 
|       | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     GameWorld.Log("ͬ²½¸ø×Ó·þ¿ç·þbossÐÅÏ¢: crossZoneName=%s,syncServerGroupID=%s" % (crossZoneName, serverGroupID))  | 
|       | 
|     # ÓÉÓÚ²»Í¬¹¦ÄܵĿç·þboss·ÖÇø¿ÉÄܲ»Ò»Ñù£¬Í¬²½×Ó·þ¾ÍÐèÒª°´·ÖÇø·Ö²½Í¬²½£¬ËùÒÔÐèÏÈ·¢ËÍÒ»Ìõ³õʼ»¯µÄÐÅÏ¢ÀàÐÍÏÈÇå¿Õ×Ó·þ±£´æµÄ¿ç·þbossÊý¾Ý£¬ÔÙ¸ù¾Ý¹¦ÄÜËùÊô·ÖÇøÍÆËÍ  | 
|     serverGroupIDList = [serverGroupID] if serverGroupID else []  | 
|     bossInfoDict = {"BossInfoType":"InitOK"}  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossInfo, bossInfoDict, serverGroupIDList)  | 
|       | 
|     for mapID, bossIDList in crossMapBossIDListDict.items():  | 
|         GameWorld.Log("    mapID=%s, bossIDList=%s" % (mapID, bossIDList))  | 
|         zoneIpyDataList = CrossRealmPlayer.GetCrossZoneIpyDataListByServerGroupID(mapID, serverGroupID)  | 
|         if not zoneIpyDataList:  | 
|             continue  | 
|         for zoneIpyData in zoneIpyDataList:  | 
|             zoneID = zoneIpyData.GetZoneID()  | 
|             serverGroupIDList = [serverGroupID] if serverGroupID else zoneIpyData.GetServerGroupIDList()  | 
|             bossInfoList = []  | 
|             for bossID in bossIDList:  | 
|                 bossRecData = __GetCrossBossRecData(zoneID, bossID)  | 
|                 killedTime = GetRecKilledTime(bossRecData)  | 
|                 refreshTime = GetRecRefreshTime(bossRecData)  | 
|                 killedRecord = GetRecKilledRecord(bossRecData)  | 
|                 isAlive = __GetCrossBossIsAlive(zoneID, bossID)  | 
|                 killerExInfo = [] # ÖØÁ¬³É¹¦µÄÐÅϢͬ²½²»·¢ËÍ»÷ɱÕßÐÅÏ¢  | 
|                 bossInfoList.append([zoneID, bossID, killedTime, refreshTime, killedRecord, isAlive, killerExInfo])  | 
|                   | 
|             if bossInfoList:  | 
|                 bossInfoDict = {"BossInfoList":bossInfoList}  | 
|                 CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossInfo, bossInfoDict, serverGroupIDList)  | 
|             else:  | 
|                 GameWorld.Log("ûÓпç·þbossÐÅÏ¢! mapID=%s,zoneID=%s" % (mapID, zoneID))  | 
|                   | 
|     return  | 
|   | 
| def DoCrossBossOnKilled(bossID, killPlayerName, mapID, realMapID, copyMapID, killerIDList):  | 
|     ## ¿ç·þboss±»É±  | 
|     zoneID = GetCrossBossZoneID(mapID, realMapID, copyMapID)  | 
|     GameWorld.Log("»÷ɱ¿ç·þboss: zoneID=%s,bossID=%s,mapID=%s,realMapID=%s,copyMapID=%s,killerIDList=%s"   | 
|                   % (zoneID, bossID, mapID, realMapID, copyMapID, killerIDList))  | 
|     if not zoneID:  | 
|         return  | 
|       | 
|     isAlive = 0  | 
|     killedTime = int(time.time())  | 
|     # ²éÕҼǼ  | 
|     bossRecData = __GetCrossBossRecData(zoneID, bossID)  | 
|       | 
|     __SetKilledRecord(bossRecData, killedTime, killPlayerName)  | 
|       | 
|     __SetCrossBossIsAlive(zoneID, bossID, isAlive)  | 
|     refreshTime = SetBossRefreshTime(zoneID, bossID, killedTime, bossRecData)  | 
|       | 
|     # ¹ã²¥×Ó·þ¿ç·þboss±»»÷ɱ  | 
|     zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByZoneID(mapID, zoneID)  | 
|     if zoneIpyData == None:  | 
|         return  | 
|     serverGroupIDList = zoneIpyData.GetServerGroupIDList()  | 
|     killedRecord = GetRecKilledRecord(bossRecData)  | 
|     killerExInfo = [killerIDList, mapID]  | 
|     bossInfoList = [[zoneID, bossID, killedTime, refreshTime, killedRecord, isAlive, killerExInfo]]  | 
|     bossInfoDict = {"BossInfoType":"OnKilled", "BossInfoList":bossInfoList}  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossInfo, bossInfoDict, serverGroupIDList)  | 
|     return  | 
|   | 
| def DoCrossBossStateChange(bossID, isAlive, mapID, realMapID, copyMapID):  | 
|     ## ¿ç·þboss״̬±ä¸ü  | 
|     zoneID = GetCrossBossZoneID(mapID, realMapID, copyMapID)  | 
|     GameWorld.Log("¿ç·þboss״̬±ä¸ü: zoneID=%s,bossID=%s,isAlive=%s,mapID=%s,realMapID=%s,copyMapID=%s"   | 
|                   % (zoneID, bossID, isAlive, mapID, realMapID, copyMapID))  | 
|     if not zoneID:  | 
|         return  | 
|       | 
|     if __GetCrossBossIsAlive(zoneID, bossID) != isAlive:  | 
|         __SetCrossBossIsAlive(zoneID, bossID, isAlive)  | 
|         if isAlive:  | 
|             # ¹ã²¥×Ó·þ¿ç·þboss¸´»î  | 
|             SendClientServerCrossBossState(mapID, zoneID, {bossID:isAlive})  | 
|     return  | 
|   | 
| def SendClientServerCrossBossState(mapID, zoneID, bossStateDict={}):  | 
|     # ¹ã²¥×Ó·þ¿ç·þboss¸´»î  | 
|     zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByZoneID(mapID, zoneID)  | 
|     if zoneIpyData != None:  | 
|         serverGroupIDList = zoneIpyData.GetServerGroupIDList()  | 
|         stateInfo = [zoneID, bossStateDict]  | 
|         CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossState, stateInfo, serverGroupIDList)  | 
|     return  | 
|   | 
| def __SetKilledRecord(bossRecData, killedTime, playerName):  | 
|     ## ÉèÖÃÊÀ½çbossÉÏÒ»´Î»÷ɱ¼Ç¼  | 
|     killedRecord = GetRecKilledRecord(bossRecData)  | 
|     killedRecordList = killedRecord.split('|') if killedRecord else []  | 
|     killedRecordList.append("%s_%s" % (killedTime, playerName))  | 
|     #¼Ç¼×î½ü5´Î  | 
|     if len(killedRecordList) > 5:  | 
|         del killedRecordList[0]  | 
|     killedRecord = '|'.join(killedRecordList)  | 
|     SetRecKilledRecord(bossRecData, killedRecord)  | 
|     SetRecKilledTime(bossRecData, killedTime)  | 
|     return  | 
|   | 
| def SetBossRefreshTime(zoneID, bossID, killedTime, bossRecData):  | 
|     '''ÉèÖÃbossË¢ÐÂʱ¼ä'''  | 
|     ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossID)  | 
|     if not ipyData:  | 
|         return 0  | 
|     #onlineCnt = 0  | 
|     #yesterdayCnt = 0  | 
|     refreshTime = eval(ipyData.GetRefreshTime())  | 
|     SetRecRefreshTime(bossRecData, refreshTime)  | 
|     __UpdateBossRefreshList(zoneID, bossID, killedTime, refreshTime)  | 
|     GameWorld.DebugLog('    ÉèÖÃbossË¢ÐÂʱ¼ä: zoneID=%s,bossID=%s,refreshTime=%s' % (zoneID, bossID, refreshTime))  | 
|     return refreshTime  | 
|   | 
| def __UpdateBossRefreshList(zoneID, bossID, killedTime=0, refreshTime=0):  | 
|     for bossInfo in PyGameData.g_sortBOSSRefreshList:  | 
|         if bossID == bossInfo[0] and zoneID == bossInfo[3]:  | 
|             if killedTime:  | 
|                 bossInfo[1] = killedTime  | 
|             if refreshTime:  | 
|                 bossInfo[2] = refreshTime  | 
|             break  | 
|     curTime = int(time.time())  | 
|     PyGameData.g_sortBOSSRefreshList.sort(key=lambda asd:max(0, asd[2] - (curTime - asd[1])))  | 
|     GameWorld.DebugLog('    PyGameData.g_sortBOSSRefreshList=%s' % PyGameData.g_sortBOSSRefreshList)  | 
|     return  | 
|   | 
| def DoCheckCrossBossReborn(tick):  | 
|     ## ¿ç·þboss¸´»î¼ì²é  | 
|       | 
|     curTime = int(time.time())  | 
|     if not PyGameData.g_sortBOSSRefreshList:  | 
|         crossZoneName = GameWorld.GetCrossZoneName()  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for i in xrange(ipyDataMgr.GetBOSSInfoCount()):  | 
|             ipyData = ipyDataMgr.GetBOSSInfoByIndex(i)  | 
|             bossID = ipyData.GetNPCID()  | 
|             mapID = ipyData.GetMapID()  | 
|             if mapID not in ChConfig.Def_CrossZoneTypeName:  | 
|                 continue  | 
|             refreshTimeStr = ipyData.GetRefreshTime()  | 
|             if not refreshTimeStr or refreshTimeStr == "0":  | 
|                 continue  | 
|             zoneTypeName = ChConfig.Def_CrossZoneTypeName[mapID]  | 
|             if not hasattr(ipyDataMgr, "Get%sCount" % zoneTypeName):  | 
|                 continue  | 
|             for i in xrange(getattr(ipyDataMgr, "Get%sCount" % zoneTypeName)()):  | 
|                 zoneIpyData = getattr(ipyDataMgr, "Get%sByIndex" % zoneTypeName)(i)  | 
|                 if zoneIpyData.GetCrossZoneName() != crossZoneName:  | 
|                     continue  | 
|                 zoneID = zoneIpyData.GetZoneID()  | 
|                 bossRecData = __GetCrossBossRecData(zoneID, bossID)  | 
|                 killedTime = GetRecKilledTime(bossRecData)  | 
|                 refreshTime = GetRecRefreshTime(bossRecData)  | 
|                 PyGameData.g_sortBOSSRefreshList.append([bossID, killedTime, refreshTime, zoneID, mapID])  | 
|         PyGameData.g_sortBOSSRefreshList.sort(key=lambda asd:max(0, asd[2] - (curTime - asd[1])))  | 
|           | 
|     #GameWorld.DebugLog("¼ì²éboss¸´»î: PyGameData.g_sortBOSSRefreshList=%s" % PyGameData.g_sortBOSSRefreshList)  | 
|     zoneMapBossStateDict = {}  | 
|     for bossInfo in PyGameData.g_sortBOSSRefreshList:  | 
|         bossID, killedTime, refreshTime, zoneID, mapID = bossInfo  | 
|         isAlive = __GetCrossBossIsAlive(zoneID, bossID)  | 
|         if isAlive:  | 
|             #GameWorld.DebugLog("    zoneID=%s,bossID=%s,δ±»»÷ɱ£¡" % (zoneID, bossID))  | 
|             continue  | 
|         rebornSecond = max(0, refreshTime - (curTime - killedTime))  | 
|           | 
|         if rebornSecond > 0:  | 
|             #GameWorld.DebugLog("    zoneID=%s,bossID=%s,refreshTime=%s,curTime=%s,killedTime=%s,ÖØÉúµ¹¼ÆÊ±Ãë(%s)£¡" % (zoneID, bossID, refreshTime, curTime, killedTime, rebornSecond))  | 
|             break  | 
|           | 
|         isAlive = 1  | 
|         __SetCrossBossIsAlive(zoneID, bossID, isAlive)  | 
|           | 
|         key = (mapID, zoneID)  | 
|         if key not in zoneMapBossStateDict:  | 
|             zoneMapBossStateDict[key] = {}  | 
|         bossStateDict = zoneMapBossStateDict[key]  | 
|         bossStateDict[bossID] = isAlive  | 
|           | 
|         GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 1)  | 
|         GameWorld.DebugLog("    Í¨ÖªMapServerÖØÉú: zoneID=%s,bossID=%s,killedTime=%s,rebornSecond=%s" % (zoneID, bossID, killedTime, rebornSecond))  | 
|           | 
|     for key, bossStateDict in zoneMapBossStateDict.items():  | 
|         mapID, zoneID = key  | 
|         SendClientServerCrossBossState(mapID, zoneID, bossStateDict)  | 
|     return  | 
|   | 
| def GetCrossBossIsAliveOrCanReborn(zoneID, bossID):  | 
|     ##BOSSÊÇ·ñ»î×Å»òÕß¿ÉÖØÉú  | 
|     if __GetCrossBossIsAlive(zoneID, bossID):  | 
|         return True  | 
|     bossRecData = __GetCrossBossRecData(zoneID, bossID)  | 
|     killedTime = GetRecKilledTime(bossRecData)  | 
|     refreshTime = GetRecRefreshTime(bossRecData)      | 
|     curTime = int(time.time())  | 
|     rebornSecond = max(0, refreshTime - (curTime - killedTime))  | 
|     return rebornSecond == 0  | 
|   | 
| def OnCrossMapServerInitOK():  | 
|     __SendMapServerAliveCrossBoss()  | 
|     return  | 
|   | 
| def __SendMapServerAliveCrossBoss():  | 
|     ## Í¬²½µ±Ç°»¹»î×ŵÄboss£¬·ÀÖ¹µØÍ¼ÖØÆôºóÒѾˢеÄboss²»Ë¢Ð  | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()):  | 
|         ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i)  | 
|         bossID = ipyData.GetNPCID()  | 
|         mapID = ipyData.GetMapID()  | 
|         if mapID not in ChConfig.Def_CrossZoneTypeName:  | 
|             continue  | 
|         zoneTypeName = ChConfig.Def_CrossZoneTypeName[mapID]  | 
|         if not hasattr(ipyDataMgr, "Get%sCount" % zoneTypeName):  | 
|             continue  | 
|         for i in xrange(getattr(ipyDataMgr, "Get%sCount" % zoneTypeName)()):  | 
|             zoneIpyData = getattr(ipyDataMgr, "Get%sByIndex" % zoneTypeName)(i)  | 
|             if zoneIpyData.GetCrossZoneName() != crossZoneName:  | 
|                 continue  | 
|             zoneID = zoneIpyData.GetZoneID()  | 
|             isAlive = __GetCrossBossIsAlive(zoneID, bossID)  | 
|             if not isAlive:  | 
|                 continue  | 
|             GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 1)  | 
|               | 
|     return  | 
|   | 
| ##------------------------------------- ÒÔÏÂÊDZ¾·þ´¦Àí -------------------------------------------  | 
|   | 
| def OnPlayerLogin(curPlayer):  | 
|     Sync_CrossBossInfo(curPlayer)  | 
|     __LoginNotifyKillCrossBoss(curPlayer)  | 
|     return  | 
|   | 
| def CrossServerMsg_CrossBossInfo(bossInfoDict):  | 
|     ## ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄ¿ç·þbossÐÅÏ¢ {"BossInfoType":"InitOK", "BossInfoList":bossInfoList}  | 
|     global g_bossRecDataDict  | 
|       | 
|     bossInfoType = bossInfoDict.get("BossInfoType", "")  | 
|     bossInfoList = bossInfoDict.get("BossInfoList", [])  | 
|       | 
|     GameWorld.DebugLog("ÊÕµ½¿ç·þͬ²½µÄ¿ç·þbossÐÅÏ¢: bossInfoType=%s" % (bossInfoType))  | 
|       | 
|     if bossInfoType == "InitOK":  | 
|         # ×Ó·þÊÕµ½³õʼ»¯Êý¾ÝµÄ£¬¸²¸Ç¸üР | 
|         recTypeListData = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_CrossBossInfo)  | 
|         recTypeListData.Clear()  | 
|         g_bossRecDataDict = {}  | 
|         return  | 
|       | 
|     syncBOSSIDList = []  | 
|     for bossInfo in bossInfoList:  | 
|         zoneID, bossID, killedTime, refreshTime, killedRecord, isAlive, killerExInfo = bossInfo  | 
|         bossRecData = __GetCrossBossRecData(zoneID, bossID)  | 
|         SetRecKilledTime(bossRecData, killedTime)  | 
|         SetRecRefreshTime(bossRecData, refreshTime)  | 
|         SetRecKilledRecord(bossRecData, killedRecord)  | 
|         __SetCrossBossIsAlive(zoneID, bossID, isAlive)  | 
|         syncBOSSIDList.append(bossID)  | 
|           | 
|         if not killerExInfo:  | 
|             continue  | 
|           | 
|         killerIDList, mapID = killerExInfo  | 
|         for playerID in killerIDList:  | 
|             killer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|             if not killer:  | 
|                 #GameWorld.ErrLog("»÷ɱ¿ç·þbossʱÖ÷·þÍæ¼Ò²»ÔÚÏß, playerID=%s,mapID=%s,bossID=%s" % (playerID, mapID, bossID))  | 
|                 #DataRecordPack.SendEventPack("CrossBoss_Error", {"PlayerID":playerID, "Error":"MainServerOffline"})  | 
|                 killTime = int(time.time())  | 
|                 PyGameData.g_unNotifyKillCrossBossDict[playerID] = [killTime, mapID, bossID]  | 
|                 continue  | 
|             msgInfo = str([mapID, bossID])  | 
|             killer.MapServer_QueryPlayerResult(0, 0, "CrossKillBoss", msgInfo, len(msgInfo))  | 
|               | 
|     Sync_CrossBossInfo(None, syncBOSSIDList)  | 
|     return  | 
|   | 
| def __LoginNotifyKillCrossBoss(curPlayer):  | 
|     ## µÇ¼ʱ֪ͨδ֪ͨµ½µÄ»÷ɱ¿ç·þboss  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if playerID not in PyGameData.g_unNotifyKillCrossBossDict:  | 
|         return  | 
|     killTime, mapID, bossID = PyGameData.g_unNotifyKillCrossBossDict.pop(playerID)  | 
|     curTime = int(time.time())  | 
|     passSeconds = curTime - killTime  | 
|     if passSeconds >= 120:  | 
|         GameWorld.DebugLog("³¬¹ý120ÃëÉÏÏß²»´¦Àí£¬Ö÷ҪΪÁË·ÀË¢ÉÏÏß¼ñÎïÆ·!", playerID)  | 
|         return  | 
|     msgInfo = str([mapID, bossID])  | 
|     curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossKillBoss", msgInfo, len(msgInfo))  | 
|     GameWorld.Log("ÉÏÏß²¹Í¨Öª»÷ɱ¿ç·þboss: passSeconds=%s, mapID=%s, bossID=%s" % (passSeconds, mapID, bossID), playerID)  | 
|     return  | 
|   | 
| def CrossServerMsg_CrossBossState(msgInfo):  | 
|     ## ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄ¿ç·þboss״̬  | 
|       | 
|     zoneID, bossStateDict = msgInfo  | 
|     GameWorld.DebugLog("ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄ¿ç·þboss״̬: zoneID=%s, bossStateDict=%s" % (zoneID, bossStateDict))  | 
|       | 
|     aliveBossIDList = []  | 
|     for bossID, isAlive in bossStateDict.items():  | 
|         __SetCrossBossIsAlive(zoneID, bossID, isAlive)  | 
|         if isAlive:  | 
|             aliveBossIDList.append(bossID)  | 
|       | 
|     if aliveBossIDList:  | 
|         Sync_CrossBossInfo(None, aliveBossIDList)  | 
|           | 
|     return  | 
|   | 
|   | 
| def Sync_CrossBossInfo(curPlayer=None, syncBOSSIDList=[]):  | 
|     ## Í¬²½bossÏà¹ØÐÅÏ¢  | 
|       | 
|     curTime = GameWorld.ChangeTimeStrToNum(GameWorld.GetCrossServerTimeStr())  | 
|       | 
|     recTypeListData = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_CrossBossInfo)  | 
|       | 
|     bossInfo = ChPyNetSendPack.tagGCGameWorldBossInfo()  | 
|     bossInfo.BossInfoList = []  | 
|     for index in xrange(recTypeListData.Count()):  | 
|         recData = recTypeListData.At(index)  | 
|         bossID = GetRecBossID(recData)  | 
|         if not bossID:  | 
|             continue  | 
|         if syncBOSSIDList and bossID not in syncBOSSIDList:  | 
|             continue  | 
|         zoneID = GetRecZoneID(recData)  | 
|         killedTime = GetRecKilledTime(recData)  | 
|         refreshTime = GetRecRefreshTime(recData)  | 
|         bossInfoObj = ChPyNetSendPack.tagBossInfoObj()  | 
|         bossInfoObj.BossID = bossID  | 
|         bossInfoObj.IsAlive = __GetCrossBossIsAlive(zoneID, bossID)  | 
|         bossInfoObj.KillRecord = GetRecKilledRecord(recData)  | 
|         bossInfoObj.RecordLen = len(bossInfoObj.KillRecord)  | 
|         bossInfoObj.RefreshSecond = max(0, refreshTime - (curTime - killedTime))  | 
|         bossInfoObj.RefreshCD = refreshTime  | 
|         bossInfo.BossInfoList.append(bossInfoObj)  | 
|           | 
|     if not bossInfo.BossInfoList:  | 
|         return  | 
|       | 
|     bossInfo.BossCnt = len(bossInfo.BossInfoList)  | 
|     if not curPlayer:  | 
|         # È«·þ¹ã²¥ÔÚÏßÍæ¼Ò  | 
|         playerManager = GameWorld.GetPlayerManager()  | 
|         for i in xrange(playerManager.GetActivePlayerCount()):  | 
|             curPlayer = playerManager.GetActivePlayerAt(i)  | 
|             if curPlayer == None:  | 
|                 continue  | 
|             if PlayerControl.GetIsTJG(curPlayer):  | 
|                 continue  | 
|             NetPackCommon.SendFakePack(curPlayer, bossInfo)  | 
|     else:  | 
|         if PlayerControl.GetIsTJG(curPlayer):  | 
|             return  | 
|         NetPackCommon.SendFakePack(curPlayer, bossInfo)  | 
|     return  | 
|   | 
|   |