hxp
2019-10-29 2941a7635bb04ca59afa820b51a23aca9dc70eb9
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
@@ -30,66 +30,141 @@
import ChEquip
import FBCommon
import BossHurtMng
import ItemCommon
import PyGameData
import PlayerTJG
import SkillShell
import time
import json
Def_Process_Tick = "ProcessPlayerCache"
##玩家下线同步
#  @param curPlayer, tick
#  @return None
def OnPlayerLogOut(curPlayer, tick):
    #发送通知GameServer 缓存数据
    curPlayer.SetDict(Def_Process_Tick, tick)
    UpdateGameServerPlayerCache(curPlayer, tick, True)
    ##玩家下线同步
    UpdateGameServerPlayerCache(curPlayer, tick, True)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipViewCacheState, 0)
    return
##玩家在线定时同步
#  @param curPlayer, tick
#  @return None
def ProcessCache(curPlayer, tick):
    if tick - curPlayer.GetDictByKey(Def_Process_Tick) > 5*60*1000:
        UpdateGameServerPlayerCache(curPlayer, tick, False)
    ##玩家在线定时同步
    lastTick = curPlayer.GetDictByKey(Def_Process_Tick)
    if not lastTick:
        curPlayer.SetDict(Def_Process_Tick, tick)
        return
    if tick - lastTick < 5 * 60 * 1000: # 同步玩家缓存间隔
        return
    UpdateGameServerPlayerCache(curPlayer, tick, False)
    return
##更新玩家当前详细信息到GameServer
#  @param curPlayer, tick
#  @return None
def UpdateGameServerPlayerCache(curPlayer, tick, IsLogouting = False):
    GameWorld.DebugLog('ViewCache### UpdateGameServerPlayerCache in')
def UpdateGameServerPlayerCache(curPlayer, tick, IsLogouting=False):
    if PlayerTJG.GetIsTJG(curPlayer):
        # 脱机不处理
        return
    curPlayer.SetDict(Def_Process_Tick, tick)
    #获取当前玩家缓存数据
    curPlayerPropData, curPlayerItemData, curPlayerPlusData = GetPlayerCache(curPlayer)
    PropData, PlusData = GetPlayerPropPlusCache(curPlayer)
    itemDataDict = __GetPlayerItemDataCache(curPlayer)
    
    #同步发送到GameServer
    sendPack = ChMapToGamePyPack.tagMGUpdatePlayerCache()
    sendPack.PlayerID = curPlayer.GetPlayerID()
    sendPack.PlayerLV = curPlayer.GetLV()
    sendPack.PropData = curPlayerPropData
    sendPack.PropDataSize = len(curPlayerPropData)
    sendPack.ItemData = curPlayerItemData
    sendPack.ItemDataSize = len(curPlayerItemData)
    sendPack.PlusData = curPlayerPlusData
    sendPack.PlusDataSize = len(curPlayerPlusData)
    sendPack.IsLogouting = IsLogouting #通知本次同步是否下线前保存
    sendPack.OffTime = int(time.time())    # 最后一次发送即当做离线时间
    sendPack.PropData = PropData
    sendPack.PropDataSize = len(sendPack.PropData)
    sendPack.PlusData = PlusData
    sendPack.PlusDataSize = len(sendPack.PlusData)
    for classLV, itemData in itemDataDict.items():
        setattr(sendPack, "ItemData%s" % classLV, itemData)
        setattr(sendPack, "ItemDataSize%s" % classLV, len(itemData))
    #GameWorld.DebugLog("同步缓存: %s" % sendPack.OutputString())
    NetPackCommon.SendPyPackToGameServer(sendPack)
    GameWorld.DebugLog('ViewCache### UpdateGameServerPlayerCache out')
    return
## 获取玩家数据缓存
#  @param curPlayer
#  @return None
def GetPlayerCache(curPlayer):
    #-----------
def __GetPlayerItemDataCache(curPlayer):
    ## 装备及装备位养成缓存,由于装备位比较多,所以按阶同步,重登第一次同步所有阶
    if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipViewCacheState):
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipViewCacheState, 1)
        needSyncClassLVList = xrange(1, IpyGameDataPY.GetFuncCfg('EquipMaxClasslv') + 1)
    else:
        playerID = curPlayer.GetPlayerID()
        needSyncClassLVList = PyGameData.g_equipChangeClassLVInfo.pop(playerID, [])
    itemDataDict = {}
    for classLV in needSyncClassLVList:
        itemDataDict[classLV] = __GetPlayerEquipClassDataCache(curPlayer, classLV)
    return itemDataDict
