| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package CrossRealmPlayer  | 
| #  | 
| # @todo:¿ç·þÍæ¼Ò  | 
| # @author hxp  | 
| # @date 2018-12-21  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ¿ç·þÍæ¼Ò  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2018-12-21 18:00"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import GameWorld  | 
| import ShareDefine  | 
| import CrossRealmMsg  | 
| import ReadChConfig  | 
| import ChConfig  | 
| import PlayerControl  | 
| import PlayerViewCache  | 
| import PlayerCompensation  | 
| import ChPyNetSendPack  | 
| import PlayerDBGSEvent  | 
| import NetPackCommon  | 
| import IpyGameDataPY  | 
| import PyGameData  | 
| import PlayerDBOper  | 
|   | 
| # »ñÈ¡Íæ¼Ò¿ç·þ·þÎñÆ÷ÉϵÄÃû×Ö  | 
| #===============================================================================  | 
| # def GetCrossPlayerName(curPlayer):  | 
| #    # Í¨¹ýÓÎÏ·Õ˺ÅÖÐµÄÆ½Ì¨±êÖ¾»ñÈ¡Ãû³Æ£¬Ä¿Ç°Îªspid  | 
| #    playerName = curPlayer.GetPlayerName()  | 
| #    nameFormat = ReadChConfig.GetPyMongoConfig("Merge", "NameFormat", True)  | 
| #    if not nameFormat:  | 
| #        return playerName  | 
| #      | 
| #    opName = ReadChConfig.GetPyMongoConfig("Merge", "OpName_%s" % GameWorld.GetPlayerPlatform(curPlayer))  | 
| #   | 
| #    return (nameFormat%{"opname":opName, "sid":GameWorld.GetPlayerServerID(curPlayer)}).decode('gbk').encode(GameWorld.GetCharacterEncoding()) + playerName  | 
| #===============================================================================  | 
|   | 
| # »ñÈ¡Íæ¼Ò¿ç·þ·þÎñÆ÷ÉϵÄÃû×Ö  | 
| def GetCrossPlayerName(curPlayer):  | 
|     # Í¨¹ýÓÎÏ·Õ˺ÅÖÐµÄÆ½Ì¨±êÖ¾»ñÈ¡Ãû³Æ£¬Ä¿Ç°Îªspid  | 
|     playerName = curPlayer.GetName()  | 
|       | 
|     opName = ReadChConfig.GetPyMongoConfig("Merge", "OpName_%s_%s" % (GameWorld.GetPlayerPlatform(curPlayer),   | 
|                                            GameWorld.GetPlayerServerSID(curPlayer)))  | 
|       | 
|     if not opName:  | 
|         return playerName  | 
|       | 
|     return opName.decode('gbk').encode(GameWorld.GetCharacterEncoding()) + playerName  | 
|   | 
| def GetCrossZoneIpyDataByZoneID(mapID, zoneID):  | 
|     ## »ñÈ¡¿ç·þ·ÖÇø  | 
|     zoneTypeName = ChConfig.Def_CrossZoneTypeName.get(mapID, "CrossZoneComm")  | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     return IpyGameDataPY.GetIpyGameData(zoneTypeName, crossZoneName, zoneID)  | 
|   | 
| def GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID):  | 
|     ## »ñÈ¡¿ç·þ·ÖÇø  | 
|     zoneTypeName = ChConfig.Def_CrossZoneTypeName.get(mapID, "CrossZoneComm")  | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition(zoneTypeName, {"CrossZoneName":crossZoneName}, True)  | 
|     if not ipyDataList:  | 
|         return  | 
|     for ipyData in ipyDataList:  | 
|         serverGroupIDList = ipyData.GetServerGroupIDList()  | 
|         for serverGroupIDInfo in serverGroupIDList:  | 
|             if (isinstance(serverGroupIDInfo, tuple) and serverGroupIDInfo[0] <= serverGroupID <= serverGroupIDInfo[1]) \  | 
|                 or (isinstance(serverGroupIDInfo, int) and serverGroupIDInfo == serverGroupID):  | 
|                 return ipyData  | 
|     GameWorld.ErrLog("ûÓÐÕÒµ½¿ç·þÍæ·¨¶ÔÓ¦·ÖÇø! mapID=%s, serverGroupID=%s, zoneTypeName=%s" % (mapID, serverGroupID, zoneTypeName))  | 
|     return  | 
|   | 
| def GetCrossZoneIpyDataListByServerGroupID(mapID, serverGroupID):  | 
|     ## »ñÈ¡¿ç·þ³£¹æ·ÖÇøÁÐ±í  | 
|     if serverGroupID:  | 
|         ipyData = GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID)  | 
|         if not ipyData:  | 
|             return  | 
|         ipyDataList = [ipyData]  | 
|     else:  | 
|         crossZoneName = GameWorld.GetCrossZoneName()  | 
|         zoneTypeName = ChConfig.Def_CrossZoneTypeName.get(mapID, "CrossZoneComm")  | 
|         ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition(zoneTypeName, {"CrossZoneName":crossZoneName}, True)  | 
|     return ipyDataList  | 
|   | 
| def GetServerCommCrossZoneID(serverGroupID):  | 
|     ## »ñÈ¡¿ç·þ³£¹æ·ÖÇø  | 
|     zoneTypeName = "CrossZoneComm"  | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition(zoneTypeName, {"CrossZoneName":crossZoneName}, True)  | 
|     if not ipyDataList:  | 
|         return 0  | 
|     for ipyData in ipyDataList:  | 
|         serverGroupIDList = ipyData.GetServerGroupIDList()  | 
|         for serverGroupIDInfo in serverGroupIDList:  | 
|             if (isinstance(serverGroupIDInfo, tuple) and serverGroupIDInfo[0] <= serverGroupID <= serverGroupIDInfo[1]) \  | 
|                 or (isinstance(serverGroupIDInfo, int) and serverGroupIDInfo == serverGroupID):  | 
|                 return ipyData.GetZoneID()  | 
|     return 0  | 
|   | 
| def GetServerCrossZoneMapIpyData(zoneID, mapID):  | 
|     ## »ñÈ¡±¾·þ¶ÔÓ¦¿ç·þÍæ·¨·ÖÇøµØÍ¼ÐÅÏ¢ - ½öÊÊÓÃÓڹ̶¨µØÍ¼¼°ÐéÄâ·ÖÏߵĿç·þÍæ·¨  | 
|     if mapID not in ChConfig.Def_CrossZoneMapTableName:  | 
|         return  | 
|     tableName = ChConfig.Def_CrossZoneMapTableName[mapID]  | 
|     return IpyGameDataPY.GetIpyGameDataByCondition(tableName, {"ZoneID":zoneID})  | 
|   | 
| def IsCrossServerOpen():  | 
|     ## ¿ç·þ·þÎñÆ÷ÊÇ·ñ¿ª·ÅÖÐ  | 
|     return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossServerOpen)  | 
|   | 
| def Sync_CrossCommInitDataToClientServer(serverGroupID=0):  | 
|     ''' Í¬²½¿ç·þ³£¹æÍ¨ÓÃÊý¾Ýµ½×Ó·þÎñÆ÷  | 
|     @param serverGroupID: Îª0ʱͬ²½ËùÓÐ×Ó·þ  | 
|     '''  | 
|       | 
|     isOpen = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossServerOpen)  | 
|     crossZoneName = GameWorld.GetCrossZoneName()  | 
|     GameWorld.Log("֪ͨµ±Ç°¿ç·þ·þÎñÆ÷״̬: isOpen=%s,crossZoneName=%s,syncServerGroupID=%s" % (isOpen, crossZoneName, serverGroupID))  | 
|     serverGroupIDList = [serverGroupID] if serverGroupID else []  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossServerState, {"isOpen":isOpen, "crossZoneName":crossZoneName}, serverGroupIDList)  | 
|     return  | 
|   | 
| def DoChangeCrossServerState(isOpen):  | 
|     ## ¿ç·þ·þÎñÆ÷״̬±ä¸ü  | 
|       | 
|     PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_CrossServerClose, 0 if isOpen else 1) # ´æDBµÄ·´×Å´æ  | 
|     GameWorld.GetGameWorld().SetDict(ShareDefine.Def_Notify_WorldKey_CrossServerOpen, isOpen)  | 
|       | 
|     if not isOpen:  | 
|         # ÌßµôËùÓÐÍæ¼Ò  | 
|         playerManager = GameWorld.GetPlayerManager()  | 
|         for i in xrange(playerManager.GetActivePlayerCount()):  | 
|             curPlayer = playerManager.GetActivePlayerAt(i)  | 
|             if curPlayer == None:  | 
|                 continue  | 
|             PlayerControl.SetCrossMapID(curPlayer, 0)  | 
|             curPlayer.Kick(0)  | 
|               | 
|     # ¹ã²¥ËùÓÐ×Ó·þ£¬±¾·þÎñÆ÷½øÈëά»¤  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossServerState, {"isOpen":isOpen})  | 
|     return  | 
|   | 
| def CrossServerMsg_CrossServerState(msgData):  | 
|     ## ×Ó·þÊÕµ½¿ç·þ·þÎñÆ÷״̬±ä¸ü£¬×Ó·þ²»´æDB£¬Ä¬ÈÏ¿ç·þά»¤ÖУ¬Á¬½Ó¿ç·þ³É¹¦ºóÓÉ¿ç·þͬ²½×´Ì¬Ö±½Ó¸üе½×ֵ伴¿É£¬Ã»Á¬ÉϾÍĬÈÏά»¤ÖÐ  | 
|     if "crossZoneName" in msgData:  | 
|         PyGameData.g_crossZoneName = msgData["crossZoneName"]  | 
|         GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossZoneName, PyGameData.g_crossZoneName)  | 
|           | 
|     isOpen = msgData["isOpen"]  | 
|     isOpen = 1 if isOpen else 0  | 
|     GameWorld.Log("ÊÕµ½¿ç·þ·þÎñÆ÷״̬±ä¸ü: ÊÇ·ñÕý³£¿ª·ÅÖÐ=%s" % isOpen)  | 
|     GameWorld.GetGameWorld().SetDict(ShareDefine.Def_Notify_WorldKey_CrossServerOpen, isOpen)  | 
|       | 
|     if not isOpen:  | 
|         playerManager = GameWorld.GetPlayerManager()  | 
|         for i in xrange(playerManager.GetActivePlayerCount()):  | 
|             curPlayer = playerManager.GetActivePlayerAt(i)  | 
|             if curPlayer == None:  | 
|                 continue  | 
|             PlayerControl.SetCrossMapID(curPlayer, 0)  | 
|               | 
|     GameWorld.GetGameWorld().SendCrossServerStateToLoginServer(isOpen)  | 
|     # Í¨ÖªµØÍ¼  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossServerOpen, isOpen)  | 
|     return  | 
|   | 
| def PlayerExitCrossServer(curPlayer):  | 
|     ## Íæ¼ÒÍ˳ö¿ç·þ·þÎñÆ÷  | 
|       | 
|     if not GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     # Í¨Öª×Ó·þÍæ¼ÒÍ˳ö¿ç·þ·þÎñÆ÷  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_ExitCrossServer, playerID, [serverGroupID])  | 
|       | 
|     # ÉèÖ÷ǿç·þ״̬£¬ÌßÏÂÏß  | 
|     PlayerControl.SetCrossMapID(curPlayer, 0)  | 
|     curPlayer.Kick(0)  | 
|     GameWorld.Log("PlayerExitCrossServer...serverGroupID=%s" % serverGroupID, playerID)  | 
|     return  | 
|   | 
| def CrossServerMsg_ExitCrossServer(msgData):  | 
|     ## ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄÍæ¼ÒÍ˳ö¿ç·þ·þÎñÆ÷  | 
|     playerID = msgData  | 
|     GameWorld.Log("ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄÍæ¼ÒÍ˳ö¿ç·þ·þÎñÆ÷: playerID=%s" % playerID)  | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|     if not curPlayer:  | 
|         GameWorld.Log("    Í˳ö¿ç·þʱ±¾·þÍæ¼Ò²»ÔÚÏß!", playerID)  | 
|         DoOfflinePlayerExitCrossServer(playerID)  | 
|         return  | 
|     PlayerControl.SetCrossMapID(curPlayer, 0)  | 
|     return  | 
|   | 
| def DoOfflinePlayerExitCrossServer(playerID):  | 
|     ## ´¦ÀíÀëÏßÍæ¼ÒÍ˳ö¿ç·þ·þÎñÆ÷¸üÐÂDBÊý¾ÝÂß¼  | 
|       | 
|     PlayerDBOper.UpdateDBOper(PlayerDBOper.Table_DBPlayer, {"PlayerID":playerID}, {"ExAttr5":0})  | 
|     return  | 
|   | 
| def SendCrossRealmReg(curPlayer, registerMap, mapID=0, dataMapID=0, copyMapID=0, posX=0, posY=0, lineID=0):  | 
|     # ·¢ËÍ¿ç·þÕ˺Å×¢²áÉÏ´«Êý¾Ý  | 
|     # @param mapID: ÕæÊµ³¡¾°µØÍ¼ID  | 
|     # @param dataMapID: ÕæÊµ³¡¾°µØÍ¼ID¶ÔÓ¦³¡¾°Êý¾ÝµØÍ¼ID  | 
|       | 
|     # ÉèÖÃÉÏ´«Êý¾ÝµÄ»î¶¯ÀàÐÍ  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_CrossRegisterMap, registerMap)  | 
|     sysMsg = str([registerMap, mapID, dataMapID, copyMapID, posX, posY, lineID])  | 
|     curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossRealmReg", sysMsg, len(sysMsg))              | 
|     GameWorld.Log("SendCrossRealmReg registerMap=%s,mapID=%s,dataMapID=%s,copyMapID=%s,posX=%s,posY=%s"   | 
|                   % (registerMap, mapID, dataMapID, copyMapID, posX, posY), curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
| def OnCrossRealmRegOK(playerID, msgList, tick):   | 
|     ## ¿ç·þ±¨Ãû½á¹û  | 
|       | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|     if not curPlayer:  | 
|         return  | 
|       | 
|     if not IsCrossServerOpen():  | 
|         return  | 
|       | 
|     registerMap = msgList[0]  | 
|     playerRegisterMap = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_CrossRegisterMap)  | 
|     if playerRegisterMap and registerMap != playerRegisterMap:  | 
|         return  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_CrossRegisterMap, 0)  | 
|       | 
|     GameWorld.Log("¿ç·þ±¨Ãû³É¹¦ , registerMap=%s" % (registerMap), playerID)  | 
|       | 
|     # ¿ç·þPKÉÏ´«Êý¾ÝÍê±Ï£¬Í¨Öª¿ç·þ·þÎñÆ÷£¬×¼±¸Íê±Ï  | 
|     if registerMap == ChConfig.Def_FBMapID_CrossRealmPK:  | 
|         regVSRoomID = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MergeRegisterRoomID)   | 
|         vsRoomID = curPlayer.GetVsRoomId()  | 
|           | 
|         if regVSRoomID != vsRoomID:  | 
|             GameWorld.Log("ÉÏ´«¿ç·þ·þÎñÆ÷µÄ regVSRoomID=%s ÓëÍæ¼Òµ±Ç°µÄ roomID=%s ²»Í¬!²»·¢ËÍ×¼±¸Íê±Ï£¡"   | 
|                           % (regVSRoomID, vsRoomID), playerID)  | 
|             return  | 
|           | 
|         dataMsg = {  | 
|                    "accID":curPlayer.GetAccID(), # ½ÇÉ«Õ˺ÅID  | 
|                    "playerID":playerID, # ½ÇÉ«ID  | 
|                    "vsRoomID":vsRoomID, # ËùÊô¶ÔÕ½·¿¼äID  | 
|                    }  | 
|         CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PKPrepareOK, dataMsg)  | 
|         GameWorld.Log("֪ͨ¿ç·þ·þÎñÆ÷, Íæ¼ÒÆ¥ÅäPK×¼±¸Íê±Ï£¡%s" % str(dataMsg), playerID)  | 
|           | 
|     # ÆäËûµÄ£¬ÔÚÉÏ´«Êý¾ÝÍê±Ïºó£¬Ê¹ÓÃͨÓõÄ֪ͨ¿É½øÈë¿ç·þ  | 
|     else:  | 
|         NotifyCanEnterMergeServer(curPlayer, registerMap)  | 
|           | 
|     # hxp 2015.09.10 ¿ç·þboss£¬ºóÃæµÄÔÝʱ²»ÐèÒª  | 
|     return  | 
|   | 
|   | 
| def NotifyCanEnterMergeServer(curPlayer, registerMap):  | 
|     # Í¨Óðü£¬Í¨Öª¿Í»§¶Ë¿É½øÈë¿ç·þ·þÎñÆ÷  | 
|     return  | 
|   | 
| #// C0 03 Ç¿ÖÆÍ˳ö¿ç·þ״̬ #tagCGForceQuitCrossState  | 
| #  | 
| #struct    tagCGForceQuitCrossState  | 
| #{  | 
| #    tagHead        Head;  | 
| #};  | 
| def OnForceQuitCrossState(index, clientData, tick):  | 
|     ''' Ô¼¶¨¸Ã·â°ü½öÍæ¼Òµ±Ç°´¦ÓÚ¿ç·þ״̬£¬µ«ÊÇÒ»Ö±Á¬²»ÉÏ¿ç·þ·þÎñÆ÷ʱ²Å»á·¢´Î°üÇ¿ÖÆÖØÖÿç·þ״̬  | 
|                 Ò»°ãÊÇ¿ç·þ·þÎñÆ÷Òì³£»òÆäËû´íÎóµ¼ÖÂÎÞ·¨µÇ¼¿ç·þ·þÎñÆ÷  | 
|     '''  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     GameWorld.ErrLog("ijЩÒì³£Çé¿öÏ£¬Ç°¶ËÇ¿ÖÆ·¢°üÍ˳ö¿ç·þ״̬! ", curPlayer.GetPlayerID())  | 
|     PlayerControl.SetCrossMapID(curPlayer, 0)  | 
|     return  | 
|   | 
| #// C0 02 ²é¿´¿ç·þÍæ¼ÒÐÅÏ¢ #tagCGViewCrossPlayerInfo  | 
| #  | 
| #struct    tagCGViewCrossPlayerInfo  | 
| #{  | 
| #    tagHead        Head;  | 
| #    DWORD        PlayerID;    // ¿ç·þÍæ¼ÒID  | 
| #    BYTE        EquipClassLV;    //´óÓÚ0Ϊ²é¿´Ö¸¶¨¾³½ç½××°±¸ÐÅÏ¢,  0Ϊ²é¿´Ä¬ÈÏÐÅÏ¢  | 
| #};  | 
| def OnViewCrossPlayerInfo(index, clientData, tick):  | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     tagPlayerID = clientData.PlayerID  | 
|     equipClassLV = clientData.EquipClassLV  | 
|     curCache = PlayerViewCache.FindViewCache(tagPlayerID)  | 
|     ## ±¾·þÓУ¬Ö±½Ó»Ø¿Í»§¶Ë  | 
|     if curCache:  | 
|         GameWorld.DebugLog("²é¿´¿ç·þÍæ¼Ò£¬ÊDZ¾·þÍæ¼Ò£¬Ö±½Ó»Ø¸´!tagPlayerID=%s" % (tagPlayerID), playerID)  | 
|         PlayerViewCache.Sync_PlayerCache(curPlayer, curCache, equipClassLV)  | 
|         return  | 
|       | 
|     if tagPlayerID in PyGameData.g_crossPlayerViewCache:  | 
|         validChaheTime = 10 * 60 * 1000  | 
|         cacheInfo, updTick = PyGameData.g_crossPlayerViewCache[tagPlayerID]  | 
|         if tick - updTick <= validChaheTime:  | 
|             GameWorld.DebugLog("²é¿´¿ç·þÍæ¼ÒÊý¾Ýͬ²½CDÖУ¬Ö±½ÓÓûº´æÊý¾Ý»Ø¸´!tagPlayerID=%s" % (tagPlayerID), playerID)  | 
|             SyncPlayerViewCrossPlayerInfo(curPlayer, tagPlayerID, equipClassLV, cacheInfo)  | 
|             return  | 
|           | 
|         for crossPlayerID, cacheInfoList in PyGameData.g_crossPlayerViewCache.items():  | 
|             if tick - cacheInfoList[1] > validChaheTime:  | 
|                 PyGameData.g_crossPlayerViewCache.pop(crossPlayerID)  | 
|                   | 
|     # ·¢ËÍ¿ç·þ·þÎñÆ÷²éѯ  | 
|     dataMsg = {"tagPlayerID":tagPlayerID, "playerID":playerID, "equipClassLV":equipClassLV}  | 
|     CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_ViewPlayerCache, dataMsg)  | 
|     return  | 
|   | 
| def ClientServerMsg_ViewPlayerCache(serverGroupID, msgData):  | 
|     tagPlayerID = msgData["tagPlayerID"]  | 
|     playerID = msgData["playerID"]  | 
|     equipClassLV = msgData["equipClassLV"]  | 
|       | 
|     GameWorld.Log("ÊÕµ½×Ó·þ²é¿´¿ç·þÍæ¼ÒÐÅÏ¢: serverGroupID=%s,playerID=%s,tagPlayerID=%s" % (serverGroupID, playerID, tagPlayerID))  | 
|       | 
|     cacheInfo = {}  | 
|     curCache = PlayerViewCache.FindViewCache(tagPlayerID)  | 
|     if curCache:  | 
|         cacheInfo = {"PropData":curCache.PropData, "PlusData":curCache.PlusData}  | 
|         for classLV in xrange(1, 15 + 1):  | 
|             attrName = "ItemData%s" % classLV  | 
|             if hasattr(curCache, attrName):  | 
|                 cacheInfo[attrName] = getattr(curCache, attrName)  | 
|                   | 
|     viewPlayerCacheRet = [playerID, tagPlayerID, equipClassLV, cacheInfo]  | 
|     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_ViewPlayerCacheRet, viewPlayerCacheRet, [serverGroupID])  | 
|     return  | 
|   | 
| def CrossServerMsg_ViewPlayerCacheRet(msgData, tick):  | 
|       | 
|     playerID, tagPlayerID, equipClassLV, cacheInfo = msgData  | 
|     GameWorld.Log("ÊÕµ½¿ç·þ·þÎñÆ÷»Ø¸´µÄ²é¿´Íæ¼ÒÐÅÏ¢: playerID=%s,tagPlayerID=%s" % (playerID, tagPlayerID))  | 
|       | 
|     PyGameData.g_crossPlayerViewCache[tagPlayerID] = [cacheInfo, tick] # ¸üÐÂÐÅÏ¢  | 
|       | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|     if curPlayer:  | 
|         SyncPlayerViewCrossPlayerInfo(curPlayer, tagPlayerID, equipClassLV, cacheInfo)  | 
|           | 
|     return  | 
|   | 
| def SyncPlayerViewCrossPlayerInfo(curPlayer, tagPlayerID, equipClassLV, cacheInfo):  | 
|     if not cacheInfo:  | 
|         PlayerControl.NotifyCode(curPlayer, "ViewPlayer_OffLine")  | 
|         return  | 
|       | 
|     if equipClassLV:  | 
|         itemData = cacheInfo.get("ItemData%s" % equipClassLV, "")  | 
|         sendPack = ChPyNetSendPack.tagSCPlayerEquipCacheResult()  | 
|         sendPack.PlayerID = tagPlayerID  | 
|         sendPack.EquipClassLV = equipClassLV  | 
|         sendPack.ItemData = itemData  | 
|         sendPack.ItemDataSize = len(sendPack.ItemData)  | 
|         NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|         return  | 
|       | 
|     #»Ø°ü¿Í»§¶Ë  | 
|     sendPack = ChPyNetSendPack.tagSCQueryPlayerCacheResult()  | 
|     sendPack.PlayerID = tagPlayerID  | 
|     sendPack.PropData = cacheInfo.get("PropData", "")  | 
|     sendPack.PropDataSize = len(sendPack.PropData)  | 
|     sendPack.PlusData = cacheInfo.get("PlusData", "")  | 
|     sendPack.PlusDataSize = len(sendPack.PlusData)  | 
|     NetPackCommon.SendFakePack(curPlayer, sendPack)  | 
|     return  | 
|   | 
| def CrossServerMsg_PutInItem(itemInfo):  | 
|     ## ¿ç·þ»ñµÃÎïÆ·  | 
|       | 
|     GameWorld.DebugLog("ÊÕµ½¿ç·þ·þÎñÆ÷»ñµÃÎïÆ·!")  | 
|     playerID = itemInfo["PlayerID"]  | 
|     itemData = itemInfo["ItemData"]  | 
|     event = itemInfo["Event"]  | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|     if curPlayer:  | 
|         # ÔÚÏߵϰÍƵ½MapServer´¦Àí  | 
|         itemMsg = str(itemInfo)  | 
|         curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossPutInItem", itemMsg, len(itemMsg))  | 
|         return  | 
|     # ÀëÏߵϰֱ½Ó·¢Óʼþ  | 
|     GameWorld.Log("ÊÕµ½¿ç·þ»ñµÃÎïÆ·£¬Íæ¼Ò²»ÔÚÏߣ¬Ö±½Ó·¢Óʼþ! itemInfo=%s" % str(itemInfo), playerID)  | 
|     itemID, itemCount, isBind, itemUserData = itemData  | 
|     addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":isBind, "UserData":itemUserData}]  | 
|     PlayerCompensation.SendMailByKey("", [playerID], addItemList, detail={"CrossPutInItem":1, "Event":event})  | 
|     return  | 
|   | 
| def CrossServerMsg_GiveMoney(msgInfo):  | 
|     ## ¿ç·þ»ñµÃ»õ±Ò  | 
|       | 
|     playerID = msgInfo["PlayerID"]  | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|     if not curPlayer:  | 
|         GameWorld.ErrLog("¿ç·þ»ñµÃ»õ±ÒÊ±Íæ¼Ò²»ÔÚÏß! msgInfo=%s" % str(msgInfo), playerID)  | 
|         return  | 
|     msgInfo = str(msgInfo)  | 
|     curPlayer.MapServer_QueryPlayerResult(0, 0, "CrossGiveMoney", msgInfo, len(msgInfo))  | 
|     return  | 
|   | 
| def SetCrossPlayerAttrValue(msgInfo, tick):  | 
|     ## ÉèÖÿç·þÍæ¼ÒÊôÐÔÖµ  | 
|     playerID, setType, setDict, isDelay = msgInfo  | 
|     if not PyGameData.g_crossSetPlayerAttr:  | 
|         GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_CrossSetPlayerAttrTick, tick)  | 
|     playerSetInfoList = PyGameData.g_crossSetPlayerAttr.get(playerID, [])  | 
|     playerSetInfoList.append([setType, setDict])  | 
|     PyGameData.g_crossSetPlayerAttr[playerID] = playerSetInfoList  | 
|     if not isDelay:  | 
|         __SendCrossServerSetPlayerAttr(0)  | 
|     return  | 
|   | 
| def OnCrossProcess(tick):  | 
|     __SendCrossServerSetPlayerAttr(tick)  | 
|     return  | 
|   | 
| def __SendCrossServerSetPlayerAttr(tick):  | 
|     if not PyGameData.g_crossSetPlayerAttr:  | 
|         return  | 
|       | 
|     if tick:  | 
|         # ÑÓ³Ù10ÃëÒ»´ÎÐÔͬ²½£¬Ö÷ÒªÊDZÈÈçOnDayµÄʱºòµ±¶à¸öÍæ¼Òͬʱ¿ç·þʱ£¬¼õÉÙͬ²½´ÎÊý£¬ÑÓ³Ùͳһ·¢ËÍ  | 
|         if tick - GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_CrossSetPlayerAttrTick) < 10 * 1000:  | 
|             return  | 
|         GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_CrossSetPlayerAttrTick, tick)  | 
|           | 
|     CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_SetPlayerAttrValue, PyGameData.g_crossSetPlayerAttr)  | 
|     PyGameData.g_crossSetPlayerAttr = {}  | 
|     return  | 
|   | 
| def OnPlayerLogin(curPlayer):  | 
|     if not IsCrossServerOpen():  | 
|         return  | 
|       | 
|     Sync_CrossZoneInfo(curPlayer)  | 
|     LoginDoUnNotifyCrossMsg(curPlayer)  | 
|     return  | 
|       | 
| def MapServer_QueryCrossPlayerResult(playerID, callName, msgInfo, offlineExitCross=False):  | 
|     ## Í¬²½µØÍ¼¿ç·þÍæ¼Ò´¦ÀíÐÅÏ¢£¬Íæ¼Ò¿ÉÄܲ»ÔÚÏߣ¬»º´æºóµÈÍæ¼ÒÉÏÏß´¦Àí£¬Ôݲ»¿¼ÂÇ´æµµÎÊÌ⣬·þÎñÆ÷ά»¤ºóδ´¦ÀíµÄÃüÁʧЧ  | 
|       | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|     if curPlayer and curPlayer.GetInitOK():  | 
|         msgInfo = str(msgInfo)  | 
|         curPlayer.MapServer_QueryPlayerResult(0, 0, callName, msgInfo, len(msgInfo))  | 
|         return curPlayer  | 
|     else:  | 
|         # »º´æÆðÀ´£¬µÈÉÏÏߺó´¦Àí  | 
|         if playerID not in PyGameData.g_unNotifyPlayerCrossMsgDict:  | 
|             PyGameData.g_unNotifyPlayerCrossMsgDict[playerID] = []  | 
|         msgList = PyGameData.g_unNotifyPlayerCrossMsgDict[playerID]  | 
|         msgList.append([callName, msgInfo])  | 
|         GameWorld.Log("Íæ¼Ò²»ÔÚÏߣ¬Ìí¼Óδ֪ͨµÄ¿ç·þÃüÁî: %s, msgInfo=%s" % (callName, msgInfo), playerID)  | 
|         if offlineExitCross:  | 
|             DoOfflinePlayerExitCrossServer(playerID)  | 
|     return  | 
|   | 
| def LoginDoUnNotifyCrossMsg(curPlayer):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     msgList = PyGameData.g_unNotifyPlayerCrossMsgDict.pop(playerID, [])  | 
|     if not msgList:  | 
|         return  | 
|     for callName, msgInfo in msgList:  | 
|         GameWorld.Log("ÉÏÏß´¦Àíδ֪ͨµÄ¿ç·þÃüÁî: %s, msgInfo=%s" % (callName, msgInfo), playerID)  | 
|         msgInfo = str(msgInfo)  | 
|         curPlayer.MapServer_QueryPlayerResult(0, 0, callName, msgInfo, len(msgInfo))  | 
|     return  | 
|   | 
| def Sync_CrossZoneInfo(curPlayer):  | 
|     clientPack = ChPyNetSendPack.tagGCCrossZoneInfo()  | 
|     clientPack.CommZoneID = GetServerCommCrossZoneID(GameWorld.GetServerGroupID())  | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  |