| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #  | 
| #  | 
| ##@package PlayerViewCache.py  | 
| #  | 
| # @todo:Íæ¼ÒÊý¾Ý»º´æ  | 
| #  | 
| # @author NathanShaw  | 
| # @date 2010-01-01 21:30  | 
| # @version 1.3  | 
| # @note:  | 
| #  | 
| # @change: "2014-11-05 11:20" xmnathan Íæ¼ÒÊý¾Ý»º´æ¹ÜÀí  | 
| # @change: "2014-12-09 17:30" xmnathan Íæ¼ÒÊý¾Ý»º´æ  | 
| # @change: "2016-05-18 16:00" hxp Õ½ÃËÓйÙÔ±³ÉÔ±»º´æ²»Çå³ý  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2016-05-18 16:00"""  | 
| #---------------------------------------------------------------------  | 
|   | 
| import GameWorld  | 
| import PlayerControl  | 
| import NetPackCommon  | 
| import GameWorldArena  | 
| import ChPyNetSendPack  | 
| import ChGameToMapPyPack  | 
| import PlayerFBHelpBattle  | 
| import GameWorldSkyTower  | 
| import CrossChampionship  | 
| import CrossBattlefield  | 
| import PyGameDataStruct  | 
| import IpyGameDataPY  | 
| import PyDataManager  | 
| import ShareDefine  | 
| import ChConfig  | 
|   | 
| import json  | 
| import time  | 
|   | 
| def DoOnDayEx():  | 
|     DelOutofTimeViewCacheData()  | 
|     return  | 
|   | 
| def IsSaveDBViewCache(playerID, playerLV):  | 
|     ## ÊÇ·ñ±£´æ»ù±¾µÄ»º´æÊý¾Ý  | 
|     if PlayerFBHelpBattle.IsInHelpBattleCheckInList(playerID):  | 
|         return True  | 
|       | 
|     if GameWorldArena.IsArenaBattlePlayer(playerID):  | 
|         return True  | 
|       | 
|     if CrossBattlefield.IsBattlefieldCallPlayer(playerID):  | 
|         return True  | 
|       | 
|     if CrossChampionship.IsChampionshipPlayer(playerID):  | 
|         return True  | 
|       | 
|     if GameWorldSkyTower.IsSkyTowerPassPlayer(playerID):  | 
|         return True  | 
|       | 
|     SaveDBLimitLV = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 1)  | 
|     #УÑéÍæ¼ÒµÈ¼¶  | 
|     if playerLV < SaveDBLimitLV:  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
| def IsSaveAllViewCache(playerID):  | 
|     ## ÊÇ·ñ±£´æËùÓлº´æÊý¾Ý  | 
|       | 
|     if PlayerFBHelpBattle.IsInHelpBattleCheckInList(playerID):  | 
|         return True  | 
|       | 
|     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()  | 
|     for BillBoardType in NeedCheckBillBoardType:  | 
|         curBillboard = billboardMgr.FindBillboard(BillBoardType)  | 
|         if not curBillboard:  | 
|             continue  | 
|         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 = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 3) * 3600 * 24  | 
|       | 
|     pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()  | 
|     playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict  | 
|     for playerID, viewCache in playerViewCachePyDict.items():  | 
|           | 
|         passTime = curTime - viewCache.OffTime  | 
|         if passTime < MaxTime:  | 
|             continue  | 
|         if IsSaveAllViewCache(playerID):  | 
|             continue  | 
|         playerViewCachePyDict.pop(playerID)  | 
|           | 
|     return  | 
|   | 
| def DeleteViewCache(playerID):  | 
|     ## É¾³ýÍæ¼Ò»º´æ  | 
|     pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()  | 
|     playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict  | 
|     playerViewCachePyDict.pop(playerID, None)  | 
|     GameWorld.DebugLog("ɾ³ý²é¿´»º´æ!", playerID)  | 
|     return  | 
|   | 
| 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:  | 
|         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 hasattr(curCache, "PropDataDict"):  | 
|         curCache.PropDataDict = {}  | 
|     if not curCache.PropDataDict and curCache.PropData:  | 
|         curCache.PropDataDict = eval(curCache.PropData)  | 
|     return curCache.PropDataDict  | 
|   | 
| #//04 01 µØÍ¼Í¬²½Íæ¼Ò»º´æÊý¾Ýµ½GameServer#tagMGUpdatePlayerCache  | 
| #  | 
| #struct    tagMGUpdatePlayerCache  | 
| #{  | 
| #    tagHead        Head;  | 
| #    DWORD        PlayerID;        //Íæ¼ÒID  | 
| #    WORD        PlayerLV;        //Íæ¼ÒµÈ¼¶  | 
| #    BYTE        IsLogouting;        //±¾´ÎÊÇ·ñΪÏÂÏßͬ²½  | 
| #    DWORD        OffTime;        // ÏÂÏßʱ¼ä´Á  | 
| #    WORD        PropDataSize;  | 
| #    char        PropData[PropDataSize];    //ÊôÐԼǼ  | 
| #    WORD        PlusDataSize;  | 
| #    char        PlusData[PlusDataSize];    //À©Õ¹¼Ç¼  | 
| #    WORD        ItemDataSize1;  | 
| #    char        ItemData1[ItemDataSize1];    //1½××°±¸Êý¾Ý  | 
| #    ...         ...  | 
| #    WORD        ItemDataSize20;  | 
| #    char        ItemData20[ItemDataSize20];  | 
| #};  | 
| def OnMGUpdatePlayerCache(routeIndex, mapID, curPackData, tick):  | 
|     playerID = curPackData.PlayerID  | 
|     playerLV = curPackData.PlayerLV  | 
|     isLogout = curPackData.IsLogouting  | 
|     GameWorld.DebugLog('ViewCache### OnMGUpdatePlayerCache isLogout=%s' % isLogout, playerID)  | 
|     isSaveAll = True # ÊÇ·ñ±£´æËùÓÐÊý¾Ý  | 
|     if isLogout:  | 
|         #²»ÐèÒª±£´æÀëÏßÊý¾ÝµÄ£¬Ö±½Óɾ³ý»º´æÊý¾Ý  | 
|         if not IsSaveDBViewCache(playerID, playerLV):  | 
|             DeleteViewCache(playerID)  | 
|             return  | 
|         isSaveAll = IsSaveAllViewCache(playerID)  | 
|         GameWorld.DebugLog("    isSaveAll=%s" % isSaveAll, playerID)  | 
|       | 
|     curCache = FindViewCache(playerID, True)  | 
|     if not curCache:  | 
|         return  | 
|     curCache.LV = curPackData.PlayerLV  | 
|     curCache.OffTime = curPackData.OffTime  | 
|       | 
|     curCache.PropDataDict = {} # Ã¿´Î¸üÐÂÊý¾Ýʱ£¬ÖØÖÃ×ֵ仺´æ£¬Ï´λñÈ¡Ê±ÖØÐÂeval»º´æ  | 
|     curCache.PropData = curPackData.PropData  | 
|     curCache.PropDataSize = curPackData.PropDataSize  | 
|     curCache.PlusData = curPackData.PlusData  | 
|     curCache.PlusDataSize = curPackData.PlusDataSize  | 
|       | 
|     #GameWorld.DebugLog("    ¸üÐÂPropÊý¾Ý: size=%s, %s" % (curCache.PropDataSize, curCache.PropData), playerID)  | 
|     #GameWorld.DebugLog("    ¸üÐÂPlusÊý¾Ý: size=%s, %s" % (curCache.PlusDataSize, curCache.PlusData), playerID)  | 
|       | 
|     # ×°±¸Êý¾Ý´æ´¢£¬²»±£´æ×°±¸Êý¾ÝµÄ»°ÔòÇå¿Õ  | 
|     for classLV in xrange(1, 20 + 1):  | 
|         if not isSaveAll:  | 
|             itemDataSize = 0  | 
|             itemData = ""  | 
|         else:  | 
|             itemDataSize = getattr(curPackData, "ItemDataSize%s" % classLV)  | 
|             if not itemDataSize:  | 
|                 continue  | 
|             itemData = getattr(curPackData, "ItemData%s" % classLV)  | 
|         setattr(curCache, "ItemData%s" % classLV, itemData)  | 
|         setattr(curCache, "ItemDataSize%s" % classLV, itemDataSize)  | 
|         #GameWorld.DebugLog("    ¸üÐÂItemÊý¾Ý: classLV=%s,size=%s, %s" % (classLV, itemDataSize, itemData), playerID)  | 
|           | 
|     #GameWorld.DebugLog("    %s" % curCache.outputString())  | 
|     # Í¬²½¸üÐÂÖúÕ½ÐÅÏ¢  | 
|     if PlayerFBHelpBattle.IsInHelpBattleCheckInList(playerID):  | 
|         PropDataDict = GetCachePropDataDict(curCache)  | 
|         fightPower = PropDataDict.get("FightPower", 0)  | 
|         familyID = PropDataDict.get("FamilyID", 0)  | 
|         playerName = PropDataDict.get("Name", "")  | 
|         PlayerFBHelpBattle.UpdateCheckInPlayerInfo(playerID, fightPower, familyID, playerName)  | 
|           | 
|     return  | 
|   | 
| #//04 02 µØÍ¼²éÑ¯Íæ¼Ò»º´æÊý¾Ý#tagMGQueryPlayerCache  | 
| #struct tagMGQueryPlayerCache  | 
| #{  | 
| #    tagHead        Head;  | 
| #    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):  | 
|     ## Í¬²½Íæ¼Ò»º´æ  | 
|     if equipClassLV:  | 
|         itemData = ""  | 
|         if hasattr(curCache, "ItemDataSize%s" % equipClassLV):  | 
|             itemData = getattr(curCache, "ItemData%s" % equipClassLV)  | 
|         sendPack = ChPyNetSendPack.tagSCPlayerEquipCacheResult()  | 
|         sendPack.PlayerID = curCache.PlayerID  | 
|         sendPack.EquipClassLV = equipClassLV  | 
|         sendPack.ItemData = itemData  | 
|         sendPack.ItemDataSize = len(sendPack.ItemData)  | 
|         NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|         return  | 
|       | 
|     #»Ø°ü¿Í»§¶Ë  | 
|     sendPack = ChPyNetSendPack.tagSCQueryPlayerCacheResult()  | 
|     sendPack.PlayerID = curCache.PlayerID  | 
|     sendPack.PropData = curCache.PropData  | 
|     sendPack.PropDataSize = len(sendPack.PropData)  | 
|     sendPack.PlusData = curCache.PlusData  | 
|     sendPack.PlusDataSize = len(sendPack.PlusData)  | 
|     NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|     return  | 
|   | 
| #===============================================================================  | 
| # //B3 06 ²éÑ¯Íæ¼ÒµÄ¼ò¶ÌÐÅÏ¢ #tagCGViewPlayerShortInfo  | 
| # struct    tagCGViewPlayerShortInfo  | 
| # {  | 
| #    tagHead        Head;  | 
| #    DWORD        PlayerID;  | 
| # };  | 
| #===============================================================================  | 
| def OnViewPlayerShortInfo(index, clientPack, tick):  | 
|     ## ·â°ü֪ͨ  | 
|     tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(clientPack.PlayerID)  | 
|     answerPack = ChPyNetSendPack.tagGCAnswerPlayerShortInfo()  | 
|     answerPack.Clear()  | 
|     if not tagPlayer:  | 
|         curCache = FindViewCache(clientPack.PlayerID)  | 
|         if not curCache:  | 
|             # ÊµÔÚÕÒ²»µ½ÉèÖÃΪ³õʼ»¯Êý¾Ý  | 
|             answerPack.PlayerID = clientPack.PlayerID  | 
|             answerPack.PlayerName = ""  | 
|             answerPack.Job = 1  | 
|             answerPack.LV = 1  | 
|             answerPack.RealmLV = 1  | 
|             answerPack.OnlineType = ChConfig.Def_Offline  | 
|             answerPack.ServerGroupID = 0  | 
|             answerPack.Face = 0  | 
|         else:  | 
|             cacheDict = GetCachePropDataDict(curCache)  | 
|             answerPack.PlayerID = clientPack.PlayerID  | 
|             answerPack.PlayerName = cacheDict["Name"]  | 
|             answerPack.Job = cacheDict["Job"]  | 
|             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)  | 
|             else:  | 
|                 answerPack.ServerGroupID = GameWorld.GetServerGroupID()  | 
|     else:  | 
|         answerPack.PlayerID = clientPack.PlayerID  | 
|         answerPack.PlayerName = tagPlayer.GetName()  | 
|         answerPack.Job = tagPlayer.GetJob()  | 
|         answerPack.LV = tagPlayer.GetLV()  | 
|         answerPack.RealmLV = tagPlayer.GetOfficialRank()  | 
|         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)  | 
|     return  | 
|   | 
| def OnPlayerFamilyChange(playerID, familyID, familyName):  | 
|     GameWorld.DebugLog("ViewCache->OnPlayerFamilyChange", playerID)  | 
|     curCache = FindViewCache(playerID)  | 
|     if not curCache:  | 
|         return  | 
|     PropData = GetCachePropDataDict(curCache)  | 
|     PropData["FamilyID"] = familyID  | 
|     PropData["FamilyName"] = familyName  | 
|     PropData = json.dumps(PropData, ensure_ascii=False).replace(" ", "")  | 
|     curCache.PropData = PropData  | 
|     curCache.PropDataSize = len(curCache.PropData)  | 
|     return  | 
|   |