def __GetPlayerEquipClassDataCache(curPlayer, classLV):
    ## 获取境界阶装备缓存数据
    ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition('EquipPlaceIndexMap', {'ClassLV':classLV}, True)
    if not ipyDataList:
        return "{}"
    packType = IPY_GameWorld.rptEquip
    equipPack = curPlayer.GetItemManager().GetPack(packType)
    classItemDataDict = {}
    for ipyData in ipyDataList:
        index = ipyData.GetGridIndex()
        curEquip = equipPack.GetAt(index)
        if not curEquip or curEquip.IsEmpty():
            continue
        itemDict = {}
        itemDict["ItemID"] = curEquip.GetItemTypeID()
        userData = curEquip.GetUserData()
        if userData and userData != "{}":
            itemDict["UserData"] = userData
        classItemDataDict[index] = itemDict
        classLV = ItemCommon.GetItemClassLV(curEquip)
        if not classLV:
            continue
        #部位升星数据
        equipStar = ChEquip.GetEquipPartStarByRank(curPlayer, index, curEquip)
        if equipStar:
            itemDict["Star"] = equipStar
        #部位强化数据
        equipPartPlusLV = ChEquip.GetEquipPartPlusLVByRank(curPlayer, packType, index, curEquip)
        equipPartPlusEvolveLV = ChEquip.GetEquipPartPlusEvolveLVByEquip(curPlayer, packType, index, curEquip)
        if equipPartPlusLV:
            itemDict["PlusLV"] = equipPartPlusLV
        if equipPartPlusEvolveLV:
            itemDict["EvolveLV"] = equipPartPlusEvolveLV
        #部位宝石数据
        stoneIDList = Operate_EquipStone.GetEquipIndexStoneIDList(curPlayer, index)
        if stoneIDList and stoneIDList.count(0) != len(stoneIDList):
            itemDict["Stone"] = stoneIDList
        #部位洗练数据
        washLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipWashLV % index)
        valueList = []
        for attrNum in xrange(1, Operate_EquipWash.Def_EquipWashMaxAttrCount + 1):
            value = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipWashValue % (index, attrNum))
            valueList.append(value)
        if valueList and valueList.count(0) != len(valueList):
            itemDict["Wash"] = {"LV":washLV, "Value":valueList}
    return json.dumps(classItemDataDict, ensure_ascii=False).replace(" ", "")
def GetPlayerPropPlusCache(curPlayer):
    #玩家属性缓存
    curPlayerPropDict = {}
    curPlayerPropDict["AccID"] = curPlayer.GetAccID()
    curPlayerPropDict["LV"] = curPlayer.GetLV()
    curPlayerPropDict["RealmLV"] = curPlayer.GetOfficialRank()
    curPlayerPropDict["Job"] = curPlayer.GetJob()
    curPlayerPropDict["JobRank"] = PlayerControl.GetJobRank(curPlayer)
    curPlayerPropDict["VIPLV"] = curPlayer.GetVIPLv()
    curPlayerPropDict["Name"] = curPlayer.GetPlayerName()
    curPlayerPropDict["FamilyID"] = curPlayer.GetFamilyID()
@@ -97,7 +172,10 @@
    curPlayerPropDict["FightPower"] = curPlayer.GetFightPower()
    curPlayerPropDict["AppID"] = GameWorld.GetPlayerPlatform(curPlayer)
    curPlayerPropDict["EquipShowSwitch"] = curPlayer.GetEquipShowSwitch()
    curPlayerPropDict["EquipShowID"] = __GetEquipShowIDList(curPlayer)
    curPlayerPropDict["ServerGroupID"] = PlayerControl.GetPlayerServerGroupID(curPlayer)
    curPlayerPropDict["LingGenPoint"] = [PlayerControl.GetMetal(curPlayer), PlayerControl.GetWood(curPlayer), PlayerControl.GetWater(curPlayer),
                                         PlayerControl.GetFire(curPlayer), PlayerControl.GetEarth(curPlayer)]
    #仙魔之争所需属性
    curPlayerPropDict["MinAtk"] = curPlayer.GetMinAtk()
    curPlayerPropDict["MaxAtk"] = curPlayer.GetMaxAtk()
