hxp
2019-04-16 767426c623624202acd0c97854946f4fafafe904
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBoss.py
@@ -20,11 +20,13 @@
import IpyGameDataPY
import ChPyNetSendPack
import CrossRealmPlayer
import DataRecordPack
import PlayerControl
import NetPackCommon
import CrossRealmMsg
import ShareDefine
import PyGameData
import PlayerFB
import time
@@ -50,15 +52,22 @@
g_bossRecDataDict = {} # boss对应rec记录缓存 {(zoneID, bossID):recData, ...}
def GetCrossBossZoneIpyData(realMapID, dataMapID, copyMapID):
def GetCrossBossZoneID(realMapID, dataMapID, copyMapID):
    ## 获取地图跨服boss所属分区
    if dataMapID not in ChConfig.Def_CrossMapIDList:
        return
    if dataMapID not in ChConfig.Def_CrossZoneTableName:
        GameWorld.ErrLog("跨服boss没有分区表!dataMapID=%s" % dataMapID)
        return
    tableName = ChConfig.Def_CrossZoneTableName[dataMapID]
    return IpyGameDataPY.GetIpyGameData(tableName, realMapID, dataMapID, copyMapID)
        return 0
    # 固定线路分配的
    if dataMapID in ChConfig.Def_CrossZoneMapTableName:
        tableName = ChConfig.Def_CrossZoneMapTableName[dataMapID]
        zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, dataMapID, copyMapID)
        if not zoneIpyData:
            return 0
        return zoneIpyData.GetZoneID()
    # 动态线路分配的
    elif dataMapID in ChConfig.Def_CrossDynamicLineMap:
        return PlayerFB.GetCrossDynamicLineZoneID(dataMapID, realMapID, copyMapID)
    return 0
def __GetCrossBossRecData(zoneID, bossID):
    ## 获取跨服Boss Rec数据
@@ -98,38 +107,49 @@
    ## 获取跨服世界boss是否活着
    return GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_CrossBossIsAlive % (zoneID, bossID))
def ClientServerMsg_ServerInitOK(serverGroupID):
    ## 子服连接成功
def Sync_CrossBossInitDataToClientServer(serverGroupID=0):
    ''' 同步跨服Boss活动数据到子服务器
    @param serverGroupID: 为0时同步所有子服
    '''
    
    bossInfoList = []
    GameWorld.Log("同步给子服跨服boss信息: syncServerGroupID=%s" % (serverGroupID))
    zoneIpyDataList = CrossRealmPlayer.GetCrossCommZoneIpyDataListByServerGroupID(serverGroupID)
    if not zoneIpyDataList:
        GameWorld.Log("    没有跨服boss分区信息!")
        return
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for i in xrange(ipyDataMgr.GetBOSSInfoCount()):
        ipyData = ipyDataMgr.GetBOSSInfoByIndex(i)
        mapID = ipyData.GetMapID()
        zoneIpyData = CrossRealmPlayer.GetServerCrossZoneIpyData(mapID, serverGroupID)
        if not zoneIpyData:
            continue
    for zoneIpyData in zoneIpyDataList:
        zoneID = zoneIpyData.GetZoneID()
        bossID = ipyData.GetNPCID()
        bossRecData = __GetCrossBossRecData(zoneID, bossID)
        killedTime = GetRecKilledTime(bossRecData)
        refreshTime = GetRecRefreshTime(bossRecData)
        killedRecord = GetRecKilledRecord(bossRecData)
        isAlive = __GetCrossBossIsAlive(zoneID, bossID)
        bossInfoList.append([zoneID, bossID, killedTime, refreshTime, killedRecord, isAlive])
    if bossInfoList:
        bossInfoDict = {"BossInfoType":"InitOK", "BossInfoList":bossInfoList}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossInfo, bossInfoDict, [serverGroupID])
        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:
            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)
    return
def DoCrossBossOnKilled(bossID, killPlayerName, realMapID, dataMapID, copyMapID):
def DoCrossBossOnKilled(bossID, killPlayerName, realMapID, dataMapID, copyMapID, killerIDList):
    ## 跨服boss被杀
    zoneIpyData = GetCrossBossZoneIpyData(realMapID, dataMapID, copyMapID)
    zoneID = 0 if not zoneIpyData else zoneIpyData.GetZoneID()
    GameWorld.Log("击杀跨服boss: zoneID=%s,bossID=%s,realMapID=%s,dataMapID=%s,copyMapID=%s"
                  % (zoneID, bossID, realMapID, dataMapID, copyMapID))
    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))
    if not zoneID:
        return
    
