#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#  
 | 
#  
 | 
##@package PlayerViewCacheTube.py  
 | 
#  
 | 
# @todo:Íæ¼ÒÊý¾Ý»º´æ µØÍ¼·þÎñÆ÷´¦ÀíÄ£¿é  
 | 
#  
 | 
# @author xmnathan  
 | 
# @date 2010-01-01 21:30  
 | 
# @version 1.0  
 | 
# @note:  
 | 
#------------------------------------------------------------------------------   
 | 
#"""Version = 2017-11-27 22:30"""  
 | 
#------------------------------------------------------------------------------   
 | 
import ChConfig  
 | 
import GameWorld  
 | 
import ShareDefine  
 | 
import NetPackCommon  
 | 
import PlayerControl  
 | 
import IPY_GameWorld  
 | 
import ChPyNetSendPack  
 | 
import ChMapToGamePyPack  
 | 
import PlayerMagicWeapon  
 | 
import Operate_EquipStone  
 | 
import Operate_EquipWash  
 | 
import PlayerAttrFruit  
 | 
import ItemControler  
 | 
import IpyGameDataPY  
 | 
import ChEquip  
 | 
import FBCommon  
 | 
import BossHurtMng  
 | 
  
 | 
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)     
 | 
      
 | 
    return  
 | 
  
 | 
##Íæ¼ÒÔÚÏß¶¨Ê±Í¬²½  
 | 
#  @param curPlayer, tick  
 | 
#  @return None  
 | 
def ProcessCache(curPlayer, tick):  
 | 
    if tick - curPlayer.GetDictByKey(Def_Process_Tick) > 5*60*1000:  
 | 
        UpdateGameServerPlayerCache(curPlayer, tick, False)    
 | 
        curPlayer.SetDict(Def_Process_Tick, tick)  
 | 
    return  
 | 
  
 | 
##¸üÐÂÍæ¼Òµ±Ç°ÏêϸÐÅÏ¢µ½GameServer  
 | 
#  @param curPlayer, tick  
 | 
#  @return None  
 | 
def UpdateGameServerPlayerCache(curPlayer, tick, IsLogouting = False):  
 | 
    GameWorld.DebugLog('ViewCache### UpdateGameServerPlayerCache in')  
 | 
    #»ñÈ¡µ±Ç°Íæ¼Ò»º´æÊý¾Ý  
 | 
    curPlayerPropData, curPlayerItemData, curPlayerPlusData = GetPlayerCache(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())    # ×îºóÒ»´Î·¢Ëͼ´µ±×öÀëÏßʱ¼ä  
 | 
    NetPackCommon.SendPyPackToGameServer(sendPack)  
 | 
    GameWorld.DebugLog('ViewCache### UpdateGameServerPlayerCache out')  
 | 
    return  
 | 
  
 | 
## »ñÈ¡Íæ¼ÒÊý¾Ý»º´æ  
 | 
#  @param curPlayer  
 | 
#  @return None  
 | 
