| #!/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  | 
|   | 
|   |