ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
@@ -19,18 +19,26 @@
#---------------------------------------------------------------------
import GameWorld
import GameWorship
import PlayerControl
import NetPackCommon
import GameWorldArena
import ChPyNetSendPack
import ChGameToMapPyPack
import PlayerFBHelpBattle
import GameWorldSkyTower
import CrossChampionship
import CrossBattlefield
import CrossRealmPlayer
import PyGameDataStruct
import IpyGameDataPY
import PyDataManager
import ShareDefine
import ChConfig
import json
import time
import random
def DoOnDayEx():
    DelOutofTimeViewCacheData()
@@ -42,6 +50,21 @@
        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 GameWorldSkyTower.IsSkyTowerPassPlayer(playerID):
        return True
    
    SaveDBLimitLV = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 1)
@@ -60,6 +83,12 @@
    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()
@@ -70,13 +99,23 @@
        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 = 30 * 3600 * 24 # 30天
    MaxTime = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 3) * 3600 * 24
    
    pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()
    playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict
@@ -99,26 +138,101 @@
    GameWorld.DebugLog("删除查看缓存!", playerID)
    return
def FindViewCache(playerID, isAddNew=False):
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:
    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 = random.randint(9900, 9950)
            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":serverID,
                           }
        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 curCache:
        return {}
    if not hasattr(curCache, "PropDataDict"):
        curCache.PropDataDict = {}
    if not curCache.PropDataDict:
    if not curCache.PropDataDict and curCache.PropData:
        curCache.PropDataDict = eval(curCache.PropData)
    return curCache.PropDataDict
def GetShotCahceDict(playerID, withEquip=False):
    ## 获取玩家简短的缓存信息字典
    cacheDict = GetCachePropDataDict(FindViewCache(playerID))
    if not cacheDict:
        return {}
    shotCacheDict = {
                     "PlayerID":playerID,
                     "Name":cacheDict["Name"],
                     "Job":cacheDict["Job"],
                     "LV":cacheDict["LV"],
                     "RealmLV":cacheDict["RealmLV"],
                     "FightPower":cacheDict["FightPower"],
                     "ServerID":GameWorld.GetAccIDServerID(cacheDict["AccID"]),
                     }
    if withEquip:
        shotCacheDict.update({
                              "TitleID":cacheDict.get("TitleID", 0),
                              "EquipShowSwitch":cacheDict.get("EquipShowSwitch", 0),
                              "EquipShowID":cacheDict.get("EquipShowID", 0),
                              })
    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", 0),
                 "ServerGroupID":PlayerControl.GetPlayerServerGroupID(curPlayer),
                 }
    return cacheBase
def UpdCrossCacheBase(playerID, cacheBase):
    ## 更新同步跨服基础查看缓存
    cacheDict = GetCachePropDataDict(FindViewCache(playerID, True))
    if not cacheBase:
        return cacheDict
    for k, v in cacheBase.items():
        cacheDict[k] = v
    return cacheDict
#//04 01 地图同步玩家缓存数据到GameServer#tagMGUpdatePlayerCache
#
@@ -136,8 +250,8 @@
#    WORD        ItemDataSize1;
#    char        ItemData1[ItemDataSize1];    //1阶装备数据
#    ...         ...
#    WORD        ItemDataSize15;
#    char        ItemData15[ItemDataSize15];
#    WORD        ItemDataSize20;
#    char        ItemData20[ItemDataSize20];
#};
def OnMGUpdatePlayerCache(routeIndex, mapID, curPackData, tick):
    playerID = curPackData.PlayerID
@@ -158,12 +272,7 @@
        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
@@ -174,7 +283,7 @@
    #GameWorld.DebugLog("    更新Plus数据: size=%s, %s" % (curCache.PlusDataSize, curCache.PlusData), playerID)
    
    # 装备数据存储,不保存装备数据的话则清空
    for classLV in xrange(1, 15 + 1):
    for classLV in xrange(1, 20 + 1):
        if not isSaveAll:
            itemDataSize = 0
            itemData = ""
@@ -205,16 +314,36 @@
#    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):
@@ -265,6 +394,7 @@
            answerPack.RealmLV = 1
            answerPack.OnlineType = ChConfig.Def_Offline
            answerPack.ServerGroupID = 0
            answerPack.Face = 0
        else:
            cacheDict = GetCachePropDataDict(curCache)
            answerPack.PlayerID = clientPack.PlayerID
@@ -273,6 +403,7 @@
            answerPack.LV = cacheDict["LV"]
            answerPack.RealmLV = cacheDict["RealmLV"]
            answerPack.OnlineType = ChConfig.Def_Offline
            answerPack.Face = cacheDict.get("Face", 0)
            
            if GameWorld.IsCrossServer():
                answerPack.ServerGroupID = cacheDict.get("ServerGroupID", 0)
@@ -287,6 +418,7 @@
        answerPack.OnlineType = ChConfig.Def_Online
        answerPack.IsInTeam = tagPlayer.GetTeamID() > 0
        answerPack.ServerGroupID = PlayerControl.GetPlayerServerGroupID(tagPlayer)
        answerPack.Face = tagPlayer.GetFace()
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    NetPackCommon.SendFakePack(curPlayer, answerPack)