#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#  
 | 
##@package E:/GameSVN/U3DGame/ProjectSServer/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerSocial.py  
 | 
# @todo:   
 | 
#  
 | 
# @author: Alee  
 | 
# @date 2017-8-21 ÏÂÎç03:59:35  
 | 
# @version 1.0  
 | 
#  
 | 
# @note: ¸öÈËÉç½»¹ÜÀí - ºÃÓÑ ³ðÈË ×î½üÁªÏµÈË ºÚÃûµ¥  
 | 
# ¹ØÏµÍø£º  ºÃÓѺͳðÈË»¥³â£¬ ºÚÃûµ¥ºÍºÃÓÑ£¬×î½üÁªÏµÈË»¥³â  
 | 
#        ºÃÓÑË«Ïò£¬×î½üÁªÏµÈË¡¢³ðÈË¡¢ºÚÃûµ¥µ¥Ïò  
 | 
#---------------------------------------------------------------------  
 | 
import PyGameDataStruct  
 | 
import CommFunc  
 | 
import GameWorld  
 | 
import ChPyNetSendPack  
 | 
import NetPackCommon  
 | 
import ChGameToMapPyPack  
 | 
import PyDataManager  
 | 
import IPY_PlayerDefine  
 | 
import ChConfig  
 | 
import PlayerControl  
 | 
import time  
 | 
import IpyGameDataPY  
 | 
import PlayerViewCache  
 | 
import PyGameData  
 | 
  
 | 
#--------------------É罻Ȧ»ù±¾½á¹¹-------------------  
 | 
# É罻Ȧ  
 | 
class SocialPlayers(object):  
 | 
    def __init__(self, PlayerID, classObject, groupType):  
 | 
        self.PlayerID = PlayerID  
 | 
        self.classObject = classObject  
 | 
        self.SocialDict = {}  
 | 
        self.GroupType = groupType  
 | 
      
 | 
    # Ìí¼ÓÉç½»¶ÔÏó  
 | 
    def Add(self, tagID, isNotify=True):  
 | 
        GameWorld.DebugLog("SocialPlayers----Add %s-%s-%s"%(self.GroupType, self.PlayerID, tagID))  
 | 
        if tagID in self.SocialDict:  
 | 
            GameWorld.DebugLog("SocialPlayers----Add Öظ´")  
 | 
            return False  
 | 
          
 | 
        self.SocialDict[tagID] = self.classObject()  
 | 
          
 | 
        newPlayer = self.SocialDict[tagID]  
 | 
        newPlayer.PlayerID = self.PlayerID  
 | 
        newPlayer.TagID = tagID  
 | 
          
 | 
        ## ·â°ü֪ͨ  
 | 
        tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagID)  
 | 
        if not tagPlayer:  
 | 
            # Ìí¼ÓÒýÓã¬×ßµ½ÕâÀï˵Ã÷ÒѼǼ¹ý¶Ô·½ÐÅÏ¢  
 | 
            playerData = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(tagID)  
 | 
            if playerData:  
 | 
                playerData.AddSocialRef()  
 | 
            else:  
 | 
                PyDataManager.GetPersonalSocialManager().AddPlayerInfoByViewCache(tagID)  
 | 
        else:  
 | 
            # Ìí¼Ó¶Ô·½ÐÅÏ¢£¬¶ÔӦɾ³ý¶Ô·½ÐÅÏ¢  
 | 
            PyDataManager.GetPersonalSocialManager().AddPlayerInfo(tagPlayer)  
 | 
          
 | 
        #·´Ïò¼Ç¼  
 | 
        AddBeSocial(tagID, self.PlayerID)  
 | 
          
 | 
        if not isNotify:  
 | 
            return True  
 | 
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(self.PlayerID)  
 | 
        if not curPlayer:  
 | 
            return True  
 | 
        self.NotifyC_Add(curPlayer, tagID)  
 | 
          
 | 
        self.Sync_SocialPlayer(curPlayer, tagID)  
 | 
          
 | 
        return True  
 | 
      
 | 
    # É¾³ýÉç½»¶ÔÏó  
 | 
    def Delete(self, tagID):  
 | 
        GameWorld.DebugLog("SocialPlayers----Delete %s-%s-%s"%(self.GroupType, self.PlayerID, tagID))  
 | 
        if tagID not in self.SocialDict:  
 | 
            GameWorld.DebugLog("SocialPlayers----Delete Òѱ»É¾³ý")  
 | 
            return  
 | 
          
 | 
        self.SocialDict.pop(tagID)  
 | 
          
 | 
        # É¾³ý¶Ô·½ÐÅÏ¢£¬¶ÔÓ¦Ìí¼Ó¶Ô·½ÐÅÏ¢  
 | 
        PyDataManager.GetPersonalSocialManager().DelPlayerInfo(tagID)  
 | 
        SubBeSocial(tagID, self.PlayerID)  
 | 
        # ·â°ü֪ͨ  
 | 
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(self.PlayerID)  
 | 
        if not curPlayer:  
 | 
            return  
 | 
              
 | 
        self.NotifyC_Del(curPlayer, tagID)  
 | 
          
 | 
          
 | 
    def GetCount(self):  
 | 
        return len(self.SocialDict)  
 | 
      
 | 
    def Find(self, tagID):  
 | 
        return self.SocialDict.get(tagID, None)  
 | 
      
 | 
    # Í¨ÖªÌí¼Ó¶ÔÏó  
 | 
    def NotifyC_Add(self, curPlayer, tagID):  
 | 
        pack = ChPyNetSendPack.tagGCAddSocialPlayer()  
 | 
        pack.Clear()  
 | 
        pack.PlayerID = tagID  
 | 
        pack.GroupType = self.GroupType  
 | 
        NetPackCommon.SendFakePack(curPlayer, pack)  
 | 
        return  
 | 
          
 | 
    # Í¨ÖªÉ¾³ý¶ÔÏó  
 | 
    def NotifyC_Del(self, curPlayer, tagID):  
 | 
        pack = ChPyNetSendPack.tagGCDelSocialPlayer()  
 | 
        pack.Clear()  
 | 
        pack.PlayerID = tagID  
 | 
        pack.GroupType = self.GroupType  
 | 
        NetPackCommon.SendFakePack(curPlayer, pack)  
 | 
        return  
 | 
  
 | 
      
 | 
    # ÉÏÏß֪ͨ   
 | 
    def Sync_SocialsInfo(self, curPlayer):  
 | 
        pack = ChPyNetSendPack.tagGCGroupPlayers()  
 | 
        pack.Clear()  
 | 
        pack.GroupType = self.GroupType  
 | 
        pack.Players = []  
 | 
        pack.Count = self.GetCount()  
 | 
          
 | 
        for player in self.SocialDict.values():  
 | 
            inPack = ChPyNetSendPack.tagGCGroupPlayer()  
 | 
            inPack.PlayerID = player.TagID  
 | 
              
 | 
            inPack.SortValue = player.Timestamp if hasattr(player, 'Timestamp') else 0  
 | 
            pack.Players.append(inPack)  
 | 
              
 | 
        NetPackCommon.SendFakePack(curPlayer, pack)  
 | 
        return  
 | 
  
 | 
      
 | 
    # Í¨ÖªÄ³Íæ¼ÒÐÅÏ¢  
 | 
    def Sync_SocialPlayer(self, curPlayer, tagID):  
 | 
        sendPack = ChPyNetSendPack.tagGCSocialPlayers()  
 | 
        sendPack.Clear()  
 | 
        sendPack.Count = 1  
 | 
        sendPack.Player = []  
 | 
        socialManager = PyDataManager.GetPersonalSocialManager()  
 | 
        socialInfo = socialManager.GetSocialPlayer(tagID).GetPackStruct(ChPyNetSendPack.tagGCSocialPlayer())  
 | 
        sendPack.Player.append(socialInfo)  
 | 
              
 | 
        NetPackCommon.SendFakePack(curPlayer, sendPack)  
 | 
        return  
 | 
      
 | 
    # »ñµÃÔÚÏßÍæ¼Ò¶ÓÁÐ  
 | 
    def GetOnlinePlayers(self):  
 | 
        onlines = []  
 | 
        for tagID in self.SocialDict:  
 | 
            player = GameWorld.GetPlayerManager().FindPlayerByID(tagID)  
 | 
            if not player:  
 | 
                continue  
 | 
              
 | 
            onlines.append(player)  
 | 
        return onlines  
 | 
      
 | 
  
 | 
  
 | 