def GetPlayerCache(curPlayer):  
 | 
    #-----------  
 | 
    #Íæ¼ÒÊôÐÔ»º´æ  
 | 
    curPlayerPropDict = {}  
 | 
    curPlayerPropDict["AccID"] = curPlayer.GetAccID()  
 | 
    curPlayerPropDict["LV"] = curPlayer.GetLV()  
 | 
    curPlayerPropDict["RealmLV"] = curPlayer.GetOfficialRank()  
 | 
    curPlayerPropDict["Job"] = curPlayer.GetJob()  
 | 
    curPlayerPropDict["VIPLV"] = curPlayer.GetVIPLv()  
 | 
    curPlayerPropDict["Name"] = curPlayer.GetPlayerName()  
 | 
    curPlayerPropDict["FamilyID"] = curPlayer.GetFamilyID()  
 | 
    curPlayerPropDict["FamilyName"] = curPlayer.GetFamilyName()  
 | 
    curPlayerPropDict["FightPower"] = curPlayer.GetFightPower()  
 | 
    curPlayerPropDict["AppID"] = GameWorld.GetPlayerPlatform(curPlayer)  
 | 
    curPlayerPropDict["EquipShowSwitch"] = curPlayer.GetEquipShowSwitch()  
 | 
    curPlayerPropDict["ServerGroupID"] = PlayerControl.GetPlayerServerGroupID(curPlayer)  
 | 
    #ÏÉħ֮ÕùËùÐèÊôÐÔ  
 | 
    curPlayerPropDict["MinAtk"] = curPlayer.GetMinAtk()  
 | 
    curPlayerPropDict["MaxAtk"] = curPlayer.GetMaxAtk()  
 | 
    curPlayerPropDict["Def"] = curPlayer.GetDef()  
 | 
    curPlayerPropDict["MaxHP"] = curPlayer.GetMaxHP()  
 | 
    #ÍÆËÍÌáÐÑ  
 | 
    curPlayerPropDict[ChConfig.Def_PDict_GeTuiSet] = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GeTuiSet)  
 | 
    curPlayerPropDict[ChConfig.Def_PDict_NoGeTuiTime] = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NoGeTuiTime)  
 | 
      
 | 
    # ¸÷À๦ÄÜ BOSS´ÎÊý, BOSSÏà¹Ø¶ÔÓ¦B.BossÐÅÏ¢.xlsxµÄCntMark  
 | 
    # ·âħ̳ʣÓà´ÎÊý  
 | 
    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)  
 | 
    # ÖïÏÉ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)  
 | 
    # ÊÀ½çBOSSÊ£Óà´ÎÊý  
 | 
    curPlayerPropDict['CntMark_%s'%ShareDefine.Def_Boss_Func_World] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_World)  
 | 
    # BOSSÖ®¼ÒÊ£Óà´ÎÊý  
 | 
    curPlayerPropDict['CntMark_%s'%ShareDefine.Def_Boss_Func_Home] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_Home)  
 | 
    # ÉñÊÞBOSSÊ£Óà´ÎÊý  
 | 
    curPlayerPropDict['CntMark_%s'%ShareDefine.Def_Boss_Func_Dogz] = BossHurtMng.GetCanKillBossCnt(curPlayer, ShareDefine.Def_Boss_Func_Dogz)  
 | 
  
 | 
    #-----------  
 | 
    #×°±¸Êý¾Ý´ò°ü»º´æ  
 | 
    curEquipItemList = __GetPackEquipCacheList(curPlayer, IPY_GameWorld.rptEquip)  
 | 
    #-----------  
 | 
    #À©Õ¹ÊôÐÔ»º´æ  
 | 
    curPlayerPlusDict = {}  
 | 
      
 | 
    #¸÷Ä£¿éÕ½Á¦  
 | 
    fightPowerDict = {}  
 | 
    for mfpType in ShareDefine.ModuleFightPowerTypeList:  
 | 
        fightPower = PlayerControl.GetMFPFightPower(curPlayer, mfpType)  
 | 
        if fightPower:  
 | 
            fightPowerDict["%s" % mfpType] = fightPower  
 | 
    curPlayerPlusDict["FightPowerDict"] = fightPowerDict  
 | 
      
 | 
    #³á°òÐÅÏ¢ÔÚ³á°ò×°±¸Î»¶ÔӦװ±¸ÐÅÏ¢  
 | 
      
 | 
    #²¿Î»Ç¿»¯Êý¾Ý  
 | 
    curPlayerPlusDict["EquipPartStarLV"] = __GetEquipPartPlusLVInfo(curPlayer)  
 | 
      
 | 
    #²¿Î»±¦Ê¯Êý¾Ý  
 | 
    curPlayerPlusDict["EquipPartStone"] = __GetEquipPartStoneInfo(curPlayer)  
 | 
      
 | 
    #²¿Î»Ï´Á·Êý¾Ý  
 | 
    curPlayerPlusDict["EquipWash"] = __GetEquipWashInfo(curPlayer)  
 | 
      
 | 
    #Áé³èÊý¾Ý  
 | 
    curPlayerPlusDict["Pet"] = __GetPetInfo(curPlayer)  
 | 
      
 | 
    #×øÆïÊý¾Ý  
 | 
    curPlayerPlusDict["Horse"] = __GetHorseInfo(curPlayer)  
 | 
      
 | 
    #ÉñÆ÷Êý¾Ý  
 | 
    curPlayerPlusDict["GodWeapon"] = __GetGodWeaponInfo(curPlayer)  
 | 
      
 | 
    #·ûÓ¡Êý¾Ý  
 | 
    curPlayerPlusDict["Rune"] = __GetRuneInfo(curPlayer)  
 | 
      
 | 
    #·¨±¦Êý¾Ý  
 | 
    curPlayerPlusDict["MagicWeapon"] = __GetMagicWeaponInfo(curPlayer)  
 | 
      
 | 
    #»êʯ¡¢µ¤Ò©Ê¹ÓøöÊý  
 | 
    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)  
 | 
  
 | 
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 __GetPetInfo(curPlayer):  
 | 
    petInfo = {}  
 | 
    petClassLVList = []  
 | 
    equipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptPet)  
 | 
    for index in xrange(equipPack.GetCount()):  
 | 
        packItem = equipPack.GetAt(index)  
 | 
        if not packItem or packItem.IsEmpty():  
 | 
            continue  
 | 
        petNPCID = packItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  
 | 
        classLV = packItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)  
 | 
        petClassLVList.append({"id":petNPCID, 'lv':classLV})  
 | 
          
 | 
    petInfo["PetLV"] = petClassLVList  
 | 
    petInfo["AtkSpeed"] = PlayerControl.GetAtkSpeed(curPlayer)  
 | 
    return petInfo  
 | 
  
 | 
