#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package Player.CrossPlayer # # @todo:¿ç·þÍæ¼Ò # @author hxp # @date 2026-02-04 # @version 1.0 # # ÏêϸÃèÊö: ¿ç·þÍæ¼Ò£¬¿ÉÊÓΪÒÔǰGameServerµÄPlayer # #------------------------------------------------------------------------------- #"""Version = 2026-02-04 19:00""" #------------------------------------------------------------------------------- import DBDataMgr import GameWorld import PyGameData import NetPackCommon import PlayerControl import PlayerOfflineSupport import ItemControler import ShareDefine import IPY_GameObj import CrossMsg import ChConfig import CommFunc class CrossPlayerObj(): ## ¿ç·þÔÚÏßÍæ¼ÒʵÀý£¬²»Èë¿â£¬ÓÉÓÎÏ··þÍæ¼ÒµÇ¼ͬ²½£¬µ±×öÒÔǰGameServerµÄPlayer´¦Àí£¬¿ç·þ¼°ÓÎÏ··þ±¾·þͨÓ㬷½±ãͳһÂß¼­ def __init__(self, playerID): self.__curPlayer = None # ½öÓÎÏ··þÔÚÏßʱÓÐÖµ self.__playerID = playerID self.__playerName = "" self.__serverID = 0 self.__mainServerID = 0 self.__familyID = 0 self.__realmLV = 0 return def SetPlayer(self, curPlayer): self.__curPlayer = curPlayer if curPlayer: self.__serverID = GameWorld.GetPlayerServerID(curPlayer) self.__mainServerID = GameWorld.GetGameWorld().GetServerID() self.__familyID = curPlayer.GetFamilyID() return def UpdByViewCache(self, curCache, fromServerID): ## ÊÕµ½Í¬²½ÐÅϢʱͬ²½¸üРself.SetPlayerName(curCache.GetPlayerName()) self.SetServerID(curCache.GetServerID()) self.SetMainServerID(fromServerID) self.SetRealmLV(curCache.GetRealmLV()) self.SetFamilyID(curCache.GetFamilyID()) return def GetPlayer(self): return self.__curPlayer def GetPlayerID(self): return self.__playerID def GetServerID(self): return self.__serverID def SetServerID(self, serverID): self.__serverID = serverID def GetMainServerID(self): return self.__mainServerID def SetMainServerID(self, mainServerID): self.__mainServerID = mainServerID def GetFamilyID(self): return self.__familyID # ½ö×ÔÉíÓÎÏ··þ¼°¹«»áËùÔÚ¿ç·þÈ¡µÃµ½Öµ£¬ÆäËû·þÎñÆ÷ÔÝʱÎÞ·¨È¡µ½ def SetFamilyID(self, familyID): self.__familyID = familyID # ÓÎÏ··þ±ä¸ü±ä¸üÐèҪͬ²½¿ç·þÒÔÏÂÖµ def GetPlayerName(self): return self.__playerName if self.__playerName else (self.__curPlayer.GetPlayerName() if self.__curPlayer else "") def SetPlayerName(self, playerName): self.__playerName = playerName def GetRealmLV(self): return self.__realmLV if self.__realmLV else (self.__curPlayer.GetOfficialRank() if self.__curPlayer else 0) def SetRealmLV(self, realmLV): self.__realmLV = realmLV class CrossPlayerMgr(): ## ¿ç·þÍæ¼Ò¹ÜÀí def __init__(self): self.__crossPlayerDict = {} # ¿ç·þÔÚÏßÍæ¼ÒÐÅÏ¢ {playerID:CrossPlayerObj, ...} return def RegistPlayer(self, playerID): cPlayer = None if playerID in self.__crossPlayerDict: cPlayer = self.__crossPlayerDict[playerID] else: cPlayer = CrossPlayerObj(playerID) self.__crossPlayerDict[playerID] = cPlayer cPlayer.SetPlayer(GameWorld.GetPlayerManager().FindPlayerByID(playerID)) return cPlayer def FindCrossPlayer(self, playerID): cPlayer = None if playerID in self.__crossPlayerDict: cPlayer = self.__crossPlayerDict[playerID] elif False: # ²»ÔÚÏß²»´´½¨£¬²»´æÔÚÊÓΪÀëÏß cPlayer = CrossPlayerObj(playerID) return cPlayer def DeletePlayer(self, playerID): self.__crossPlayerDict.pop(playerID, None) return def GetPlayerIDList(self): return self.__crossPlayerDict.keys() def GetCrossPlayerMgr(): mgr = PyGameData.g_crossPlayerMgr if mgr == None: mgr = CrossPlayerMgr() PyGameData.g_crossPlayerMgr = mgr return mgr def __checkCrossPlayer(crossPlayer): ## ¼ì²é crossPlayer ÊÇ·ñºÏ·¨£¬·ÀÖ¹Îó´«Èë IPY_Player µ¼Ö±¨´í if not crossPlayer: return if isinstance(crossPlayer, IPY_GameObj.IPY_Player): GameWorld.ErrLog("__checkCrossPlayer isinstance IPY_Player") return return True def SendFakePackByFamily(familyID, clientPack, excludeIDList=None, parseFunc=None, *args): if not clientPack: return family = DBDataMgr.GetFamilyMgr().FindFamily(familyID) if not family: return isCrossServer = GameWorld.IsCrossServer() crossPlayerList = [] crossPlayerMgr = GetCrossPlayerMgr() for index in range(family.GetCount()): member = family.GetAt(index) playerID = member.GetPlayerID() if excludeIDList and playerID in excludeIDList: continue crossPlayer = crossPlayerMgr.FindCrossPlayer(playerID) if not crossPlayer: continue if parseFunc and not parseFunc(member, *args): continue curPlayer = crossPlayer.GetPlayer() if curPlayer: # ÓÐÍæ¼Ò£¬Ò»°ãÖ»ÓÐÓÎÏ··þÓУ¬¿ÉÊÓΪÓÎÏ··þÔÚÏߣ¬Ö±½Ó·¢ËÍ curPlayer.SendFakePack(clientPack.GetBuffer(), clientPack.GetLength()) continue if isCrossServer: crossPlayerList.append(crossPlayer) if crossPlayerList: SendFakePackToPlayerList(crossPlayerList, clientPack) return def SendFackPackToServerList(clientPack, serverIDList): ## ¸ø·þÎñÆ÷·¶Î§µÄÔÚÏßÍæ¼Ò·¢ËÍ·â°ü toCrossPlayerList = [] crossPlayerMgr = GetCrossPlayerMgr() playerIDList = crossPlayerMgr.GetPlayerIDList() for playerID in playerIDList: crossPlayer = crossPlayerMgr.FindCrossPlayer(playerID) mainServerID = crossPlayer.GetMainServerID() if not GameWorld.CheckServerIDInList(mainServerID, serverIDList): continue curPlayer = crossPlayer.GetPlayer() if curPlayer: # ÓÐÍæ¼Ò£¬Ò»°ãÖ»ÓÐÓÎÏ··þÓУ¬¿ÉÊÓΪÓÎÏ··þÔÚÏߣ¬Ö±½Ó·¢ËÍ curPlayer.SendFakePack(clientPack.GetBuffer(), clientPack.GetLength()) continue toCrossPlayerList.append(crossPlayer) SendFakePackToPlayerList(toCrossPlayerList, clientPack) return def SendFakePackToPlayerList(crossPlayerList, clientPack): '''¸øcrossPlayerÍæ¼Ò·¢ËÍ·â°ü£¬ÊÊÓÃÓÚ½ÓÊܵÄÍæ¼Ò·â°üÊý¾ÝÒ»Öµģ¬¿ç·þ¡¢ÓÎÏ··þͨÓà ''' if not clientPack: return if not crossPlayerList: return curServerID = GameWorld.GetGameWorld().GetServerID() crossServerPlayerDict = {} for crossPlayer in crossPlayerList: curPlayer = crossPlayer.GetPlayer() if curPlayer: # ÓÐÍæ¼Ò£¬Ò»°ãÖ»ÓÐÓÎÏ··þÓУ¬¿ÉÊÓΪÓÎÏ··þÔÚÏߣ¬Ö±½Ó·¢ËÍ NetPackCommon.SendFakePack(curPlayer, clientPack) continue playerID = crossPlayer.GetPlayerID() mainServerID = crossPlayer.GetMainServerID() if mainServerID == curServerID: #±¾ÓÎÏ··þÓÖûÓÐÍæ¼ÒµÄ²»´¦Àí continue if mainServerID not in crossServerPlayerDict: crossServerPlayerDict[mainServerID] = [] playerIDList = crossServerPlayerDict[mainServerID] if playerID not in playerIDList: playerIDList.append(playerID) if not crossServerPlayerDict: return packBuff, packLen, packHead = clientPack.GetBuffer(), clientPack.GetLength(), CommFunc.GetPackHead(clientPack) for mainServerID, playerIDList in crossServerPlayerDict.items(): dataMsg = {"playerIDList":playerIDList, "packBuff":packBuff, "packLen":packLen, "packHead":packHead} playerID = playerIDList[0] CrossMsg.SendToClientServer(ShareDefine.C2S_SendFakePack, dataMsg, [mainServerID], playerID) return def SendFakePack(crossPlayer, clientPack): if not clientPack: return if not __checkCrossPlayer(crossPlayer): return curPlayer = crossPlayer.GetPlayer() if curPlayer: # ÓÐÍæ¼Ò£¬Ò»°ãÖ»ÓÐÓÎÏ··þÓУ¬¿ÉÊÓΪÓÎÏ··þÔÚÏߣ¬Ö±½Ó·¢ËÍ NetPackCommon.SendFakePack(curPlayer, clientPack) return mainServerID = crossPlayer.GetMainServerID() if mainServerID == GameWorld.GetGameWorld().GetServerID(): #±¾ÓÎÏ··þÓÖûÓÐÍæ¼ÒµÄ²»´¦Àí return playerID = crossPlayer.GetPlayerID() packBuff, packLen = clientPack.GetBuffer(), clientPack.GetLength() dataMsg = {"playerIDList":[playerID], "packBuff":packBuff, "packLen":packLen, "packHead":CommFunc.GetPackHead(clientPack)} CrossMsg.SendToClientServer(ShareDefine.C2S_SendFakePack, dataMsg, [mainServerID], playerID) return def SendFakePackByID(playerID, clientPack, fromServerID=0): if not clientPack: return packBuff, packLen = clientPack.GetBuffer(), clientPack.GetLength() dataMsg = {"playerIDList":[playerID], "packBuff":packBuff, "packLen":packLen, "packHead":CommFunc.GetPackHead(clientPack)} CrossMsg.SendToClientServer(ShareDefine.C2S_SendFakePack, dataMsg, [fromServerID], playerID) CrossMsg.SendToServer(ShareDefine.C2S_SendFakePack, dataMsg, [fromServerID], ShareDefine.dirType_All, playerID) return def C2S_SendFakePack(dataMsg): ## ÓÎÏ··þÊÕµ½¿ç·þÖ±½Ó·¢Ë͸øÍæ¼ÒµÄ·â°ü playerIDList = dataMsg["playerIDList"] packBuff = dataMsg["packBuff"] packLen = dataMsg["packLen"] playerManager = GameWorld.GetPlayerManager() for playerID in playerIDList: curPlayer = playerManager.FindPlayerByID(playerID) if curPlayer == None: continue curPlayer.SendFakePack(packBuff, packLen) return def NotifyCode(crossPlayer, msgMark, msgParamList=[]): if not __checkCrossPlayer(crossPlayer): return curPlayer = crossPlayer.GetPlayer() if curPlayer: PlayerControl.NotifyCode(curPlayer, msgMark, msgParamList) return mainServerID = crossPlayer.GetMainServerID() if mainServerID == GameWorld.GetGameWorld().GetServerID(): #±¾ÓÎÏ··þÓÖûÓÐÍæ¼ÒµÄ²»´¦Àí return playerID = crossPlayer.GetPlayerID() dataMsg = {"playerIDList":[playerID], "msgMark":msgMark, "msgParamList":msgParamList} CrossMsg.SendToClientServer(ShareDefine.C2S_NotifyCode, dataMsg, [mainServerID], playerID) return def SendToFamilyPlayer(familyID, msgType, dataMsg, excludeIDList=[], onlyIDList=[], havePlayerCall=None): ## ·¢Ë͸øÄ³¸ö¹«»áËùÓÐÔÚÏßÓÎÏ··þ³ÉÔ±£¬¿ç·þÓÎÏ··þͨÓà # @param havePlayerCall: ÓÐcurPlayerʱ»Øµ÷º¯Êý£¬Ò»°ãÊÇÓÎÏ··þʱÓУ¬Ö±½Ó±¾·þÖ´ÐÐ func(curPlayer, familyID, dataMsg) family = DBDataMgr.GetFamilyMgr().FindFamily(familyID) if not family: return curServerID = GameWorld.GetGameWorld().GetServerID() crossServerPlayerDict = {} crossPlayerMgr = GetCrossPlayerMgr() for index in range(family.GetCount()): member = family.GetAt(index) playerID = member.GetPlayerID() if onlyIDList and playerID not in onlyIDList: continue if excludeIDList and playerID in excludeIDList: continue crossPlayer = crossPlayerMgr.FindCrossPlayer(playerID) if not crossPlayer: # ²»ÔÚÏß continue curPlayer = crossPlayer.GetPlayer() if curPlayer: # ÓÐÍæ¼Ò£¬Ò»°ãÖ»ÓÐÓÎÏ··þÓУ¬¿ÉÊÓΪÓÎÏ··þÔÚÏߣ¬Ö±½Ó·¢ËÍ if havePlayerCall: havePlayerCall(curPlayer, familyID, dataMsg) continue mainServerID = crossPlayer.GetMainServerID() if mainServerID == curServerID: #±¾ÓÎÏ··þÓÖûÓÐÍæ¼ÒµÄ²»´¦Àí continue if mainServerID not in crossServerPlayerDict: crossServerPlayerDict[mainServerID] = [] playerIDList = crossServerPlayerDict[mainServerID] if playerID not in playerIDList: playerIDList.append(playerID) for mainServerID, playerIDList in crossServerPlayerDict.items(): sendDataMsg = {"playerIDList":playerIDList, "familyID":familyID} sendDataMsg.update(dataMsg) CrossMsg.SendToClientServer(msgType, sendDataMsg, [mainServerID]) return def FamilyNotify(familyID, msgMark, msgParamList=[], excludeIDList=[]): family = DBDataMgr.GetFamilyMgr().FindFamily(familyID) if not family: return def havePlayerCall(curPlayer, familyID, dataMsg): PlayerControl.NotifyCode(curPlayer, dataMsg["msgMark"], dataMsg["msgParamList"]) return dataMsg = {"msgMark":msgMark, "msgParamList":msgParamList} SendToFamilyPlayer(familyID, ShareDefine.C2S_NotifyCode, dataMsg, excludeIDList, havePlayerCall=havePlayerCall) return def C2S_NotifyCode(dataMsg): msgMark = dataMsg["msgMark"] msgParamList = dataMsg["msgParamList"] playerIDList = dataMsg["playerIDList"] playerManager = GameWorld.GetPlayerManager() for playerID in playerIDList: curPlayer = playerManager.FindPlayerByID(playerID) if curPlayer == None: continue PlayerControl.NotifyCode(curPlayer, msgMark, msgParamList) return def OnPlayerLogin(curPlayer): PlayerOfflineSupport.DoOfflineUnprocessed(curPlayer, "CostPlayerResources", __doCostPlayerResources) PlayerOfflineSupport.DoOfflineUnprocessed(curPlayer, "GivePlayerResources", __doGivePlayerResources) PlayerOfflineSupport.DoOfflineUnprocessed(curPlayer, "SetPlayerNomalDict", __doSetPlayerNomalDict) return def CostPlayerResources(crossPlayer, eventName, costMoneyDict=None, costItemDict=None, drDict=None): '''¿Û³ý¿ç·þÍæ¼Ò×ÊÔ´ @param eventName: ÏûºÄʼþÖµ @param costMoneyDict: ¿Û³ý»õ±Ò {»õ±ÒÀàÐÍ:ÏûºÄÖµ, ...} @param costItemDict: ¿Û³ýÎïÆ· {ÎïÆ·ID:¸öÊý, ...}£¬Ôݲ»Ö§³Ö£¬ÓÐÐèÒªÔÙÀ©Õ¹ @param drDict: ¼Ç¼Á÷ÏòÐÅÏ¢ ''' if not __checkCrossPlayer(crossPlayer): return dataMsg = {"eventName":eventName} if costMoneyDict: dataMsg["costMoneyDict"] = costMoneyDict if costItemDict: dataMsg["costItemDict"] = costItemDict if drDict: dataMsg["drDict"] = drDict playerID = crossPlayer.GetPlayerID() curPlayer = crossPlayer.GetPlayer() if curPlayer: __doCostPlayerResources(curPlayer, None, "CostPlayerResources", dataMsg) return mainServerID = crossPlayer.GetMainServerID() if mainServerID == GameWorld.GetGameWorld().GetServerID(): #±¾ÓÎÏ··þÓÖûÓÐÍæ¼ÒµÄ²»´¦Àí return CrossMsg.SendToClientServer(ShareDefine.C2S_CostPlayerResources, dataMsg, [mainServerID], playerID) return def C2S_CostPlayerResources(dataMsg, playerID): curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if not curPlayer: PlayerOfflineSupport.AddOfflineUnprocessed(playerID, "CostPlayerResources", dataMsg, outtimeDays=0) return __doCostPlayerResources(curPlayer, None, "CostPlayerResources", dataMsg) return def __doCostPlayerResources(curPlayer, recData, eventName, eventData): # recData ´Ë¹¦ÄÜÖÐΪNone£¬²»ÒªÓà playerID = curPlayer.GetPlayerID() eventName = eventData["eventName"] costMoneyDict = eventData.get("costMoneyDict") costItemDict = eventData.get("costItemDict") drDict = eventData.get("drDict", {}) if costMoneyDict: for moneyType, costMoney in costMoneyDict.items(): if not PlayerControl.PayMoney(curPlayer, moneyType, costMoney, eventName, drDict): GameWorld.ErrLog("__doCostPlayerResources error! eventName=%s,moneyType=%s,costMoney=%s" % (eventName, moneyType, costMoney), playerID) if costItemDict: pass # ´ýÀ©Õ¹ return def GivePlayerResources(crossPlayer, awardItemList=None, moneyDict=None, eventName="", drDict=None, isNotifyAward=True): '''¸øÍæ¼Ò×ÊÔ´ @param awardItemList: ¸øÎïÆ·Áбí [[itemID,itemCnt], ...] @param moneyDict: ¸ø»õ±Ò {»õ±ÒÀàÐÍ:ÏûºÄÖµ, ...} ''' if not __checkCrossPlayer(crossPlayer): return dataMsg = {"eventName":eventName} if awardItemList: dataMsg["awardItemList"] = awardItemList if moneyDict: dataMsg["moneyDict"] = moneyDict if drDict: dataMsg["drDict"] = drDict if not isNotifyAward: dataMsg["isNotifyAward"] = isNotifyAward playerID = crossPlayer.GetPlayerID() curPlayer = crossPlayer.GetPlayer() if curPlayer: __doGivePlayerResources(curPlayer, None, "GivePlayerResources", dataMsg) return mainServerID = crossPlayer.GetMainServerID() if mainServerID == GameWorld.GetGameWorld().GetServerID(): #±¾ÓÎÏ··þÓÖûÓÐÍæ¼ÒµÄ²»´¦Àí return CrossMsg.SendToClientServer(ShareDefine.C2S_GivePlayerResources, dataMsg, [mainServerID], playerID) return def C2S_GivePlayerResources(dataMsg, playerID): curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if not curPlayer: PlayerOfflineSupport.AddOfflineUnprocessed(playerID, "GivePlayerResources", dataMsg, outtimeDays=0) return __doGivePlayerResources(curPlayer, None, "GivePlayerResources", dataMsg) return def __doGivePlayerResources(curPlayer, recData, eventName, eventData): # recData ´Ë¹¦ÄÜÖÐΪNone£¬²»ÒªÓà #playerID = curPlayer.GetPlayerID() GameWorld.DebugLog("__doGivePlayerResources %s, %s" % (eventName, eventData)) eventName = eventData["eventName"] awardItemList = eventData.get("awardItemList", []) moneyDict = eventData.get("moneyDict", {}) drDict = eventData.get("drDict", {}) isNotifyAward = eventData.get("isNotifyAward", True) GameWorld.DebugLog("awardItemList=%s" % awardItemList) if awardItemList: itemDRDict = {} itemDRDict.update(drDict) ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=[eventName, False, itemDRDict], isNotifyAward=False) if moneyDict: moneyRDict = {} moneyRDict.update(drDict) for moneyType, moneyValue in moneyDict.items(): PlayerControl.GiveMoney(curPlayer, moneyType, moneyValue, eventName, moneyRDict) if isNotifyAward: ItemControler.NotifyGiveAwardInfo(curPlayer, awardItemList, eventName, moneyInfo=moneyDict) return def SetPlayerNomalDict(crossPlayer, setDict, isDayReset=False): '''¿Û³ý¿ç·þÍæ¼Ò×ÊÔ´ @param setDict: ÒªÉèÖõÄNomalDictSetProperty¶ÔÓ¦key:value {key:value, ...} @param isDayReset: ×ÖµäÊÇ·ñÿÈÕÖØÖÃµÄ ''' if not __checkCrossPlayer(crossPlayer): return playerID = crossPlayer.GetPlayerID() curPlayer = crossPlayer.GetPlayer() dataMsg = {"setDict":setDict} if curPlayer: # ÓÎÏ··þcurPlayerÔÚÏßµÄÖ±½Óµ±×öÓÀ¾ÃµÄ´¦Àí£¬Ö±½ÓÉèÖà __doSetPlayerNomalDict(curPlayer, None, "SetPlayerNomalDict", dataMsg) return mainServerID = crossPlayer.GetMainServerID() if mainServerID == GameWorld.GetGameWorld().GetServerID(): GameWorld.ErrLog("CrossPlayerÉèÖÃ×Öµäʱ±¾·þÍæ¼Ò²»´æÔÚ! setDict=%s" % setDict, playerID) return resetType = "" if isDayReset: resetType = "Day" if resetType != "": centerEventValue = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_CrossCenterEvent) dataMsg.update({"resetType":resetType, "centerEventValue":centerEventValue}) CrossMsg.SendToClientServer(ShareDefine.C2S_SetPlayerNomalDict, dataMsg, [mainServerID], playerID) return def C2S_SetPlayerNomalDict(dataMsg, playerID): curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if not curPlayer: PlayerOfflineSupport.AddOfflineUnprocessed(playerID, "SetPlayerNomalDict", dataMsg, outtimeDays=0) return __doSetPlayerNomalDict(curPlayer, None, "SetPlayerNomalDict", dataMsg) return def __doSetPlayerNomalDict(curPlayer, recData, eventName, eventData): # recData ´Ë¹¦ÄÜÖÐΪNone£¬²»ÒªÓà playerID = curPlayer.GetPlayerID() setDict = eventData["setDict"] resetType = eventData.get("resetType", "") # ·ÇÓÀ¾ÃÉèÖõģ¬Ñé֤ʱЧÐÔ if resetType != "": centerEventValue = eventData.get("centerEventValue", 0) playerEventValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OnCrossEvent) centerEventTime = GameWorld.ChangeStrToDatetime("%s" % centerEventValue, ChConfig.TYPE_Time_Format_YmdH) playerEventTime = GameWorld.ChangeStrToDatetime("%s" % playerEventValue, ChConfig.TYPE_Time_Format_YmdH) center_Day = centerEventTime.day center_Month = centerEventTime.month center_Year = centerEventTime.year player_Day = playerEventTime.day player_Month = playerEventTime.month player_Year = playerEventTime.year # ÿÈÕÖØÖõģ¬ÑéÖ¤ÊÇ·ñͬһÌì if resetType == "Day": if (center_Day != player_Day or center_Month != player_Month or center_Year != player_Year): GameWorld.Log("·ÇͬһÌìÁ˲»ÔÙÉèÖÃÍæ¼Ò¸ÃkeyÖµ! setDict=%s" % setDict, playerID) return for key, value in setDict.items(): PlayerControl.NomalDictSetProperty(curPlayer, key, value) return