#!/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 PlayerControl
|
import NetPackCommon
|
import GameWorldArena
|
import ChPyNetSendPack
|
import ChGameToMapPyPack
|
import PlayerFBHelpBattle
|
import GameWorldSkyTower
|
import CrossChampionship
|
import CrossBattlefield
|
import PyGameDataStruct
|
import IpyGameDataPY
|
import PyDataManager
|
import ShareDefine
|
import ChConfig
|
|
import json
|
import time
|
|
def DoOnDayEx():
|
DelOutofTimeViewCacheData()
|
return
|
|
def IsSaveDBViewCache(playerID, playerLV):
|
## ÊÇ·ñ±£´æ»ù±¾µÄ»º´æÊý¾Ý
|
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 GameWorldSkyTower.IsSkyTowerPassPlayer(playerID):
|
return True
|
|
SaveDBLimitLV = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 1)
|
#УÑéÍæ¼ÒµÈ¼¶
|
if playerLV < SaveDBLimitLV:
|
return False
|
|
return True
|
|
def IsSaveAllViewCache(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
|
|
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
|
|
#¿ç·þ°ñµ¥ÉϵÄĬÈϱ£Áô
|
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
|
|
return False
|
|
def DelOutofTimeViewCacheData():
|
## ɾ³ý¹ýÆÚµÄ²é¿´»º´æÊý¾Ý
|
|
curTime = int(time.time())
|
MaxTime = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 3) * 3600 * 24
|
|
pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()
|
playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict
|
for playerID, viewCache in playerViewCachePyDict.items():
|
|
passTime = curTime - viewCache.OffTime
|
if passTime < MaxTime:
|
continue
|
if IsSaveAllViewCache(playerID):
|
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:
|
curCache = PyGameDataStruct.tagPlayerViewCachePy()
|
curCache.PlayerID = playerID
|
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 hasattr(curCache, "PropDataDict"):
|
curCache.PropDataDict = {}
|
if not curCache.PropDataDict and curCache.PropData:
|
curCache.PropDataDict = eval(curCache.PropData)
|
return curCache.PropDataDict
|
|
#//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 # ÊÇ·ñ±£´æËùÓÐÊý¾Ý
|
if isLogout:
|
#²»ÐèÒª±£´æÀëÏßÊý¾ÝµÄ£¬Ö±½Óɾ³ý»º´æÊý¾Ý
|
if not IsSaveDBViewCache(playerID, playerLV):
|
DeleteViewCache(playerID)
|
return
|
isSaveAll = IsSaveAllViewCache(playerID)
|
GameWorld.DebugLog(" isSaveAll=%s" % isSaveAll, playerID)
|
|
curCache = FindViewCache(playerID, True)
|
if not curCache:
|
return
|
curCache.LV = curPackData.PlayerLV
|
curCache.OffTime = curPackData.OffTime
|
if isLogout:
|
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
if curPlayer:
|
curCache.GeTuiID = curPlayer.GetGeTuiClientID()
|
curCache.GeTuiIDSize = len(curCache.GeTuiID)
|
|
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)
|
|
#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Ϊ²é¿´Ä¬ÈÏÐÅÏ¢
|
# BYTE CallMap; //ÊÇ·ñÐèҪ֪ͨµØÍ¼
|
#};
|
def OnMGQueryPlayerCache(routeIndex, mapID, curPackData, tick):
|
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPackData.PlayerID)
|
findPlayerID = curPackData.FindPlayerID
|
equipClassLV = curPackData.EquipClassLV
|
callMap = curPackData.CallMap
|
curCache = FindViewCache(findPlayerID)
|
if not curCache:
|
PlayerControl.NotifyCode(curPlayer, "ViewPlayer_OffLine")
|
if callMap:
|
sendPack = ChGameToMapPyPack.tagGMPlayerCache()
|
sendPack.PlayerID = curPlayer.GetPlayerID()
|
sendPack.FindPlayerID = findPlayerID
|
sendPack.PropData = ""
|
sendPack.PropDataSize = len(sendPack.PropData)
|
sendPack.PlusData = ""
|
sendPack.PlusDataSize = len(sendPack.PlusData)
|
NetPackCommon.SendPyPackToMapServer(routeIndex, mapID, sendPack)
|
return
|
Sync_PlayerCache(curPlayer, curCache, equipClassLV)
|
if callMap:
|
sendPack = ChGameToMapPyPack.tagGMPlayerCache()
|
sendPack.PlayerID = curPlayer.GetPlayerID()
|
sendPack.FindPlayerID = findPlayerID
|
sendPack.PropData = curCache.PropData
|
sendPack.PropDataSize = len(sendPack.PropData)
|
sendPack.PlusData = curCache.PlusData
|
sendPack.PlusDataSize = len(sendPack.PlusData)
|
NetPackCommon.SendPyPackToMapServer(routeIndex, mapID, sendPack)
|
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
|
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
|
|
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)
|
|
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
|
|