#-------------------ºÃÓÑ------------------------------  
 | 
# Ä³¸öÍæ¼ÒµÄºÃÓÑ×é¹ÜÀí  
 | 
class Friends(SocialPlayers):  
 | 
    def __init__(self, PlayerID):  
 | 
        super(Friends, self).__init__(PlayerID, PyGameDataStruct.tagDBPyPlayerFriend,   
 | 
                               ChConfig.Def_SocialGroup_Friend)  
 | 
      
 | 
    # Ìí¼ÓÍæ¼Òij¸öºÃÓÑ£¬Ò»¶¨ÊÇÔÚÏß  
 | 
    def AddFriend(self, friendID):  
 | 
        self.Add(friendID)  
 | 
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(self.PlayerID)  
 | 
        self.MapServer_SyncFriendInfo(curPlayer)  
 | 
          
 | 
      
 | 
    # É¾³ýÍæ¼Òij¸öºÃÓÑ  
 | 
    def DelFriend(self, delFriendID):  
 | 
        self.Delete(delFriendID)  
 | 
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(self.PlayerID)  
 | 
        self.MapServer_SyncFriendInfo(curPlayer)  
 | 
      
 | 
      
 | 
    # Í¨ÖªµØÍ¼ºÃÓÑÐÅÏ¢  
 | 
    def MapServer_SyncFriendInfo(self, curPlayer):  
 | 
        if not curPlayer:  
 | 
            return  
 | 
        sendPack = ChGameToMapPyPack.tagGMFriendInfo()   
 | 
        sendPack.PlayerID = curPlayer.GetPlayerID()  
 | 
        sendPack.FriendCnt = self.GetCount()  
 | 
        sendPack.Friends = []  
 | 
          
 | 
        for friendInfo in self.SocialDict.values():  
 | 
            playerFriend = ChGameToMapPyPack.tagGMPlayerFrendInfo()  
 | 
            playerFriend.TagID = friendInfo.PlayerID  
 | 
            sendPack.Friends.append(playerFriend)  
 | 
        NetPackCommon.SendPyPackToMapServer(curPlayer.GetLineNO(), curPlayer.GetRealMapID(), sendPack)   
 | 
      
 | 
  
 | 
# Õû¸öÓÎÏ·µÄºÃÓѹÜÀí  
 | 
