From d5e51e22a6ba5d69da195f9621af8450af2291f1 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期二, 13 五月 2025 16:51:43 +0800 Subject: [PATCH] 10367 【越南】【英语】【BT】【砍树】仙盟攻城战-服务端(点赞奖励不限制是否有参赛资格;) --- ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py | 866 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 791 insertions(+), 75 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py index 71cff36..e779af4 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py @@ -29,18 +29,25 @@ import DataRecordPack import PlayerFamilyBoss import IpyGameDataPY +import PlayerFamilyZhenbaoge import PlayerFamilyRedPacket import GameWorldFamilyWar import ChPyNetSendPack import NetPackCommon import PyDataManager import PyGameData +import PlayerBillboard +import PlayerActBossTrial import PlayerCompensation +import PlayerFamilyEmblem import PlayerFamilyParty import PlayerFamilySWRH import PlayerViewCache import GameWorldBoss +import CrossRealmMsg +import CrossFamilyGCZ import AuctionHouse +import PlayerAssist import PlayerTalk import PlayerTeam @@ -56,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 ## ------------------ 仙盟 ---------------------- ## 仙盟联赛排名 @@ -66,12 +129,19 @@ 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) if not family: return 0 return GetFamilyTotalFightPower(family) +# 徽章ID +def GetFamilyEmblemID(curFamily): return curFamily.GetExtra6() +def SetFamilyEmblemID(curFamily, emblemID): + curFamily.SetExtra6(emblemID) + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID()) # 徽章变更 + return # 公告修改次数 def GetFamilyBroadcastCnt(curFamily): return curFamily.GetExtra3() @@ -88,12 +158,68 @@ def GetFamilyMixServerDay(curFamily): return curFamily.GetExtra1() def SetFamilyMixServerDay(curFamily, value): return curFamily.SetExtra1(value) ## ------------------ 成员 ---------------------- -def GetMemberFightPower(curMember): return curMember.GetExattr3() -def SetMemberFightPower(curMember, fightPower): return curMember.SetExattr3(fightPower) +def GetMemberFightPower(curMember): return curMember.GetExattr3() + curMember.GetExattr5() * ChConfig.Def_PerPointValue +def SetMemberFightPower(curMember, fightPower): + curMember.SetExattr5(fightPower / ChConfig.Def_PerPointValue) + curMember.SetExattr3(fightPower % ChConfig.Def_PerPointValue) + return def GetMemberJoinTime(curMember): return curMember.GetExattr4() def SetMemberJoinTime(curMember, joinTime): return curMember.SetExattr4(joinTime) #---------------------------------------------------------------------- + +def OnGameServerInitOK(): + ## 服务器启动成功处理 + if GameWorld.IsCrossServer(): + pass + else: + DoFamilySort() + return + +def OnMixServerInit(): + ## 合服后首次启动成功处理 + + if GameWorld.IsCrossServer(): + return + + # 仙盟联赛重置 + GameWorldFamilyWar.DoFamilyWarReset() + # 重置所有仙盟联赛评级 + familyManager = GameWorld.GetFamilyManager() + for i in xrange(familyManager.GetCount()): + family = familyManager.GetAt(i) + SetFamilyWarRank(family, 0) + + # 仙盟榜相关榜单重新上榜 + familyID = family.GetID() + familyBillInfo = GetFamilyBillboardInfo(family) + + familySubmitTotal = PlayerActBossTrial.GetFamilySubmitTotalByID(familyID) + PlayerBillboard.UpdateFamilyBillboard(ShareDefine.Def_BT_BossTrialSubmitFamily, familyBillInfo, familySubmitTotal) + + DoFamilySort() + return + +def OnLoadDBPlayerOK(): + ## 服务器启动加载DB玩家成功处理 + + # 检查仙盟ServerID + familyManager = GameWorld.GetFamilyManager() + for i in xrange(familyManager.GetCount()): + family = familyManager.GetAt(i) + if family.GetServerID(): + continue + familyID = family.GetID() + # 没有则默认取盟主的 + leaderID = family.GetLeaderID() + leaderAccID = PlayerControl.GetDBPlayerAccIDByID(leaderID) + if not leaderAccID: + continue + serverID = GameWorld.GetAccIDServerID(leaderAccID) + family.SetServerID(serverID) + GameWorld.Log("启动更新仙盟所属服务器ID: familyID=%s,serverID=%s,leaderID=%s,%s" % (familyID, serverID, leaderID, leaderAccID)) + + return def RandomFakeFamily(): '''随机3个假仙盟''' @@ -132,9 +258,25 @@ if not lackCnt: break elif lackCnt < 0: - GameWorld.ErrLog(' 随机假仙盟异常 已存在的随机数大于还需要的随机个数lackFakeCnt=%s,fakeIDList=%s'%(lackFakeCnt, fakeIDList)) + #GameWorld.DebugLog(' 随机假仙盟异常 已存在的随机数大于还需要的随机个数lackFakeCnt=%s,fakeIDList=%s'%(lackFakeCnt, fakeIDList)) return [] return fakeIDList + +def GetFamilyNameFakeIndex(familyName): + ## 获取仙盟名是否是系统随机出来的假仙盟名 + # @return: 0-不是, >0 对应的 fakeIndex + fakeFamilyNameList = IpyGameDataPY.GetFuncEvalCfg('FakeFamilyName') + randomCnt = IpyGameDataPY.GetFuncCfg('FakeFamilyName', 2) + for i in xrange(randomCnt): + fakeID = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_FakeFamilyIndex % i) + if not fakeID: + continue + nameIndex = fakeID - 1 + if nameIndex >=0 and nameIndex < len(fakeFamilyNameList): + fakeName = GameWorld.GbkToCode(fakeFamilyNameList[nameIndex]) + if familyName == fakeName: + return fakeID + return 0 def SyncFakeFamilyInfo(curPlayer=None): '''通知假仙盟信息''' @@ -162,6 +304,28 @@ NetPackCommon.SendFakePack(curPlayer, fakeFamilyPack) return +def SyncCreatFamilyTimes(curPlayer=None): + # 通知建盟次数 + packData = ChPyNetSendPack.tagGCServerCreatFamilyTimes() + packData.Clear() + packData.Times = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerCreatFamilyTimes) + if not curPlayer: + # 全服广播在线玩家 + playerManager = GameWorld.GetPlayerManager() + for i in range(0, playerManager.GetPlayerCount()): + curPlayer = playerManager.GetPlayerByIndex(i) + if curPlayer == None or not curPlayer.GetInitOK(): + continue + + if PlayerControl.GetIsTJG(curPlayer): + continue + NetPackCommon.SendFakePack(curPlayer, packData) + else: + if PlayerControl.GetIsTJG(curPlayer): + return + NetPackCommon.SendFakePack(curPlayer, packData) + return + #输入家族名称 #class IPY_CInputFamilyName #{ @@ -176,7 +340,7 @@ # @param tick 当前时间 # @return None # @remarks 函数详细说明. -def DoCreateFamily(curPlayer, familyName, fakeIndex, tick): +def DoCreateFamily(curPlayer, familyName, fakeIndex, tick, emblemID=0): #---验证玩家属性--- curPlayerID = curPlayer.GetPlayerID() @@ -233,11 +397,16 @@ if curFamily == None: GameWorld.ErrLog("家族创建数目已满, 创建家族失败", curPlayerID) return - GameWorld.Log("创建仙盟: familyID=%s,playerID=%s" % (curFamily.GetID(), curPlayerID)) + emblemIDList = PlayerFamilyEmblem.GetDefaultFamilyEmblemIDList() + if not emblemID or emblemID not in emblemIDList: + emblemID = random.choice(emblemIDList) # 从默认徽章中随机选择一个 + GameWorld.Log("创建仙盟: familyID=%s,playerID=%s,emblemID=%s" % (curFamily.GetID(), curPlayerID, emblemID)) #---创建家族--- + curFamily.SetServerID(GameWorld.GetAccIDServerID(curPlayer.GetAccID())) curFamily.SetCreateTime(GameWorld.GetCurrentDataTimeStr()) curFamily.SetLV(1) curFamily.SetAcceptJoin(ShareDefine.FamilyAcceptJoin_Agree) #设置收人方式为直接通过申请 + SetFamilyEmblemID(curFamily, emblemID) PyDataManager.GetFamilyStoreItemManager().DelFamilyStoreItemAll(curFamily.GetID()) #新创建的仙盟默认设置已处理过合服 @@ -245,11 +414,19 @@ #-设置家族成员属性 DoPlayerJionFamily(curFamily, curPlayer, IPY_GameServer.fmlLeader) - + creatFamilyTimes = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerCreatFamilyTimes) + # 如果是手动指定仙盟名创建的,判断是否在系统随机的假仙盟里,如果是的话就当做创建系统分配的假仙盟处理 + if familyName and not fakeIndex: + fakeIndex = GetFamilyNameFakeIndex(familyName) + GameWorld.DebugLog(" 玩家手动输入创建仙盟名与系统随机的假仙盟名相同,默认当做创建假仙盟!fakeIndexID=%s" % (fakeIndex)) #扣道具(前N个战盟并且假编号在随机编号里不要钱) if fakeIndex and fakeIndex in fakeIndexList: PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_FakeFamilyIndex % fakeIndexList.index(fakeIndex), 0) - GameWorld.DebugLog(' 创建前3个仙盟不扣钱! 假仙盟索引%s'%fakeIndexList.index(fakeIndex)) + GameWorld.Log(' 创建前n个假仙盟不扣钱! 假仙盟索引%s'%fakeIndexList.index(fakeIndex)) + fakeAwardItemList = IpyGameDataPY.GetFuncEvalCfg("FakeFamilyName", 3) + PlayerCompensation.SendMailByKey("FackFamilyNotice", [curPlayerID], fakeAwardItemList) + elif creatFamilyTimes < IpyGameDataPY.GetFuncCfg('CreateFamilyNeedMoney', 3): + GameWorld.Log(' 创建前n个仙盟不扣钱! creatFamilyTimes=%s' % creatFamilyTimes) else: for i, findex in enumerate(fakeIndexList): if findex: @@ -259,7 +436,9 @@ needMoney = IpyGameDataPY.GetFuncCfg('CreateFamilyNeedMoney') if needMoney: moneyType = IpyGameDataPY.GetFuncCfg('CreateFamilyNeedMoney', 2) - curPlayer.MapServer_PayMoney(moneyType, needMoney) + sendMsg = str([moneyType, needMoney]) + curPlayer.MapServer_QueryPlayerResult(0, 0, "CreateFamilyPayMoney", sendMsg, len(sendMsg)) + #curPlayer.MapServer_PayMoney(moneyType, needMoney) #玩家创建家族费用转化为家族初始资金 #PlayerAddFamilyMoney(curPlayer, curFamily, needMoney) @@ -285,13 +464,16 @@ #XW_JZ_EstablishSud <n color="255,255,0">恭喜您,家族建立成功!</n> 25 - - PlayerControl.NotifyCode(curPlayer, "XW_JZ_EstablishSud") - + PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerCreatFamilyTimes, min(creatFamilyTimes + 1, ShareDefine.Def_UpperLimit_DWord)) + SyncCreatFamilyTimes() #帮会创建流向 DataRecordPack.DR_CreateFamily(curPlayer.GetAccID(), curPlayerID, curPlayer.GetName(), - fullFamilyName, curFamily.GetID()) + fullFamilyName, curFamily.GetID(), creatFamilyTimes+1) - GameWorld.Log('创建家族 : %s(%s), fakeIndex=%s' % (fullFamilyName, curFamily.GetID(), fakeIndex), curPlayerID) + GameWorld.Log('创建家族 : %s(%s), fakeIndex=%s, creatFamilyTimes=%s' % (fullFamilyName, curFamily.GetID(), fakeIndex, creatFamilyTimes+1), curPlayerID) PlayerControl.WorldNotify(0, "jiazu_liubo_671654", [curPlayer.GetName(), fullFamilyName, curFamily.GetID()]) + + PlayerFamilyZhenbaoge.OnZhenbaogeReset(curFamily) return ## 获取家族全名 @@ -326,7 +508,7 @@ #加入家族 familyMember = curFamily.AddMember(jionPlayer) #刷新基本信息 - RefreshFamilyMemberBaseMsg(familyMember, jionPlayer) + RefreshFamilyMemberBaseMsg(curFamily, familyMember, jionPlayer) #族长设置 if jionFamilySetLv == IPY_GameServer.fmlLeader: @@ -365,19 +547,21 @@ #通知战盟红包信息 PlayerFamilyRedPacket.NotifyRedPacketInfo(jionPlayer) - #通知战盟BOSS开启信息 - PlayerFamilyBoss.NotifyFamilyBossFBInfo(jionPlayer) + #通知战盟BOSS + PlayerFamilyBoss.OnPlayerJionFamily(curFamily, jionPlayer) #通知家族仓库 PyDataManager.GetFamilyStoreItemManager().SyncFamilyStoreItem(jionPlayer, curFamily.GetID()) #仙盟拍品 AuctionHouse.Sync_FamilyAuctionItemInfo(jionPlayer, curFamily.GetID()) - SetMemberFightPower(familyMember, jionPlayer.GetFightPower()) - AddFamilyIDToFightPowerChangeList(curFamily.GetID()) + SetMemberFightPower(familyMember, PlayerControl.GetFightPower(jionPlayer)) + GetFamilyMgr().AddFamilyIDToFightPowerChangeList(curFamily.GetID(), jionPlayer.GetPlayerID()) #通知仙盟盛宴题目 PlayerFamilyParty.NotifyFamilyPartyQuestion(jionPlayer) #通知守卫人皇信息 PlayerFamilySWRH.NotifySWRHInfo(jionPlayer, curFamily.GetID()) + #通知仙盟协助信息 + PlayerAssist.SyncFamilyAssist(jionPlayer) #oss记录加入家族信息 DataRecordPack.DR_PlayerJoinFamily(jionPlayer, curFamily.GetID(), curFamily.GetName(), curFamily.GetCount()) return @@ -387,7 +571,6 @@ GameWorld.DebugLog(' 玩家战盟名变更处理, newFamilyName=%s' % familyName, playerID) #不处理排行榜 needChangeFamilyBillboardList = [ - #ShareDefine.Def_BT_RechargeTeHui, # 充值特惠活动排行榜-当前期记录 ] billboardMgr = GameWorld.GetBillboard() for billboardIndex in needChangeFamilyBillboardList: @@ -490,6 +673,7 @@ # tagHead Head; # char Name[33]; # WORD FakeID; +# BYTE EmblemID; //选择徽章ID,解锁仙盟等级为1级的均为可选ID #}; ## 查看申请帮会的成员信息 # @param index 玩家索引 @@ -500,8 +684,9 @@ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) inputName = clientPack.Name fakeIndex = clientPack.FakeID + emblemID = clientPack.EmblemID #执行创建家族逻辑 - DoCreateFamily(curPlayer, inputName, fakeIndex, tick) + DoCreateFamily(curPlayer, inputName, fakeIndex, tick, emblemID) #重置查看家族状态(仅创建家族时候重置, 其余状态由MapServer退出事件时重置) __ClearViewFamilyState(curPlayer) #玩家离开事件 @@ -561,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): @@ -582,7 +767,7 @@ #=============================================================================================== return -def SendFamilyFakePack(familyID, clientPack): +def SendFamilyFakePack(familyID, clientPack, excludePlayerIDList=[]): ## 广播家族成员PY封包 family = GameWorld.GetFamilyManager().FindFamily(familyID) if not family: @@ -591,12 +776,16 @@ for index in xrange(family.GetCount()): member = family.GetAt(index) memPlayer = member.GetPlayer() - if memPlayer: - NetPackCommon.SendFakePack(memPlayer, clientPack) + if not memPlayer: + continue + if excludePlayerIDList and memPlayer.GetPlayerID() in excludePlayerIDList: + continue + NetPackCommon.SendFakePack(memPlayer, clientPack) 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 @@ -607,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 @@ -634,6 +823,7 @@ totalFightPower = GetFamilyTotalFightPower(family) familyView.TotalFightPower = totalFightPower % ChConfig.Def_PerPointValue familyView.TotalFightPowerEx = totalFightPower / ChConfig.Def_PerPointValue + familyView.EmblemID = GetFamilyEmblemID(family) return familyView ## 玩家模糊查询家族,0F 0D封包 @@ -664,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 @@ -701,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 @@ -715,6 +905,76 @@ familyViewPack.PageCount = len(familyViewPack.Family) NetPackCommon.SendFakePack(curPlayer, familyViewPack) return + +#// A4 13 修改家族徽章 #tagCGChangeFamilyEmblem +# +#struct tagCGChangeFamilyEmblem +#{ +# tagHead Head; +# BYTE EmblemID; // 更换的徽章ID +#}; +def OnChangeFamilyEmblem(index, clientData, tick): + curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) + changeEmblemID = clientData.EmblemID + PlayerFamilyEmblem.OnChangeFamilyEmblem(curPlayer, changeEmblemID) + return + +#// A4 14 查看目标仙盟 #tagCGViewTagFamily +# +#struct tagCGViewTagFamily +#{ +# tagHead Head; +# DWORD TagFamilyID; // 目标仙盟ID,支持查看跨服仙盟 +#}; +def OnViewTagFamily(index, clientData, tick): + curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) + playerID = curPlayer.GetPlayerID() + tagFamilyID = clientData.TagFamilyID + clientPack = __GetTagFamilyInfoPack(tagFamilyID) + if not clientPack: + # 发送跨服服务器查询,可能是跨服仙盟 + dataMsg = {"playerID":playerID, "tagFamilyID":tagFamilyID} + CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_QueryCrossFamily, dataMsg) + return + NetPackCommon.SendFakePack(curPlayer, clientPack) + return + +def __GetTagFamilyInfoPack(tagFamilyID): + ## 获取查看目标仙盟同步封包 + familyManager = GameWorld.GetFamilyManager() + family = familyManager.FindFamily(tagFamilyID) + if not family: + return + clientPack = ChPyNetSendPack.tagGCTagFamilyInfo() + clientPack.FamilyID = tagFamilyID + clientPack.FamilyName = family.GetName() + clientPack.FamilyLV = family.GetLV() + clientPack.Broadcast = family.GetBroadcast() + clientPack.BroadcastLen = len(clientPack.Broadcast) + clientPack.Member = [] + for index in range(family.GetCount()): + curMember = family.GetAt(index) + mem = ChPyNetSendPack.tagGCTagFamilyMember() + mem.PlayerID = curMember.GetPlayerID() + mem.Name = curMember.GetName() + mem.NameLen = len(mem.Name) + mem.FamilyLV = curMember.GetFamilyLV() + mem.LV = curMember.GetLV() + mem.Job = curMember.GetJob() + mem.Face = curMember.GetFace() + mem.FacePic = curMember.GetFacePic() + mem.OfficialRank = curMember.GetOfficialRank() + fightPower = GetMemberFightPower(curMember) + mem.FightPower = fightPower % ChConfig.Def_PerPointValue + mem.FightPowerEx = fightPower / ChConfig.Def_PerPointValue + clientPack.Member.append(mem) + clientPack.MemberCount = len(clientPack.Member) + familyFightPower = GetFamilyTotalFightPower(family) + clientPack.FightPower = familyFightPower % ChConfig.Def_PerPointValue + clientPack.FightPowerEx = familyFightPower / ChConfig.Def_PerPointValue + clientPack.EmblemID = GetFamilyEmblemID(family) + clientPack.ServerID = family.GetServerID() + return clientPack #class IPY_CFamilyChangeBroadcast #{ @@ -774,6 +1034,7 @@ continue curPlayer.ChatMi(notifyPlayer, 1, pack.GetMsg(), 0, PlayerTalk.GetTalkExtraValue(curPlayer)) PyDataManager.GetContactsManager().AddContactsBoth(curPlayer.GetID(), notifyPlayer.GetID()) + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID()) # 公告变更 return ## 检测目标玩家是否可以加入家族 @@ -1426,7 +1687,9 @@ if PlayerFamilyBoss.IsInAllFamilyBoss(): PlayerControl.NotifyCode(curPlayer, "LeagueBOSSExitError1") return - + if AuctionHouse.IsFamilyMemberBiddingAuctionItem(curFamily.GetID(), tagMemberID): + PlayerControl.NotifyCode(curPlayer, "Paimai7") + return tagPlayerName = curTagMember.GetName() # 被踢玩家名 tagPlayerID = curTagMember.GetPlayerID() # 被踢玩家ID tagFamilyLV = curTagMember.GetFamilyLV() # 被踢玩家职位 @@ -1437,10 +1700,10 @@ PlayerFamilyAction.AddFamilyActionNote(tagPlayerName, curFamily.GetID(), ShareDefine.Def_ActionType_FamilyEvent, [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_KickOut], tick) #删除玩家 - curFamily.DeleteMember(tagPlayerID) - __DoPlayerLeaveFamilyByID(curFamily, tagPlayerID) - + curFamily.DeleteMember(tagPlayerID) tagPlayer = playerManager.FindPlayerByID(tagMemberID) + + __DoPlayerLeaveFamilyByID(curFamily, tagPlayerID, tagPlayer) #玩家在线, 设置这个玩家的属性 PlayerForceLeaveFamily(tagPlayer, tick) @@ -1508,6 +1771,9 @@ if PlayerFamilyBoss.IsInAllFamilyBoss(): PlayerControl.NotifyCode(curPlayer, "LeagueBOSSExitError1") return + if AuctionHouse.IsFamilyMemberBiddingAuctionItem(curFamily.GetID(), curMember.GetPlayerID()): + PlayerControl.NotifyCode(curPlayer, "Paimai8") + return #判断退出时间间隔 curTime = int(time.time()) lastLeaveFamilyTime = PlayerControl.GetLeaveFamilyTime(curPlayer) @@ -1534,7 +1800,7 @@ curFamily.DeleteMember(curMember.GetPlayerID()) #玩家在线, 设置这个玩家的属性 PlayerForceLeaveFamily(curPlayer, tick) - __DoPlayerLeaveFamilyByID(curFamily, curPlayerID) + __DoPlayerLeaveFamilyByID(curFamily, curPlayerID, curPlayer) DataRecordPack.DR_PlayerLeaveFamily(curPlayer, curFamily.GetID(), curFamily.GetName(), curFamily.GetCount(), familyLV, curPlayer.GetPlayerID(), curPlayer.GetName(), familyLV, updTime) @@ -1552,14 +1818,17 @@ # @param curFamily 离开的家族 # @param leavePlayerID 离开的玩家ID # @return None -def __DoPlayerLeaveFamilyByID(curFamily, leavePlayerID): +def __DoPlayerLeaveFamilyByID(curFamily, leavePlayerID, tagPlayer=None): + PlayerCompensation.SendMailByKey("LeaveFamilyNotice", [leavePlayerID], []) 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 #////////////////////////////////////////////////////////////// @@ -1678,8 +1947,10 @@ addFamilyMoney, curFamily.GetFamilyActiveValue(), addFamilyActiveValue) #通知客户端 - #curFamily.Broadcast_FamilyChange() - curPlayer.Sync_FamilyInfo() + if addFamilyHornor: + curFamily.Broadcast_FamilyChange() + else: + curPlayer.Sync_FamilyInfo() #金钱变更时才通知 if addFamilyMoney != 0: @@ -1702,7 +1973,7 @@ SetMemberFightPower(curMember, fightPower) GameWorld.DebugLog("仙盟成员战力变更 familyID=%s,fightPower=%s" % (familyID, fightPower), playerID) - AddFamilyIDToFightPowerChangeList(familyID) + GetFamilyMgr().AddFamilyIDToFightPowerChangeList(familyID, playerID) return ## A4 07 升级家族#tagCGFamilyLVUp @@ -1811,6 +2082,7 @@ #世界服务器家族重新排序 #GameWorld.GetFamilyManager().SortByLV() DoFamilySort() # 升级直接强排一次 + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID(), syncNow=True) # 仙盟等级变更 return True #--------------------------------------------------------------------- @@ -1859,6 +2131,8 @@ # @remarks 函数详细说明. def OnPlayerChangeMap(curPlayer, tick): #同步给玩家, 最新的家族信息(家族等级刷新) + if GameWorld.IsCrossServer(): + return curPlayer.MapServer_FamilyRefresh() return @@ -1870,6 +2144,7 @@ # @remarks 函数详细说明. def PlayerLoginRefreshFamily(curPlayer, tick): SyncFakeFamilyInfo(curPlayer) + SyncCreatFamilyTimes(curPlayer) familyID = curPlayer.GetFamilyID() curFamily = None @@ -1923,8 +2198,10 @@ if not PlayerControl.GetIsTJG(curPlayer): #上线重置离线时间为0, 非脱机挂才设置 - curMember.SetExattr2(0) + curMember.SetExattr2(0) # 在线0,脱机1,>1离线时间 curPlayer.Sync_FamilyInfo() + else: + curMember.SetExattr2(1) # 脱机1 curPlayer.MapServer_FamilyRefresh() curMember = GetPlayerFamilyMember(curPlayer) @@ -2005,13 +2282,16 @@ # @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()) curMember.SetJob(curPlayer.GetJob()) curMember.SetOperateInfo(curPlayer.GetOperateInfo()) curMember.SetOfficialRank(curPlayer.GetOfficialRank()) + curMember.SetFace(curPlayer.GetFace()) + curMember.SetFacePic(curPlayer.GetFacePic()) + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID(), curPlayer.GetPlayerID()) # 成员基础信息刷新,含加入仙盟刷新 return #--------------------------------------------------------------------- ## 玩家刷新 @@ -2026,9 +2306,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 @@ -2144,8 +2424,7 @@ #重新排序家族 #GameWorld.GetFamilyManager().SortByLV() - if familyID in PyGameData.g_sortFamilyIDList: - PyGameData.g_sortFamilyIDList.remove(familyID) # 直接从排序列表中移除, 不需要重新排序 + GetFamilyMgr().OnDeleteFamilyID(familyID) #家族科技删除, 改为地图直接处理, 暂屏蔽 #PlayerFamilyTech.DelFamilyTechData(familyID) @@ -2174,6 +2453,7 @@ #设置族长权限 ChangeFamilyMemberLv(familyMember, IPY_GameServer.fmlLeader) GameWorldFamilyWar.OnChangeFamilyLeader(curFamily.GetID(), familyMember.GetPlayerID()) + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamily.GetID(), syncNow=True) # 盟主变更 return #--------------------------------------------------------------------- ##更改家族成员等级. @@ -2205,6 +2485,8 @@ # 变为普通成员,删除模型装备信息 elif changeFamilyLV == IPY_GameServer.fmlMember: PlayerFamilyAction.DelFamilyOfficerModelEquip(familyMember.GetFamilyID(), familyMember.GetPlayerID()) + + GetFamilyMgr().SetSyncCrossFamilyUpd(familyMember.GetFamilyID(), familyMember.GetPlayerID(), syncNow=True) # 成员职位变更 return #--------------------------------------------------------------------- @@ -2383,6 +2665,7 @@ #通知家族刷新 curFamily.Broadcast_FamilyChange() + GetFamilyMgr().SetSyncCrossFamilyUpd(curFamilyID, syncNow=True) # 仙盟改名 playerManager = GameWorld.GetPlayerManager() #仙盟联赛 @@ -2563,6 +2846,8 @@ # @return 返回值无意义 # @remarks 家族过天 def FamilyOnDay(tick): + if GameWorld.IsCrossServer(): + return #---设置所有玩家可以再次加入家族--- GameWorld.GetPlayerManager().ClearForbiddenEnterFamily() #---扣除地图上所有家族的维护费--- @@ -2620,6 +2905,17 @@ __SetFamilyActivityDayStateValue(0) return +def FamilyOnDayEx(tick): + if GameWorld.IsCrossServer(): + return + familyManager = GameWorld.GetFamilyManager() + for i in range(0, familyManager.GetCount()): + family = familyManager.GetAt(i) + #仙盟boss + PlayerFamilyBoss.FamilyBossFBOnDayEx(family) + #珍宝阁 + PlayerFamilyZhenbaoge.OnDayEx(family) + return #--------------------------------------------------------------------- ##家族过周 @@ -2627,7 +2923,8 @@ # @return 返回值无意义 # @remarks 家族过周 def FamilyOnWeek(tick): - + if GameWorld.IsCrossServer(): + return #---计算上周家族活跃度--- familyManager = GameWorld.GetFamilyManager() for i in range(0, familyManager.GetCount()): @@ -2654,11 +2951,13 @@ DataRecordPack.DR_FamilyActiveValueByOnWeek(familyID, family.GetName(), familyActiveValue) #清除家族boss副本信息 - PlayerFamilyBoss.FamilyBossFBOnWeek(familyID) + PlayerFamilyBoss.FamilyBossFBOnWeek(family) return def FamilyOnHour(): + if GameWorld.IsCrossServer(): + return familyManager = GameWorld.GetFamilyManager() for i in xrange(familyManager.GetCount()): family = familyManager.GetAt(i) @@ -2728,12 +3027,35 @@ return cmp(GetMemberJoinTime(member1), GetMemberJoinTime(member2)) return ret +def SortCrossFamily(serverIDList, getCnt=0, page=1): + ''' 跨服仙盟排序, 排序规则: 总战力 > 等级 > ID + @param serverIDList: 仙盟所属区服ID范围列表 + @param getCnt: 返回排序靠前x个仙盟,0则全部返回 + @param page: 第几页 + ''' + 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) + if getCnt: + startIndex = (page - 1) * getCnt + return familyList[startIndex:startIndex + getCnt], totalCnt + return familyList, totalCnt + #--------------------------------------------------------------------- ##通知地图服务器, 玩家家族属性刷新 # @param curFamily 家族实例 # @return 返回值无意义 # @remarks IPY_MFamilyRefresh def SendPack_MapServer_PlayerFamilyRefresh(curFamily): + if GameWorld.IsCrossServer(): + return #=============================================================================== # 当家族以下权限变更时要通知地图服务器 IPY_MFamilyRefresh # GetFamilyLV @@ -2772,7 +3094,7 @@ GameWorld.ErrLog("key = %s not in tagFamily.txt" % familyLv) return 0 keyStr = ChConfig.FamilySettingDict[index] - return getattr(curFamilyLvSetting, keyStr) + return getattr(curFamilyLvSetting, "Get%s" % keyStr)() #=============================================================================== @@ -2852,7 +3174,7 @@ GameWorld.Log("GetLeaderOfflineTime->FindMember, None;%s" % leaderID) return 0 offLineTimeNum = curMember.GetExattr2() - if not offLineTimeNum: + if not offLineTimeNum or offLineTimeNum == 1: return 0 offLineTime = GameWorld.ChangeTimeNumToStr(offLineTimeNum) return GameWorld.GetPastHour(offLineTime) @@ -2863,7 +3185,7 @@ for i in range(0, family.GetCount()): member = family.GetAt(i) offLineTimeNum = member.GetExattr2() - if not offLineTimeNum: + if not offLineTimeNum or offLineTimeNum == 1: #有人在线直接返回 return 0 if not offLineTime: @@ -2898,7 +3220,7 @@ elif toMember2.GetExattr1() < member.GetExattr1(): toMember2 = member - offLineHour = GameWorld.GetPastHour(GameWorld.ChangeTimeNumToStr(member.GetExattr2())) if member.GetExattr2() else 0 + offLineHour = GameWorld.GetPastHour(GameWorld.ChangeTimeNumToStr(member.GetExattr2())) if member.GetExattr2() > 1 else 0 #GameWorld.DebugLog('memberID=%s 离线%s小时,历史贡献度%s'%(member.GetPlayerID(), offLineHour, member.GetExattr1())) if offLineHour < 48: if not toMember1: @@ -3266,17 +3588,6 @@ PlayerFamilyAction.ViewFamilyRequestInfo(curPlayer) return - -## 开启家族boss副本 -# @param index 玩家索引 -# @param clientData 封包数据结构体 -# @param tick 时间戳 -# @return None -def OpenFamilyBossFB(index, clientData, tick): - curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) - fbMapID = clientData.MapID - PlayerFamilyBoss.OpenFamilyBossFB(curPlayer, tick) - return #=============================================================================== # //A4 06 变更家族成员加入审核方式#tagCGChangeFamilyAcceptJoinType #struct tagCGChangeFamilyAcceptJoinType @@ -3388,21 +3699,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 @@ -3414,19 +3734,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): ''' 仙盟排序, 排序规则: 联赛评级 > 总战力 > 等级 > 创建时间 @@ -3444,12 +3762,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): @@ -3498,7 +3817,8 @@ requestPlayerName = curPlayer.GetName() playerLV = curPlayer.GetLV() #玩家Id, 等级,职业,战斗力 - actionDataList = [curPlayer.GetID(), playerLV, curPlayer.GetJob(), curPlayer.GetFightPower()] + fightPower = PlayerControl.GetFightPower(curPlayer) + actionDataList = [curPlayer.GetID(), playerLV, curPlayer.GetJob(), fightPower % ChConfig.Def_PerPointValue, fightPower / ChConfig.Def_PerPointValue] allFamilyActionManager = GameWorld.GetFamilyActionManager() familyManager = GameWorld.GetFamilyManager() indexList = range(familyManager.GetCount()) @@ -3553,3 +3873,399 @@ PlayerControl.NotifyCode(curPlayer, "jiazu_pan_500807") return + +##--------------------------------------- 仙盟传功 -------------------------------------------------- +def MapServer_FamilyChuangong(curPlayer, msgList): + msgType, msgData = msgList + + if msgType == "Invite": + tagPlayerID = msgData[0] + __DoChuangong_Invite(curPlayer, tagPlayerID) + return + + if msgType == "Response": + tagPlayerID, isOK = msgData + __DoChuangong_Response(curPlayer, tagPlayerID, isOK) + return + + if msgType == "ThanksGift": + __DoChuangong_ThanksGift(curPlayer, msgData) + return + +def __CheckChuangongPlayer(curPlayer, tagPlayerID): + curFamily = curPlayer.GetFamily() + if not curFamily: + return + tagMember = curFamily.FindMember(tagPlayerID) + if not tagMember: + GameWorld.DebugLog("非盟友无法传功! tagPlayerID=%s" % tagPlayerID, curPlayer.GetPlayerID()) + return + tagPlayer = tagMember.GetPlayer() + if not tagPlayer: + PlayerControl.NotifyCode(curPlayer, "FairyFeastPlayerOffline") + return + return tagPlayer + +def __DoChuangong_Invite(curPlayer, tagPlayerID): + ## 邀请 + playerID = curPlayer.GetPlayerID() + curFamily = curPlayer.GetFamily() + if not curFamily: + return + tagMember = curFamily.FindMember(tagPlayerID) + if not tagMember: + GameWorld.DebugLog("非盟友无法传功! tagPlayerID=%s" % tagPlayerID, curPlayer.GetPlayerID()) + return + tagPlayer = tagMember.GetPlayer() + if not tagPlayer: + clientPack = ChPyNetSendPack.tagGCChuangongStart() + clientPack.Clear() + clientPack.PlayerID = tagMember.GetPlayerID() + clientPack.Name = tagMember.GetName() + clientPack.NameLen = len(clientPack.Name) + clientPack.LV = tagMember.GetLV() + clientPack.Job = tagMember.GetJob() + clientPack.RealmLV = tagMember.GetOfficialRank() + NetPackCommon.SendFakePack(curPlayer, clientPack) + PyGameData.g_chuangongTagPlayerDict[playerID] = tagPlayerID + GameWorld.DebugLog("对方离线,则自己直接开始传功: tagPlayerID=%s, %s" % (tagPlayerID, PyGameData.g_chuangongPlayerDict), playerID) + return + invitePlayerIDList = PyGameData.g_chuangongPlayerDict.get(playerID, []) + if tagPlayerID not in invitePlayerIDList: + invitePlayerIDList.append(tagPlayerID) + PyGameData.g_chuangongPlayerDict[playerID] = invitePlayerIDList + clientPack = ChPyNetSendPack.tagGCChuangongInviteInfo() + clientPack.Clear() + clientPack.PlayerID = curPlayer.GetPlayerID() + clientPack.Name = curPlayer.GetName() + clientPack.NameLen = len(clientPack.Name) + clientPack.LV = curPlayer.GetLV() + clientPack.Job = curPlayer.GetJob() + clientPack.RealmLV = curPlayer.GetOfficialRank() + clientPack.Face = curPlayer.GetFace() + clientPack.FacePic = curPlayer.GetFacePic() + NetPackCommon.SendFakePack(tagPlayer, clientPack) + GameWorld.DebugLog("邀请传功: tagPlayerID=%s, %s" % (tagPlayerID, PyGameData.g_chuangongPlayerDict), playerID) + return + +def __DoChuangong_Response(curPlayer, tagPlayerID, isOK): + ## 相应 + playerID = curPlayer.GetPlayerID() + tagPlayer = __CheckChuangongPlayer(curPlayer, tagPlayerID) + if not tagPlayer: + return + invitePlayerIDList = PyGameData.g_chuangongPlayerDict.get(tagPlayerID, []) + if not isOK: + if playerID in invitePlayerIDList: + invitePlayerIDList.remove(playerID) + PyGameData.g_chuangongPlayerDict[tagPlayerID] = invitePlayerIDList + GameWorld.DebugLog("拒绝传功: tagPlayerID=%s, %s" % (tagPlayerID, PyGameData.g_chuangongPlayerDict), playerID) + return + if not invitePlayerIDList: + PlayerControl.NotifyCode(curPlayer, "TagHadFinishChuangong") + return + if playerID not in invitePlayerIDList: + GameWorld.DebugLog("不在对方邀请列表了,无法传功: tagPlayerID=%s, %s" % (tagPlayerID, invitePlayerIDList), playerID) + return + PyGameData.g_chuangongPlayerDict.pop(tagPlayerID) + + # 通知双方开始传功 + __NotifyChuangongStart(curPlayer, tagPlayer) + __NotifyChuangongStart(tagPlayer, curPlayer) + return + +def __NotifyChuangongStart(curPlayer, tagPlayer): + clientPack = ChPyNetSendPack.tagGCChuangongStart() + clientPack.Clear() + clientPack.PlayerID = tagPlayer.GetPlayerID() + clientPack.Name = tagPlayer.GetName() + clientPack.NameLen = len(clientPack.Name) + clientPack.LV = tagPlayer.GetLV() + clientPack.Job = tagPlayer.GetJob() + clientPack.RealmLV = tagPlayer.GetOfficialRank() + NetPackCommon.SendFakePack(curPlayer, clientPack) + PyGameData.g_chuangongTagPlayerDict[curPlayer.GetPlayerID()] = tagPlayer.GetPlayerID() + return + +def __DoChuangong_ThanksGift(curPlayer, msgData): + itemID = msgData[0] + playerID = curPlayer.GetPlayerID() + tagPlayerID = PyGameData.g_chuangongTagPlayerDict.pop(playerID, 0) + GameWorld.DebugLog("__DoChuangong_ThanksGift tagPlayerID=%s" % tagPlayerID, playerID) + if not tagPlayerID: + return + curFamily = curPlayer.GetFamily() + if not curFamily: + return + tagMember = curFamily.FindMember(tagPlayerID) + if not tagMember: + return + assistPlayerDict = {tagPlayerID:{"PlayerName":tagMember.GetName(), "Job":tagMember.GetJob(), + "LV":tagMember.GetLV(), "RealmLV":tagMember.GetOfficialRank(), + "Face":tagMember.GetFace(), "FacePic":tagMember.GetFacePic()}} + GameWorld.DebugLog(" assistPlayerDict %s" % assistPlayerDict, playerID) + PlayerAssist.AddNewAssistThanksEx(curPlayer, itemID, assistPlayerDict) + return + +##-------------------------------------------------------------------------------------------------- + +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() + name = curFamily.GetName() + id2 = curFamily.GetLeaderID() + name2 = curFamily.GetLeaderName() + fightPower = GetFamilyTotalFightPower(curFamily) + value1 = fightPower / ChConfig.Def_PerPointValue + value2 = fightPower % ChConfig.Def_PerPointValue + value3 = GetFamilyEmblemID(curFamily) + value4 = curFamily.GetLV() + value5 = curFamily.GetServerID() + 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 + +def ClientServerMsg_QueryCrossFamily(serverGroupID, msgData): + ## 子服查询跨服仙盟 + playerID = msgData["playerID"] + tagFamilyID = msgData.get("tagFamilyID", 0) + if tagFamilyID: + clientPack = __GetTagFamilyInfoPack(tagFamilyID) + if clientPack: + NetPackCommon.SendFakePackByCross({playerID:serverGroupID}, clientPack) + else: + PlayerControl.NotifyCodeCross(serverGroupID, playerID, "TagFamilyNotExist") + return + + # 可扩展查看跨服仙盟列表信息... + + return -- Gitblit v1.8.0