@@ -111,21 +189,18 @@
    # 封魔坛剩余次数
    enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % ChConfig.Def_FBMapID_SealDemon)
    maxCnt = FBCommon.GetEnterFBMaxCnt(curPlayer, ChConfig.Def_FBMapID_SealDemon)
    curPlayerPropDict['CntMark_%s'%ChConfig.Def_FBMapID_SealDemon] = max(maxCnt - enterCnt, 0)
    curPlayerPropDict['CntMark_%s' % ChConfig.Def_FBMapID_SealDemon] = max(maxCnt - enterCnt, 0)
    # 诛仙BOSS剩余次数
    enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % ChConfig.Def_FBMapID_ZhuXianBoss)
    maxCnt = FBCommon.GetEnterFBMaxCnt(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss)
    curPlayerPropDict['CntMark_%s'%ChConfig.Def_FBMapID_ZhuXianBoss] = max(maxCnt - enterCnt, 0)
    curPlayerPropDict['CntMark_%s' % ChConfig.Def_FBMapID_ZhuXianBoss] = max(maxCnt - enterCnt, 0)
    # 世界BOSS剩余次数
    curPlayerPropDict['CntMark_%s'%ShareDefine.Def_Boss_Func_World] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_World)
    curPlayerPropDict['CntMark_%s' % ShareDefine.Def_Boss_Func_World] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_World)[0]
    # BOSS之家剩余次数
    curPlayerPropDict['CntMark_%s'%ShareDefine.Def_Boss_Func_Home] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_Home)
    curPlayerPropDict['CntMark_%s' % ShareDefine.Def_Boss_Func_Home] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_Home)[0]
    # 神兽BOSS剩余次数
    curPlayerPropDict['CntMark_%s'%ShareDefine.Def_Boss_Func_Dogz] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_Dogz)
    #-----------
    #装备数据打包缓存
    curEquipItemList = __GetPackEquipCacheList(curPlayer, IPY_GameWorld.rptEquip)
    curPlayerPropDict['CntMark_%s' % ShareDefine.Def_Boss_Func_Dogz] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_Dogz)[0]
    #-----------
    #扩展属性缓存
    curPlayerPlusDict = {}
@@ -138,17 +213,15 @@
            fightPowerDict["%s" % mfpType] = fightPower
    curPlayerPlusDict["FightPowerDict"] = fightPowerDict
    
    #翅膀信息在翅膀装备位对应装备信息
    #部位强化数据
    curPlayerPlusDict["EquipPartStarLV"] = __GetEquipPartPlusLVInfo(curPlayer)
    #部位宝石数据
    curPlayerPlusDict["EquipPartStone"] = __GetEquipPartStoneInfo(curPlayer)
    #部位洗练数据
    curPlayerPlusDict["EquipWash"] = __GetEquipWashInfo(curPlayer)
    #装备汇总信息
    curPlayerPlusDict["EquipOrangeCount"] = ChEquip.GetEquipOrangeCount(curPlayer)
    curPlayerPlusDict["TotalEquipStar"] = ChEquip.GetTotalEquipStars(curPlayer)
    curPlayerPlusDict["TotalPlusLV"] = ChEquip.GetTotalPlusLV(curPlayer)
    curPlayerPlusDict["TotalPlusEvolveLV"] = ChEquip.GetTotalPlusEvolveLV(curPlayer)
    curPlayerPlusDict["TotalStoneLV"] = Operate_EquipStone.GetTotalStoneLV(curPlayer)
    curPlayerPlusDict["TotalEquipWashLV"] = Operate_EquipWash.GetTotalEquipWashLV(curPlayer)
    #主动技能总等级
    curPlayerPlusDict["TotalSkillLV"] = SkillShell.GetAllSkillLV(curPlayer, ChConfig.Def_SkillFuncType_FbSkill)
    #灵宠数据
    curPlayerPlusDict["Pet"] = __GetPetInfo(curPlayer)
    
@@ -167,57 +240,21 @@
    #魂石、丹药使用个数
    curPlayerPlusDict["Fruit"] = PlayerAttrFruit.GetAttrFruitEatCntDict(curPlayer)
    
    #-----------
    curPlayerPropData = json.dumps(curPlayerPropDict, ensure_ascii=False)
    curPlayerItemData = json.dumps(curEquipItemList, ensure_ascii=False)
    curPlayerPlusData = json.dumps(__RemoveEmptyDataKey(curPlayerPlusDict), ensure_ascii=False)
    return (curPlayerPropData, curPlayerItemData, curPlayerPlusData)
    PropData = json.dumps(curPlayerPropDict, ensure_ascii=False).replace(" ", "")
    PlusData = json.dumps(curPlayerPlusDict, ensure_ascii=False).replace(" ", "")
    return PropData, PlusData