class FriendManager(object):  
 | 
    def __init__(self):  
 | 
        self.PlayerFriends = {}     # PyGameDataStruct.tagDBPyPlayerFriend  
 | 
          
 | 
    # Ìí¼ÓºÃÓÑ Ò»¶¨ÊÇÔÚÏß  
 | 
    def AddFriendBoth(self, friendAID, friendBID):  
 | 
        if friendAID not in self.PlayerFriends:  
 | 
            self.PlayerFriends[friendAID] = Friends(friendAID)  
 | 
          
 | 
        friends = self.PlayerFriends[friendAID]  
 | 
        friends.AddFriend(friendBID)  
 | 
  
 | 
        # È¡Ïû³ðÈË   
 | 
        PyDataManager.GetEnemyManager().DelEnemy(friendAID, friendBID)  
 | 
        if friendBID not in self.PlayerFriends:  
 | 
            self.PlayerFriends[friendBID] = Friends(friendBID)  
 | 
          
 | 
        friends = self.PlayerFriends[friendBID]  
 | 
        friends.AddFriend(friendAID)  
 | 
        # È¡Ïû³ðÈË   
 | 
        PyDataManager.GetEnemyManager().DelEnemy(friendBID, friendAID)  
 | 
        return  
 | 
      
 | 
    # ´ÓË«·½ÖÐɾ³ý¶Ô·½ºÃÓÑ  
 | 
    def DelFriendBoth(self, friendAID, friendBID):  
 | 
          
 | 
        friendAStruct = self.PlayerFriends.get(friendAID, None)  
 | 
          
 | 
        if friendAStruct:  
 | 
            friendAStruct.Delete(friendBID)  
 | 
          
 | 
              
 | 
        friendBStruct = self.PlayerFriends.get(friendBID, None)  
 | 
          
 | 
        if friendBStruct:  
 | 
            friendBStruct.Delete(friendAID)  
 | 
                  
 | 
    # »ñÈ¡ºÃÓÑ×é  
 | 
    def GetFriends(self, playerID):  
 | 
        return self.PlayerFriends.get(playerID, None)  
 | 
      
 | 
    # ÐÂÔöºÃÓÑ×é  
 | 
    def AddFriends(self, playerID):  
 | 
        self.PlayerFriends[playerID] = Friends(playerID)  
 | 
  
 | 
        return self.GetFriends(playerID)  
 | 
      
 | 
    # ±£´æºÃÓÑÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  
 | 
    def GetSaveData(self):  
 | 
        savaData = ""  
 | 
        cntData = ""  
 | 
        cnt = 0  
 | 
        for friends in self.PlayerFriends.values():  
 | 
            for friend in friends.SocialDict.values():  
 | 
                cnt += 1  
 | 
                savaData += friend.getBuffer()  
 | 
          
 | 
        GameWorld.Log("SaveFriendData cnt :%s"%cnt)  
 | 
        return CommFunc.WriteDWORD(cntData, cnt) + savaData  
 | 
  
 | 
    # ´ÓÊý¾Ý¿âÔØÈëºÃÓÑÊý¾Ý  
 | 
    def LoadPyGameData(self, datas, pos, dataslen):  
 | 
        cnt, pos = CommFunc.ReadDWORD(datas, pos)  
 | 
        GameWorld.Log("LoadFriendData cnt :%s"%cnt)  
 | 
          
 | 
        self.PlayerFriends = {}  
 | 
          
 | 
        for i in xrange(cnt):  
 | 
            playerFriend = PyGameDataStruct.tagDBPyPlayerFriend()  
 | 
            playerFriend.clear()  
 | 
            pos += playerFriend.readData(datas, pos, dataslen)  
 | 
            if playerFriend.PlayerID not in self.PlayerFriends:  
 | 
                self.PlayerFriends[playerFriend.PlayerID] = Friends(playerFriend.PlayerID)   
 | 
            self.PlayerFriends[playerFriend.PlayerID].SocialDict[playerFriend.TagID] = playerFriend  
 | 
              
 | 
            AddBeSocial(playerFriend.TagID, playerFriend.PlayerID)  
 | 
        return pos  
 | 
      
 | 
#-------------------³ðÈË------------------------------  
 | 
# Õû¸öÓÎÏ·µÄ³ðÈ˹ÜÀí  
 | 
class EnemyManager(object):  
 | 
    def __init__(self):  
 | 
        self.Players = {}     # PyGameDataStruct.tagPlayerEnemy  
 | 
          
 | 
    # Ìí¼Ó³ðÈË Ò»¶¨ÊÇÔÚÏß  
 | 
    def AddEnemy(self, playerID, tagID):  
 | 
        timestamp = int(time.time())  
 | 
        if playerID in self.Players:  
 | 
            socialPlayer = self.Players[playerID]  
 | 
            if socialPlayer.Find(tagID):  
 | 
                socialPlayer.Find(tagID).timestamp = timestamp  
 | 
                # Í¨Öª¿Í»§¶Ë  
 | 
                curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
                if curPlayer:  
 | 
                    self.Notify_UpdateTag(curPlayer, tagID, timestamp)  
 | 
                      
 | 
                return  
 | 
        else:  
 | 
            self.Players[playerID] = SocialPlayers(playerID, PyGameDataStruct.tagPlayerEnemy,   
 | 
                                               ChConfig.Def_SocialGroup_Enemy)  
 | 
          
 | 
        socialPlayer = self.Players[playerID]  
 | 
        if socialPlayer.Add(tagID, False):  
 | 
            socialPlayer.Find(tagID).timestamp = timestamp  
 | 
              
 | 
            #֪ͨ¿Í»§¶Ë  
 | 
            curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
            if curPlayer:  
 | 
                socialPlayer.Sync_SocialPlayer(curPlayer, tagID)  
 | 
                self.Notify_UpdateTag(curPlayer, tagID, timestamp)  
 | 
                  
 | 
            self.DelOldEnemy(playerID)  
 | 
        return  
 | 
      
 | 
    def Notify_UpdateTag(self, curPlayer, tagID, timestamp):  
 | 
        pack = ChPyNetSendPack.tagGCAddSocialPlayer()  
 | 
        pack.Clear()  
 | 
        pack.PlayerID = tagID  
 | 
        pack.GroupType = ChConfig.Def_SocialGroup_Enemy  
 | 
        pack.SortValue = timestamp  
 | 
        NetPackCommon.SendFakePack(curPlayer, pack)  
 | 
  
 | 
      
 | 
    # É¾³ý³ðÈË£¨°Ñ¶Ô·½¼ÓΪºÃÓѼ´¿Éɾ³ý£©  
 | 
    def DelEnemy(self, playerID, tagID):  
 | 
          
 | 
        socialPlayer = self.Players.get(playerID, None)  
 | 
        if not socialPlayer:  
 | 
            return  
 | 
          
 | 
        socialPlayer.Delete(tagID)  
 | 
                
 | 
    #ɾ³ý¾É¶ÔÏó  
 | 
    def DelOldEnemy(self, playerID):  
 | 
        socialPlayer = self.Players.get(playerID, None)  
 | 
        if not socialPlayer:  
 | 
            return  
 | 
          
 | 
        enemiesMaxCnt = IpyGameDataPY.GetFuncCfg("EnemiesMaxCnt")  
 | 
            
 | 
        #´Ë´¦ÀíÂÛֻҪɾ³ýÒ»¸ö¾Í¿ÉÒÔ  
 | 
        delcnt = socialPlayer.GetCount() - enemiesMaxCnt  
 | 
        if delcnt <= 0:  
 | 
            return  
 | 
        delList = []  
 | 
          
 | 
        for tmpID, player in socialPlayer.SocialDict.items():  
 | 
            playerData = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(tmpID)  
 | 
  
 | 
            delList.append([tmpID, playerData.playerInfo.OnlineType, player.Timestamp])  
 | 
  
 | 
        delList.sort(cmp=SortOldList)  
 | 
  
 | 
        for i in xrange(delcnt):  
 | 
            result = delList.pop()  
 | 
            self.DelEnemy(playerID, result[0])  
 | 
              
 | 
        return              
 | 
                       
 | 
  
 | 
    # »ñÈ¡³ðÈË×é  
 | 
    def GetEnemies(self, playerID):  
 | 
        return self.Players.get(playerID, None)  
 | 
      
 | 
    # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  
 | 
    def GetSaveData(self):  
 | 
        savaData = ""  
 | 
        cntData = ""  
 | 
        cnt = 0  
 | 
        for socialPlayers in self.Players.values():  
 | 
            for socialPlayer in socialPlayers.SocialDict.values():  
 | 
                cnt += 1  
 | 
                savaData += socialPlayer.getBuffer()  
 | 
          
 | 
        GameWorld.Log("!!SaveEnemyData cnt :%s"%cnt)  
 | 
        return CommFunc.WriteDWORD(cntData, cnt) + savaData  
 | 
  
 | 
    # ´ÓÊý¾Ý¿âÔØÈë  
 | 
    def LoadPyGameData(self, datas, pos, dataslen):  
 | 
        cnt, pos = CommFunc.ReadDWORD(datas, pos)  
 | 
        GameWorld.Log("!!LoadEnemyData cnt :%s"%cnt)  
 | 
          
 | 
        self.Players = {}  
 | 
          
 | 
        for i in xrange(cnt):  
 | 
            playerEnemy = PyGameDataStruct.tagPlayerEnemy()  
 | 
            playerEnemy.clear()  
 | 
            pos += playerEnemy.readData(datas, pos, dataslen)  
 | 
            if playerEnemy.PlayerID not in self.Players:  
 | 
                self.Players[playerEnemy.PlayerID] = SocialPlayers(playerEnemy.PlayerID, PyGameDataStruct.tagPlayerEnemy,   
 | 
                                                                    ChConfig.Def_SocialGroup_Enemy)  
 | 
            self.Players[playerEnemy.PlayerID].SocialDict[playerEnemy.TagID] = playerEnemy  
 | 
  
 | 
            AddBeSocial(playerEnemy.TagID, playerEnemy.PlayerID)  
 | 
        return pos  
 | 
  
 | 
  
 | 
