From 8978dd1c93b322806bac51090d40e65cee33d90d Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期三, 09 一月 2019 15:26:09 +0800 Subject: [PATCH] 5722 【后端】【1.5】跨服BOSS开发(支持刷跨服boss) --- ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py | 29 ++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py | 7 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py | 8 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py | 40 -- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py | 81 ++++++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossRealmPlayer.py | 22 + ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py | 57 +++- ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py | 22 + ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py | 8 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBoss.py | 377 +++++++++++++++++++++++++++++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Boss.py | 15 + ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py | 9 ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py | 8 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 47 ++- PySysDB/PySysDBPY.h | 7 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py | 7 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py | 2 PySysDB/PySysDBG.h | 11 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 5 19 files changed, 683 insertions(+), 79 deletions(-) diff --git a/PySysDB/PySysDBG.h b/PySysDB/PySysDBG.h index 3fd8260..95b8039 100644 --- a/PySysDB/PySysDBG.h +++ b/PySysDB/PySysDBG.h @@ -470,6 +470,17 @@ list MatchRange; //可匹配到的玩家段位区间 [从段位A, 到段位B],配[]代表只匹配本段位的 }; +//跨服Boss蓬莱仙境分区表 + +struct tagCrossPenglaiZone +{ + BYTE ZoneID; //分区ID + list ServerGroupIDList; //服务器组ID列表 + DWORD _MapID; //场景地图ID + DWORD _DataMapID; //数据地图ID + BYTE _CopyMapID; //虚拟线路ID +}; + //周狂欢活动时间表 struct tagActWeekParty diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h index 03f35a6..e30678a 100644 --- a/PySysDB/PySysDBPY.h +++ b/PySysDB/PySysDBPY.h @@ -1446,10 +1446,11 @@ struct tagCrossPenglaiZone { - BYTE _ZoneID; //分区ID + BYTE ZoneID; //分区ID list ServerGroupIDList; //服务器组ID列表 - DWORD MapID; //场景地图ID - BYTE CopyMapID; //虚拟线路ID + DWORD _MapID; //场景地图ID + DWORD _DataMapID; //数据地图ID + BYTE _CopyMapID; //虚拟线路ID WORD PosX; //坐标X WORD PosY; //坐标Y }; diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py index f9d1fcf..51f8a52 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py @@ -371,7 +371,7 @@ Def_WorldKey_BossIsGeTui = "BossGeTui%s" #当前复活通知 Def_WorldKey_OperationActionState = "OperationActState_%s" #运营活动状态,参数为运营活动名 Def_WorldKey_BossRebornNeedPoint = "BossRebornNeedPoint" #boss复活需要总点数 -Def_WorldKey_BossIsAlive = 'BossIsAlive_%s' #boss是否活着 +Def_WorldKey_CrossBossIsAlive = 'CrossBossIsAlive_%s_%s' #跨服boss是否活着,参数(zoneID, bossID) Def_WorldKey_IsGameWorldInit = 'IsGameWorldInit' #GameWold是否初始化完成 Def_WorldKey_CrossPKZoneSeasonID = "CrossPKZoneSeasonID_%s" #跨服PK赛区对应赛季,跨服服务器控制,参数(zoneID) Def_WorldKey_CrossPKZoneSeasonState = "CrossPKZoneSeasonState_%s" #跨服PK赛区赛季状态,跨服服务器控制,参数(zoneID)0-未开启,1-开启中,2-已结束 @@ -685,6 +685,12 @@ #跨服蓬莱仙境 Def_FBMapID_CrossPenglai = 32020 +#跨服地图 +Def_CrossMapIDList = [Def_FBMapID_CrossRealmPK, Def_FBMapID_CrossPenglai] +#跨服对应分区配置表名 +Def_CrossZoneTableName = {Def_FBMapID_CrossPenglai:"CrossPenglaiZone", + } + #同系职业枚举 JOB_TYPY_COUNT = 5 ( diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBoss.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBoss.py new file mode 100644 index 0000000..af21a5e --- /dev/null +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBoss.py @@ -0,0 +1,377 @@ +#!/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 PlayerControl +import NetPackCommon +import CrossRealmMsg +import ShareDefine +import PyGameData + +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 GetCrossBossZoneIpyData(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) + +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 ClientServerMsg_ServerInitOK(serverGroupID): + ## 子服连接成功 + + bossInfoList = [] + 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 + 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]) + + return + +def DoCrossBossOnKilled(bossID, killPlayerName, realMapID, dataMapID, copyMapID): + ## 跨服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)) + 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被击杀 + serverGroupIDList = zoneIpyData.GetServerGroupIDList() + killedRecord = GetRecKilledRecord(bossRecData) + bossInfoList = [[zoneID, bossID, killedTime, refreshTime, killedRecord, isAlive]] + 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() + GameWorld.Log("跨服boss状态变更: zoneID=%s,bossID=%s,isAlive=%s,realMapID=%s,dataMapID=%s,copyMapID=%s" + % (zoneID, bossID, isAlive, realMapID, dataMapID, copyMapID)) + if not zoneID: + return + + __SetCrossBossIsAlive(zoneID, bossID, isAlive) + + if isAlive: + # 广播子服跨服boss复活 + serverGroupIDList = zoneIpyData.GetServerGroupIDList() + stateInfo = [zoneID, bossID, isAlive] + 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: + 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: + continue + tableName = ChConfig.Def_CrossZoneTableName[mapID] + if not hasattr(ipyDataMgr, "Get%sCount" % tableName): + continue + for i in xrange(getattr(ipyDataMgr, "Get%sCount" % tableName)()): + zoneIpyData = getattr(ipyDataMgr, "Get%sByIndex" % tableName)(i) + zoneID = zoneIpyData.GetZoneID() + bossRecData = __GetCrossBossRecData(zoneID, bossID) + killedTime = GetRecKilledTime(bossRecData) + refreshTime = GetRecRefreshTime(bossRecData) + PyGameData.g_sortBOSSRefreshList.append([bossID, killedTime, refreshTime, zoneID]) + 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 = [] + for bossInfo in PyGameData.g_sortBOSSRefreshList: + bossID, killedTime, refreshTime, zoneID = 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 + + __SetCrossBossIsAlive(zoneID, bossID, 1) + syncBOSSIDList.append(bossID) + + 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)) + + return + +def OnCrossMapServerInitOK(): + __SendMapServerAliveCrossBoss() + return + +def __SendMapServerAliveCrossBoss(): + ## 同步当前还活着的boss,防止地图重启后已经刷新的boss不刷新 + 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: + continue + tableName = ChConfig.Def_CrossZoneTableName[mapID] + if not hasattr(ipyDataMgr, "Get%sCount" % tableName): + continue + for i in xrange(getattr(ipyDataMgr, "Get%sCount" % tableName)()): + zoneIpyData = getattr(ipyDataMgr, "Get%sByIndex" % tableName)(i) + zoneID = zoneIpyData.GetZoneID() + isAlive = __GetCrossBossIsAlive(zoneID, bossID) + if not isAlive: + continue + GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 1) + + return + +##------------------------------------- 以下是本服处理 ------------------------------------------- + +def OnPlayerLogin(curPlayer): + Sync_CrossBossInfo(curPlayer) + return + +def CrossServerMsg_CrossBossInfo(bossInfoDict): + ## 收到跨服服务器同步的跨服boss信息 {"BossInfoType":"InitOK", "BossInfoList":bossInfoList} + global g_bossRecDataDict + + bossInfoType = bossInfoDict["BossInfoType"] + bossInfoList = bossInfoDict["BossInfoList"] + + GameWorld.DebugLog("收到跨服同步的跨服boss信息: bossInfoType=%s" % (bossInfoType)) + + if bossInfoType == "InitOK": + # 子服收到初始化数据的,覆盖更新 + recTypeListData = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_CrossBossInfo) + recTypeListData.Clear() + g_bossRecDataDict = {} + + syncBOSSIDList = [] + for bossInfo in bossInfoList: + zoneID, bossID, killedTime, refreshTime, killedRecord, isAlive = bossInfo + bossRecData = __GetCrossBossRecData(zoneID, bossID) + SetRecKilledTime(bossRecData, killedTime) + SetRecRefreshTime(bossRecData, refreshTime) + SetRecKilledRecord(bossRecData, killedRecord) + __SetCrossBossIsAlive(zoneID, bossID, isAlive) + syncBOSSIDList.append(bossID) + + Sync_CrossBossInfo(None, syncBOSSIDList) + return + +def CrossServerMsg_CrossBossState(msgInfo): + ## 收到跨服服务器同步的跨服boss状态 + + zoneID, bossID, isAlive = msgInfo + GameWorld.DebugLog("收到跨服服务器同步的跨服boss状态: zoneID=%s, bossID=%s, isAlive=%s" % (zoneID, bossID, isAlive)) + + __SetCrossBossIsAlive(zoneID, bossID, isAlive) + + if isAlive: + Sync_CrossBossInfo(None, [bossID]) + + return + + +def Sync_CrossBossInfo(curPlayer=None, syncBOSSIDList=[]): + ## 同步boss相关信息 + + curTime = int(time.time()) + + 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) + + 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 + + diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py index 4929e94..0f714f0 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py @@ -21,6 +21,7 @@ import IPY_GameServer import CrossRealmPlayer import CrossRealmPK +import CrossBoss import ChConfig import GMShell @@ -85,6 +86,7 @@ GameWorld.Log("收到跨服子服连接成功通知!") CrossRealmPlayer.ClientServerMsg_ServerInitOK(serverGroupID) CrossRealmPK.ClientServerMsg_ServerInitOK(serverGroupID, tick) + CrossBoss.ClientServerMsg_ServerInitOK(serverGroupID) return ## ================================================================================================ @@ -151,6 +153,12 @@ elif msgType == ShareDefine.CrossServerMsg_PKSyncBillboard: CrossRealmPK.CrossServerMsg_PKSyncBillboard(msgData) + elif msgType == ShareDefine.CrossServerMsg_CrossBossInfo: + CrossBoss.CrossServerMsg_CrossBossInfo(msgData) + + elif msgType == ShareDefine.CrossServerMsg_CrossBossState: + CrossBoss.CrossServerMsg_CrossBossState(msgData) + elif msgType == ShareDefine.CrossServerMsg_CrossServerState: CrossRealmPlayer.CrossServerMsg_CrossServerState(msgData) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py index c1fae3c..a9dd91e 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py @@ -45,6 +45,7 @@ import PyGameData import PlayerGeTui import IPY_GameServer +import CrossBoss import time @@ -101,12 +102,13 @@ if bossID <= 0: return - # 设置不存活,击杀玩家名 - killPlayerName = msgList[1] - hurtValue = msgList[2] - isAddKillCnt = msgList[3] - isNotify = msgList[4] if len(msgList) > 4 else True - mapID = msgList[5] if len(msgList) > 5 else None + bossID, killPlayerName, hurtValue, isNotify, realMapID, dataMapID, copyMapID = msgList + if GameWorld.IsCrossServer(): + CrossBoss.DoCrossBossOnKilled(bossID, killPlayerName, realMapID, dataMapID, copyMapID) + return + + mapID = dataMapID + isAddKillCnt = False isMapNeedShunt = IsMapNeedBossShunt(mapID) isAlive = __GetIsAlive(bossID) @@ -157,10 +159,12 @@ if len(msgList) <= 0: return - bossID = msgList[0] - isAlive = msgList[1] - mapID = msgList[2] if len(msgList) > 2 else None - lineID = msgList[3] if len(msgList) > 3 else None + bossID, isAlive, dataMapID, realMapID, copyMapID = msgList + if GameWorld.IsCrossServer(): + CrossBoss.DoCrossBossStateChange(bossID, isAlive, dataMapID, realMapID, copyMapID) + return + + mapID, lineID = dataMapID, copyMapID GameWorld.Log("世界boss状态变更: mapID=%s,lineID=%s,bossID=%s,state=%s,tick=%s" % (mapID, lineID, bossID, isAlive, tick)) if bossID <= 0: @@ -212,7 +216,7 @@ recTypeListData = __GetBossPrizeRecData() # 查找是否已有记录 bossRec = None - for index in range(recTypeListData.Count()): + for index in xrange(recTypeListData.Count()): universalRecData = recTypeListData.At(index) if universalRecData.GetValue1() == bossID: bossRec = universalRecData @@ -332,12 +336,18 @@ recTypeListData = __GetBossPrizeRecData() bossInfo.BossInfoList = [] #GameWorld.DebugLog("Sync_BossInfo...count=%s,curTime=%s" % (recTypeListData.Count(), curTime)) - for index in range(recTypeListData.Count()): + for index in xrange(recTypeListData.Count()): universalRecData = recTypeListData.At(index) bossID = universalRecData.GetValue1() if not bossID: continue if syncBOSSIDList and bossID not in syncBOSSIDList: + continue + ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossID) + if not ipyData: + continue + mapID = ipyData.GetMapID() + if mapID in ChConfig.Def_CrossMapIDList: continue bossInfoObj = ChPyNetSendPack.tagBossInfoObj() bossInfoObj.BossID = bossID @@ -359,7 +369,7 @@ if not curPlayer: # 全服广播在线玩家 playerManager = GameWorld.GetPlayerManager() - for i in range(0, playerManager.GetActivePlayerCount()): + for i in xrange(playerManager.GetActivePlayerCount()): curPlayer = playerManager.GetActivePlayerAt(i) if curPlayer == None or not curPlayer.GetInitOK(): continue @@ -379,6 +389,9 @@ if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossProcessTick, tick): #间隔未到 return + if GameWorld.IsCrossServer(): + CrossBoss.DoCheckCrossBossReborn(tick) + return curTime = int(time.time()) DoCheckWorldBossShuntInfo(curTime, tick) BossRebornWorldNotify(curTime) @@ -386,6 +399,9 @@ for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()): ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i) bossID = ipyData.GetNPCID() + mapID = ipyData.GetMapID() + if mapID in ChConfig.Def_CrossMapIDList: + continue bossPrizeRec = __GetBossRecDataByID(bossID) killedTime = bossPrizeRec.GetValue2() refreshTime = __GetBossRefreshTime(bossID) @@ -426,7 +442,8 @@ if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossGeTuiTick, tick): #间隔未到 return - + if GameWorld.IsCrossServer(): + return curTime = int(time.time()) for bossInfo in PyGameData.g_sortBOSSRefreshList: bossID, killedTime, refreshTime = bossInfo @@ -459,6 +476,9 @@ for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()): ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i) bossID = ipyData.GetNPCID() + mapID = ipyData.GetMapID() + if mapID in ChConfig.Def_CrossMapIDList: + continue isAlive = __GetIsAlive(bossID) if not isAlive: continue @@ -471,6 +491,7 @@ # @param curPlayer # @return None def OnPlayerLogin(curPlayer): + CrossBoss.OnPlayerLogin(curPlayer) Sync_BossInfo(curPlayer) PyDataManager.GetBossAttentionManager().NotifyBossAttentionInfo(curPlayer) if IsMapNeedBossShunt(0): @@ -487,6 +508,9 @@ # @param None # @return None def OnMapServerInitOK(): + if GameWorld.IsCrossServer(): + CrossBoss.OnCrossMapServerInitOK() + return SendMapServerBossKilledCnt() __SendMapServerAliveBoss() if IsMapNeedBossShunt(0): @@ -555,11 +579,16 @@ if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossOnlineCntTick, tick): #间隔未到 return + if GameWorld.IsCrossServer(): + return GameWorld.DebugLog('世界boss在线人数统计') bossRebornDict = {} for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()): ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i) bossID = ipyData.GetNPCID() + mapID = ipyData.GetMapID() + if mapID in ChConfig.Def_CrossMapIDList: + continue refreshTimeStr = ipyData.GetRefreshTime() if 'onlineCnt' in refreshTimeStr: bossRebornDict[bossID] = ipyData.GetLVLimit() diff --git a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py index e3da4dc..f7f269e 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py @@ -397,6 +397,14 @@ ("list", "MatchRange", 0), ), + "CrossPenglaiZone":( + ("BYTE", "ZoneID", 0), + ("list", "ServerGroupIDList", 0), + ("DWORD", "MapID", 1), + ("DWORD", "DataMapID", 1), + ("BYTE", "CopyMapID", 1), + ), + "ActWeekParty":( ("DWORD", "CfgID", 1), ("char", "ActMark", 0), @@ -1178,6 +1186,23 @@ def GetLVUpScore(self): return self.LVUpScore # 升段位所需积分 def GetMatchRange(self): return self.MatchRange # 可匹配到的玩家段位区间 [从段位A, 到段位B],配[]代表只匹配本段位的 +# 跨服Boss蓬莱仙境分区表 +class IPY_CrossPenglaiZone(): + + def __init__(self): + self.ZoneID = 0 + self.ServerGroupIDList = [] + self.MapID = 0 + self.DataMapID = 0 + self.CopyMapID = 0 + return + + def GetZoneID(self): return self.ZoneID # 分区ID + def GetServerGroupIDList(self): return self.ServerGroupIDList # 服务器组ID列表 + def GetMapID(self): return self.MapID # 场景地图ID + def GetDataMapID(self): return self.DataMapID # 数据地图ID + def GetCopyMapID(self): return self.CopyMapID # 虚拟线路ID + # 周狂欢活动时间表 class IPY_ActWeekParty(): @@ -1301,6 +1326,8 @@ self.ipyCrossRealmPKSeasonLen = len(self.ipyCrossRealmPKSeasonCache) self.ipyCrossRealmPKDanCache = self.__LoadFileData("CrossRealmPKDan", IPY_CrossRealmPKDan) self.ipyCrossRealmPKDanLen = len(self.ipyCrossRealmPKDanCache) + self.ipyCrossPenglaiZoneCache = self.__LoadFileData("CrossPenglaiZone", IPY_CrossPenglaiZone) + self.ipyCrossPenglaiZoneLen = len(self.ipyCrossPenglaiZoneCache) self.ipyActWeekPartyCache = self.__LoadFileData("ActWeekParty", IPY_ActWeekParty) self.ipyActWeekPartyLen = len(self.ipyActWeekPartyCache) Log("IPY_FuncConfig count=%s" % len(self.ipyFuncConfigDict)) @@ -1539,6 +1566,8 @@ def GetCrossRealmPKSeasonByIndex(self, index): return self.ipyCrossRealmPKSeasonCache[index] def GetCrossRealmPKDanCount(self): return self.ipyCrossRealmPKDanLen def GetCrossRealmPKDanByIndex(self, index): return self.ipyCrossRealmPKDanCache[index] + def GetCrossPenglaiZoneCount(self): return self.ipyCrossPenglaiZoneLen + def GetCrossPenglaiZoneByIndex(self, index): return self.ipyCrossPenglaiZoneCache[index] def GetActWeekPartyCount(self): return self.ipyActWeekPartyLen def GetActWeekPartyByIndex(self, index): return self.ipyActWeekPartyCache[index] diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py index 3937a1b..cde4e6f 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py @@ -25,6 +25,7 @@ import ChPyNetSendPack import PlayerDBGSEvent import NetPackCommon +import IpyGameDataPY import PyGameData # 获取玩家跨服服务器上的名字 @@ -54,6 +55,27 @@ return opName.decode('gbk').encode(GameWorld.GetCharacterEncoding()) + playerName +def GetServerCrossZoneIpyData(mapID, serverGroupID=0): + ## 获取本服对应跨服玩法分区地图信息 + if mapID not in ChConfig.Def_CrossZoneTableName: + return + if not serverGroupID: + serverGroupID = GameWorld.GetServerGroupID() + + tableName = ChConfig.Def_CrossZoneTableName[mapID] + ipyDataMgr = IpyGameDataPY.IPY_Data() + if not hasattr(ipyDataMgr, "Get%sCount" % tableName): + return + + for i in xrange(getattr(ipyDataMgr, "Get%sCount" % tableName)()): + ipyData = getattr(ipyDataMgr, "Get%sByIndex" % tableName)(i) + serverGroupIDList = ipyData.GetServerGroupIDList() + for serverGroupIDInfo in serverGroupIDList: + if (isinstance(serverGroupIDInfo, tuple) and serverGroupIDInfo[0] <= serverGroupID <= serverGroupIDInfo[1]) \ + or (isinstance(serverGroupIDInfo, int) and serverGroupIDInfo == serverGroupID): + return ipyData + return + def IsCrossServerOpen(): ## 跨服服务器是否开放中 return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossServerOpen) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py index b2a89aa..8d8c4a1 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py @@ -177,7 +177,8 @@ Def_Notify_WorldKey_MixServerCampaignSaveData = "MixServerCampaignSaveData_%s" # 合服活动记录数据时机0-否 1-是 Def_Notify_WorldKey_MixServerCampaignGetAward = "MixServerCampaignGetAward_%s" # 合服活动可领奖时机0-否 1-是 -Def_Notify_WorldKey_GameWorldBossReborn = 'GameWorldBossReborn_%s' # 世界boss重生, %s为标识点28,29 +Def_Notify_WorldKey_GameWorldBossRebornCross = 'BossRebornCross_%s_%s' # 跨服世界boss重生, 参数为(zoneID, bossID) +Def_Notify_WorldKey_GameWorldBossReborn = 'BossReborn_%s' # 世界boss重生, 参数为(bossID) Def_Notify_WorldKey_BossKilledCnt = 'BossKilledCnt_%s' # boss击杀次数, 参数为NPCID Def_Notify_WorldKey_GameWorldBossOnlineCnt = "GameWorldBossOnlineCnt_%s" #世界boss重生时间计算 在线人数统计 %s为bossid Def_Notify_WorldKey_BossShuntPlayer = 'BossShuntPlayer' # boss分流玩家信息 @@ -975,7 +976,7 @@ Def_UniversalGameRecType_27, Def_UniversalGameRecType_28, Def_UniversalGameRecType_BossInfo, # boss信息29 - Def_UniversalGameRecType_30, + Def_UniversalGameRecType_CrossBossInfo, # 跨服boss信息 Def_UniversalGameRecType_31, Def_UniversalGameRecType_32, Def_UniversalGameRecType_ManorWarInfo, # 领地争夺战占领结果33 @@ -1198,6 +1199,8 @@ CrossServerMsg_PKOverInfo = "PKOverInfo" # 跨服PK结果 CrossServerMsg_PKSeasonInfo = "PKSeasonInfo" # 跨服PK赛季信息 CrossServerMsg_PKSyncBillboard = "PKSyncBillboard" # 跨服PK同步排行榜 +CrossServerMsg_CrossBossInfo = "CrossBossInfo" # 跨服Boss信息 +CrossServerMsg_CrossBossState = "CrossBossState" # 跨服Boss状态 # 子服发送跨服信息定义 ClientServerMsg_ServerInitOK = "ServerInitOK" # 子服启动成功 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py index b4f5ec6..c400c4e 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py @@ -1795,6 +1795,11 @@ #注册上传跨服服务器数据后直接进入跨服服务器的地图 RegisterEnter_CrossServerMapIDList = [Def_FBMapID_CrossPenglai] +#跨服地图 +Def_CrossMapIDList = [Def_FBMapID_CrossRealmPK, Def_FBMapID_CrossPenglai] +#跨服对应分区配置表名 +Def_CrossZoneTableName = {Def_FBMapID_CrossPenglai:"CrossPenglaiZone", + } #副本关闭时未拾取的物品邮件发放给玩家 #这里只有需要的副本才配置,不做默认逻辑,防止某些副本实际不能给导致刷物品,如麒麟之府 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Boss.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Boss.py index e9213c6..03e5d59 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Boss.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Boss.py @@ -12,7 +12,7 @@ # @change: "2013-01-16 19:00" wdb 防范死亡的召唤兽被reborn # @change: "2014-10-29 23:30" hxp 增加可刷新标识点刷新的世界boss #------------------------------------------------------------------------------ -"""Version = 2014-10-29 23:30""" +#"""Version = 2014-10-29 23:30""" #--------------------------------------------------------------------- # 模块详细说明 @@ -23,6 +23,7 @@ import NPCCommon import ShareDefine import IpyGameDataPY +import CrossRealmPlayer #--------------------------------------------------------------------- #全局变量 #--------------------------------------------------------------------- @@ -46,7 +47,17 @@ if not bossID: continue - key = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID + if mapID in ChConfig.Def_CrossZoneTableName: + tableName = ChConfig.Def_CrossZoneTableName[mapID] + realMapID = GameWorld.GetGameWorld().GetRealMapID() + copyMapID = GameWorld.GetGameWorld().GetCopyMapID() + zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, mapID, copyMapID) + if not zoneIpyData: + continue + zoneID = zoneIpyData.GetZoneID() + key = ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID) + else: + key = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID GameWorld.GetGameWorld().SetGameWorldDict(key, 1) bossKey = ChConfig.Map_NPC_WorldBossLastReBornTick % bossID diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py index 7226ad5..591de6a 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py @@ -421,12 +421,8 @@ if playerHurtList: killerName, hurtValue = playerHurtList[0][1] NPCCommon.GameServer_KillGameWorldBoss(bossID, killerName, hurtValue) - - msgList = [bossID, 0] - GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'GameWorldBossState', - '%s' % (msgList), len(str(msgList))) - bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID - GameWorld.GetGameWorld().SetGameWorldDict(bosskey, 0) + + NPCCommon.GameServe_GameWorldBossState(bossID, 0) __DoLogicSealDemonOver(1, tick, dropPosX, dropPosY) gameFB.SetGameFBDict(FBDict_IsOver, tick) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py index 1fe83aa..74c3a97 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py @@ -1140,10 +1140,11 @@ ), "CrossPenglaiZone":( - ("BYTE", "ZoneID", 1), + ("BYTE", "ZoneID", 0), ("list", "ServerGroupIDList", 0), - ("DWORD", "MapID", 0), - ("BYTE", "CopyMapID", 0), + ("DWORD", "MapID", 1), + ("DWORD", "DataMapID", 1), + ("BYTE", "CopyMapID", 1), ("WORD", "PosX", 0), ("WORD", "PosY", 0), ), @@ -3541,6 +3542,7 @@ self.ZoneID = 0 self.ServerGroupIDList = [] self.MapID = 0 + self.DataMapID = 0 self.CopyMapID = 0 self.PosX = 0 self.PosY = 0 @@ -3549,6 +3551,7 @@ def GetZoneID(self): return self.ZoneID # 分区ID def GetServerGroupIDList(self): return self.ServerGroupIDList # 服务器组ID列表 def GetMapID(self): return self.MapID # 场景地图ID + def GetDataMapID(self): return self.DataMapID # 数据地图ID def GetCopyMapID(self): return self.CopyMapID # 虚拟线路ID def GetPosX(self): return self.PosX # 坐标X def GetPosY(self): return self.PosY # 坐标Y diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py index 1266f07..fe4c469 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py @@ -2068,13 +2068,7 @@ # 通知GameServer boss状态 封魔坛在副本里单独处理 ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', npcid) if ipyData and ipyData.GetMapID() != ChConfig.Def_FBMapID_SealDemon: - mapID = GameWorld.GetMap().GetMapID() - lineID = GameWorld.GetGameWorld().GetLineID() - msgList = [npcid, 0, mapID, lineID] - GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'GameWorldBossState', - '%s' % (msgList), len(str(msgList))) - bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % npcid - GameWorld.GetGameWorld().SetGameWorldDict(bosskey, 0) + GameServe_GameWorldBossState(npcid, 0) #GameWorld.GetGameWorld().SetGameWorldDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick()) #因为存在boss分流,所以用gameFB字典,但是存活状态还是用GameWorld字典 GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick()) @@ -2100,11 +2094,35 @@ curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID)) return -def GameServer_KillGameWorldBoss(bossID, killerName, hurtValue, isNotify=True): - isAddKillCnt = 0 # 页游逻辑,手游暂写死不增 - mapID = GameWorld.GetMap().GetMapID() - killMsg = str([bossID, killerName, hurtValue, isAddKillCnt, isNotify, mapID]) +def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True): + dataMapID = GameWorld.GetGameWorld().GetMapID() + realMapID = GameWorld.GetGameWorld().GetRealMapID() + copyMapID = GameWorld.GetGameWorld().GetCopyMapID() + killMsg = str([bossID, killPlayerName, hurtValue, isNotify, realMapID, dataMapID, copyMapID]) GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'KillGameWorldBoss', killMsg, len(killMsg)) + GameWorld.DebugLog("Boss被击杀: bossID=%s,dataMapID=%s,realMapID=%s,copyMapID=%s" % (bossID, dataMapID, realMapID, copyMapID)) + return + +def GameServe_GameWorldBossState(bossID, isAlive): + dataMapID = GameWorld.GetGameWorld().GetMapID() + realMapID = GameWorld.GetGameWorld().GetRealMapID() + copyMapID = GameWorld.GetGameWorld().GetCopyMapID() + stateMsg = str([bossID, isAlive, dataMapID, realMapID, copyMapID]) + GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'GameWorldBossState', '%s' % stateMsg, len(stateMsg)) + GameWorld.DebugLog("Boss状态变更: bossID=%s,isAlive=%s,dataMapID=%s,realMapID=%s,copyMapID=%s" + % (bossID, isAlive, dataMapID, realMapID, copyMapID)) + if not isAlive: + if dataMapID in ChConfig.Def_CrossZoneTableName: + tableName = ChConfig.Def_CrossZoneTableName[dataMapID] + realMapID = GameWorld.GetGameWorld().GetRealMapID() + copyMapID = GameWorld.GetGameWorld().GetCopyMapID() + zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, dataMapID, copyMapID) + if not zoneIpyData: + return + zoneID = zoneIpyData.GetZoneID() + GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 0) + else: + GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 0) return ################################################# @@ -3508,12 +3526,7 @@ # 通知GameServer boss刷新成功 ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', curNPCID) if ipyData: - mapID = GameWorld.GetMap().GetMapID() - lineID = GameWorld.GetGameWorld().GetLineID() - msgList = [curNPCID, 1, mapID, lineID] - GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'GameWorldBossState', - '%s' % (msgList), len(str(msgList))) - + GameServe_GameWorldBossState(curNPCID, 1) if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family: FamilyRobBoss.FamilyOwnerBossOnReborn(curNPC) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py index 6aa5ef7..5a8c626 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py @@ -17,6 +17,7 @@ import ShareDefine import ReadChConfig import GameLogic_SealDemon +import CrossRealmPlayer import PlayerControl import IPY_GameWorld import IpyGameDataPY @@ -389,6 +390,9 @@ '''非分流地图boss只在一线刷 分流地图boss每条线都刷新,其他分流线路boss在没人打的情况下同生同死 ''' + if GameWorld.IsCrossServer(): + __DoRefreshWorldBossCrossServer(npcRefresh, tick) + return mapID = GameWorld.GetMap().GetMapID() refreshMark = npcRefresh.GetRefreshMark() lineID = GameWorld.GetGameWorld().GetLineID() @@ -531,6 +535,83 @@ #=================================================================================================== +def __DoRefreshWorldBossCrossServer(npcRefresh, tick): + ## 跨服服务器刷boss + + mapID = GameWorld.GetGameWorld().GetMapID() # dataMapID + if mapID not in ChConfig.Def_CrossMapIDList: + return + + refreshMark = npcRefresh.GetRefreshMark() + lineID = GameWorld.GetGameWorld().GetLineID() + bossIpyData = IpyGameDataPY.GetIpyGameDataByCondition('BOSSInfo', {'RefreshMark':refreshMark, 'MapID':mapID}, isLogNone=False) + if not bossIpyData: + return + + stoneNPCID = bossIpyData.GetStoneNPCID() + bossID = bossIpyData.GetNPCID() + if not bossID and not stoneNPCID: + return + + if mapID not in ChConfig.Def_CrossZoneTableName: + return + tableName = ChConfig.Def_CrossZoneTableName[mapID] + realMapID = GameWorld.GetGameWorld().GetRealMapID() + copyMapID = GameWorld.GetGameWorld().GetCopyMapID() + zoneIpyData = IpyGameDataPY.GetIpyGameDataNotLog(tableName, realMapID, mapID, copyMapID) + if not zoneIpyData: + return + zoneID = zoneIpyData.GetZoneID() + + gameFB = GameWorld.GetGameFB() + bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID) + rebornBossState = GameWorld.GetGameWorld().GetGameWorldDictByKey(bosskey) + curNPC = None + if npcRefresh.GetCount() > 0: + curNPC = npcRefresh.GetAt(0) + + # 复活状态 + if rebornBossState: + if curNPC: + if curNPC.GetNPCID() == bossID: + return + #去掉非bossNPC + NPCCommon.SetDeadEx(curNPC) + + # 死亡状态 + else: + if curNPC: + if curNPC.GetNPCID() == stoneNPCID: + return + #去掉非墓碑NPC + NPCCommon.SetDeadEx(curNPC) + + # 延迟刷墓碑 + bossDeadTick = gameFB.GetGameFBDictByKey(ChConfig.Map_NPC_WorldBossDeadTick % bossID) + bossStoneDelayTime = IpyGameDataPY.GetFuncCfg('BossStoneDelayTime') + if tick - bossDeadTick <= bossStoneDelayTime: + return + gameFB.SetGameFBDict(ChConfig.Map_NPC_WorldBossDeadTick % bossID, tick) + + rebornNPCID = bossID if rebornBossState else stoneNPCID + if not rebornNPCID: + return + rebornTickKey = ChConfig.Map_NPC_WorldBossLastReBornTick % rebornNPCID + lastRebornTick = gameFB.GetGameFBDictByKey(rebornTickKey) + if tick - lastRebornTick <= 50 * 1000: + GameWorld.DebugLog("CrossBossRefresh mapID=%s,realMapID=%s,copyMapID=%s,refreshMark=%s,rebornNPCID=%s,tick=%s,lastRebornTick=%s 不重复刷新!" + % (mapID, realMapID, copyMapID, refreshMark, rebornNPCID, tick, lastRebornTick)) + return + + npcRefresh.Refresh(rebornNPCID, ChConfig.Def_SuperBossAngryCount, 1, False) + #初始化NPC + __InitNewBornNPC(npcRefresh, tick) + gameFB.SetGameFBDict(rebornTickKey, tick) + + GameWorld.DebugLog("CrossBossRefresh mapID=%s,realMapID=%s,copyMapID=%s,refreshMark=%s,rebornNPCID=%s,OK!" + % (mapID, realMapID, copyMapID, refreshMark, rebornNPCID), lineID) + return + ################################ 通用刷怪逻辑 #################################### def GetNPCRefreshCountList(refreshID): ## 获取刷怪标识点规则ID需要刷新的NPC个数信息; diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossRealmPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossRealmPlayer.py index 11a0900..4c13c2d 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossRealmPlayer.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossRealmPlayer.py @@ -17,6 +17,7 @@ import GameWorld import ReadChConfig import PlayerControl +import IpyGameDataPY import IPY_GameWorld import ShareDefine import ChConfig @@ -35,6 +36,27 @@ return opName.decode('gbk').encode(GameWorld.GetCharacterEncoding()) + playerName +def GetServerCrossZoneIpyData(mapID, serverGroupID=0): + ## 获取本服对应跨服玩法分区地图信息 + if mapID not in ChConfig.Def_CrossZoneTableName: + return + if not serverGroupID: + serverGroupID = GameWorld.GetServerGroupID() + + tableName = ChConfig.Def_CrossZoneTableName[mapID] + ipyDataMgr = IpyGameDataPY.IPY_Data() + if not hasattr(ipyDataMgr, "Get%sCount" % tableName): + return + + for i in xrange(getattr(ipyDataMgr, "Get%sCount" % tableName)()): + ipyData = getattr(ipyDataMgr, "Get%sByIndex" % tableName)(i) + serverGroupIDList = ipyData.GetServerGroupIDList() + for serverGroupIDInfo in serverGroupIDList: + if (isinstance(serverGroupIDInfo, tuple) and serverGroupIDInfo[0] <= serverGroupID <= serverGroupIDInfo[1]) \ + or (isinstance(serverGroupIDInfo, int) and serverGroupIDInfo == serverGroupID): + return ipyData + return + def IsCrossServerOpen(): ## 跨服服务器是否开放中 return GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossServerOpen) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py index 1ca199f..7f703a6 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py @@ -1222,7 +1222,7 @@ pack = IPY_GameWorld.IPY_MBroadcastMsg() msg = pack.GetMsg() - if not msg.startswith(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn[:-2]): + if not msg.startswith(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn[:-3]): GameWorld.Log('GameServer_BroadcastMsg msg = %s'%(msg)) #---接收世界服务器发来的消息--- diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py index f3ff343..c7ab3e3 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py @@ -21,7 +21,6 @@ import IPY_GameWorld import ChPyNetSendPack import NetPackCommon -import IpyGameDataPY import ChConfig @@ -55,6 +54,9 @@ return def RegisterEnterCrossServer(curPlayer, registerType, mapID=0, dataMapID=0, copyMapID=0, posX=0, posY=0): + ''' + @param registerType: 一般是dataMapID + ''' playerID = curPlayer.GetPlayerID() if GameWorld.IsCrossServer(): GameWorld.Log(" 跨服服务器不允许上传报名数据!", playerID) @@ -65,18 +67,15 @@ GameWorld.ErrLog("跨服已经在上传数据,不重复提交!playerRegisterType=%s,registerType=%s" % (playerRegisterType, registerType), curPlayer.GetPlayerID()) return + zoneID = 0 if not mapID: - if registerType in ChConfig.RegisterEnter_CrossServerMapIDList: - registerTableName = "CrossPenglaiZone" - else: + zoneIpyData = CrossRealmPlayer.GetServerCrossZoneIpyData(registerType) + if not zoneIpyData: + GameWorld.ErrLog("找不到该服务器对应跨服分区: registerType=%s" % (registerType)) return - RegisterMapInfo = GetCurServerGroupIDRegisterMapInfo(registerTableName) - if not RegisterMapInfo: - GameWorld.ErrLog("找不到该服务器对应跨服分区: registerType=%s,registerTableName=%s" % (registerType, registerTableName)) - return - mapID, copyMapID, posX, posY = RegisterMapInfo - dataMapID = mapID - + zoneID, mapID, dataMapID, copyMapID, posX, posY = zoneIpyData.GetZoneID(), zoneIpyData.GetMapID(), \ + zoneIpyData.GetDataMapID(), zoneIpyData.GetCopyMapID(), zoneIpyData.GetPosX(), zoneIpyData.GetPosY() + if not mapID: return @@ -90,23 +89,8 @@ curPlayer.SetDict(ChConfig.Def_PlayerKey_CrossRegisterType, registerType) #curPlayer.SendMergeRegisterPlayer(mapID, dataMapID, copyMapID, posX, posY) curPlayer.SendMergeRegisterPlayerAfterChange(CrossRealmPlayer.GetCrossPlayerName(curPlayer), mapID, dataMapID, copyMapID, posX, posY) - GameWorld.Log(" 发送跨服玩家数据注册: registerType=%s,mapID=%s,dataMapID=%s,copyMapID=%s,posX=%s,posY=%s,GetVsRoomId=%s" - % (registerType, mapID, dataMapID, copyMapID, posX, posY, curPlayer.GetVsRoomId()), playerID) - return - -def GetCurServerGroupIDRegisterMapInfo(tableName): - ipyDataMgr = IpyGameDataPY.IPY_Data() - if not hasattr(ipyDataMgr, "Get%sCount" % tableName): - return - - serverGroupID = GameWorld.GetServerGroupID() - for i in xrange(getattr(ipyDataMgr, "Get%sCount" % tableName)()): - ipyData = getattr(ipyDataMgr, "Get%sByIndex" % tableName)(i) - serverGroupIDList = ipyData.GetServerGroupIDList() - for serverGroupIDInfo in serverGroupIDList: - if (isinstance(serverGroupIDInfo, tuple) and serverGroupIDInfo[0] <= serverGroupID <= serverGroupIDInfo[1]) \ - or (isinstance(serverGroupIDInfo, int) and serverGroupIDInfo == serverGroupID): - return ipyData.GetMapID(), ipyData.GetCopyMapID(), ipyData.GetPosX(), ipyData.GetPosY() + GameWorld.Log(" 发送跨服玩家数据注册: registerType=%s,zoneID=%s,mapID=%s,dataMapID=%s,copyMapID=%s,posX=%s,posY=%s,GetVsRoomId=%s" + % (registerType, zoneID, mapID, dataMapID, copyMapID, posX, posY, curPlayer.GetVsRoomId()), playerID) return ## 跨服赛报名结果(上传数据) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py index b2a89aa..8d8c4a1 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py @@ -177,7 +177,8 @@ Def_Notify_WorldKey_MixServerCampaignSaveData = "MixServerCampaignSaveData_%s" # 合服活动记录数据时机0-否 1-是 Def_Notify_WorldKey_MixServerCampaignGetAward = "MixServerCampaignGetAward_%s" # 合服活动可领奖时机0-否 1-是 -Def_Notify_WorldKey_GameWorldBossReborn = 'GameWorldBossReborn_%s' # 世界boss重生, %s为标识点28,29 +Def_Notify_WorldKey_GameWorldBossRebornCross = 'BossRebornCross_%s_%s' # 跨服世界boss重生, 参数为(zoneID, bossID) +Def_Notify_WorldKey_GameWorldBossReborn = 'BossReborn_%s' # 世界boss重生, 参数为(bossID) Def_Notify_WorldKey_BossKilledCnt = 'BossKilledCnt_%s' # boss击杀次数, 参数为NPCID Def_Notify_WorldKey_GameWorldBossOnlineCnt = "GameWorldBossOnlineCnt_%s" #世界boss重生时间计算 在线人数统计 %s为bossid Def_Notify_WorldKey_BossShuntPlayer = 'BossShuntPlayer' # boss分流玩家信息 @@ -975,7 +976,7 @@ Def_UniversalGameRecType_27, Def_UniversalGameRecType_28, Def_UniversalGameRecType_BossInfo, # boss信息29 - Def_UniversalGameRecType_30, + Def_UniversalGameRecType_CrossBossInfo, # 跨服boss信息 Def_UniversalGameRecType_31, Def_UniversalGameRecType_32, Def_UniversalGameRecType_ManorWarInfo, # 领地争夺战占领结果33 @@ -1198,6 +1199,8 @@ CrossServerMsg_PKOverInfo = "PKOverInfo" # 跨服PK结果 CrossServerMsg_PKSeasonInfo = "PKSeasonInfo" # 跨服PK赛季信息 CrossServerMsg_PKSyncBillboard = "PKSyncBillboard" # 跨服PK同步排行榜 +CrossServerMsg_CrossBossInfo = "CrossBossInfo" # 跨服Boss信息 +CrossServerMsg_CrossBossState = "CrossBossState" # 跨服Boss状态 # 子服发送跨服信息定义 ClientServerMsg_ServerInitOK = "ServerInitOK" # 子服启动成功 -- Gitblit v1.8.0