#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package Script.DB.StructData.DBPlayerViewCache
|
#
|
# @todo:DBÍæ¼Ò²é¿´»º´æ
|
# @author hxp
|
# @date 2025-05-09
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: DBÍæ¼Ò²é¿´»º´æ
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2025-05-09 12:20"""
|
#-------------------------------------------------------------------------------
|
|
import DBComm
|
import DBStruct
|
import GameWorld
|
import ShareDefine
|
import PlayerControl
|
import DBDataMgr
|
import CommFunc
|
import ChConfig
|
import GameObj
|
|
import random
|
import time
|
|
Key_UpdViewCacheTick = "UpdViewCacheTick"
|
|
class PlayerViewCache():
|
|
def __init__(self, dbData=None):
|
self.__dbData = DBStruct.tagDBPlayerViewCache() if not dbData else dbData
|
self.__plusDict = DBComm.UserDataDict(self.__dbData, "PlusData", "PlusDataSize", True)
|
return
|
|
def GetPlayerID(self): return self.__dbData.PlayerID
|
def SetPlayerID(self, playerID): self.__dbData.PlayerID = playerID
|
def GetAccID(self): return self.__dbData.AccID
|
def SetAccID(self, accID): self.__dbData.AccID = accID
|
def GetPlayerName(self): return self.__dbData.PlayerName
|
def SetPlayerName(self, playerName): self.__dbData.PlayerName = playerName
|
def GetLV(self): return self.__dbData.LV
|
def SetLV(self, lv): self.__dbData.LV = lv
|
def GetJob(self): return self.__dbData.Job
|
def SetJob(self, job): self.__dbData.Job = job
|
def GetRealmLV(self): return self.__dbData.RealmLV
|
def SetRealmLV(self, realmLV): self.__dbData.RealmLV = realmLV
|
def GetFace(self): return self.__dbData.Face
|
def SetFace(self, face): self.__dbData.Face = face
|
def GetFacePic(self): return self.__dbData.FacePic
|
def SetFacePic(self, facePic): self.__dbData.FacePic = facePic
|
def GetFamilyID(self): return self.__dbData.FamilyID
|
def SetFamilyID(self, familyID): self.__dbData.FamilyID = familyID
|
def GetFamilyName(self): return self.__dbData.FamilyName
|
def SetFamilyName(self, familyName): self.__dbData.FamilyName = familyName
|
def GetFamilyEmblemID(self): return self.__dbData.FamilyEmblemID
|
def SetFamilyEmblemID(self, familyEmblemID): self.__dbData.FamilyEmblemID = familyEmblemID
|
def GetTitleID(self): return self.__dbData.TitleID
|
def SetTitleID(self, titleID): self.__dbData.TitleID = titleID
|
def GetFightPower(self): return self.__dbData.FightPower
|
def GetFightPowerEx(self): return self.__dbData.FightPowerEx
|
def GetFightPowerTotal(self): return self.__dbData.FightPowerEx * ChConfig.Def_PerPointValue + self.__dbData.FightPower
|
def SetFightPowerTotal(self, fightPowerTotal):
|
self.__dbData.FightPower = fightPowerTotal % ChConfig.Def_PerPointValue
|
self.__dbData.FightPowerEx = fightPowerTotal / ChConfig.Def_PerPointValue
|
return
|
def GetServerID(self): return self.__dbData.ServerID
|
def SetServerID(self, serverID): self.__dbData.ServerID = serverID
|
def GetOffTime(self): return self.__dbData.OffTime
|
def SetOffTime(self, offTime): self.__dbData.OffTime = offTime
|
def GetPlusDict(self): return self.__plusDict.GetData()
|
def GetPlusData(self): return self.__plusDict.ToString()
|
def GetBuffer(self):
|
self.__plusDict.ToString()
|
return self.__dbData.getBuffer()
|
|
## -----------------------------------------------------------------------
|
|
class PlayerViewCacheMgr():
|
|
def __init__(self):
|
self.__viewCacheList = [] # [PlayerViewCache, ...]
|
self.__idIndexDict = {} # {playerID:index, ...}
|
self.__needSort = False
|
self.__serverIDRangePlayerIDDict = {} # {serverIDRangeTuple:[playerID, ...], ....}
|
return
|
|
def InitViewCacheInstance(self, dbData):
|
'''³õʼ»¯¹¦ÄÜÊý¾ÝʵÀý£¬´´½¨»ò¼ÓÔØÊý¾ÝʱͨÓ㬹¦ÄÜÒ»°ã²»µ÷ÓÃ
|
@param dbData: ʵÀý¶ÔÓ¦°ó¶¨µÄdbData
|
@return: ³É¹¦·µ»ØÊµÀý¶ÔÏó£¬Ê§°Ü·µ»ØNone
|
'''
|
playerID = dbData.PlayerID
|
self.__refreshIDIndex()
|
if playerID in self.__idIndexDict:
|
return
|
viewCache = PlayerViewCache(dbData)
|
self.__viewCacheList.append(viewCache)
|
self.__idIndexDict[playerID] = len(self.__viewCacheList) - 1
|
self.__needSort = True
|
return viewCache
|
|
def CheckUpdViewCache(self, playerID):
|
if playerID <= ShareDefine.FackPlayerIDMax:
|
return
|
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
if not curPlayer:
|
return
|
lastUpdTick = curPlayer.GetDictByKey(Key_UpdViewCacheTick)
|
tick = GameWorld.GetGameWorld().GetTick()
|
if lastUpdTick and tick - lastUpdTick < 60000:
|
GameWorld.DebugLog("1·ÖÖÓÄÚÖ»¸üÐÂÒ»´ÎÍæ¼Ò»º´æ", playerID)
|
return
|
curPlayer.SetDict(Key_UpdViewCacheTick, tick)
|
return UpdPlayerViewCache(curPlayer)
|
|
def FindViewCache(self, playerID, isAdd=False):
|
'''²éÕÒÍæ¼Ò»º´æ£¬Èç¹û²»´æÔÚ£¬Ôò»áÓжîÍâÂß¼£¬Èç´Óredis¡¢dbÖ±½ÓÕÒ£¬
|
¿ç·þÍæ¼Ò´Ó¿ç·þÈ¡£¬¿ÉÄÜÑÓ³Ù»ñµÃ
|
'''
|
curCache = self.GetPlayerViewCache(playerID)
|
if curCache:
|
updCache = self.CheckUpdViewCache(playerID)
|
if updCache:
|
curCache = updCache
|
|
# ÕæÊµÍæ¼Ò
|
elif playerID > ShareDefine.FackPlayerIDMax:
|
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
# ±¾·þÔÚÏßÍæ¼Ò£¬Ö±½ÓÉú³ÉÐÂÊý¾Ý
|
if curPlayer:
|
dbData = DBStruct.tagDBPlayerViewCache()
|
dbData.PlayerID = playerID
|
self.InitViewCacheInstance(dbData)
|
UpdPlayerViewCache(curPlayer)
|
|
# ÀëÏßÍæ¼Ò
|
else:
|
pass
|
# ±¾·þÍæ¼Ò£¬´Óredis»òdb¶ÁÈ¡ÖØÐ¼ÓÔØ¶ÁÈ¡£¬»»¾ä»°Ëµ£¬±¾·þÍæ¼ÒÖ»Òª»ñȡһ¶¨Óв鿴»º´æÊý¾Ý
|
# ¿ç·þÍæ¼Ò£¬È¥×Ó·þÀÈ¡Êý¾Ý£¬ÀíÂÛÉÏÒ²Ò»¶¨ÓУ¬µ«ÊÇÈç¹ûÐèÒªÀÊý¾Ý£¬ÓÐÒ»¶¨ÑÓ³Ù
|
# Âß¼´ýÀ©Õ¹
|
|
# ¼ÙÍæ¼Ò£¬Ä¬ÈÏÌí¼Ó
|
elif ShareDefine.FackPlayerIDStart <= playerID <= ShareDefine.FackPlayerIDMax:
|
serverID = playerID % 100 + 1 # 1 ~ 100 ·þ
|
accID = "fake%s@test@s%s" % (playerID, serverID)
|
fightPower = random.randint(1000000, 100000000) # ÏÈËæ»ú£¬Íâ²ãÓÐÐèÒªµÄ»°ÔÙ×Ô¼ºÉèÖÃ
|
|
dbData = DBStruct.tagDBPlayerViewCache()
|
dbData.PlayerID = playerID
|
dbData.PlayerName = "%s%s" % (GameWorld.GbkToCode("ÉñÃØµÀÓÑ"), playerID)
|
dbData.AccID = accID
|
dbData.LV = random.randint(100, 200)
|
dbData.Job = random.randint(1, 2)
|
dbData.RealmLV = random.randint(5, 15)
|
dbData.FightPower = fightPower % ChConfig.Def_PerPointValue
|
dbData.FightPowerEx = fightPower / ChConfig.Def_PerPointValue
|
dbData.ServerID = serverID
|
dbData.OffTime = int(time.time()) - random.randint(1, 3600 * 24 * 10) # Ëæ»úÀëÏß 0~10Ìì
|
curCache = self.InitViewCacheInstance(dbData)
|
|
return curCache
|
|
def GetPlayerViewCache(self, playerID):
|
## »ñÈ¡Íæ¼Ò²é¿´»º´æ£¬½öÄÚ´æÖÐÊý¾Ý£¬ÎÞ¶îÍâÂß¼
|
self.__refreshIDIndex()
|
viewCache = None
|
if playerID in self.__idIndexDict:
|
index = self.__idIndexDict[playerID]
|
if index < len(self.__viewCacheList):
|
viewCache = self.__viewCacheList[index]
|
|
if not viewCache and False:
|
viewCache = PlayerViewCache()
|
|
return viewCache
|
|
def GetPlayerIDListByServerIDInfo(self, serverIDList):
|
## ¸ù¾Ý·þÎñÆ÷IDÁбíÐÅÏ¢»ñÈ¡¶ÔÓ¦·þÎñÆ÷ID·¶Î§µÄÍæ¼ÒIDÕ½Á¦ÅÅÐòÁбí
|
if serverIDList == None:
|
return []
|
self.Sort()
|
key = tuple(serverIDList)
|
if key not in self.__serverIDRangePlayerIDDict:
|
playerIDList = []
|
for viewCache in self.__viewCacheList:
|
playerID = viewCache.GetPlayerID()
|
serverID = viewCache.GetServerID()
|
for idInfo in serverIDList:
|
if (isinstance(idInfo, int) and serverID == idInfo) \
|
or ((isinstance(idInfo, tuple) or isinstance(idInfo, list)) \
|
and len(idInfo) == 2 and idInfo[0] <= serverID <= idInfo[1]):
|
playerIDList.append(playerID)
|
GameWorld.DebugLog("ÖØÐ¼ÓÔØÇø·þÍæ¼Ò²é¿´»º´æIDÁбí: %s, %s, %s" % (key, len(playerIDList), playerIDList))
|
self.__serverIDRangePlayerIDDict[key] = playerIDList
|
return self.__serverIDRangePlayerIDDict[key]
|
|
def IsPlayerIn(self, playerID):
|
self.__refreshIDIndex()
|
return playerID in self.__idIndexDict
|
|
def __refreshIDIndex(self):
|
if not self.__idIndexDict:
|
self.__idIndexDict = {}
|
for index, viewCache in enumerate(self.__viewCacheList):
|
self.__idIndexDict[viewCache.GetPlayerID()] = index
|
return self.__idIndexDict
|
|
def DelPlayerViewCache(self, playerID):
|
self.__refreshIDIndex()
|
index = self.__idIndexDict.pop(playerID, -1)
|
if index >= 0 and index < len(self.__viewCacheList):
|
self.__viewCacheList.pop(index)
|
for playerIDList in self.__serverIDRangePlayerIDDict.values():
|
if playerID in playerIDList:
|
playerIDList.remove(playerID)
|
self.__idIndexDict = {}
|
self.__serverIDRangePlayerIDDict = {}
|
return
|
|
def GetCount(self): return len(self.__viewCacheList)
|
def At(self, index):
|
viewCache = self.__viewCacheList[index]
|
if not viewCache and False:
|
viewCache = PlayerViewCache() # ²»»áÖ´Ðе½£¬Ö»ÎªÁË.³ö´úÂëÌáʾ
|
return viewCache
|
|
def Sort(self):
|
## ĬÈϰ´Õ½Á¦µ¹ÐòÅÅ
|
if not self.__needSort:
|
return
|
self.__needSort = False
|
self.__viewCacheList.sort(key=lambda v: (v.GetFightPowerTotal(), v.GetLV()), reverse=True)
|
self.__idIndexDict = {}
|
self.__serverIDRangePlayerIDDict = {}
|
self.__refreshIDIndex()
|
return
|
|
# ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup
|
def GetSaveData(self):
|
savaData = ""
|
cntData = ""
|
cnt = 0
|
|
for dbData in self.__viewCacheList:
|
cnt += 1
|
savaData += dbData.GetBuffer()
|
|
GameWorld.Log("Save DBPlayerViewCache count :%s len=%s" % (cnt, len(savaData)))
|
return CommFunc.WriteDWORD(cntData, cnt) + savaData
|
|
# ´ÓÊý¾Ý¿âÔØÈëÊý¾Ý
|
def LoadPyGameData(self, datas, pos, dataslen):
|
cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
GameWorld.Log("Load DBPlayerViewCache count :%s" % cnt)
|
|
for _ in xrange(cnt):
|
dbData = DBStruct.tagDBPlayerViewCache()
|
pos += dbData.readData(datas, pos, dataslen)
|
self.InitViewCacheInstance(dbData)
|
|
self.Sort()
|
return pos
|
|
def OnPlayerLogout(curPlayer):
|
if curPlayer.GetLV() >= 10:
|
UpdPlayerViewCache(curPlayer)
|
|
return
|
|
def UpdPlayerViewCache(curPlayer, isOffline=False):
|
'''¸üÐÂÍæ¼Ò²é¿´»º´æÊý¾Ý£¬¸üÐÂʱ»úÓÉÍâ²ã×Ô¼ºÅжϣ¬ÕâÀïÖ»×ö¸üÐÂÂß¼
|
1. ÏÂÏßÊ±Ç¿ÖÆ¸üÐÂÒ»´Î£¬ÉÏÏßÔݲ»¸üУ¬ÉÏÏßʱÓɸ÷¹¦ÄÜÈç¹ûÓÐÐèÒªÓõ½´¥·¢¸üÐÂ
|
2. ÓÐÐèÒªÓõ½»º´æÊý¾Ýʱ£¬Èç¹ûÍæ¼ÒÔÚÏߣ¬1·ÖÖÓÄÚ¶à´Î»ñȡʱ×î¶à¸üÐÂÒ»´Î£¬Ã»ÓлñÈ¡»º´æÊý¾ÝÔò²»¸üÐÂ
|
'''
|
if not curPlayer:
|
return
|
|
playerID = curPlayer.GetPlayerID()
|
curCache = DBDataMgr.GetPlayerViewCacheMgr().GetPlayerViewCache(playerID)
|
if not curCache:
|
return
|
|
tick = GameWorld.GetGameWorld().GetTick()
|
curPlayer.SetDict(Key_UpdViewCacheTick, tick)
|
GameWorld.DebugLog("¸üÐÂÍæ¼Ò²é¿´»º´æÊý¾Ý! isOffline=%s" % isOffline, playerID)
|
curCache.SetAccID(curPlayer.GetAccID())
|
curCache.SetPlayerName(curPlayer.GetPlayerName())
|
curCache.SetLV(curPlayer.GetLV())
|
curCache.SetJob(curPlayer.GetJob())
|
curCache.SetRealmLV(curPlayer.GetOfficialRank())
|
curCache.SetFace(curPlayer.GetFace())
|
curCache.SetFacePic(curPlayer.GetFacePic())
|
curCache.SetFamilyID(curPlayer.GetFamilyID())
|
curCache.SetFamilyName(curPlayer.GetFamilyName())
|
curCache.SetFamilyEmblemID(PlayerControl.GetFamilyEmblemID(curPlayer))
|
curCache.SetTitleID(PlayerControl.GetTitleID(curPlayer))
|
curCache.SetFightPowerTotal(PlayerControl.GetFightPower(curPlayer))
|
curCache.SetServerID(GameWorld.GetPlayerServerID(curPlayer))
|
if isOffline:
|
curCache.SetOffTime(int(time.time()))
|
|
plusDict = curCache.GetPlusDict()
|
|
#Õ½¶·ÊôÐÔ
|
plusDict.update({
|
"MinAtk":curPlayer.GetMinAtk(),
|
"MaxAtk":curPlayer.GetMaxAtk(),
|
"Def":curPlayer.GetDef(),
|
"MaxHP":GameObj.GetMaxHP(curPlayer),
|
"Hit":curPlayer.GetHit(),
|
"Miss":curPlayer.GetMiss(),
|
"SuperHitRate":curPlayer.GetSuperHitRate(), # ±©»÷ÂÊ
|
})
|
|
# ¹¦ÄÜÊý¾Ý
|
|
# ÆäËû
|
|
return curCache
|
|
|