#-------------------×î½üÁªÏµÈË------------------------------  
 | 
# Õû¸öÓÎÏ·µÄ×î½üÁªÏµÈ˹ÜÀí  
 | 
class ContactsManager(object):  
 | 
    def __init__(self):  
 | 
        self.Players = {}     # PyGameDataStruct.tagDBPyPlayerContacts  
 | 
          
 | 
    def FindContact(self, playerID, tagID):  
 | 
        if playerID not in self.Players:  
 | 
            return False  
 | 
  
 | 
        socialPlayer = self.Players[playerID]  
 | 
        if not socialPlayer.Find(tagID):  
 | 
            return False  
 | 
        return True  
 | 
      
 | 
          
 | 
    # Ìí¼Óʱ˫·½, É¾³ý¿ÉÄÜÊǵ¥·½  
 | 
    def AddContactsBoth(self, playerID, tagID):  
 | 
        timestamp = int(time.time())  
 | 
        if playerID not in self.Players:  
 | 
            self.Players[playerID] = SocialPlayers(playerID, PyGameDataStruct.tagDBPyPlayerContacts,   
 | 
                                                   ChConfig.Def_SocialGroup_Contacts)  
 | 
  
 | 
        #¸üÐÂ×îÐÂʱ¼ä  
 | 
        socialPlayer = self.Players[playerID]  
 | 
        notifySocial = False  
 | 
        if not socialPlayer.Find(tagID):  
 | 
            socialPlayer.Add(tagID, False)  
 | 
            #µÚÒ»´ÎºÍ¶Ô·½ÁÄÌìÐè֪ͨÏÔʾ¶Ô·½Éç½»ÐÅÏ¢  
 | 
            notifySocial = True  
 | 
            socialPlayer.Find(tagID).Timestamp = timestamp  
 | 
            self.DelOldContact(playerID)  
 | 
        else:  
 | 
            socialPlayer.Find(tagID).Timestamp = timestamp  
 | 
              
 | 
        # Í¨Öª¿Í»§¶Ë  
 | 
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
        if curPlayer:  
 | 
            self.Notify_UpdateTag(curPlayer, tagID, timestamp)  
 | 
            if notifySocial:  
 | 
                socialPlayer.Sync_SocialPlayer(curPlayer, tagID)  
 | 
                  
 | 
        # Í¨Öª¶Ô·½     
 | 
        if tagID not in self.Players:  
 | 
            self.Players[tagID] = SocialPlayers(tagID, PyGameDataStruct.tagDBPyPlayerContacts,   
 | 
                                                   ChConfig.Def_SocialGroup_Contacts)  
 | 
  
 | 
        #¸üÐÂ×îÐÂʱ¼ä  
 | 
        socialPlayer = self.Players[tagID]  
 | 
        notifySocial = False  
 | 
        if not socialPlayer.Find(playerID):  
 | 
            socialPlayer.Add(playerID, False)  
 | 
            #µÚÒ»´ÎºÍ¶Ô·½ÁÄÌìÐè֪ͨÏÔʾ¶Ô·½Éç½»ÐÅÏ¢  
 | 
            notifySocial = True  
 | 
            socialPlayer.Find(playerID).Timestamp = timestamp  
 | 
            self.DelOldContact(tagID)  
 | 
        else:  
 | 
            socialPlayer.Find(playerID).Timestamp = timestamp  
 | 
              
 | 
        # Í¨Öª¿Í»§¶Ë  
 | 
        tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagID)  
 | 
        if tagPlayer:  
 | 
            self.Notify_UpdateTag(tagPlayer, playerID, timestamp)  
 | 
            if notifySocial:  
 | 
                socialPlayer.Sync_SocialPlayer(tagPlayer, playerID)  
 | 
        return  
 | 
      
 | 
    #֪ͨ×îзÖ×é״̬  
 | 
    def Notify_UpdateTag(self, curPlayer, tagID, timestamp):  
 | 
        pack = ChPyNetSendPack.tagGCAddSocialPlayer()  
 | 
        pack.Clear()  
 | 
        pack.PlayerID = tagID  
 | 
        pack.GroupType = ChConfig.Def_SocialGroup_Contacts  
 | 
        pack.SortValue = timestamp  
 | 
        NetPackCommon.SendFakePack(curPlayer, pack)  
 | 
      
 | 
    # É¾³ýÁªÏµÈË  
 | 
    def DelContact(self, playerID, tagID):  
 | 
          
 | 
        socialPlayer = self.Players.get(playerID, None)  
 | 
        if not socialPlayer:  
 | 
            return  
 | 
          
 | 
        socialPlayer.Delete(tagID)  
 | 
          
 | 
          
 | 
    # É¾³ýË«·½  
 | 
    def DelContactBoth(self, playerID, tagID):  
 | 
          
 | 
        self.DelContact(playerID, tagID)  
 | 
        self.DelContact(tagID, playerID)  
 | 
      
 | 
    #ɾ³ý¾É¶ÔÏó  
 | 
    def DelOldContact(self, playerID):  
 | 
        socialPlayer = self.Players.get(playerID, None)  
 | 
        if not socialPlayer:  
 | 
            return  
 | 
          
 | 
        contactsMaxCnt = IpyGameDataPY.GetFuncCfg("ContactsMaxCnt")  
 | 
          
 | 
        #´Ë´¦ÀíÂÛֻҪɾ³ýÒ»¸ö¾Í¿ÉÒÔ  
 | 
        delcnt = socialPlayer.GetCount() - contactsMaxCnt  
 | 
        if delcnt <= 0:  
 | 
            return  
 | 
          
 | 
        delList = []  
 | 
          
 | 
        for tmpID, player in socialPlayer.SocialDict.items():  
 | 
            playerData = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(tmpID)  
 | 
  
 | 
            delList.append([tmpID, playerData.playerInfo.OnlineType, player.Timestamp])  
 | 
  
 | 
        delList.sort(cmp=SortOldList)  
 | 
  
 | 
        for i in xrange(delcnt):  
 | 
            result = delList.pop()  
 | 
            self.DelContact(playerID, result[0])  
 | 
        return              
 | 
                  
 | 
  
 | 
    def GetContacts(self, playerID):  
 | 
        return self.Players.get(playerID, None)  
 | 
      
 | 
    # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  
 | 
    def GetSaveData(self):  
 | 
        savaData = ""  
 | 
        cntData = ""  
 | 
        cnt = 0  
 | 
        for socialPlayers in self.Players.values():  
 | 
            for socialPlayer in socialPlayers.SocialDict.values():  
 | 
                cnt += 1  
 | 
                savaData += socialPlayer.getBuffer()  
 | 
          
 | 
        GameWorld.Log("!!SaveContactsData cnt :%s"%cnt)  
 | 
        return CommFunc.WriteDWORD(cntData, cnt) + savaData  
 | 
  
 | 
    # ´ÓÊý¾Ý¿âÔØÈë  
 | 
    def LoadPyGameData(self, datas, pos, dataslen):  
 | 
        cnt, pos = CommFunc.ReadDWORD(datas, pos)  
 | 
        GameWorld.Log("!!LoadContactsData cnt :%s"%cnt)  
 | 
          
 | 
        self.Players = {}  
 | 
          
 | 
        for i in xrange(cnt):  
 | 
            player = PyGameDataStruct.tagDBPyPlayerContacts()  
 | 
            player.clear()  
 | 
            pos += player.readData(datas, pos, dataslen)  
 | 
            if player.PlayerID not in self.Players:  
 | 
                self.Players[player.PlayerID] = SocialPlayers(player.PlayerID, PyGameDataStruct.tagDBPyPlayerContacts,   
 | 
                                                                    ChConfig.Def_SocialGroup_Contacts)  
 | 
            self.Players[player.PlayerID].SocialDict[player.TagID] = player  
 | 
  
 | 
            AddBeSocial(player.TagID, player.PlayerID)  
 | 
        return pos  
 | 
  
 | 