## ×øÆïÐÅÏ¢  
 | 
def __GetHorseInfo(curPlayer):  
 | 
    horseList = []  
 | 
    ipyDataMgr = IpyGameDataPY.IPY_Data()  
 | 
    for i in xrange(ipyDataMgr.GetHorseCount()):  
 | 
        ipyData = ipyDataMgr.GetHorseByIndex(i)  
 | 
        horseID = ipyData.GetHorseID()  
 | 
        horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID, 0, ChConfig.Def_PDictType_Horse)  
 | 
        if horseLV:  
 | 
            horseList.append({"id":horseID, 'lv':horseLV})  
 | 
    return horseList  
 | 
  
 | 
## ÉñÆ÷ÐÅÏ¢  
 | 
def __GetGodWeaponInfo(curPlayer):  
 | 
    godWeaponDict = {}  
 | 
    ipyDataMgr = IpyGameDataPY.IPY_Data()  
 | 
    maxType = ipyDataMgr.GetGodWeaponByIndex(ipyDataMgr.GetGodWeaponCount()-1).GetType()  
 | 
    for gwType in xrange(1, maxType + 1):  
 | 
        gwLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GodWeaponLV % gwType)  
 | 
        if gwLV:  
 | 
            godWeaponDict[gwType] = gwLV  
 | 
    return godWeaponDict  
 | 
  
 | 
## ·ûÓ¡ÐÅÏ¢  
 | 
def __GetRuneInfo(curPlayer):  
 | 
    runeDict = {}  
 | 
    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)  
 | 
        runeItemPlusLV = ItemControler.GetRuneItemPlusLV(runeData)  
 | 
        runeDict[holeNum] = [runeItemID, runeItemPlusLV]  
 | 
    return len(runeDict)  
 | 
  
 | 
## ·¨±¦ÐÅÏ¢  
 | 
def __GetMagicWeaponInfo(curPlayer):  
 | 
    mwDict = {}  
 | 
    ipyDataMgr = IpyGameDataPY.IPY_Data()  
 | 
    for i in xrange(ipyDataMgr.GetTreasureCount()):  
 | 
        treasureIpyData = ipyDataMgr.GetTreasureByIndex(i)  
 | 
        magicWeaponID = treasureIpyData.GetID()  
 | 
        treasureType = treasureIpyData.GetTreasureType()  
 | 
        if PlayerMagicWeapon.GetIsActiveMagicWeapon(curPlayer, magicWeaponID):  
 | 
            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["IsAuctionItem"] = int(ItemControler.GetIsAuctionItem(curEquip))  
 | 
        #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  
 | 
def OnCMViewPlayerInfo(index, clientPack, tick):  
 | 
    GameWorld.DebugLog('ViewCache### OnCMViewPlayerInfo in')  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
      
 | 
    findPlayerID = clientPack.PlayerID  
 | 
    findPlayer = GameWorld.GetPlayerManager().FindPlayerByID(findPlayerID)  
 | 
    if findPlayer:  
 | 
        #±¾µØÍ¼Íæ¼ÒÖ±½Ó·µ»Ø  
 | 
        curPlayerPropData, curPlayerItemData, curPlayerPlusData = GetPlayerCache(findPlayer)  
 | 
        #GameWorld.DebugLog("PropData=%s" % curPlayerPropData)  
 | 
        #GameWorld.DebugLog("ItemData=%s" % curPlayerItemData)  
 | 
        #GameWorld.DebugLog("PlusData=%s" % curPlayerPlusData)  
 | 
        sendPack = ChPyNetSendPack.tagSCQueryPlayerCacheResult()  
 | 
        sendPack.PlayerID = findPlayerID  
 | 
        sendPack.PropData = curPlayerPropData  
 | 
        sendPack.PropDataSize = len( sendPack.PropData)  
 | 
        sendPack.ItemData = curPlayerItemData  
 | 
        sendPack.ItemDataSize = len(sendPack.ItemData)  
 | 
        sendPack.PlusData = curPlayerPlusData  
 | 
        sendPack.PlusDataSize = len(sendPack.PlusData)  
 | 
          
 | 
        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  
 | 
      
 | 
    NetPackCommon.SendPyPackToGameServer(sendPack)    
 | 
    GameWorld.DebugLog('ViewCache### OnCMViewPlayerInfo SendToGameServer Query out')  
 | 
    return  
 | 
  
 | 
  
 | 
  
 | 
  
 | 
  
 |