#!/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
|
|