#-------------------ºÚÃûµ¥------------------------------  
 | 
# Õû¸öÓÎÏ·µÄºÚÃûµ¥¹ÜÀí  
 | 
class BlacklistManager(object):  
 | 
    def __init__(self):  
 | 
        self.Players = {}     # PyGameDataStruct.tagDBPyPlayerBlack  
 | 
          
 | 
    # ¼ÓÈëºÚÃûµ¥  
 | 
    def JoinBlacklist(self, playerID, tagID):  
 | 
        if not self.Players.get(playerID, None):  
 | 
            self.Players[playerID] = SocialPlayers(playerID, PyGameDataStruct.tagDBPyPlayerBlack,   
 | 
                                                   ChConfig.Def_SocialGroup_Black)  
 | 
          
 | 
        socialPlayer = self.Players[playerID]  
 | 
        socialPlayer.Add(tagID)  
 | 
          
 | 
        # È¡ÏûË«·½ºÃÓÑ   
 | 
        PyDataManager.GetFriendManager().DelFriendBoth(playerID, tagID)  
 | 
          
 | 
        # È¡ÏûË«·½×î½üÁªÏµÈË  
 | 
        PyDataManager.GetContactsManager().DelContactBoth(playerID, tagID)  
 | 
        return  
 | 
      
 | 
    def DelBlacklist(self, playerID, tagID):  
 | 
          
 | 
        socialPlayer = self.Players.get(playerID, None)  
 | 
        if not socialPlayer:  
 | 
            return  
 | 
        GameWorld.DebugLog("DelBlacklist")  
 | 
        socialPlayer.Delete(tagID)  
 | 
           
 | 
    # ¼ì²éºÚÃûµ¥×´Ì¬  
 | 
    def CheckBlacklistBoth(self, playerID, tagID, curPlayer=None):  
 | 
        if playerID in self.Players and self.Players[playerID].Find(tagID):  
 | 
            #ÌáʾÇëÏÈÒÆ³ýºÚÃûµ¥  
 | 
            if curPlayer:  
 | 
                PlayerControl.NotifyCode(curPlayer, 'Friend_RemoveBlacklist')  
 | 
            return True  
 | 
                  
 | 
        if tagID in self.Players and self.Players[tagID].Find(playerID):  
 | 
            #Ìáʾ¶Ô·½°ÑÄãÀºÚ  
 | 
            if curPlayer:  
 | 
                PlayerControl.NotifyCode(curPlayer, 'Friend_Blacklist')  
 | 
            return True  
 | 
        return False  
 | 
      
 | 
      
 | 
    def GetBlacklist(self, playerID):  
 | 
        return self.Players.get(playerID, None)  
 | 
      
 | 
    # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  
 | 
    def GetSaveData(self):  
 | 
        savaData = ""  
 | 
        cntData = ""  
 | 
        cnt = 0  
 | 
        for socialPlayers in self.Players.values():  
 | 
            for socialPlayer in socialPlayers.SocialDict.values():  
 | 
                cnt += 1  
 | 
                savaData += socialPlayer.getBuffer()  
 | 
          
 | 
        GameWorld.Log("!!SaveBlacklistData cnt :%s"%cnt)  
 | 
        return CommFunc.WriteDWORD(cntData, cnt) + savaData  
 | 
  
 | 
    # ´ÓÊý¾Ý¿âÔØÈë  
 | 
    def LoadPyGameData(self, datas, pos, dataslen):  
 | 
        cnt, pos = CommFunc.ReadDWORD(datas, pos)  
 | 
        GameWorld.Log("!!LoadBlacklistData cnt :%s"%cnt)  
 | 
          
 | 
        self.Players = {}  
 | 
          
 | 
        for i in xrange(cnt):  
 | 
            player = PyGameDataStruct.tagDBPyPlayerBlack()  
 | 
            player.clear()  
 | 
            pos += player.readData(datas, pos, dataslen)  
 | 
            if player.PlayerID not in self.Players:  
 | 
                self.Players[player.PlayerID] = SocialPlayers(player.PlayerID, PyGameDataStruct.tagDBPyPlayerBlack,   
 | 
                                                                    ChConfig.Def_SocialGroup_Black)  
 | 
            self.Players[player.PlayerID].SocialDict[player.TagID] = player  
 | 
  
 | 
            AddBeSocial(player.TagID, player.PlayerID)  
 | 
        return pos  
 | 
      
 | 