@@ -144,17 +164,20 @@
    refreshTime = SetBossRefreshTime(zoneID, bossID, killedTime, bossRecData)
    
    # 广播子服跨服boss被击杀
    zoneIpyData = CrossRealmPlayer.GetCrossCommZoneIpyDataByZoneID(zoneID)
    if zoneIpyData == None:
        return
    serverGroupIDList = zoneIpyData.GetServerGroupIDList()
    killedRecord = GetRecKilledRecord(bossRecData)
    bossInfoList = [[zoneID, bossID, killedTime, refreshTime, killedRecord, isAlive]]
    killerExInfo = [killerIDList, dataMapID]
    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):
    ## 跨服boss状态变更
    zoneIpyData = GetCrossBossZoneIpyData(realMapID, dataMapID, copyMapID)
    zoneID = 0 if not zoneIpyData else zoneIpyData.GetZoneID()
    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))
    if not zoneID:
@@ -164,10 +187,12 @@
    
    if isAlive:
        # 广播子服跨服boss复活
        serverGroupIDList = zoneIpyData.GetServerGroupIDList()
        stateInfo = [zoneID, bossID, isAlive]
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossState, stateInfo, serverGroupIDList)
        zoneIpyData = CrossRealmPlayer.GetCrossCommZoneIpyDataByZoneID(zoneID)
        if zoneIpyData != None:
            serverGroupIDList = zoneIpyData.GetServerGroupIDList()
            stateInfo = [zoneID, bossID, isAlive]
            CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossState, stateInfo, serverGroupIDList)
    return
def __SetKilledRecord(bossRecData, killedTime, playerName):
@@ -214,18 +239,21 @@
    
    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_CrossZoneTableName:
            if mapID not in ChConfig.Def_CrossZoneTypeName:
                continue
            tableName = ChConfig.Def_CrossZoneTableName[mapID]
            if not hasattr(ipyDataMgr, "Get%sCount" % tableName):
            zoneTypeName = ChConfig.Def_CrossZoneTypeName[mapID]
            if not hasattr(ipyDataMgr, "Get%sCount" % zoneTypeName):
                continue
            for i in xrange(getattr(ipyDataMgr, "Get%sCount" % tableName)()):
                zoneIpyData = getattr(ipyDataMgr, "Get%sByIndex" % tableName)(i)
            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)
@@ -255,24 +283,38 @@
        
    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_CrossZoneTableName:
        if mapID not in ChConfig.Def_CrossZoneTypeName:
            continue
        tableName = ChConfig.Def_CrossZoneTableName[mapID]
        if not hasattr(ipyDataMgr, "Get%sCount" % tableName):
        zoneTypeName = ChConfig.Def_CrossZoneTypeName[mapID]
        if not hasattr(ipyDataMgr, "Get%sCount" % zoneTypeName):
            continue
        for i in xrange(getattr(ipyDataMgr, "Get%sCount" % tableName)()):
            zoneIpyData = getattr(ipyDataMgr, "Get%sByIndex" % tableName)(i)
        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:
@@ -304,7 +346,7 @@
        
    syncBOSSIDList = []
    for bossInfo in bossInfoList:
        zoneID, bossID, killedTime, refreshTime, killedRecord, isAlive = bossInfo
        zoneID, bossID, killedTime, refreshTime, killedRecord, isAlive, killerExInfo = bossInfo
        bossRecData = __GetCrossBossRecData(zoneID, bossID)
        SetRecKilledTime(bossRecData, killedTime)
        SetRecRefreshTime(bossRecData, refreshTime)
@@ -312,6 +354,19 @@
        __SetCrossBossIsAlive(zoneID, bossID, isAlive)
        syncBOSSIDList.append(bossID)
        
        if not killerExInfo:
            continue
        killerIDList, dataMapID = 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))
                DataRecordPack.SendEventPack("CrossBoss_Error", {"PlayerID":playerID, "Error":"MainServerOffline"})
                continue
            msgInfo = str([dataMapID, bossID])
            killer.MapServer_QueryPlayerResult(0, 0, "CrossKillBoss", msgInfo, len(msgInfo))
    Sync_CrossBossInfo(None, syncBOSSIDList)
    return