def __RemoveEmptyDataKey(dataDict):
    for key in dataDict.keys():
        if not dataDict[key]:
            dataDict.pop(key)
    return dataDict
## 公共部位强化星级信息{部位索引:强化等级, ...}
def __GetEquipPartPlusLVInfo(curPlayer):
    pType = IPY_GameWorld.rptEquip # 暂时只取装备背包,之后有扩展再修改
    indexList = ChConfig.Pack_EquipPart_CanPlusStar[pType]
    starLVInfoDict = {}
    for i in indexList:
        starLV = ChEquip.GetEquipPartPlusLV(curPlayer, pType, i)
        if starLV:
            starLVInfoDict[i] = starLV
    return starLVInfoDict
## 公共部位宝石信息{部位索引:[宝石ID, ...], ...}
def __GetEquipPartStoneInfo(curPlayer):
    stoneInfoDict = {}
    stoneCanPlaceList = Operate_EquipStone.GetAllStoneEquipIndexList() # 获得所有可镶嵌宝石装备位
    for equipIndex in stoneCanPlaceList:
        stoneIDList = Operate_EquipStone.GetEquipIndexStoneIDList(curPlayer, equipIndex)
        if stoneIDList and stoneIDList.count(0) != len(stoneIDList):
            stoneInfoDict[equipIndex] = stoneIDList
    return stoneInfoDict
## 公共部位洗练信息[{"Place":部位索引, "LV":洗练等级, "Value":[洗练值1,洗练值2,... ]}, ...]
def __GetEquipWashInfo(curPlayer):
    stoneInfoList = []
    washPlaceList = Operate_EquipWash.GetAllEquipWashPlace() # 获取所有可洗练的装备位
    for place in washPlaceList:
        washLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipWashLV % place) + 1
        valueList = []
        hasValue = False
        for attrNum in xrange(1, Operate_EquipWash.Def_EquipWashMaxAttrCount + 1):
            value = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipWashValue % (place, attrNum))
            if value:
                valueList.append(value)
                hasValue = True
        if hasValue:
            stoneInfoList.append({"Place":place, "LV":washLV, "Value":valueList})
    return stoneInfoList
def __GetEquipShowIDList(curPlayer):
    ## 获取外观装备ID列表
    equipShowIDList = []
    indexList = range(10) + PlayerControl.GetFaceEquipIndexList(curPlayer) # 暂写死前10个物品 + 展示的境界装备部位
    equipPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)
    for index in indexList:
        curEquip = equipPack.GetAt(index)
        if not curEquip or curEquip.IsEmpty():
            continue
        equipShowIDList.append(curEquip.GetItemTypeID())
    return equipShowIDList
## 灵宠信息
def __GetPetInfo(curPlayer):
@@ -252,7 +289,7 @@
def __GetGodWeaponInfo(curPlayer):
    godWeaponDict = {}
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    maxType = ipyDataMgr.GetGodWeaponByIndex(ipyDataMgr.GetGodWeaponCount()-1).GetType()
    maxType = ipyDataMgr.GetGodWeaponByIndex(ipyDataMgr.GetGodWeaponCount() - 1).GetType()
    for gwType in xrange(1, maxType + 1):
        gwLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GodWeaponLV % gwType)
        if gwLV:
@@ -261,16 +298,18 @@
## 符印信息
def __GetRuneInfo(curPlayer):
    runeDict = {}
    #runeDict = {}
    maxLV = 0
    runeHoleCnt = IpyGameDataPY.GetFuncCfg("RuneUnlock", 4)
    for holeNum in xrange(1, runeHoleCnt + 1):
        runeData = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Rune_Data % holeNum, 0)
        if not runeData:
            continue
        runeItemID = ItemControler.GetRuneItemID(runeData)
        #runeItemID = ItemControler.GetRuneItemID(runeData)
        runeItemPlusLV = ItemControler.GetRuneItemPlusLV(runeData)
        runeDict[holeNum] = [runeItemID, runeItemPlusLV]
    return len(runeDict)
        #runeDict[holeNum] = [runeItemID, runeItemPlusLV]
        maxLV += runeItemPlusLV
    return maxLV