#-------------------¸öÈËÉç½»ÐÅÏ¢------------------------------  
 | 
#¸öÈËÉç½»ÐÅÏ¢  
 | 
class SocialPlayerData(object):  
 | 
    def __init__(self, playerSocial = None, player = None):  
 | 
        self.playerInfo = PyGameDataStruct.tagPersonalSocial()  
 | 
          
 | 
        if playerSocial:  
 | 
            self.playerInfo = playerSocial  
 | 
        elif player:  
 | 
            self.UpdateByPlayer(player)  
 | 
        return  
 | 
      
 | 
    # ¼ÇÂ¼Íæ¼ÒÉç½»ÐÅÏ¢  
 | 
    def UpdateByPlayer(self, curPlayer):  
 | 
        self.playerInfo.PlayerID = curPlayer.GetPlayerID()  
 | 
        self.playerInfo.PlayerName = curPlayer.GetName()  
 | 
        self.playerInfo.Job = curPlayer.GetJob()  
 | 
        self.playerInfo.LV = curPlayer.GetLV()  
 | 
        self.playerInfo.RealmLV = curPlayer.GetOfficialRank()  
 | 
        self.playerInfo.OnlineType = 1      # 0 ²»ÔÚÏß  1 ÔÚÏß 2 ÍÑ»úÔÚÏß    
 | 
        if not self.playerInfo.RefCount:  
 | 
            self.playerInfo.RefCount = 1  
 | 
        return  
 | 
      
 | 
    # »ñµÃ·¢ËÍ·â°üÊý¾Ý  
 | 
    def GetPackStruct(self, packStruct):  
 | 
        packStruct.PlayerID = self.playerInfo.PlayerID  
 | 
        packStruct.PlayerName = self.playerInfo.PlayerName  
 | 
        packStruct.Job = self.playerInfo.Job  
 | 
        packStruct.LV = self.playerInfo.LV  
 | 
        packStruct.RealmLV = self.playerInfo.RealmLV  
 | 
        packStruct.OnlineType = self.playerInfo.OnlineType  
 | 
        return packStruct  
 | 
      
 | 
      
 | 
    # ¸üÐÂÍæ¼ÒÊý¾ÝÒýÓÃ, ¸ù¾ÝÐèÇóÊÇ·ñ¸üÐÂÍæ¼ÒÊý¾Ý  
 | 
    def AddSocialRef(self, curPlayer = None):  
 | 
        self.playerInfo.RefCount += 1  
 | 
        GameWorld.DebugLog("AddSocialRef %s-%s"%(self.playerInfo.RefCount, self.playerInfo.PlayerID))  
 | 
        return  
 | 
      
 | 
    # É¾³ýÍæ¼ÒÊý¾ÝÒýÓà  
 | 
    def SubSocialRef(self):  
 | 
        self.playerInfo.RefCount -= 1  
 | 
        GameWorld.DebugLog("SubSocialRef %s-%s"%(self.playerInfo.RefCount, self.playerInfo.PlayerID))  
 | 
        return  
 | 
      
 | 
    def GetRefCount(self):  
 | 
        return self.playerInfo.RefCount  
 | 
  
 | 
#Éç½»ÐÅÏ¢¹ÜÀí  
 | 
