| #!/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  | 
| import ShareDefine  | 
| #--------------------É罻Ȧ»ù±¾½á¹¹-------------------  | 
| # É罻Ȧ  | 
| 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):  | 
|         if not PlayerControl.GetDBPlayerAccIDByID(tagID):  | 
|             GameWorld.ErrLog("ÊÔͼÌí¼Ó·Ç±¾·þÍæ¼ÒÉç½»¶ÔÏó: tagID=%s,GroupType=%s" % (tagID, self.GroupType))  | 
|             return False  | 
|         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 GetSocialIDList(self): return self.SocialDict.keys()  | 
|       | 
|     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, playerIDList=None):  | 
|         if playerIDList == None:  | 
|             playerIDList = self.SocialDict.keys()  | 
|         pack = ChPyNetSendPack.tagGCGroupPlayers()  | 
|         pack.Clear()  | 
|         pack.GroupType = self.GroupType  | 
|         pack.Players = []  | 
|           | 
|         for playerID in playerIDList:  | 
|             if playerID not in self.SocialDict:  | 
|                 continue  | 
|             player = self.SocialDict[playerID]  | 
|             inPack = ChPyNetSendPack.tagGCGroupPlayer()  | 
|             inPack.PlayerID = player.TagID  | 
|               | 
|             if hasattr(player, 'Intimacy'):  | 
|                 inPack.SortValue = player.Intimacy  | 
|             else:  | 
|                 inPack.SortValue = player.Timestamp if hasattr(player, 'Timestamp') else 0  | 
|             pack.Players.append(inPack)  | 
|               | 
|         pack.Count = len(pack.Players)  | 
|         NetPackCommon.SendFakePack(curPlayer, pack)  | 
|         return  | 
|   | 
|       | 
|     # Í¨ÖªÄ³Íæ¼ÒÐÅÏ¢  | 
|     def Sync_SocialPlayer(self, curPlayer, tagID):  | 
|         sendPack = ChPyNetSendPack.tagGCSocialPlayers()  | 
|         sendPack.Clear()  | 
|         sendPack.Count = 1  | 
|         sendPack.Player = []  | 
|         socialManager = PyDataManager.GetPersonalSocialManager()  | 
|         socialPlayer = socialManager.GetSocialPlayer(tagID)  | 
|         if not socialPlayer:  | 
|             return  | 
|         socialInfo = socialPlayer.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):  | 
|         return  | 
|         #=======================================================================  | 
|         # 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.TagID  | 
|         #    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 len=%s" % (cnt, len(savaData)))  | 
|         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 Intimacys(SocialPlayers):  | 
|     def __init__(self, PlayerID):  | 
|         super(Intimacys, self).__init__(PlayerID, PyGameDataStruct.tagDBPyPlayerIntimacy,   | 
|                                         ChConfig.Def_SocialGroup_Intimacy)  | 
|           | 
|     def GetIntimacyObj(self, tagID):  | 
|         if tagID not in self.SocialDict:  | 
|             self.Add(tagID)  | 
|         return self.SocialDict.get(tagID)  | 
|       | 
|     def GetTagIntimacy(self, tagID):  | 
|         intimacyObj = self.Find(tagID)  | 
|         return intimacyObj.Intimacy if intimacyObj else 0  | 
|       | 
|     def AddIntimacy(self, curPlayer, tagID, addValue):  | 
|         ## Ôö¼ÓÇ×ÃܶȠ- Ö§³ÖÕý¸º¡¢Ö§³ÖÀëÏߣ¬ curPlayer ¿ÉÄÜΪNone  | 
|         intimacyObj = self.GetIntimacyObj(tagID)  | 
|         if not intimacyObj:  | 
|             return 0  | 
|         if not intimacyObj.Intimacy and addValue < 0:  | 
|             return 0  | 
|         intimacyObj.Intimacy = min(max(0, intimacyObj.Intimacy + addValue), ShareDefine.Def_UpperLimit_DWord)  | 
|         nowIntimacy = intimacyObj.Intimacy  | 
|           | 
|         if nowIntimacy <= 0:  | 
|             self.Delete(tagID)  | 
|               | 
|         if not curPlayer:  | 
|             return nowIntimacy  | 
|           | 
|         self.__SyncMapServerCoupleIntimacy(curPlayer, tagID)  | 
|           | 
|         tagName = ""  | 
|         socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(tagID)  | 
|         if socialPlayer:  | 
|             tagName = socialPlayer.playerInfo.PlayerName  | 
|               | 
|         if addValue > 0:  | 
|             PlayerControl.NotifyCode(curPlayer, "AddIntimacy", [tagName, addValue])  | 
|         elif addValue < 0:  | 
|             PlayerControl.NotifyCode(curPlayer, "DelIntimacy", [tagName, abs(addValue)])  | 
|               | 
|         self.Sync_SocialsInfo(curPlayer, [tagID])  | 
|         return nowIntimacy  | 
|       | 
|     def SetIntimacy(self, curPlayer, tagID, setValue):  | 
|         ## Ö±½ÓÉèÖÃÇ×ÃܶȠ- Ò»°ãGM²âÊÔʹÓà  | 
|         intimacyObj = self.GetIntimacyObj(tagID)  | 
|         if not intimacyObj:  | 
|             return 0  | 
|         intimacyObj.Intimacy = setValue  | 
|         if curPlayer:  | 
|             self.__SyncMapServerCoupleIntimacy(curPlayer, tagID)  | 
|             self.Sync_SocialsInfo(curPlayer, [tagID])  | 
|         return intimacyObj.Intimacy  | 
|       | 
|     def __SyncMapServerCoupleIntimacy(self, curPlayer, tagID):  | 
|         ## Í¬²½µØÍ¼Íæ¼Ò°éÂÂÇ×ÃÜ¶È  | 
|         playerID = curPlayer.GetPlayerID()  | 
|         couple = PyDataManager.GetDBPyCoupleManager().GetCouple(playerID)  | 
|         if not couple:  | 
|             return  | 
|         if couple.GetCoupleID(playerID) != tagID:  | 
|             return  | 
|         self.SyncMapServerIntimacy(curPlayer, tagID)  | 
|         return  | 
|       | 
|     def SyncMapServerIntimacy(self, curPlayer, tagID):  | 
|         ## Í¬²½µØÍ¼Íæ¼Ò°éÂÂÇ×ÃÜ¶È  | 
|         playerID = curPlayer.GetPlayerID()  | 
|         intimacyValue = 0  | 
|         intimacyObj = self.GetIntimacyObj(tagID)  | 
|         if intimacyObj:  | 
|             intimacyValue = intimacyObj.Intimacy  | 
|         cmdInfo = ["SyncMapServerIntimacy", [tagID, intimacyValue]]  | 
|         PlayerControl.MapServer_QueryPlayer_DoLogic(curPlayer, "Love", cmdInfo, playerID)  | 
|         return  | 
|       | 
| # Õû¸öÓÎÏ·µÄÇ×ÃܹÜÀí  | 
| class IntimacyManager(object):  | 
|     def __init__(self):  | 
|         self.PlayerIntimacys = {}     # PyGameDataStruct.tagDBPyPlayerIntimacy  | 
|         return  | 
|       | 
|     # Ôö¼ÓË«·½Ç×ÃÜ¶È  | 
|     def AddIntimacyBoth(self, aID, bID, addValue):  | 
|           | 
|         for playerID, tagPlayerID in {aID:bID, bID:aID}.items():  | 
|             intimacys = self.GetIntimacys(playerID)  | 
|             if not intimacys:  | 
|                 continue  | 
|             intimacyObj = intimacys.GetIntimacyObj(tagPlayerID)  | 
|             if not intimacyObj:  | 
|                 continue  | 
|               | 
|             curIntimacy = intimacyObj.Intimacy  | 
|             curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|             updIntimacy = intimacys.AddIntimacy(curPlayer, tagPlayerID, addValue)  | 
|               | 
|             GameWorld.DebugLog("Ôö¼ÓÇ×ÃܶÈ: playerID=%s,tagPlayerID=%s,curIntimacy=%s,addValue=%s,updIntimacy=%s"   | 
|                                % (playerID, tagPlayerID, curIntimacy, addValue, updIntimacy), playerID)  | 
|         return  | 
|       | 
|     # ¿Û³ýË«·½Ç×ÃܶȠ- °´°Ù·Ö±È  | 
|     def DelIntimacyBothPer(self, aID, bID, delPer):  | 
|           | 
|         for playerID, tagPlayerID in {aID:bID, bID:aID}.items():  | 
|             intimacys = self.GetIntimacys(playerID)  | 
|             if not intimacys:  | 
|                 continue  | 
|             intimacyObj = intimacys.GetIntimacyObj(tagPlayerID)  | 
|             if not intimacyObj:  | 
|                 continue  | 
|               | 
|             curIntimacy = intimacyObj.Intimacy  | 
|             delValue = -max(1, int(curIntimacy * delPer / 100.0))  | 
|             curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|             updIntimacy = intimacys.AddIntimacy(curPlayer, tagPlayerID, delValue)  | 
|             GameWorld.DebugLog("¿Û³ýÇ×ÃܶÈ: playerID=%s,tagPlayerID=%s,curIntimacy=%s,delPer=%s,delValue=%s,updIntimacy=%s"   | 
|                                % (playerID, tagPlayerID, curIntimacy, delPer, delValue, updIntimacy), playerID)  | 
|               | 
|         return  | 
|       | 
|     # »ñÈ¡Ç×ÃÜ×é  | 
|     def GetIntimacys(self, playerID):  | 
|         if not PlayerControl.GetDBPlayerAccIDByID(playerID):  | 
|             GameWorld.ErrLog("ÊÔͼ»ñÈ¡·Ç±¾·þÍæ¼ÒÇ×ÃÜ×é: playerID=%s" % playerID)  | 
|             return  | 
|         if playerID not in self.PlayerIntimacys:  | 
|             self.PlayerIntimacys[playerID] = Intimacys(playerID)  | 
|         return self.PlayerIntimacys[playerID]  | 
|       | 
|     # ±£´æÇ×ÃÜÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  | 
|     def GetSaveData(self):  | 
|         savaData = ""  | 
|         cntData = ""  | 
|         cnt = 0  | 
|         for intimacys in self.PlayerIntimacys.values():  | 
|             for playerIntimacy in intimacys.SocialDict.values():  | 
|                 cnt += 1  | 
|                 savaData += playerIntimacy.getBuffer()  | 
|           | 
|         GameWorld.Log("Save DBPyPlayerIntimacy cnt :%s len=%s" % (cnt, len(savaData)))  | 
|         return CommFunc.WriteDWORD(cntData, cnt) + savaData  | 
|   | 
|     # ´ÓÊý¾Ý¿âÔØÈëÇ×ÃÜÊý¾Ý  | 
|     def LoadPyGameData(self, datas, pos, dataslen):  | 
|         cnt, pos = CommFunc.ReadDWORD(datas, pos)  | 
|         GameWorld.Log("Load DBPyPlayerIntimacy cnt :%s"%cnt)  | 
|           | 
|         self.PlayerIntimacys = {}  | 
|           | 
|         for i in xrange(cnt):  | 
|             playerIntimacy = PyGameDataStruct.tagDBPyPlayerIntimacy()  | 
|             playerIntimacy.clear()  | 
|             pos += playerIntimacy.readData(datas, pos, dataslen)  | 
|             playerID = playerIntimacy.PlayerID  | 
|             if playerID not in self.PlayerIntimacys:  | 
|                 self.PlayerIntimacys[playerID] = Intimacys(playerID)   | 
|             self.PlayerIntimacys[playerID].SocialDict[playerIntimacy.TagID] = playerIntimacy  | 
|               | 
|             AddBeSocial(playerIntimacy.TagID, playerIntimacy.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 len=%s" % (cnt, len(savaData)))  | 
|         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 len=%s" % (cnt, len(savaData)))  | 
|         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 len=%s" % (cnt, len(savaData)))  | 
|         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 ÍÑ»úÔÚÏß    | 
|         self.playerInfo.Face = curPlayer.GetFace()  | 
|         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  | 
|         packStruct.Face = self.playerInfo.Face  | 
|         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.FindViewCache(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  | 
|             playerSocial.Face = 0  | 
|         else:  | 
|             cacheDict = PlayerViewCache.GetCachePropDataDict(curCache)  | 
|       | 
|             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  | 
|             playerSocial.Face = cacheDict.get("Face", 0)  | 
|               | 
|         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 SyncSocialCoupleInfo(self, curPlayer):  | 
|         coupleMgr = PyDataManager.GetDBPyCoupleManager()  | 
|         coupleList = []  | 
|         for playerID in self.SocialInfo.keys():  | 
|             couple = coupleMgr.GetCouple(playerID)  | 
|             if not couple:  | 
|                 continue  | 
|             socialCouple = ChPyNetSendPack.tagGCSocialCouple()  | 
|             socialCouple.PlayerID = playerID  | 
|             socialCouple.CoupleID = couple.GetCoupleID(playerID)  | 
|             coupleList.append(socialCouple)  | 
|               | 
|         if not coupleList:  | 
|             return  | 
|           | 
|         clientPack = ChPyNetSendPack.tagGCSocialCouples()  | 
|         clientPack.Player = coupleList  | 
|         clientPack.Count = len(clientPack.Player)  | 
|         NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|         return  | 
|       | 
|     # ±£´æÓÐÉç½»µÄÍæ¼ÒÐÅÏ¢  | 
|     def GetSaveData(self):  | 
|         savaData = ""  | 
|         cntData = ""  | 
|         cnt = 0  | 
|         for playerID, socialPlayer in self.SocialInfo.items():  | 
|             if PyGameData.g_dbPlayerIDMap and not PlayerControl.GetDBPlayerAccIDByID(playerID):  | 
|                 GameWorld.ErrLog("·Ç±¾·þÉç½»Íæ¼Ò£¬²»´æµµ£¡ playerID=%s" % playerID)  | 
|                 continue  | 
|             cnt += 1  | 
|             savaData += socialPlayer.playerInfo.getBuffer()  | 
|           | 
|         GameWorld.Log("SaveSocialData cnt :%s len=%s" % (cnt, len(savaData)))  | 
|         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 GetSocialPlayerName(playerID):  | 
|     ## »ñÈ¡Íæ¼ÒÉç½»êÇ³Æ  | 
|     socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(playerID)  | 
|     if socialPlayer:  | 
|         return socialPlayer.playerInfo.PlayerName  | 
|       | 
|     curCache = PlayerViewCache.FindViewCache(playerID)  | 
|     if curCache:  | 
|         cacheDict = PlayerViewCache.GetCachePropDataDict(curCache)  | 
|         return cacheDict["Name"]  | 
|       | 
|     if playerID < 10000:  | 
|         return "testName%s" % playerID  | 
|       | 
|     return ""  | 
|   | 
| def GetSocialPlayerJob(playerID):  | 
|     ## »ñÈ¡Íæ¼ÒÉç½»Ö°Òµ  | 
|     socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(playerID)  | 
|     if socialPlayer:  | 
|         return socialPlayer.playerInfo.Job  | 
|       | 
|     curCache = PlayerViewCache.FindViewCache(playerID)  | 
|     if curCache:  | 
|         cacheDict = PlayerViewCache.GetCachePropDataDict(curCache)  | 
|         return cacheDict["Job"]  | 
|       | 
|     if playerID < 10000:  | 
|         job = 2 if playerID % 2 == 0 else 1  | 
|         return job  | 
|       | 
|     return 1  | 
|   | 
| # ÏòÏà¹ØÁªµÄÉç½»¶ÔÏó֪ͨµ±Ç°Íæ¼ÒÐÅÏ¢  | 
| # ×î½üÁªÏµÈË¡¢³ðÈ˺ͺÚÃûµ¥´æÔÚµ¥ÏòÇé¿ö£¬ Ïò¶Ô·½Í¨ÖªÐÅÏ¢  | 
| 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)  | 
|     return  | 
|   | 
| def NotifySocialCoupleChange(playerID, coupleID):  | 
|     ## Í¨Öª°é±ä¸ü¸øÏà¹ØÉç½»ÈËÔ±  | 
|     if playerID not in PyGameData.g_BeSocialList:  | 
|         return  | 
|       | 
|     couple = ChPyNetSendPack.tagGCSocialCouple()  | 
|     couple.PlayerID = playerID  | 
|     couple.CoupleID = coupleID  | 
|       | 
|     clientPack = ChPyNetSendPack.tagGCSocialCouples()  | 
|     clientPack.Player.append(couple)  | 
|     clientPack.Count = len(clientPack.Player)  | 
|       | 
|     for tagID in PyGameData.g_BeSocialList[playerID]:  | 
|         player = GameWorld.GetPlayerManager().FindPlayerByID(tagID)  | 
|         if not player:  | 
|             continue  | 
|           | 
|         if PlayerControl.GetIsTJG(player):  | 
|             continue  | 
|           | 
|         NetPackCommon.SendFakePack(player, clientPack)  | 
|     return  | 
|       | 
|   | 
| #¸üÐÂÍæ¼ÒÉç½»ÐÅÏ¢  | 
| def UpdateSocialInfo(playerID, notifyType, value):  | 
|     socialPlayer = PyDataManager.GetPersonalSocialManager().GetSocialPlayer(playerID)  | 
|     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  | 
|     elif notifyType == IPY_PlayerDefine.CDBPlayerRefresh_Face:  | 
|         socialPlayer.playerInfo.Face = value  | 
|     else:  | 
|         return  | 
|       | 
|     Notify_All(playerID, notifyType, value)  | 
|     return  | 
|   | 
| # Ïòµ±Ç°Íæ¼Ò֪ͨÏà¹ØÁªµÄËùÓÐÍæ¼ÒÐÅÏ¢  | 
| 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 []  | 
|     intimacys = PyDataManager.GetIntimacyManager().GetIntimacys(playerID)  | 
|     list5 = intimacys.SocialDict.keys() if intimacys else []  | 
|   | 
|     #ÐÅÏ¢²¢¼¯ºó·¢ËÍ, Íæ¼ÒID  | 
|     resultSet = set(list1)|set(list2)|set(list3)|set(list4)|set(list5)  | 
|       | 
|     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)  | 
|       | 
|     socialManager.SyncSocialCoupleInfo(curPlayer)  | 
|     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  | 
|   | 
|   |