#!/usr/bin/python # -*- coding: GBK -*- # # ##@package PlayerViewCache.py # # @todo:Íæ¼ÒÊý¾Ý»º´æ # # @author NathanShaw # @date 2010-01-01 21:30 # @version 1.3 # @note: # # @change: "2014-11-05 11:20" xmnathan Íæ¼ÒÊý¾Ý»º´æ¹ÜÀí # @change: "2014-12-09 17:30" xmnathan Íæ¼ÒÊý¾Ý»º´æ # @change: "2016-05-18 16:00" hxp Õ½ÃËÓйÙÔ±³ÉÔ±»º´æ²»Çå³ý #--------------------------------------------------------------------- #"""Version = 2016-05-18 16:00""" #--------------------------------------------------------------------- import GameWorld import GameWorship import GameXiangong import PlayerControl import NetPackCommon import GameWorldArena import ChPyNetSendPack import PlayerFBHelpBattle import GameWorldSkyTower import CrossChampionship import CrossBattlefield import CrossRealmPlayer import PyGameDataStruct import IpyGameDataPY import PyDataManager import CrossRealmPK import ShareDefine import ChPlayer import ChConfig import json import time import random def DoOnDayEx(): DelOutofTimeViewCacheData() return def IsSaveDBViewCache(viewCache): ## »º´æÊý¾ÝÊÇ·ñÈë¿â if not viewCache: return False playerID = viewCache.PlayerID if PlayerFBHelpBattle.IsInHelpBattleCheckInList(playerID): return True if GameWorldArena.IsArenaBattlePlayer(playerID): return True if CrossBattlefield.IsBattlefieldCallPlayer(playerID): return True if CrossChampionship.IsChampionshipPlayer(playerID): return True if GameWorship.IsWorshipPlayer(playerID): return True if PyDataManager.GetDBPyFuncTeamManager().IsTeamPlayer(playerID): return True if GameXiangong.IsXiangongPlayer(playerID): return True if GameWorldSkyTower.IsSkyTowerPassPlayer(playerID): return True #¿ç·þ°ñµ¥ÉϵÄĬÈϱ£Áô if GameWorld.IsCrossServer(): billboardMgr = PyDataManager.GetCrossBillboardManager() for billboardType in ShareDefine.CrossBillboardTypeList: groupList = billboardMgr.GetBillboardGroupList(billboardType) for billboardType, groupValue1, groupValue2 in groupList: billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) if billboardObj.FindByID(playerID): return True if CrossRealmPK.IsCrossRealmPKPlayer(playerID, checkPreSeason=True): return True else: NeedCheckBillBoardType = IpyGameDataPY.GetFuncEvalCfg("PlayerViewCache", 2) #УÑéÍæ¼ÒÊÇ·ñÉÏÅÅÐаñ billboardMgr = GameWorld.GetBillboard() for BillBoardType in NeedCheckBillBoardType: curBillboard = billboardMgr.FindBillboard(BillBoardType) if not curBillboard: continue if curBillboard.FindByID(playerID): return True # ÒÔÉÏÊÇÏà¹Ø¹¦ÄÜÐèÒªÓõ½µÄÊý¾Ý£¬±Ø¶¨²»ÄÜɾ³ýµÄ # ÒÔÏÂÊDZ£Áô½üÆÚ»îÔ¾Íæ¼Ò£¬µÈ¼¶ÏÞÖÆ playerLV = viewCache.LV offTime = viewCache.OffTime if not playerLV and not offTime: # ¿ç·þ·þÎñÆ÷֮ǰijЩÇé¿öûÓд洢LV¼°OffTime£¬·ÀÖ¹Îóɾ£¬×ö¾ÉÊý¾Ý¼æÈÝÓà return True SaveDBLimitLV = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 1) if playerLV >= SaveDBLimitLV: maxDays = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 3) if not maxDays: maxDays = 7 # ĬÈÏ7Ìì MaxTime = maxDays * 3600 * 24 curTime = int(time.time()) passTime = curTime - viewCache.OffTime if passTime < MaxTime: return True return False def DelOutofTimeViewCacheData(): ## ɾ³ý¹ýÆÚµÄ²é¿´»º´æÊý¾Ý pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager() playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict for playerID, viewCache in playerViewCachePyDict.items(): if IsSaveDBViewCache(viewCache): continue playerViewCachePyDict.pop(playerID) return def DeleteViewCache(playerID): ## ɾ³ýÍæ¼Ò»º´æ pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager() playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict playerViewCachePyDict.pop(playerID, None) GameWorld.DebugLog("ɾ³ý²é¿´»º´æ!", playerID) return def FindViewCache(playerID, isAddNew=False, newPropData={}): ## ²éÕÒÍæ¼Ò»º´æ # @param newPropData: ÐÂÊý¾Ý³õʼPropData {}, key: LV,RealmLV,Job,VIPLV,Name,FamilyID,FamilyName,FightPower curCache = None pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager() playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict if playerID in playerViewCachePyDict: curCache = playerViewCachePyDict[playerID] elif isAddNew or playerID < 10000: # ÄÚÍø²âÊÔ¼ÙÍæ¼Ò if playerID < 10000 and not newPropData: openJobList = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1) fakeName = "ÉñÃØµÀÓÑ".decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding()) fakeName = "%s%s" % (fakeName, playerID) serverID = playerID % 200 + 1 # 1 ~ 200 ·þ serverGroupID = serverID if serverID < 50: serverGroupID = serverGroupID / 10 + 1 # ǰ50·þÿ10·þ1Ö÷·þ isOnline = True if playerID % 2 == 0 else False olMgr = ChPlayer.GetOnlinePlayerMgr() olMgr.SetOnlineState(playerID, isOnline, serverGroupID) accID = "fake%s@test@s%s" % (playerID, serverID) newPropData = { "AccID":accID, "PlayerID":playerID, "Name":fakeName, "Job":random.choice(openJobList) if openJobList else 1, "LV":random.randint(100, 200), "RealmLV":random.randint(5, 15), "FightPower":random.randint(1000000, 100000000), "ServerGroupID":serverGroupID, } curCache = PyGameDataStruct.tagPlayerViewCachePy() curCache.PlayerID = playerID curCache.OffTime = int(time.time()) if newPropData: curCache.PropData = json.dumps(newPropData, ensure_ascii=False).replace(" ", "") curCache.PropDataSize = len(curCache.PropData) playerViewCachePyDict[playerID] = curCache return curCache def GetCachePropDataDict(curCache): ## »ñÈ¡»º´æ»ù´¡ÊôÐÔ×ÖµäÐÅÏ¢ if not curCache: return {} if not hasattr(curCache, "PropDataDict"): curCache.PropDataDict = {} if not curCache.PropDataDict and curCache.PropData: curCache.PropDataDict = eval(curCache.PropData) return curCache.PropDataDict def GetShotCacheDict(playerID, *exAttrs): ## »ñÈ¡Íæ¼Ò¼ò¶ÌµÄ»º´æÐÅÏ¢×Öµä viewCache = FindViewCache(playerID) cacheDict = GetCachePropDataDict(viewCache) if not cacheDict: return {} shotCacheDict = { "Name":cacheDict["Name"], "Job":cacheDict["Job"], "LV":cacheDict["LV"], "RealmLV":cacheDict["RealmLV"], } for attrName in exAttrs: if attrName == "PlayerID": shotCacheDict["PlayerID"] = playerID elif attrName == "ServerID": shotCacheDict["ServerID"] = GameWorld.GetAccIDServerID(cacheDict["AccID"]) elif attrName == "OfflineValue": olMgr = ChPlayer.GetOnlinePlayerMgr() shotCacheDict["OfflineValue"] = olMgr.GetOfflineValue(playerID, viewCache) # ¸½´øÍâ¹ÛÄ£ÐÍչʾÏà¹Ø elif attrName == "Model": shotCacheDict.update({ "TitleID":cacheDict.get("TitleID", 0), "EquipShowSwitch":cacheDict.get("EquipShowSwitch", 0), "EquipShowID":cacheDict.get("EquipShowID", []), }) elif attrName in cacheDict: shotCacheDict[attrName] = cacheDict[attrName] return shotCacheDict def GetSyncCrossCacheBase(curPlayer): ## »ñȡͬ²½¿ç·þ»ù´¡²é¿´»º´æ£¬Ö÷ÒªÓÃÓÚ¸ö±ð¹¦ÄÜÐèÒªÌáǰÏÈͬ²½Íæ¼Ò»ù´¡»º´æµ½¿ç·þ£¬ÒòΪ¿ç·þ²»Ò»¶¨ÓÐÍæ¼Ò»º´æ£¬ÐèÒªÌáǰͬ²½ playerID = curPlayer.GetPlayerID() cacheDict = GetCachePropDataDict(FindViewCache(playerID)) cacheBase = { "AccID":curPlayer.GetAccID(), "LV":curPlayer.GetLV(), "RealmLV":curPlayer.GetOfficialRank(), "Job":curPlayer.GetJob(), "VIPLV":curPlayer.GetVIPLv(), "Name":CrossRealmPlayer.GetCrossPlayerName(curPlayer), "FamilyID":curPlayer.GetFamilyID(), "FamilyName":cacheDict.get("FamilyName", ""), "TitleID":cacheDict.get("TitleID", 0), "FightPower":PlayerControl.GetFightPower(curPlayer), "EquipShowSwitch":cacheDict.get("EquipShowSwitch", 0), "EquipShowID":cacheDict.get("EquipShowID", []), "ServerGroupID":PlayerControl.GetPlayerServerGroupID(curPlayer), } return cacheBase def UpdCrossCacheBase(playerID, cacheBase, isLogout=False): ## ¸üÐÂͬ²½¿ç·þ»ù´¡²é¿´»º´æ #¸üпç·þÔÚÏß״̬£¬Ö»ÒªÓÐͬ²½¼´ÊÓΪÔÚÏߣ¬³ýÁËÖ¸¶¨ÊÇLogoutµÄ olMgr = ChPlayer.GetOnlinePlayerMgr() olMgr.SetOnlineState(playerID, not isLogout, cacheBase.get("ServerGroupID", 0)) curCache = FindViewCache(playerID, True) if not curCache: return {} curCache.LV = cacheBase.get("LV", 0) curCache.OffTime = int(time.time()) # ÿ´Î¶¼¸üУ¬×îºóÒ»´Î¿ÉÊÓΪ¿ç·þÍæ¼ÒµÄ×î½üÒ»´ÎÀëÏßʱ¼ä cacheDict = GetCachePropDataDict(curCache) if not cacheBase: return cacheDict for k, v in cacheBase.items(): cacheDict[k] = v if isLogout: if not IsSaveDBViewCache(curCache): DeleteViewCache(playerID) return {} return cacheDict #//04 01 µØÍ¼Í¬²½Íæ¼Ò»º´æÊý¾Ýµ½GameServer#tagMGUpdatePlayerCache # #struct tagMGUpdatePlayerCache #{ # tagHead Head; # DWORD PlayerID; //Íæ¼ÒID # WORD PlayerLV; //Íæ¼ÒµÈ¼¶ # BYTE IsLogouting; //±¾´ÎÊÇ·ñΪÏÂÏßͬ²½ # DWORD OffTime; // ÏÂÏßʱ¼ä´Á # WORD PropDataSize; # char PropData[PropDataSize]; //ÊôÐԼǼ # WORD PlusDataSize; # char PlusData[PlusDataSize]; //À©Õ¹¼Ç¼ # WORD ItemDataSize1; # char ItemData1[ItemDataSize1]; //1½××°±¸Êý¾Ý # ... ... # WORD ItemDataSize20; # char ItemData20[ItemDataSize20]; #}; def OnMGUpdatePlayerCache(routeIndex, mapID, curPackData, tick): playerID = curPackData.PlayerID #playerLV = curPackData.PlayerLV isLogout = curPackData.IsLogouting GameWorld.DebugLog('ViewCache### OnMGUpdatePlayerCache isLogout=%s' % isLogout, playerID) isSaveAll = True # ÊÇ·ñ±£´æËùÓÐÊý¾Ý curCache = FindViewCache(playerID, True) if not curCache: return curCache.LV = curPackData.PlayerLV curCache.OffTime = curPackData.OffTime curCache.PropDataDict = {} # ÿ´Î¸üÐÂÊý¾Ýʱ£¬ÖØÖÃ×ֵ仺´æ£¬Ï´λñÈ¡Ê±ÖØÐÂeval»º´æ curCache.PropData = curPackData.PropData curCache.PropDataSize = curPackData.PropDataSize curCache.PlusData = curPackData.PlusData curCache.PlusDataSize = curPackData.PlusDataSize #GameWorld.DebugLog(" ¸üÐÂPropÊý¾Ý: size=%s, %s" % (curCache.PropDataSize, curCache.PropData), playerID) #GameWorld.DebugLog(" ¸üÐÂPlusÊý¾Ý: size=%s, %s" % (curCache.PlusDataSize, curCache.PlusData), playerID) # ×°±¸Êý¾Ý´æ´¢£¬²»±£´æ×°±¸Êý¾ÝµÄ»°ÔòÇå¿Õ for classLV in xrange(1, 20 + 1): if not isSaveAll: itemDataSize = 0 itemData = "" else: itemDataSize = getattr(curPackData, "ItemDataSize%s" % classLV) if not itemDataSize: continue itemData = getattr(curPackData, "ItemData%s" % classLV) setattr(curCache, "ItemData%s" % classLV, itemData) setattr(curCache, "ItemDataSize%s" % classLV, itemDataSize) #GameWorld.DebugLog(" ¸üÐÂItemÊý¾Ý: classLV=%s,size=%s, %s" % (classLV, itemDataSize, itemData), playerID) if isLogout: #²»ÐèÒª±£´æÀëÏßÊý¾ÝµÄ£¬Ö±½Óɾ³ý»º´æÊý¾Ý if not IsSaveDBViewCache(curCache): DeleteViewCache(playerID) return curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if curPlayer: curCache.GeTuiID = curPlayer.GetGeTuiClientID() curCache.GeTuiIDSize = len(curCache.GeTuiID) #GameWorld.DebugLog(" %s" % curCache.outputString()) # ͬ²½¸üÐÂÖúÕ½ÐÅÏ¢ if PlayerFBHelpBattle.IsInHelpBattleCheckInList(playerID): PropDataDict = GetCachePropDataDict(curCache) fightPower = PropDataDict.get("FightPower", 0) familyID = PropDataDict.get("FamilyID", 0) playerName = PropDataDict.get("Name", "") PlayerFBHelpBattle.UpdateCheckInPlayerInfo(playerID, fightPower, familyID, playerName) return #//04 02 µØÍ¼²éÑ¯Íæ¼Ò»º´æÊý¾Ý#tagMGQueryPlayerCache #struct tagMGQueryPlayerCache #{ # tagHead Head; # DWORD PlayerID; //Íæ¼ÒID # DWORD FindPlayerID; //Òª²éѯµÄÍæ¼ÒID # BYTE EquipClassLV; //´óÓÚ0Ϊ²é¿´Ö¸¶¨¾³½ç½××°±¸ÐÅÏ¢, 0Ϊ²é¿´Ä¬ÈÏÐÅÏ¢ #}; def OnMGQueryPlayerCache(routeIndex, mapID, curPackData, tick): curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPackData.PlayerID) findPlayerID = curPackData.FindPlayerID equipClassLV = curPackData.EquipClassLV curCache = FindViewCache(findPlayerID) if not curCache: PlayerControl.NotifyCode(curPlayer, "ViewPlayer_OffLine") return Sync_PlayerCache(curPlayer, curCache, equipClassLV) return def Sync_PlayerCache(curPlayer, curCache, equipClassLV=0): ## ͬ²½Íæ¼Ò»º´æ if equipClassLV: itemData = "" if hasattr(curCache, "ItemDataSize%s" % equipClassLV): itemData = getattr(curCache, "ItemData%s" % equipClassLV) sendPack = ChPyNetSendPack.tagSCPlayerEquipCacheResult() sendPack.PlayerID = curCache.PlayerID sendPack.EquipClassLV = equipClassLV sendPack.ItemData = itemData sendPack.ItemDataSize = len(sendPack.ItemData) NetPackCommon.SendFakePack(curPlayer, sendPack) return #»Ø°ü¿Í»§¶Ë sendPack = ChPyNetSendPack.tagSCQueryPlayerCacheResult() sendPack.PlayerID = curCache.PlayerID sendPack.PropData = curCache.PropData sendPack.PropDataSize = len(sendPack.PropData) sendPack.PlusData = curCache.PlusData sendPack.PlusDataSize = len(sendPack.PlusData) NetPackCommon.SendFakePack(curPlayer, sendPack) return #=============================================================================== # //B3 06 ²éÑ¯Íæ¼ÒµÄ¼ò¶ÌÐÅÏ¢ #tagCGViewPlayerShortInfo # struct tagCGViewPlayerShortInfo # { # tagHead Head; # DWORD PlayerID; # }; #=============================================================================== def OnViewPlayerShortInfo(index, clientPack, tick): ## ·â°ü֪ͨ tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(clientPack.PlayerID) answerPack = ChPyNetSendPack.tagGCAnswerPlayerShortInfo() answerPack.Clear() if not tagPlayer: curCache = FindViewCache(clientPack.PlayerID) if not curCache: # ʵÔÚÕÒ²»µ½ÉèÖÃΪ³õʼ»¯Êý¾Ý answerPack.PlayerID = clientPack.PlayerID answerPack.PlayerName = "" answerPack.Job = 1 answerPack.LV = 1 answerPack.RealmLV = 1 answerPack.OnlineType = ChConfig.Def_Offline answerPack.ServerGroupID = 0 answerPack.Face = 0 answerPack.FacePic = 0 else: cacheDict = GetCachePropDataDict(curCache) answerPack.PlayerID = clientPack.PlayerID answerPack.PlayerName = cacheDict["Name"] answerPack.Job = cacheDict["Job"] answerPack.LV = cacheDict["LV"] answerPack.RealmLV = cacheDict["RealmLV"] answerPack.OnlineType = ChConfig.Def_Offline answerPack.Face = cacheDict.get("Face", 0) answerPack.FacePic = cacheDict.get("FacePic", 0) if GameWorld.IsCrossServer(): answerPack.ServerGroupID = cacheDict.get("ServerGroupID", 0) else: answerPack.ServerGroupID = GameWorld.GetServerGroupID() else: answerPack.PlayerID = clientPack.PlayerID answerPack.PlayerName = tagPlayer.GetName() answerPack.Job = tagPlayer.GetJob() answerPack.LV = tagPlayer.GetLV() answerPack.RealmLV = tagPlayer.GetOfficialRank() answerPack.OnlineType = ChConfig.Def_Online answerPack.IsInTeam = tagPlayer.GetTeamID() > 0 answerPack.ServerGroupID = PlayerControl.GetPlayerServerGroupID(tagPlayer) answerPack.Face = tagPlayer.GetFace() answerPack.FacePic = tagPlayer.GetFacePic() curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) NetPackCommon.SendFakePack(curPlayer, answerPack) return def OnPlayerFamilyChange(playerID, familyID, familyName): GameWorld.DebugLog("ViewCache->OnPlayerFamilyChange", playerID) curCache = FindViewCache(playerID) if not curCache: return PropData = GetCachePropDataDict(curCache) PropData["FamilyID"] = familyID PropData["FamilyName"] = familyName PropData = json.dumps(PropData, ensure_ascii=False).replace(" ", "") curCache.PropData = PropData curCache.PropDataSize = len(curCache.PropData) return