## 法宝信息
def __GetMagicWeaponInfo(curPlayer):
@@ -284,65 +323,49 @@
            mwDict[treasureType] = mwDict.get(treasureType, 0) + 1
            
    return mwDict
## 获取玩家背包类型里的装备信息缓存列表
def __GetPackEquipCacheList(curPlayer, packType):
    equipPack = curPlayer.GetItemManager().GetPack(packType)
    itemList = []
    for index in xrange(equipPack.GetCount()):
        curEquip = equipPack.GetAt(index)
        if not curEquip or curEquip.IsEmpty():
            continue
        itemDict = {}
        itemDict["ItemIndex"] = curEquip.GetItemPlaceIndex()
        itemDict["ItemID"] = curEquip.GetItemTypeID()
        itemDict["IsBind"] = int(curEquip.GetIsBind())
        itemDict["IsSuite"] = int(curEquip.GetIsSuite())
        userData = curEquip.GetUserData()
        if userData and userData != "{}":
            itemDict["UserData"] = userData
        itemList.append(__RemoveEmptyDataKey(itemDict))
    return itemList
##//A2 12 查看玩家详细信息#tagCMViewPlayerInfo
#  @param curPlayer, tick
#  @return None
#//A2 12 查看玩家详细信息#tagCMViewPlayerInfo
#struct tagCMViewPlayerInfo
#{
#    tagHead        Head;
#    DWORD        PlayerID;
#    BYTE        EquipClassLV;    //大于0为查看指定境界阶装备信息,  0为查看默认信息
#};
def OnCMViewPlayerInfo(index, clientPack, tick):
    GameWorld.DebugLog('ViewCache### OnCMViewPlayerInfo in')
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    
    findPlayerID = clientPack.PlayerID
    equipClassLV = clientPack.EquipClassLV
    findPlayer = GameWorld.GetPlayerManager().FindPlayerByID(findPlayerID)
    if findPlayer:
        if equipClassLV:
            sendPack = ChPyNetSendPack.tagSCPlayerEquipCacheResult()
            sendPack.PlayerID = findPlayerID
            sendPack.EquipClassLV = equipClassLV
            sendPack.ItemData = __GetPlayerEquipClassDataCache(findPlayer, equipClassLV)
            sendPack.ItemDataSize = len(sendPack.ItemData)
            NetPackCommon.SendFakePack(curPlayer, sendPack)
            return
        #本地图玩家直接返回
        curPlayerPropData, curPlayerItemData, curPlayerPlusData = GetPlayerCache(findPlayer)
        #GameWorld.DebugLog("PropData=%s" % curPlayerPropData)
        #GameWorld.DebugLog("ItemData=%s" % curPlayerItemData)
        #GameWorld.DebugLog("PlusData=%s" % curPlayerPlusData)
        PropData, PlusData = GetPlayerPropPlusCache(findPlayer)
        sendPack = ChPyNetSendPack.tagSCQueryPlayerCacheResult()
        sendPack.PlayerID = findPlayerID
        sendPack.PropData = curPlayerPropData
        sendPack.PropDataSize = len( sendPack.PropData)
        sendPack.ItemData = curPlayerItemData
        sendPack.PropData = PropData
        sendPack.PropDataSize = len(sendPack.PropData)
        sendPack.ItemData = ""
        sendPack.ItemDataSize = len(sendPack.ItemData)
        sendPack.PlusData = curPlayerPlusData
        sendPack.PlusData = PlusData
        sendPack.PlusDataSize = len(sendPack.PlusData)
        GameWorld.DebugLog('ViewCache### OnCMViewPlayerInfo len: %s , sendPack: %s'%(sendPack.GetLength(),sendPack.OutputString()))
        #GameWorld.DebugLog('ViewCache### OnCMViewPlayerInfo len: %s , sendPack: %s' % (sendPack.GetLength(), sendPack.OutputString()))
        NetPackCommon.SendFakePack(curPlayer, sendPack)
        GameWorld.DebugLog('ViewCache### OnCMViewPlayerInfo Return MapPlayerInfo out')
        return
    #发送到GameServer去查询
    sendPack = ChMapToGamePyPack.tagMGQueryPlayerCache()
    sendPack.PlayerID = curPlayer.GetPlayerID()
    sendPack.FindPlayerID = findPlayerID
    sendPack.EquipClassLV = equipClassLV
    
    NetPackCommon.SendPyPackToGameServer(sendPack)  
    GameWorld.DebugLog('ViewCache### OnCMViewPlayerInfo SendToGameServer Query out')
    return