| #!/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 ItemCommon  | 
| import PyGameData  | 
| import PlayerTJG  | 
|   | 
| import time  | 
| import json  | 
|   | 
| Def_Process_Tick = "ProcessPlayerCache"  | 
|   | 
| def OnPlayerLogOut(curPlayer, tick):  | 
|     ##Íæ¼ÒÏÂÏßͬ²½  | 
|     UpdateGameServerPlayerCache(curPlayer, tick, True)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipViewCacheState, 0)  | 
|     return  | 
|   | 
| def ProcessCache(curPlayer, tick):  | 
|     ##Íæ¼ÒÔÚÏß¶¨Ê±Í¬²½  | 
|     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):  | 
|     if PlayerTJG.GetIsTJG(curPlayer):  | 
|         # ÍÑ»ú²»´¦Àí  | 
|         return  | 
|     curPlayer.SetDict(Def_Process_Tick, tick)  | 
|     #»ñÈ¡µ±Ç°Íæ¼Ò»º´æÊý¾Ý  | 
|     PropData, PlusData = GetPlayerPropPlusCache(curPlayer)  | 
|     itemDataDict = __GetPlayerItemDataCache(curPlayer)  | 
|       | 
|     #ͬ²½·¢Ë͵½GameServer  | 
|     sendPack = ChMapToGamePyPack.tagMGUpdatePlayerCache()  | 
|     sendPack.PlayerID = curPlayer.GetPlayerID()  | 
|     sendPack.PlayerLV = curPlayer.GetLV()  | 
|     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)  | 
|     return  | 
|   | 
| 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) + 1  | 
|         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["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["EquipShowID"] = __GetEquipShowIDList(curPlayer)  | 
|     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)  | 
|       | 
|     #-----------  | 
|     #À©Õ¹ÊôÐÔ»º´æ  | 
|     curPlayerPlusDict = {}  | 
|       | 
|     #¸÷Ä£¿éÕ½Á¦  | 
|     fightPowerDict = {}  | 
|     for mfpType in ShareDefine.ModuleFightPowerTypeList:  | 
|         fightPower = PlayerControl.GetMFPFightPower(curPlayer, mfpType)  | 
|         if fightPower:  | 
|             fightPowerDict["%s" % mfpType] = fightPower  | 
|     curPlayerPlusDict["FightPowerDict"] = fightPowerDict  | 
|       | 
|     #Áé³èÊý¾Ý  | 
|     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)  | 
|       | 
|     PropData = json.dumps(curPlayerPropDict, ensure_ascii=False).replace(" ", "")  | 
|     PlusData = json.dumps(curPlayerPlusDict, ensure_ascii=False).replace(" ", "")  | 
|     return PropData, PlusData  | 
|   | 
| 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):  | 
|     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  | 
|   | 
| #//A2 12 ²é¿´Íæ¼ÒÏêϸÐÅÏ¢#tagCMViewPlayerInfo  | 
| #struct tagCMViewPlayerInfo  | 
| #{  | 
| #    tagHead        Head;  | 
| #    DWORD        PlayerID;  | 
| #    BYTE        EquipClassLV;    //´óÓÚ0Ϊ²é¿´Ö¸¶¨¾³½ç½××°±¸ÐÅÏ¢,  0Ϊ²é¿´Ä¬ÈÏÐÅÏ¢  | 
| #};  | 
| def OnCMViewPlayerInfo(index, clientPack, tick):  | 
|     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(curPlayer, equipClassLV)  | 
|             sendPack.ItemDataSize = len(sendPack.ItemData)  | 
|             NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|             return  | 
|           | 
|         #±¾µØÍ¼Íæ¼ÒÖ±½Ó·µ»Ø  | 
|         PropData, PlusData = GetPlayerPropPlusCache(curPlayer)  | 
|         sendPack = ChPyNetSendPack.tagSCQueryPlayerCacheResult()  | 
|         sendPack.PlayerID = findPlayerID  | 
|         sendPack.PropData = PropData  | 
|         sendPack.PropDataSize = len(sendPack.PropData)  | 
|         sendPack.ItemData = ""  | 
|         sendPack.ItemDataSize = len(sendPack.ItemData)  | 
|         sendPack.PlusData = PlusData  | 
|         sendPack.PlusDataSize = len(sendPack.PlusData)  | 
|         #GameWorld.DebugLog('ViewCache### OnCMViewPlayerInfo len: %s , sendPack: %s' % (sendPack.GetLength(), sendPack.OutputString()))  | 
|         NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|         return  | 
|     #·¢Ë͵½GameServerÈ¥²éѯ  | 
|     sendPack = ChMapToGamePyPack.tagMGQueryPlayerCache()  | 
|     sendPack.PlayerID = curPlayer.GetPlayerID()  | 
|     sendPack.FindPlayerID = findPlayerID  | 
|     sendPack.EquipClassLV = equipClassLV  | 
|       | 
|     NetPackCommon.SendPyPackToGameServer(sendPack)    | 
|     return  | 
|   |