From 415c7723223a95ab35f3f135bdf12a982ec879e6 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期五, 11 四月 2025 16:30:22 +0800 Subject: [PATCH] 10367 【越南】【英语】【BT】【砍树】仙盟攻城战-服务端(跨服仙盟支持;后台查询区服仙盟支持;活动时间流程支持;攻城战主活动功能完整流程:公示、分组、战备、战斗、榜单、竞猜、领奖等;) --- ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py | 406 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 374 insertions(+), 32 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py index d9af3a4..ff60117 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py @@ -44,6 +44,8 @@ import PlayerFamilySWRH import PlayerViewCache import GameWorldBoss +import CrossRealmMsg +import CrossFamilyGCZ import AuctionHouse import PlayerAssist import PlayerTalk @@ -61,6 +63,62 @@ ImpeachLastTime # 弹劾需要持续的时间 ) = range(3) +class FamilyMgr(): + + def __init__(self): + self.sortFamilyIDList = [] #本服仙盟排序顺序 [familyID, ...] + self.fightPowerChangeFamilyIDList = [] # 仙盟成员战力有变更的仙盟ID [familyID, ...] + + #这里仅针对增改信息,删除的另外处理,因为删除的需要确保成功删除,所以需要入库未成功删除的记录 + #而变更同步的会定时同步,每次重连服务器也会强制同步,所以不需要有成功回复 + self.syncCrossFamilyDict = {} # 需要同步跨服的仙盟 {familyID:[需要同步的成员ID, ...], ...} + return + + def OnDeleteFamilyID(self, familyID): + if familyID in self.sortFamilyIDList: + self.sortFamilyIDList.remove(familyID) # 直接从排序列表中移除, 不需要重新排序 + self.SetSyncCrossFamilyDel(familyID) # 解散仙盟 + return + + def GetFamilyIDRank(self, familyID): + if familyID not in self.sortFamilyIDList: + return len(self.sortFamilyIDList) + 1 + return self.sortFamilyIDList.index(familyID) + 1 + + def AddFamilyIDToFightPowerChangeList(self, familyID, playerID=0): + if familyID not in self.fightPowerChangeFamilyIDList: + self.fightPowerChangeFamilyIDList.append(familyID) + GameWorld.DebugLog("仙盟战力变更待处理列表: fightPowerChangeFamilyIDList=%s" % self.fightPowerChangeFamilyIDList) + self.SetSyncCrossFamilyUpd(familyID, playerID) # 仙盟战力变更、成员战力变更 + return + + def SetSyncCrossFamilyUpd(self, familyID, playerID=0, syncNow=False): + if familyID not in self.syncCrossFamilyDict: + self.syncCrossFamilyDict[familyID] = [] + if playerID: + needSyncMemIDList = self.syncCrossFamilyDict[familyID] + if playerID not in needSyncMemIDList: + needSyncMemIDList.append(playerID) + # 变更数据是否立即同步跨服,否则等待定时同步即可 + if syncNow: + Sync_ClientFamilyUpdToCrossServer() + return + + def SetSyncCrossFamilyDel(self, familyID, playerID=0): + ## 设置同步跨服服务器仙盟删除 + # @param playerID: 如果有值代表仅成员删除 + valueSetList = [playerID] + gameRecMgr = PyDataManager.GetDBGameRecDataManager() + gameRecMgr.AddGameRecData(ShareDefine.Def_GameRecType_FamilyDelSyncCross, familyID, valueSetList) + Sync_ClientFamilyDelToCrossServer() # 删除的立马同步 + return + +def GetFamilyMgr(): + mgr = PyGameData.g_familyMgr + if not mgr: + mgr = FamilyMgr() + PyGameData.g_familyMgr = mgr + return mgr ## ------------------ 仙盟 ---------------------- ## 仙盟联赛排名 @@ -71,6 +129,7 @@ def SetFamilyTotalFightPower(curFamily, totalFightPower): curFamily.SetExtra4(totalFightPower / ChConfig.Def_PerPointValue) curFamily.SetExtra5(totalFightPower % ChConfig.Def_PerPointValue) + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID()) # 仙盟战力变更 return def GetFamilyTotalFightPowerByID(familyID): family = GameWorld.GetFamilyManager().FindFamily(familyID) @@ -79,7 +138,10 @@ return GetFamilyTotalFightPower(family) # 徽章ID def GetFamilyEmblemID(curFamily): return curFamily.GetExtra6() -def SetFamilyEmblemID(curFamily, emblemID): return curFamily.SetExtra6(emblemID) +def SetFamilyEmblemID(curFamily, emblemID): + curFamily.SetExtra6(emblemID) + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID()) # 徽章变更 + return # 公告修改次数 def GetFamilyBroadcastCnt(curFamily): return curFamily.GetExtra3() @@ -108,11 +170,17 @@ def OnGameServerInitOK(): ## 服务器启动成功处理 - DoFamilySort() + if GameWorld.IsCrossServer(): + pass + else: + DoFamilySort() return def OnMixServerInit(): ## 合服后首次启动成功处理 + + if GameWorld.IsCrossServer(): + return # 仙盟联赛重置 GameWorldFamilyWar.DoFamilyWarReset() @@ -440,7 +508,7 @@ #加入家族 familyMember = curFamily.AddMember(jionPlayer) #刷新基本信息 - RefreshFamilyMemberBaseMsg(familyMember, jionPlayer) + RefreshFamilyMemberBaseMsg(curFamily, familyMember, jionPlayer) #族长设置 if jionFamilySetLv == IPY_GameServer.fmlLeader: @@ -486,7 +554,7 @@ #仙盟拍品 AuctionHouse.Sync_FamilyAuctionItemInfo(jionPlayer, curFamily.GetID()) SetMemberFightPower(familyMember, PlayerControl.GetFightPower(jionPlayer)) - AddFamilyIDToFightPowerChangeList(curFamily.GetID()) + GetFamilyMgr().AddFamilyIDToFightPowerChangeList(curFamily.GetID(), jionPlayer.GetPlayerID()) #通知仙盟盛宴题目 PlayerFamilyParty.NotifyFamilyPartyQuestion(jionPlayer) @@ -678,7 +746,7 @@ # @remarks 通知客户端服务器家族信息 def Sync_AllFamilyInfo(curPlayer, viewPage, pageCnt=ChConfig.Def_ViewAllFamilyPageCount, sortRule=IPY_GameServer.fsrHornor): #familyCount = GameWorld.GetFamilyManager().GetCount() - familyCount = len(PyGameData.g_sortFamilyIDList) + familyCount = len(GetFamilyMgr().sortFamilyIDList) allPageCnt = GameWorld.GetIntUpper(familyCount, pageCnt) if allPageCnt != 0 and (viewPage < 0 or viewPage >= allPageCnt): @@ -716,7 +784,8 @@ return def Sync_PyAllFamilyInfo(curPlayer, allPageCnt, viewPage, startIndex, endIndex): - familyCount = len(PyGameData.g_sortFamilyIDList) + sortFamilyIDList = GetFamilyMgr().sortFamilyIDList + familyCount = len(sortFamilyIDList) if startIndex < 0 or endIndex >= familyCount: return @@ -727,7 +796,7 @@ familyViewPack.CurPage = viewPage familyViewPack.Family = [] for i in xrange(startIndex, endIndex + 1): - familyID = PyGameData.g_sortFamilyIDList[i] + familyID = sortFamilyIDList[i] family = familyMgr.FindFamily(familyID) if not family: continue @@ -785,7 +854,7 @@ familyViewPack.TotalCount = 1 #familyViewPack.CurPage = viewPage familyViewPack.Family = [] - for i, familyID in enumerate(PyGameData.g_sortFamilyIDList): + for i, familyID in enumerate(GetFamilyMgr().sortFamilyIDList): family = familyMgr.FindFamily(familyID) if not family: continue @@ -822,7 +891,7 @@ familyViewPack.TotalCount = 1 #familyViewPack.CurPage = viewPage familyViewPack.Family = [] - for i, familyID in enumerate(PyGameData.g_sortFamilyIDList): + for i, familyID in enumerate(GetFamilyMgr().sortFamilyIDList): family = familyMgr.FindFamily(familyID) if not family: continue @@ -908,6 +977,7 @@ continue curPlayer.ChatMi(notifyPlayer, 1, pack.GetMsg(), 0, PlayerTalk.GetTalkExtraValue(curPlayer)) PyDataManager.GetContactsManager().AddContactsBoth(curPlayer.GetID(), notifyPlayer.GetID()) + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID()) # 公告变更 return ## 检测目标玩家是否可以加入家族 @@ -1696,11 +1766,12 @@ PlayerFamilyAction.DelFamilyOfficerModelEquip(curFamily.GetID(), leavePlayerID) # 玩家战盟名变更处理 __OnFamilyNameChange(leavePlayerID, '') - AddFamilyIDToFightPowerChangeList(curFamily.GetID()) + GetFamilyMgr().AddFamilyIDToFightPowerChangeList(curFamily.GetID(), leavePlayerID) PlayerViewCache.OnPlayerFamilyChange(leavePlayerID, 0, "") PlayerAssist.OnPlayerLeaveFamily(curFamily.GetID(), leavePlayerID, tagPlayer) if leavePlayerID in PyGameData.g_autoViceleaderDict.get(curFamily.GetID(),[]): PyGameData.g_autoViceleaderDict[curFamily.GetID()].remove(leavePlayerID) + GetFamilyMgr().SetSyncCrossFamilyDel(curFamily.GetID(), leavePlayerID) # 成员离开、踢出 return #////////////////////////////////////////////////////////////// @@ -1845,7 +1916,7 @@ SetMemberFightPower(curMember, fightPower) GameWorld.DebugLog("仙盟成员战力变更 familyID=%s,fightPower=%s" % (familyID, fightPower), playerID) - AddFamilyIDToFightPowerChangeList(familyID) + GetFamilyMgr().AddFamilyIDToFightPowerChangeList(familyID, playerID) return ## A4 07 升级家族#tagCGFamilyLVUp @@ -1954,6 +2025,7 @@ #世界服务器家族重新排序 #GameWorld.GetFamilyManager().SortByLV() DoFamilySort() # 升级直接强排一次 + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID(), syncNow=True) # 仙盟等级变更 return True #--------------------------------------------------------------------- @@ -2002,6 +2074,8 @@ # @remarks 函数详细说明. def OnPlayerChangeMap(curPlayer, tick): #同步给玩家, 最新的家族信息(家族等级刷新) + if GameWorld.IsCrossServer(): + return curPlayer.MapServer_FamilyRefresh() return @@ -2151,7 +2225,7 @@ # @param curPlayer 真实玩家 # @return None # @remarks 刷新家族成员基本信息 -def RefreshFamilyMemberBaseMsg(curMember, curPlayer): +def RefreshFamilyMemberBaseMsg(curFamily, curMember, curPlayer): curMember.SetName(curPlayer.GetName()) curMember.SetLV(curPlayer.GetLV()) curMember.SetReincarnationLv(curPlayer.GetReincarnationLv()) @@ -2160,6 +2234,7 @@ curMember.SetOfficialRank(curPlayer.GetOfficialRank()) curMember.SetFace(curPlayer.GetFace()) curMember.SetFacePic(curPlayer.GetFacePic()) + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID(), curPlayer.GetPlayerID()) # 成员基础信息刷新,含加入仙盟刷新 return #--------------------------------------------------------------------- ## 玩家刷新 @@ -2174,9 +2249,9 @@ if curMember == None: return - RefreshFamilyMemberBaseMsg(curMember, curPlayer) - #家族长境界 family = curPlayer.GetFamily() + RefreshFamilyMemberBaseMsg(family, curMember, curPlayer) + #家族长境界 if family.GetLeaderID() == curPlayer.GetID(): family.SetLeaderOfficialRank(curPlayer.GetOfficialRank()) return @@ -2292,8 +2367,7 @@ #重新排序家族 #GameWorld.GetFamilyManager().SortByLV() - if familyID in PyGameData.g_sortFamilyIDList: - PyGameData.g_sortFamilyIDList.remove(familyID) # 直接从排序列表中移除, 不需要重新排序 + GetFamilyMgr().OnDeleteFamilyID(familyID) #家族科技删除, 改为地图直接处理, 暂屏蔽 #PlayerFamilyTech.DelFamilyTechData(familyID) @@ -2322,6 +2396,7 @@ #设置族长权限 ChangeFamilyMemberLv(familyMember, IPY_GameServer.fmlLeader) GameWorldFamilyWar.OnChangeFamilyLeader(curFamily.GetID(), familyMember.GetPlayerID()) + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID(), syncNow=True) # 盟主变更 return #--------------------------------------------------------------------- ##更改家族成员等级. @@ -2353,6 +2428,8 @@ # 变为普通成员,删除模型装备信息 elif changeFamilyLV == IPY_GameServer.fmlMember: PlayerFamilyAction.DelFamilyOfficerModelEquip(familyMember.GetFamilyID(), familyMember.GetPlayerID()) + + GetFamilyMgr().SetSyncCrossFamilyUpd(familyMember.GetFamilyID(), familyMember.GetPlayerID(), syncNow=True) # 成员职位变更 return #--------------------------------------------------------------------- @@ -2531,6 +2608,7 @@ #通知家族刷新 curFamily.Broadcast_FamilyChange() + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamilyID, syncNow=True) # 仙盟改名 playerManager = GameWorld.GetPlayerManager() #仙盟联赛 @@ -2711,6 +2789,8 @@ # @return 返回值无意义 # @remarks 家族过天 def FamilyOnDay(tick): + if GameWorld.IsCrossServer(): + return #---设置所有玩家可以再次加入家族--- GameWorld.GetPlayerManager().ClearForbiddenEnterFamily() #---扣除地图上所有家族的维护费--- @@ -2769,6 +2849,8 @@ return def FamilyOnDayEx(tick): + if GameWorld.IsCrossServer(): + return familyManager = GameWorld.GetFamilyManager() for i in range(0, familyManager.GetCount()): family = familyManager.GetAt(i) @@ -2784,7 +2866,8 @@ # @return 返回值无意义 # @remarks 家族过周 def FamilyOnWeek(tick): - + if GameWorld.IsCrossServer(): + return #---计算上周家族活跃度--- familyManager = GameWorld.GetFamilyManager() for i in range(0, familyManager.GetCount()): @@ -2816,6 +2899,8 @@ return def FamilyOnHour(): + if GameWorld.IsCrossServer(): + return familyManager = GameWorld.GetFamilyManager() for i in xrange(familyManager.GetCount()): family = familyManager.GetAt(i) @@ -2885,12 +2970,31 @@ return cmp(GetMemberJoinTime(member1), GetMemberJoinTime(member2)) return ret +def SortCrossFamily(serverIDList, top=0): + ''' 跨服仙盟排序, 排序规则: 总战力 > 等级 > ID + @param serverIDList: 仙盟所属区服ID范围列表 + @param top: 返回排序靠前x个仙盟,0则全部返回 + ''' + familyList = [] + familyManager = GameWorld.GetFamilyManager() + for i in xrange(familyManager.GetCount()): + family = familyManager.GetAt(i) + serverID = family.GetServerID() + if not GameWorld.CheckServerIDInList(serverID, serverIDList): + continue + familyList.append(family) + familyList.sort(key=lambda f: (GetFamilyTotalFightPower(f), f.GetLV(), f.GetID()), reverse=True) + totalCnt = len(familyList) + return familyList[:top] if top else familyList, totalCnt + #--------------------------------------------------------------------- ##通知地图服务器, 玩家家族属性刷新 # @param curFamily 家族实例 # @return 返回值无意义 # @remarks IPY_MFamilyRefresh def SendPack_MapServer_PlayerFamilyRefresh(curFamily): + if GameWorld.IsCrossServer(): + return #=============================================================================== # 当家族以下权限变更时要通知地图服务器 IPY_MFamilyRefresh # GetFamilyLV @@ -3534,21 +3638,30 @@ break return leaderLV -def AddFamilyIDToFightPowerChangeList(familyID): - if familyID not in PyGameData.g_fightPowerChangeFamilyIDList: - PyGameData.g_fightPowerChangeFamilyIDList.append(familyID) - GameWorld.DebugLog("仙盟战力变更待处理列表: fightPowerChangeFamilyIDList=%s" % PyGameData.g_fightPowerChangeFamilyIDList) +def OnMinuteProcess(curMinute): + if GameWorld.IsCrossServer(): + return + + #每5分钟触发一次仙盟更新 + if curMinute % 5 != 0: + return + + UpdFamilyTotalFightPower() + PlayerFamilyRedPacket.CheckDelRedpacketData() + PlayerFamilyEmblem.CheckExpireEmblem() + Sync_ClientFamilyUpdToCrossServer() return def UpdFamilyTotalFightPower(): ## 更新仙盟总战力 - if not PyGameData.g_fightPowerChangeFamilyIDList: + mgr = GetFamilyMgr() + if not mgr.fightPowerChangeFamilyIDList: #GameWorld.DebugLog("不需要更新仙盟总战力!") return - GameWorld.DebugLog("更新仙盟总战力 fightPowerChangeFamilyIDList=%s" % PyGameData.g_fightPowerChangeFamilyIDList) + GameWorld.DebugLog("更新仙盟总战力 fightPowerChangeFamilyIDList=%s" % mgr.fightPowerChangeFamilyIDList) familyManager = GameWorld.GetFamilyManager() - for familyID in PyGameData.g_fightPowerChangeFamilyIDList: + for familyID in mgr.fightPowerChangeFamilyIDList: family = familyManager.FindFamily(familyID) if not family: continue @@ -3560,19 +3673,17 @@ SetFamilyTotalFightPower(family, totalFightPower) GameWorld.DebugLog(" familyID=%s,totalFightPower=%s" % (familyID, totalFightPower)) - PyGameData.g_fightPowerChangeFamilyIDList = [] + mgr.fightPowerChangeFamilyIDList = [] DoFamilySort(False) # 此处必须为False return True -def GetSortFamilyIDList(): return PyGameData.g_sortFamilyIDList +def GetSortFamilyIDList(): return GetFamilyMgr().sortFamilyIDList def GetFamilyIDRank(familyID): '''获取仙盟的排名, 注意与联赛排名区分 每个仙盟一定有排名,但是不一定有联赛排名,联赛排名只是决定仙盟最终排名的一个比较因素 ''' - if familyID not in PyGameData.g_sortFamilyIDList: - return len(PyGameData.g_sortFamilyIDList) + 1 - return PyGameData.g_sortFamilyIDList.index(familyID) + 1 + return GetFamilyMgr().GetFamilyIDRank(familyID) def DoFamilySort(isUpdTotalFightPower=True): ''' 仙盟排序, 排序规则: 联赛评级 > 总战力 > 等级 > 创建时间 @@ -3590,12 +3701,13 @@ familyList.append(family) familyList.sort(cmp=CmpFamilySort) - PyGameData.g_sortFamilyIDList = [] + mgr = GetFamilyMgr() + mgr.sortFamilyIDList = [] for i, family in enumerate(familyList, 1): GameWorld.DebugLog(" i=%s,warRank=%s,fightPower=%s,LV=%s,CreateTime=%s,familyID=%s" % (i, GetFamilyWarRank(family), GetFamilyTotalFightPower(family), family.GetLV(), family.GetCreateTime(), family.GetID())) - PyGameData.g_sortFamilyIDList.append(family.GetID()) - GameWorld.DebugLog(" sortFamilyIDList=%s" % PyGameData.g_sortFamilyIDList) + mgr.sortFamilyIDList.append(family.GetID()) + GameWorld.DebugLog(" sortFamilyIDList=%s" % mgr.sortFamilyIDList) return def CmpFamilySort(family1, family2): @@ -3836,6 +3948,17 @@ ##-------------------------------------------------------------------------------------------------- +def CrossServerMsg_FamilyDelRet(msgData): + ## 跨服仙盟删除结果,有收到结果即代表成功 + familyID = msgData["familyID"] + playerID = msgData.get("playerID", 0) + gameRecMgr = PyDataManager.GetDBGameRecDataManager() + if playerID: + gameRecMgr.DelGameRecDataByTypeValue(ShareDefine.Def_GameRecType_FamilyDelSyncCross, [playerID], familyID) + else: + gameRecMgr.DelGameRecDataByTypeID(ShareDefine.Def_GameRecType_FamilyDelSyncCross, familyID) + return + def GetFamilyBillboardInfo(curFamily): ## 获取仙盟榜单信息 区服ID、徽章、仙盟名、盟主名、仙盟总战力、仙盟等级 familyID = curFamily.GetID() @@ -3851,3 +3974,222 @@ return {"id":familyID, "name":name, "id2":id2, "name2":name2, "value1":value1, "value2":value2, "value3":value3, "value4":value4, "value5":value5} +def Sync_ClientFamilyUpdToCrossServer(): + ## 定时同步仙盟变更数据到跨服服务器 + + Sync_ClientFamilyDelToCrossServer() # 防止未删除成功,这里补通知 + + mgr = GetFamilyMgr() + if not mgr.syncCrossFamilyDict: + return + + familyManager = GameWorld.GetFamilyManager() + for familyID, updMemIDList in mgr.syncCrossFamilyDict.items(): + family = familyManager.FindFamily(familyID) + if not family: + continue + Send_ClientServerMsg_SyncFamilyInfo("FamilyUpd", GetSyncCrossServerFamilyInfo(family, updMemIDList)) + + mgr.syncCrossFamilyDict = {} + return + +def Sync_ClientFamilyAllToCrossServer(): + ## 同步子服所有仙盟信息到跨服 + + if GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_SyncFamilyAllToCross): + return + GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_SyncFamilyAllToCross, 1) + GameWorld.Log("开始同步本服所有仙盟到跨服服务器!") + + Sync_ClientFamilyDelToCrossServer() # 防止未删除成功,这里补通知 + + familyManager = GameWorld.GetFamilyManager() + for i in xrange(familyManager.GetCount()): + family = familyManager.GetAt(i) + if not family: + continue + Send_ClientServerMsg_SyncFamilyInfo("FamilyUpd", GetSyncCrossServerFamilyInfo(family)) + return + +def Sync_ClientFamilyDelToCrossServer(): + ## 同步仙盟删除数据到跨服服务器 + gameRecMgr = PyDataManager.GetDBGameRecDataManager() + recDataDict = gameRecMgr.GetGameRecDataDict(ShareDefine.Def_GameRecType_FamilyDelSyncCross) + for familyID, recDataList in recDataDict.items(): + for recData in recDataList: + playerID = recData.GetValue1() + Send_ClientServerMsg_SyncFamilyInfo("FamilyDel", {"familyID":familyID, "playerID":playerID}) + return + +def GetCrossFamilyBaseInfo(family): + return {"ID": family.GetID(), "Name": family.GetName(), "LV":family.GetLV(), "FightPower":GetFamilyTotalFightPower(family), + "LeaderID": family.GetLeaderID(), "LeaderName": family.GetLeaderName(), "EmblemID":GetFamilyEmblemID(family), + "ServerID":family.GetServerID(), "Broadcast":family.GetBroadcast()} + +def GetCrossFamilyMemInfo(member): + return {"Name":member.GetName(), "LV":member.GetLV(), "Job":member.GetJob(), "OfficialRank":member.GetOfficialRank(), + "Face":member.GetFace(), "FacePic":member.GetFacePic(), "FamilyLV":member.GetFamilyLV(), "FightPower":GetMemberFightPower(member)} + +def GetSyncCrossServerFamilyInfo(family, memIDList=None): + ## 获取仙盟跨服所需信息 + # @param memIDList: 需要获取成员信息ID列表,不传则取所有成员 + + crossFamilyInfo = GetCrossFamilyBaseInfo(family) + + memAll = True if memIDList == None else False + memInfo = {} + for m in xrange(family.GetCount()): + member = family.GetAt(m) + memID = member.GetPlayerID() + if not memID: + continue + if memIDList and memID not in memIDList: + continue + memInfo[memID] = GetCrossFamilyMemInfo(member) + + crossFamilyInfo.update({"memInfo":memInfo, "memAll":memAll}) + return crossFamilyInfo + +def Send_ClientServerMsg_SyncFamilyInfo(syncType, syncInfo): + dataMsg = {"syncType":syncType, "syncInfo":syncInfo} + CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_SyncFamilyInfo, dataMsg) + return + +def ClientServerMsg_SyncFamilyInfo(serverGroupID, msgData): + ## 收到子服 - 仙盟信息 + + syncType = msgData["syncType"] + syncInfo = msgData["syncInfo"] + + if syncType == "FamilyUpd": + __CrossServer_FamilyUpd(syncInfo) + + elif syncType == "FamilyDel": + __CrossServer_FamilyDel(serverGroupID, syncInfo) + + return + +def __CrossServer_FamilyDel(serverGroupID, syncInfo): + ## 跨服服务器删除子服仙盟、成员 + familyID = syncInfo["familyID"] + playerID = syncInfo.get("playerID", 0) + if playerID: + curFamily = GameWorld.GetFamilyManager().FindFamily(familyID) + if curFamily: + curFamily.DeleteMember(playerID) + else: + #删除家族 + GameWorld.GetFamilyManager().DelFamily(familyID) + #删除家族行为数据 + PlayerFamilyAction.ClearFamilyAction(familyID) + + # 直接回复就是删除成功 + CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FamilyDelRet, syncInfo, [serverGroupID]) + return + +def __CrossServer_FamilyUpd(familyInfo): + ## 跨服服务器更新子服仙盟 - 这里只覆盖更新,不考虑删除的情况 + + familyID = familyInfo["ID"] + familyName = familyInfo["Name"] + curFamily = FindAndFixCrossFamilyByIDName(familyID, familyName) + if not curFamily: + GameWorld.ErrLog("跨服更新仙盟失败! 仙盟不存在或者创建失败! familyID=%s" % familyID) + return + + #curFamily.SetName(familyInfo["Name"]) # 这里不再更新名称 + curFamily.SetLV(familyInfo["LV"]) + SetFamilyTotalFightPower(curFamily, familyInfo["FightPower"]) + curFamily.SetLeaderID(familyInfo["LeaderID"]) + curFamily.SetLeaderName(familyInfo["LeaderName"]) + SetFamilyEmblemID(curFamily, familyInfo["EmblemID"]) + curFamily.SetServerID(familyInfo["ServerID"]) + curFamily.SetBroadcast(familyInfo["Broadcast"]) + + updMemIDList = [] + memAll = familyInfo.get("memAll", False) + memInfoDict = familyInfo.get("memInfo", {}) + if memInfoDict: + for m in range(curFamily.GetCount())[::-1]: + member = curFamily.GetAt(m) + memID = member.GetPlayerID() + if not memID: + continue + if memID not in memInfoDict: + if memAll: + curFamily.DeleteMember(memID) + continue + memInfo = memInfoDict.pop(memID) + __updCrossFamilyMemberInfo(curFamily, member, memInfo) + updMemIDList.append(memID) + + # 剩下的就是新增的成员 + for memID, memInfo in memInfoDict.items(): + member = curFamily.AddMemberEx(memID) + if not member: + continue + __updCrossFamilyMemberInfo(curFamily, member, memInfo) + updMemIDList.append(memID) + + # 相关活动数据更新 + CrossFamilyGCZ.OnCrossJoinFamilyMemberUpd(curFamily, updMemIDList) + return + +def FindAndFixCrossFamilyByIDName(familyID, familyName): + ## 按仙盟名及ID查找跨服仙盟,重名时系统会自动修改仙盟名 + + familyManager = GameWorld.GetFamilyManager() + curFamily = familyManager.FindFamily(familyID) + if not curFamily: + for i in range(100): + crossFamilyName = familyName if i == 0 else ("%s_%s" % (familyName, i)) + curFamily = familyManager.AddFamilyEx(crossFamilyName, familyID) + if curFamily: + GameWorld.DebugLog("跨服添加新仙盟! familyID=%s, i=%s" % (familyID, i)) + break + return curFamily + + # 验证当前名字是否还是唯一的,因为延迟同步的原因,仙盟可能改名时在本服唯一,但是在跨服不唯一 + nameFamily = familyManager.FindFamilyByName(familyName) + if not nameFamily: + GameWorld.DebugLog("新同步的名字已经不存在仙盟了,可直接替换新仙盟名! familyID=%s" % familyID) + curFamily.SetName(familyName) + return curFamily + + if nameFamily.GetID() == familyID: + #GameWorld.DebugLog("还是自己原来的仙盟名,直接返回! familyID=%s" % familyID) + return curFamily + + # 尝试修改仙盟名,如果没有唯一名,则不修改保留最后一次同步的仙盟名,至少最后一次的名字还是唯一的 + for i in range(1, 100): + fixFamilyName = "%s_%s" % (familyName, i) + family = familyManager.FindFamilyByName(fixFamilyName) + if family: + if family.GetID() == familyID: + #GameWorld.DebugLog("保留原系统修改的仙盟名! familyID=%s" % familyID) + break + # 已存在该仙盟名,且不是自己的仙盟 + continue + curFamily.SetName(fixFamilyName) + GameWorld.Log("跨服强制修改仙盟名: familyID=%s,%s,%s" % (familyID, i, fixFamilyName)) + break + + return curFamily + +def __updCrossFamilyMemberInfo(curFamily, member, memInfo): + member.SetName(memInfo.get("Name", "")) + member.SetLV(memInfo.get("LV", 1)) + member.SetJob(memInfo.get("Job", 1)) + member.SetOfficialRank(memInfo.get("OfficialRank", 1)) + member.SetFace(memInfo.get("Face", 0)) + member.SetFacePic(memInfo.get("FacePic", 0)) + SetMemberFightPower(member, memInfo.get("FightPower", 0)) + memFamilyLV = memInfo.get("FamilyLV", 0) + member.SetFamilyLV(memFamilyLV) + if memFamilyLV == IPY_GameServer.fmlLeader: + curFamily.SetLeaderID(member.GetPlayerID()) + curFamily.SetLeaderName(member.GetName()) + curFamily.SetLeaderOfficialRank(member.GetOfficialRank()) + + return + -- Gitblit v1.8.0