| #!/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 DBStruct  | 
| import ChMapToGamePyPack  | 
| import PlayerMagicWeapon  | 
| import Operate_EquipStone  | 
| import Operate_EquipWash  | 
| import PlayerAttrFruit  | 
| import ItemControler  | 
| import IpyGameDataPY  | 
| import PlayerHorse  | 
| import ChEquip  | 
| import ItemCommon  | 
| import PyGameData  | 
| import PlayerTJG  | 
| import SkillShell  | 
| import GameObj  | 
|   | 
| import base64  | 
| import time  | 
| import json  | 
|   | 
| TempDBPlayer = DBStruct.tagDBPlayer()  | 
|   | 
| Def_Process_Tick = "ProcessPlayerCache"  | 
|   | 
| def OnPlayerLogOut(curPlayer, tick):  | 
|     ##Íæ¼ÒÏÂÏßͬ²½  | 
|     UpdateGameServerPlayerCache(curPlayer, tick, True)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipViewCacheState, 0)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PackDataSyncState, 0)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PackDataSyncFightPower, 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  | 
|   | 
| def GetDBPlayerByPackData(packData):  | 
|     ## ¸ù¾Ý curPlayer.GetPackData() ´ò°ü·µ»ØµÄÊý¾Ý»ñÈ¡DBPlayerÊý¾Ý  | 
|     TempDBPlayer.clear()  | 
|     if packData:  | 
|         TempDBPlayer.readData(base64.b64decode(packData))  | 
|     return TempDBPlayer  | 
|   | 
| def GetSyncPlayerPackData(curPlayer, force=False):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     fightPower = curPlayer.GetFightPower()  | 
|       | 
|     if not force:  | 
|         syncState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncState)  | 
|         if not syncState:  | 
|             GameWorld.DebugLog("²»ÐèҪͬ²½´ò°üÊý¾Ý", playerID)  | 
|             return ""  | 
|         # ÖµÅжÏÇóÓಿ·Ö¼´¿É  | 
|         syncFightPower = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncFightPower)  | 
|         if syncFightPower == fightPower:  | 
|             GameWorld.DebugLog("Õ½Á¦²»±ä£¬²»ÐèҪͬ²½´ò°üÊý¾Ý! syncFightPower=%s" % syncFightPower, playerID)  | 
|             return ""  | 
|           | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PackDataSyncFightPower, fightPower)  | 
|     packData = curPlayer.GetPackData()  | 
|     #GameWorld.DebugLog("packData=%s %s %s" % (type(packData), len(packData), packData), playerID)  | 
|     return packData  | 
|   | 
| def UpdPackDataSyncState(curPlayer, msgData):  | 
|     ## ¸üдò°üÊý¾Ýͬ²½×´Ì¬£¬ÕâÀïÖ»¸üÐÂ״̬¼´¿É£¬¾ßÌåͬ²½Óɶ¨Ê±Í¬²½´¦Àí  | 
|     syncState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncState)  | 
|     updSyncState = syncState  | 
|     if msgData.get("PackData"):  | 
|         updSyncState = GameWorld.SetBitValue(updSyncState, 0, 1)  | 
|     if msgData.get("PackDataCross"):  | 
|         updSyncState = GameWorld.SetBitValue(updSyncState, 1, 1)  | 
|     if msgData.get("ViewCacheCross"):  | 
|         updSyncState = GameWorld.SetBitValue(updSyncState, 2, 1)  | 
|     if syncState == updSyncState:  | 
|         return  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PackDataSyncState, updSyncState)  | 
|     GameWorld.DebugLog("¸üдò°üÊý¾Ýͬ²½×´Ì¬: msgData=%s,syncState=%s,updSyncState=%s"   | 
|                        % (msgData, syncState, updSyncState), curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def SetPackDataSyncState(curPlayer): UpdPackDataSyncState(curPlayer, {"PackData":1})  | 
| def SetPackDataCrossSyncState(curPlayer): UpdPackDataSyncState(curPlayer, {"PackDataCross":1})  | 
| def SetViewCacheCrossSyncState(curPlayer): UpdPackDataSyncState(curPlayer, {"ViewCacheCross":1})  | 
|   | 
| def NormalSyncPackData(curPlayer):  | 
|     '''³£¹æÍ¬²½´ò°üÊý¾Ý£¬½ö×÷Ϊ²¹³äͬ²½Ó㬲»Ç¿ÖÆÍ¬²½  | 
|     Ò»°ãÓÉÐèÒª´ò°üÊý¾ÝµÄ¹¦ÄÜ·¢Æð¼ì²é×Ô¶¯Í¬²½Óã¬×öÕ½Á¦ÑéÖ¤£¬Õ½Á¦±ä¸üʱÖ÷¶¯Í¬²½Ò»´Î  | 
|     ·ÀÖ¹¶Ìʱ¼äÄÚÇ¿»¯ÁËÕ½Á¦£¬µ¼Ö¾µÏñÊý¾Ý²îÒìÌ«´ó£¬Ó°Ïì¾µÏñÕ½¶·½á¹û  | 
|     '''  | 
|       | 
|     syncFightPower = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncFightPower)  | 
|     if PlayerControl.GetFightPower(curPlayer) == syncFightPower:  | 
|         GameWorld.DebugLog("Õ½Á¦Óë´ò°üÊý¾ÝÏàͬ£¬²»Í¬²½!", curPlayer.GetPlayerID())  | 
|         return  | 
|     GameWorld.DebugLog("Õ½Á¦Óë´ò°üÊý¾Ý²»Í¬£¬Á¢¼´Í¬²½!", curPlayer.GetPlayerID())  | 
|       | 
|     syncState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncState)  | 
|     if not syncState:  | 
|         SetPackDataSyncState(curPlayer)  | 
|         SetPackDataCrossSyncState(curPlayer)  | 
|           | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     UpdateGameServerPlayerCache(curPlayer, tick)  | 
|     return  | 
|   | 
| ##¸üÐÂÍæ¼Òµ±Ç°ÏêϸÐÅÏ¢µ½GameServer  | 
| #  @param curPlayer, tick  | 
| #  @return None  | 
| def UpdateGameServerPlayerCache(curPlayer, tick, IsLogouting=False, forcePackData=False, packMsg=None, isOnlyViewCache=False):  | 
|     if PlayerTJG.GetIsTJG(curPlayer):  | 
|         # ÍÑ»ú²»´¦Àí  | 
|         return  | 
|     curPlayer.SetDict(Def_Process_Tick, tick)  | 
|     PackDataSyncState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncState)  | 
|     isAllEquip = False  | 
|     # ÐèҪͬ²½¿ç·þ»º´æ ÇÒ »¹Ã»Í¬²½×°±¸µÄ  | 
|     if PackDataSyncState&pow(2, 2) and curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipViewCacheState) != 2:  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipViewCacheState, 2)  | 
|         isAllEquip = True  | 
|         GameWorld.DebugLog("±¾´ÎµÇ¼Ê×´Îͬ²½¿ç·þ»º´æ£¬È«×°±¸Í¬²½", curPlayer.GetPlayerID())  | 
|           | 
|     if forcePackData:  | 
|         SetPackDataSyncState(curPlayer)  | 
|         SetPackDataCrossSyncState(curPlayer)  | 
|         PackDataSyncState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncState)  | 
|           | 
|     #»ñÈ¡µ±Ç°Íæ¼Ò»º´æÊý¾Ý  | 
|     PropData, PlusData = GetPlayerPropPlusCache(curPlayer)  | 
|     itemDataDict = __GetPlayerItemDataCache(curPlayer, isAllEquip)  | 
|       | 
|     #ͬ²½·¢Ë͵½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))  | 
|     # ´ò°üÊý¾ÝÏà¹Ø  | 
|     sendPack.PackDataSyncState = PackDataSyncState  | 
|     sendPack.PackData = "" if isOnlyViewCache else GetSyncPlayerPackData(curPlayer, forcePackData)  | 
|     sendPack.PackDataLen = len(sendPack.PackData)  | 
|     sendPack.PackMsg = str(packMsg) if packMsg else "{}"  | 
|     sendPack.PackMsgLen = len(sendPack.PackMsg)  | 
|     GameWorld.DebugLog("ͬ²½»º´æ: logout=%s,forcePackData=%s,isOnlyViewCache=%s,PackDataSyncState=%s,isAllEquip=%s,classList=%s"   | 
|                        % (IsLogouting, forcePackData, isOnlyViewCache, PackDataSyncState, isAllEquip, itemDataDict.keys()), curPlayer.GetPlayerID())  | 
|     NetPackCommon.SendPyPackToGameServer(sendPack)  | 
|     return  | 
|   | 
| def __GetPlayerItemDataCache(curPlayer, isAllEquip=False):  | 
|     ## ×°±¸¼°×°±¸Î»Ñø³É»º´æ£¬ÓÉÓÚ×°±¸Î»±È½Ï¶à£¬ËùÒÔ°´½×ͬ²½£¬ÖصǵÚÒ»´Îͬ²½ËùÓÐ½×  | 
|     if not isAllEquip and not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipViewCacheState):  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipViewCacheState, 1)  | 
|         isAllEquip = True  | 
|           | 
|     if isAllEquip:  | 
|         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.GetEquipPartPlusLV(curPlayer, packType, index)  | 
|         equipPartPlusEvolveLV = ChEquip.GetEquipPartPlusEvolveLV(curPlayer, packType, index)  | 
|         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["VIPLV"] = curPlayer.GetVIPLv()  | 
|     curPlayerPropDict["Name"] = curPlayer.GetPlayerName()  | 
|     curPlayerPropDict["Face"] = curPlayer.GetFace()  | 
|     curPlayerPropDict["FacePic"] = curPlayer.GetFacePic()  | 
|     curPlayerPropDict["FamilyID"] = curPlayer.GetFamilyID()  | 
|     curPlayerPropDict["FamilyName"] = curPlayer.GetFamilyName()  | 
|     curPlayerPropDict["FamilyEmblemID"] = PlayerControl.GetFamilyEmblemID(curPlayer)  | 
|     curPlayerPropDict["TitleID"] = PlayerControl.GetTitleID(curPlayer)  | 
|     curPlayerPropDict["CoupleName"] = PlayerControl.GetCoupleName(curPlayer)  | 
|     curPlayerPropDict["FightPower"] = PlayerControl.GetFightPower(curPlayer)  | 
|     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()  | 
|     curPlayerPropDict["Def"] = curPlayer.GetDef()  | 
|     curPlayerPropDict["MaxHP"] = GameObj.GetMaxHP(curPlayer)  | 
|     curPlayerPropDict["Hit"] = curPlayer.GetHit()  | 
|     curPlayerPropDict["Miss"] = curPlayer.GetMiss()  | 
|     curPlayerPropDict["SkillAtkRate"] = curPlayer.GetSkillAtkRate() # ¼¼Äܹ¥»÷±ÈÀý¼Ó³É  | 
|     curPlayerPropDict["SkillAtkRateReduce"] = PlayerControl.GetSkillAtkRateReduce(curPlayer) # ¼¼Äܹ¥»÷±ÈÀý¼õÉÙ  | 
|     curPlayerPropDict["LuckyHitRate"] = curPlayer.GetLuckyHitRate() # »áÐÄÒ»»÷¼¸ÂÊ  | 
|     curPlayerPropDict["LuckyHitVal"] = curPlayer.GetLuckyHitVal() # »áÐÄÒ»»÷É˺¦¹Ì¶¨Öµ  | 
|     curPlayerPropDict["LuckyHitRateReduce"] = PlayerControl.GetLuckyHitRateReduce(curPlayer) # »áÐÄÒ»»÷¸ÅÂÊ¿¹ÐÔ  | 
|     curPlayerPropDict["LuckyHitReduce"] = PlayerControl.GetLuckyHitReduce(curPlayer) # »áÐÄÒ»»÷É˺¦¼õÃâ¹Ì¶¨Öµ  | 
|     curPlayerPropDict["SuperHitRate"] = curPlayer.GetSuperHitRate() # ±©»÷¸ÅÂÊ  | 
|     curPlayerPropDict["SuperHit"] = curPlayer.GetSuperHit() # ±©»÷É˺¦¹Ì¶¨Öµ  | 
|     curPlayerPropDict["SuperHitRateReduce"] = PlayerControl.GetSuperHitRateReduce(curPlayer) # ±©»÷¸ÅÂÊ¿¹ÐÔ  | 
|     curPlayerPropDict["SuperHitReduce"] = PlayerControl.GetSuperHitReduce(curPlayer) # ±©»÷É˺¦¿¹ÐԹ̶¨Öµ  | 
|     curPlayerPropDict["IceAtk"] = curPlayer.GetIceAtk() # ÕæÊµÉ˺¦            ¹Ì¶¨Öµ  | 
|     curPlayerPropDict["IceDef"] = curPlayer.GetIceDef() # ÕæÊµÉ˺¦·ÀÓù        ¹Ì¶¨Öµ  | 
|     curPlayerPropDict["IgnoreDefRate"] = curPlayer.GetIgnoreDefRate() # ÎÞÊÓ·ÀÓù¼¸ÂÊ  | 
|     curPlayerPropDict["IgnoreDefRateReduce"] = PlayerControl.GetIgnoreDefRateReduce(curPlayer) # ÎÞÊÓ·ÀÓù¸ÅÂÊ¿¹ÐÔ  | 
|     curPlayerPropDict["IgnoreDefReducePer"] = PlayerControl.GetIgnoreDefReducePer(curPlayer) # ÎÞÊÓ·ÀÓùÉ˺¦¼õÃâ  | 
|     curPlayerPropDict["DamagePVE"] = PlayerControl.GetDamagePVE(curPlayer) # É˺¦Êä³ö¼ÆËã¹Ì¶¨ÖµPVE  | 
|     curPlayerPropDict["DamagePerPVP"] = PlayerControl.GetDamagePerPVP(curPlayer) # É˺¦Êä³ö¼ÆËã°Ù·Ö±ÈPVP  | 
|     curPlayerPropDict["DamagePerPVPReduce"] = PlayerControl.GetDamagePerPVPReduce(curPlayer) # É˺¦Êä³ö¼ÆËã°Ù·Ö±ÈPVP¼õÉÙ  | 
|     curPlayerPropDict["DamagePVP"] = PlayerControl.GetDamagePVP(curPlayer) # PVP¹Ì¶¨É˺¦  | 
|     curPlayerPropDict["DamagePVPReduce"] = PlayerControl.GetDamagePVPReduce(curPlayer) # PVP¹Ì¶¨¼õÉË  | 
|     curPlayerPropDict["FinalHurt"] = PlayerControl.GetFinalHurt(curPlayer) # ×îÖչ̶¨É˺¦Ôö¼Ó  | 
|     curPlayerPropDict["FinalHurtReduce"] = PlayerControl.GetFinalHurtReduce(curPlayer) # ×îÖչ̶¨É˺¦¼õÉÙ  | 
|     curPlayerPropDict["FinalHurtPer"] = PlayerControl.GetFinalHurtPer(curPlayer) # ×îÖÕÉ˺¦°Ù·Ö±È  | 
|     curPlayerPropDict["FinalHurtReducePer"] = PlayerControl.GetFinalHurtReducePer(curPlayer) # ×îÖÕÉ˺¦¼õÉÙ°Ù·Ö±È  | 
|     curPlayerPropDict["OnlyFinalHurt"] = PlayerControl.GetOnlyFinalHurt(curPlayer) # ¶îÍâÊä³öÉ˺¦  | 
|     curPlayerPropDict["DamChanceDef"] = PlayerControl.GetDamChanceDef(curPlayer) # 20%µÄ¸ÅÂʵÖÓùÉ˺¦±ÈÂÊ  | 
|     curPlayerPropDict["NPCHurtAddPer"] = PlayerControl.GetNPCHurtAddPer(curPlayer) # ¶Ô¹ÖÎïÉ˺¦¼Ó³É  | 
|     curPlayerPropDict["AtkBackHPPer"] = PlayerControl.GetAtkBackHPPer(curPlayer) # ¹¥»÷»Ø¸´ÑªÁ¿¹Ì¶¨Öµ  | 
|     curPlayerPropDict["PVPAtkBackHP"] = PlayerControl.GetPVPAtkBackHP(curPlayer) # PVP¹¥»÷»ØÑª  | 
|     curPlayerPropDict["FaintRate"] = PlayerControl.GetFaintRate(curPlayer) # ´¥·¢»÷ÔÎ  | 
|     curPlayerPropDict["FaintDefRate"] = PlayerControl.GetFaintDefRate(curPlayer) # »÷Ôεֿ¹  | 
|       | 
|     #-----------  | 
|     #À©Õ¹ÊôÐÔ»º´æ  | 
|     curPlayerPlusDict = {}  | 
|       | 
|     #¸÷Ä£¿éÕ½Á¦  | 
|     fightPowerDict = {}  | 
|     for mfpType in ShareDefine.ModuleFightPowerTypeList:  | 
|         fightPower = PlayerControl.GetMFPFightPower(curPlayer, mfpType)  | 
|         if fightPower:  | 
|             fightPowerDict["%s" % mfpType] = fightPower  | 
|     curPlayerPlusDict["FightPowerDict"] = fightPowerDict  | 
|       | 
|     #×°±¸»ã×ÜÐÅÏ¢  | 
|     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)  | 
|       | 
|     #×øÆïÊý¾Ý  | 
|     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):  | 
|     skinEndTimeInfo = {}  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for index in xrange(ipyDataMgr.GetHorseSkinPlusCount()):  | 
|         skinPlusIpyData = ipyDataMgr.GetHorseSkinPlusByIndex(index)  | 
|         skinID = skinPlusIpyData.GetID()  | 
|         if not skinPlusIpyData.GetSkinValidTime():  | 
|             continue  | 
|         skinEndTimeInfo[skinID] = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserSkinEndTime % skinID)  | 
|     horseInfo = {"LV":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserLV),  | 
|                  "EatItemCount":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserEatItemCount),  | 
|                  "SkinPlusStateList":PlayerHorse.GetHorseSkinPlusStateList(curPlayer),  | 
|                  "SkinEndTimeInfo":skinEndTimeInfo,  | 
|                  }  | 
|     return horseInfo  | 
|   | 
| ## ÉñÆ÷ÐÅÏ¢  | 
| 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 = {}  | 
|     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)  | 
|         runeItemPlusLV = ItemControler.GetRuneItemPlusLV(runeData)  | 
|         #runeDict[holeNum] = [runeItemID, runeItemPlusLV]  | 
|         maxLV += runeItemPlusLV  | 
|     return maxLV  | 
|   | 
| ## ·¨±¦ÐÅÏ¢  | 
| 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(findPlayer, equipClassLV)  | 
|             sendPack.ItemDataSize = len(sendPack.ItemData)  | 
|             NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|             return  | 
|           | 
|         #±¾µØÍ¼Íæ¼ÒÖ±½Ó·µ»Ø  | 
|         PropData, PlusData = GetPlayerPropPlusCache(findPlayer)  | 
|         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  | 
|   |