class SocialInfoManager(object):  
 | 
    def __init__(self):  
 | 
        self.SocialInfo = {}  
 | 
        return  
 | 
      
 | 
    # Ôö¼ÓÉç½»¶ÔÏóÐÅÏ¢  
 | 
    def AddPlayerInfo(self, curPlayer):  
 | 
        playerID = curPlayer.GetPlayerID()  
 | 
        if playerID not in self.SocialInfo:  
 | 
            self.SocialInfo[playerID] = SocialPlayerData(player = curPlayer)  
 | 
            return  
 | 
          
 | 
        socialPlayer = self.SocialInfo[playerID]  
 | 
        # ¸üÐÂ×îÐÂÄÚÈݺÍÒýÓà  
 | 
        socialPlayer.AddSocialRef()  
 | 
          
 | 
    # Ôö¼ÓÉç½»¶ÔÏóÐÅÏ¢£¬Õë¶Ô²»ÔÚÉ罻Ȧ¼Ç¼²¢ÇÒ²»ÔÚÏßÍæ¼ÒµÄÇé¿ö  
 | 
    def AddPlayerInfoByViewCache(self, playerID):  
 | 
        curCache = PlayerViewCache.ViewCacheMgr.FindCache(playerID)  
 | 
        playerSocial = PyGameDataStruct.tagPersonalSocial()  
 | 
        if not curCache:  
 | 
            # ÊµÔÚÕÒ²»µ½ÉèÖÃΪ³õʼ»¯Êý¾Ý  
 | 
            playerSocial.clear()  
 | 
            playerSocial.PlayerID = playerID  
 | 
            playerSocial.PlayerName = ""  
 | 
            playerSocial.Job = 1  
 | 
            playerSocial.LV = 1  
 | 
            playerSocial.RealmLV = 1  
 | 
            playerSocial.OnlineType = ChConfig.Def_Offline  
 | 
        else:  
 | 
            cacheDict = eval(curCache.GetPropData())  
 | 
      
 | 
            playerSocial.clear()  
 | 
            playerSocial.PlayerID = playerID  
 | 
            playerSocial.PlayerName = cacheDict["Name"]  
 | 
            playerSocial.Job = cacheDict["Job"]  
 | 
            playerSocial.LV = cacheDict["LV"]  
 | 
            playerSocial.RealmLV = cacheDict["RealmLV"]  
 | 
            playerSocial.OnlineType = ChConfig.Def_Offline  
 | 
              
 | 
        self.SocialInfo[playerID] = SocialPlayerData(playerSocial)  
 | 
        socialPlayer = self.SocialInfo[playerID]  
 | 
        # ¸üÐÂ×îÐÂÄÚÈݺÍÒýÓà  
 | 
        socialPlayer.AddSocialRef()  
 | 
          
 | 
    # ¼õÉÙÉç½»¶ÔÏóÐÅÏ¢  
 | 
    def DelPlayerInfo(self, delPlayerID):  
 | 
        if delPlayerID not in self.SocialInfo:  
 | 
            return  
 | 
          
 | 
        socialPlayer = self.SocialInfo[delPlayerID]  
 | 
        # ¸üÐÂ×îÐÂÄÚÈݺÍÒýÓà  
 | 
        socialPlayer.SubSocialRef()  
 | 
        if socialPlayer.GetRefCount() <= 0:  
 | 
            self.SocialInfo.pop(delPlayerID)  
 | 
              
 | 
      
 | 
    def GetSocialPlayer(self, playerID):  
 | 
        return self.SocialInfo.get(playerID, None)  
 | 
      
 | 
      
 | 
    # ±£´æÓÐÉç½»µÄÍæ¼ÒÐÅÏ¢  
 | 
    def GetSaveData(self):  
 | 
        savaData = ""  
 | 
        cntData = ""  
 | 
        cnt = 0  
 | 
        for socialPlayer in self.SocialInfo.values():  
 | 
            cnt += 1  
 | 
            savaData += socialPlayer.playerInfo.getBuffer()  
 | 
          
 | 
        GameWorld.Log("SaveSocialData cnt :%s"%cnt)  
 | 
        return CommFunc.WriteDWORD(cntData, cnt) + savaData  
 | 
  
 | 
  
 | 
    # ´ÓÊý¾Ý¿âÔØÈëÓÐÉç½»µÄÍæ¼ÒÐÅÏ¢  
 | 
    def LoadPyGameData(self, datas, pos, dataslen):  
 | 
        cnt, pos = CommFunc.ReadDWORD(datas, pos)  
 | 
        GameWorld.Log("LoadSocialData cnt :%s"%cnt)  
 | 
        # ¼ÓÔØÇ°±ØÇå¿Õ  
 | 
        self.SocialInfo = {}  
 | 
        for i in xrange(cnt):  
 | 
            playerSocial = PyGameDataStruct.tagPersonalSocial()  
 | 
            playerSocial.clear()  
 | 
            pos += playerSocial.readData(datas, pos, dataslen)  
 | 
            self.SocialInfo[playerSocial.PlayerID] = SocialPlayerData(playerSocial)  
 | 
                  
 | 
        return pos  
 | 
  
 | 
  
 | 
# ÏòÏà¹ØÁªµÄÉç½»¶ÔÏó֪ͨµ±Ç°Íæ¼ÒÐÅÏ¢  
 | 
# ×î½üÁªÏµÈË¡¢³ðÈ˺ͺÚÃûµ¥´æÔÚµ¥ÏòÇé¿ö£¬ Ïò¶Ô·½Í¨ÖªÐÅÏ¢  
 | 
def Notify_All(playerID, notifyType, value, setInfo=set()):  
 | 
    if playerID not in PyGameData.g_BeSocialList:  
 | 
        return  
 | 
      
 | 
    if notifyType == IPY_PlayerDefine.CDBPlayerRefresh_PlayerName:  
 | 
        pack = ChPyNetSendPack.tagGCSocialName()  
 | 
        pack.PlayerID = playerID  
 | 
        pack.Name = value  
 | 
    elif notifyType == ChConfig.Def_CDBPlayerRefresh_Online:  
 | 
        pack = ChPyNetSendPack.tagGCSocialOnline()  
 | 
        pack.PlayerID = playerID  
 | 
        pack.OnlineType = value  
 | 
    else:  
 | 
        pack = ChPyNetSendPack.tagGCSocialRefreshType()  
 | 
        pack.PlayerID = playerID  
 | 
        pack.RefreshType = notifyType  
 | 
        pack.Value = value  
 | 
          
 | 
    for tagID in PyGameData.g_BeSocialList[playerID]:  
 | 
        player = GameWorld.GetPlayerManager().FindPlayerByID(tagID)  
 | 
        if not player:  
 | 
            continue  
 | 
          
 | 
        if PlayerControl.GetIsTJG(player):  
 | 
            continue  
 | 
        NetPackCommon.SendFakePack(player, pack)  
 | 
          
 | 
  
 | 
  
 | 
