|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | g_bossRecDataDict = {} # boss对应rec记录缓存 {(zoneID, bossID):recData, ...} | 
|---|
|  |  |  |  | 
|---|
|  |  |  | def GetCrossBossZoneID(realMapID, dataMapID, copyMapID): | 
|---|
|  |  |  | def GetCrossBossZoneID(mapID, realMapID, copyMapID): | 
|---|
|  |  |  | ## 获取地图跨服boss所属分区 | 
|---|
|  |  |  | if dataMapID not in ChConfig.Def_CrossMapIDList: | 
|---|
|  |  |  | if mapID not in ChConfig.Def_CrossMapIDList: | 
|---|
|  |  |  | return 0 | 
|---|
|  |  |  | # 固定线路分配的 | 
|---|
|  |  |  | if dataMapID in ChConfig.Def_CrossZoneMapTableName: | 
|---|
|  |  |  | tableName = ChConfig.Def_CrossZoneMapTableName[dataMapID] | 
|---|
|  |  |  | zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, dataMapID, copyMapID) | 
|---|
|  |  |  | 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 dataMapID in ChConfig.Def_CrossDynamicLineMap: | 
|---|
|  |  |  | return PlayerFB.GetCrossDynamicLineZoneID(dataMapID, realMapID, copyMapID) | 
|---|
|  |  |  | elif mapID in ChConfig.Def_CrossDynamicLineMap: | 
|---|
|  |  |  | return PlayerFB.GetCrossDynamicLineZoneID(mapID, realMapID, copyMapID) | 
|---|
|  |  |  | return 0 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | def __GetCrossBossRecData(zoneID, bossID): | 
|---|
|  |  |  | 
|---|
|  |  |  | @param serverGroupID: 为0时同步所有子服 | 
|---|
|  |  |  | ''' | 
|---|
|  |  |  |  | 
|---|
|  |  |  | GameWorld.Log("同步给子服跨服boss信息: syncServerGroupID=%s" % (serverGroupID)) | 
|---|
|  |  |  | zoneIpyDataList = CrossRealmPlayer.GetCrossCommZoneIpyDataListByServerGroupID(serverGroupID) | 
|---|
|  |  |  | if not zoneIpyDataList: | 
|---|
|  |  |  | GameWorld.Log("    没有跨服boss分区信息!") | 
|---|
|  |  |  | return | 
|---|
|  |  |  |  | 
|---|
|  |  |  | crossMapBossIDListDict = {} | 
|---|
|  |  |  | ipyDataMgr = IpyGameDataPY.IPY_Data() | 
|---|
|  |  |  | for zoneIpyData in zoneIpyDataList: | 
|---|
|  |  |  | zoneID = zoneIpyData.GetZoneID() | 
|---|
|  |  |  | bossInfoList = [] | 
|---|
|  |  |  | for i in xrange(ipyDataMgr.GetBOSSInfoCount()): | 
|---|
|  |  |  | ipyData = ipyDataMgr.GetBOSSInfoByIndex(i) | 
|---|
|  |  |  | mapID = ipyData.GetMapID() | 
|---|
|  |  |  | if mapID not in ChConfig.Def_CrossMapIDList: | 
|---|
|  |  |  | continue | 
|---|
|  |  |  | bossID = ipyData.GetNPCID() | 
|---|
|  |  |  | 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: | 
|---|
|  |  |  | 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() | 
|---|
|  |  |  | bossInfoDict = {"BossInfoType":"InitOK", "BossInfoList":bossInfoList} | 
|---|
|  |  |  | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossInfo, bossInfoDict, serverGroupIDList) | 
|---|
|  |  |  | else: | 
|---|
|  |  |  | GameWorld.Log("没有跨服boss信息! zoneID=%s" % zoneID) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 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, realMapID, dataMapID, copyMapID, killerIDList): | 
|---|
|  |  |  | def DoCrossBossOnKilled(bossID, killPlayerName, mapID, realMapID, copyMapID, killerIDList): | 
|---|
|  |  |  | ## 跨服boss被杀 | 
|---|
|  |  |  | zoneID = GetCrossBossZoneID(realMapID, dataMapID, copyMapID) | 
|---|
|  |  |  | GameWorld.Log("击杀跨服boss: zoneID=%s,bossID=%s,realMapID=%s,dataMapID=%s,copyMapID=%s,killerIDList=%s" | 
|---|
|  |  |  | % (zoneID, bossID, realMapID, dataMapID, copyMapID, killerIDList)) | 
|---|
|  |  |  | 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 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | refreshTime = SetBossRefreshTime(zoneID, bossID, killedTime, bossRecData) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | # 广播子服跨服boss被击杀 | 
|---|
|  |  |  | zoneIpyData = CrossRealmPlayer.GetCrossCommZoneIpyDataByZoneID(zoneID) | 
|---|
|  |  |  | zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByZoneID(mapID, zoneID) | 
|---|
|  |  |  | if zoneIpyData == None: | 
|---|
|  |  |  | return | 
|---|
|  |  |  | serverGroupIDList = zoneIpyData.GetServerGroupIDList() | 
|---|
|  |  |  | killedRecord = GetRecKilledRecord(bossRecData) | 
|---|
|  |  |  | killerExInfo = [killerIDList, dataMapID] | 
|---|
|  |  |  | 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, dataMapID, realMapID, copyMapID): | 
|---|
|  |  |  | def DoCrossBossStateChange(bossID, isAlive, mapID, realMapID, copyMapID): | 
|---|
|  |  |  | ## 跨服boss状态变更 | 
|---|
|  |  |  | zoneID = GetCrossBossZoneID(realMapID, dataMapID, copyMapID) | 
|---|
|  |  |  | GameWorld.Log("跨服boss状态变更: zoneID=%s,bossID=%s,isAlive=%s,realMapID=%s,dataMapID=%s,copyMapID=%s" | 
|---|
|  |  |  | % (zoneID, bossID, isAlive, realMapID, dataMapID, copyMapID)) | 
|---|
|  |  |  | 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 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | __SetCrossBossIsAlive(zoneID, bossID, isAlive) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if isAlive: | 
|---|
|  |  |  | # 广播子服跨服boss复活 | 
|---|
|  |  |  | zoneIpyData = CrossRealmPlayer.GetCrossCommZoneIpyDataByZoneID(zoneID) | 
|---|
|  |  |  | if zoneIpyData != None: | 
|---|
|  |  |  | serverGroupIDList = zoneIpyData.GetServerGroupIDList() | 
|---|
|  |  |  | stateInfo = [zoneID, bossID, isAlive] | 
|---|
|  |  |  | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossState, stateInfo, serverGroupIDList) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 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): | 
|---|
|  |  |  | 
|---|
|  |  |  | bossRecData = __GetCrossBossRecData(zoneID, bossID) | 
|---|
|  |  |  | killedTime = GetRecKilledTime(bossRecData) | 
|---|
|  |  |  | refreshTime = GetRecRefreshTime(bossRecData) | 
|---|
|  |  |  | PyGameData.g_sortBOSSRefreshList.append([bossID, killedTime, refreshTime, zoneID]) | 
|---|
|  |  |  | 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) | 
|---|
|  |  |  | syncBOSSIDList = [] | 
|---|
|  |  |  | zoneMapBossStateDict = {} | 
|---|
|  |  |  | for bossInfo in PyGameData.g_sortBOSSRefreshList: | 
|---|
|  |  |  | bossID, killedTime, refreshTime, zoneID = bossInfo | 
|---|
|  |  |  | bossID, killedTime, refreshTime, zoneID, mapID = bossInfo | 
|---|
|  |  |  | isAlive = __GetCrossBossIsAlive(zoneID, bossID) | 
|---|
|  |  |  | if isAlive: | 
|---|
|  |  |  | #GameWorld.DebugLog("    zoneID=%s,bossID=%s,未被击杀!" % (zoneID, bossID)) | 
|---|
|  |  |  | 
|---|
|  |  |  | #GameWorld.DebugLog("    zoneID=%s,bossID=%s,refreshTime=%s,curTime=%s,killedTime=%s,重生倒计时秒(%s)!" % (zoneID, bossID, refreshTime, curTime, killedTime, rebornSecond)) | 
|---|
|  |  |  | break | 
|---|
|  |  |  |  | 
|---|
|  |  |  | __SetCrossBossIsAlive(zoneID, bossID, 1) | 
|---|
|  |  |  | syncBOSSIDList.append(bossID) | 
|---|
|  |  |  | 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信息 {"BossInfoType":"InitOK", "BossInfoList":bossInfoList} | 
|---|
|  |  |  | global g_bossRecDataDict | 
|---|
|  |  |  |  | 
|---|
|  |  |  | bossInfoType = bossInfoDict["BossInfoType"] | 
|---|
|  |  |  | bossInfoList = bossInfoDict["BossInfoList"] | 
|---|
|  |  |  | bossInfoType = bossInfoDict.get("BossInfoType", "") | 
|---|
|  |  |  | bossInfoList = bossInfoDict.get("BossInfoList", []) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | GameWorld.DebugLog("收到跨服同步的跨服boss信息: bossInfoType=%s" % (bossInfoType)) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | 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 | 
|---|
|  |  |  | 
|---|
|  |  |  | if not killerExInfo: | 
|---|
|  |  |  | continue | 
|---|
|  |  |  |  | 
|---|
|  |  |  | killerIDList, dataMapID = killerExInfo | 
|---|
|  |  |  | killerIDList, mapID = killerExInfo | 
|---|
|  |  |  | for playerID in killerIDList: | 
|---|
|  |  |  | killer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) | 
|---|
|  |  |  | if not killer: | 
|---|
|  |  |  | GameWorld.ErrLog("击杀跨服boss时主服玩家不在线, playerID=%s,dataMapID=%s,bossID=%s" % (playerID, dataMapID, bossID)) | 
|---|
|  |  |  | GameWorld.ErrLog("击杀跨服boss时主服玩家不在线, playerID=%s,mapID=%s,bossID=%s" % (playerID, mapID, bossID)) | 
|---|
|  |  |  | DataRecordPack.SendEventPack("CrossBoss_Error", {"PlayerID":playerID, "Error":"MainServerOffline"}) | 
|---|
|  |  |  | continue | 
|---|
|  |  |  | msgInfo = str([dataMapID, bossID]) | 
|---|
|  |  |  | msgInfo = str([mapID, bossID]) | 
|---|
|  |  |  | killer.MapServer_QueryPlayerResult(0, 0, "CrossKillBoss", msgInfo, len(msgInfo)) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Sync_CrossBossInfo(None, syncBOSSIDList) | 
|---|
|  |  |  | 
|---|
|  |  |  | def CrossServerMsg_CrossBossState(msgInfo): | 
|---|
|  |  |  | ## 收到跨服服务器同步的跨服boss状态 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | zoneID, bossID, isAlive = msgInfo | 
|---|
|  |  |  | GameWorld.DebugLog("收到跨服服务器同步的跨服boss状态: zoneID=%s, bossID=%s, isAlive=%s" % (zoneID, bossID, isAlive)) | 
|---|
|  |  |  | zoneID, bossStateDict = msgInfo | 
|---|
|  |  |  | GameWorld.DebugLog("收到跨服服务器同步的跨服boss状态: zoneID=%s, bossStateDict=%s" % (zoneID, bossStateDict)) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | __SetCrossBossIsAlive(zoneID, bossID, isAlive) | 
|---|
|  |  |  | aliveBossIDList = [] | 
|---|
|  |  |  | for bossID, isAlive in bossStateDict.items(): | 
|---|
|  |  |  | __SetCrossBossIsAlive(zoneID, bossID, isAlive) | 
|---|
|  |  |  | if isAlive: | 
|---|
|  |  |  | aliveBossIDList.append(bossID) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if isAlive: | 
|---|
|  |  |  | Sync_CrossBossInfo(None, [bossID]) | 
|---|
|  |  |  | if aliveBossIDList: | 
|---|
|  |  |  | Sync_CrossBossInfo(None, aliveBossIDList) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return | 
|---|
|  |  |  |  | 
|---|