#¸üÐÂÍæ¼ÒÉç½»ÐÅÏ¢  
 | 
def UpdateSocialInfo(curPlayer, notifyType, value):  
 | 
    socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(curPlayer.GetID())  
 | 
    if socialPlayer == None:  
 | 
        return  
 | 
      
 | 
    if notifyType == IPY_PlayerDefine.CDBPlayerRefresh_LV:  
 | 
        socialPlayer.playerInfo.LV = value  
 | 
    elif notifyType == IPY_PlayerDefine.CDBPlayerRefresh_OfficialRank:  
 | 
        socialPlayer.playerInfo.RealmLV = value  
 | 
    elif notifyType == IPY_PlayerDefine.CDBPlayerRefresh_PlayerName:  
 | 
        socialPlayer.playerInfo.PlayerName = value  
 | 
          
 | 
    Notify_All(curPlayer.GetID(), notifyType, value)  
 | 
  
 | 
  
 | 
  
 | 
# Ïòµ±Ç°Íæ¼Ò֪ͨÏà¹ØÁªµÄËùÓÐÍæ¼ÒÐÅÏ¢  
 | 
def Sync_AllSocialsInfo(curPlayer):  
 | 
    playerID = curPlayer.GetID()  
 | 
    friends = PyDataManager.GetFriendManager().GetFriends(playerID)  
 | 
    list1 = friends.SocialDict.keys() if friends else []  
 | 
    enemies = PyDataManager.GetEnemyManager().GetEnemies(playerID)  
 | 
    list2 = enemies.SocialDict.keys() if enemies else []  
 | 
    contacts = PyDataManager.GetContactsManager().GetContacts(playerID)  
 | 
    list3 = contacts.SocialDict.keys() if contacts else []  
 | 
    blacklists = PyDataManager.GetBlacklistManager().GetBlacklist(playerID)  
 | 
    list4 = blacklists.SocialDict.keys() if blacklists else []  
 | 
  
 | 
    #ÐÅÏ¢²¢¼¯ºó·¢ËÍ, Íæ¼ÒID  
 | 
    resultSet = set(list1)|set(list2)|set(list3)|set(list4)  
 | 
      
 | 
    sendPack = ChPyNetSendPack.tagGCSocialPlayers()  
 | 
    sendPack.Clear()  
 | 
    sendPack.Player = []  
 | 
    socialManager = PyDataManager.GetPersonalSocialManager()  
 | 
    for tagID in resultSet:  
 | 
        socialPlayer = socialManager.GetSocialPlayer(tagID)  
 | 
        if not socialPlayer:  
 | 
            continue  
 | 
        socialInfo = socialPlayer.GetPackStruct(ChPyNetSendPack.tagGCSocialPlayer())  
 | 
        sendPack.Player.append(socialInfo)  
 | 
          
 | 
    sendPack.Count = len(sendPack.Player)  
 | 
    NetPackCommon.SendFakePack(curPlayer, sendPack)  
 | 
    return  
 | 
      
 | 
  
 | 
#===============================================================================  
 | 
# #Íæ¼ÒÉ罻Ȧ´æÔÚµ¥ÏòµÄÇé¿ö£¬¼Ç¼±»É罻ȺÌå  
 | 
# #ÀýÈçAÍæ¼Ò±»BÍæ¼Ò¼ÓÈëºÚÃûµ¥£¬µ«ÊÇAÍæ¼Ò²»¸ÐÖª£¬µ±AÍæ¼ÒÉý¼¶Ê±ÒªÍ¨ÖªBÍæ¼Ò  
 | 
# #{AÍæ¼ÒID£º{BÍæ¼ÒID£º¼Ç¼´ÎÊý}}  
 | 
# g_BeSocialList = {}  
 | 
#===============================================================================  
 | 
def AddBeSocial(playerID, tagPlayerID):  
 | 
    if playerID not in PyGameData.g_BeSocialList:  
 | 
        PyGameData.g_BeSocialList[playerID] = {}  
 | 
      
 | 
    if tagPlayerID not in PyGameData.g_BeSocialList[playerID]:  
 | 
        PyGameData.g_BeSocialList[playerID][tagPlayerID] = 1  
 | 
    else:  
 | 
        PyGameData.g_BeSocialList[playerID][tagPlayerID] = PyGameData.g_BeSocialList[playerID][tagPlayerID] + 1  
 | 
          
 | 
def SubBeSocial(playerID, tagPlayerID):  
 | 
    if playerID not in PyGameData.g_BeSocialList:  
 | 
        # °²È«·À·¶Â©¼Ç¼  
 | 
        return  
 | 
      
 | 
    if tagPlayerID not in PyGameData.g_BeSocialList[playerID]:  
 | 
        return  
 | 
      
 | 
    curCount = PyGameData.g_BeSocialList[playerID][tagPlayerID]  
 | 
    PyGameData.g_BeSocialList[playerID][tagPlayerID] = curCount - 1  
 | 
      
 | 
    if curCount == 1:  
 | 
        PyGameData.g_BeSocialList[playerID].pop(tagPlayerID)  
 | 
      
 | 
      
 | 
# ÅÅÐò[id£¬ÔÚÏߣ¬Ê±¼ä] ÓÃÓÚɾ³ý×î½üÁªÏµÈ˺ͳðÈ˵ľÉÊý¾Ý  
 | 
def SortOldList(info1, info2):  
 | 
    result1 = 1 if info1[1] else 0  
 | 
    result2 = 1 if info2[1] else 0  
 | 
      
 | 
    if result1 > result2:  
 | 
        return -1  
 | 
    elif result1 < result2:  
 | 
        return 1  
 | 
    else:  
 | 
        if info1[2] > info2[2]:  
 | 
            return -1  
 | 
        elif info1[2] < info2[2]:  
 | 
            return 1  
 | 
        else:  
 | 
            return 0  
 | 
      
 | 
    return 0  
 | 
  
 | 
  
 |