#!/usr/bin/python # -*- coding: GBK -*- # ---------------------------------------------------------------------------------------------------- # # ---------------------------------------------------------------------------------------------------- ##@package NetPackManager # @todo: ·â°ü´¦Àí # # @author: zfl # @date 2011-10-17 19:50 # @version 1.6 # # ÐÞ¸Äʱ¼ä ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ # @change: "2013-05-17 14:30" Alee ·â°ü³ö´í²»ÔÙÊÜÀí£¬ÐÞ¸´BUG # @change: "2014-03-11 20:00" Alee ·â°ü´íÎó²»Å׳öÒì³£ # @change: "2014-05-16 13:30" xmnathan Ôö¼Ó GameServerºÍMapServerÖ®¼äµÄ×Ô¶¨Òå·â°ü # @change: "2014-08-19 14:00" xmnathan GameServerºÍMapServerÖ®¼äµÄ×Ô¶¨Òå·â°ü »ñÈ¡MapID±ØÐëÓÃGetRealMapID½Ó¿Ú # @change: "2014-12-09 17:30" xmnathan ÐÞ¸ÄÍæ¼ÒM->S×Ô¶¨Òå·â°ü·¢ËÍ # @change: "2014-12-19 19:30" hxp DebugÏ·â°ü´íÎóÅ׳öÒì³£ #------------------------------------------------------------------------------- #"""Version = 2014-12-19 19:30""" #------------------------------------------------------------------------------- #---µ¼Èë--- import IPY_GameWorld import ChConfig import GameWorld import CommFunc import ConfigParser import ChPyNetPack import ChPyNetSendPack import traceback import ChGameToMapPyPack from PyMongoDB.DBCommon import CommonDefine import ChServerToServerPyPack from PyMongoDB.Protocol import MergeServerRecvProtocol import ShareDefine import CrossPlayer import DBDataMgr import CrossMsg #------------------------------------------------------------------------------- #---È«¾Ö±äÁ¿--- PY_NAME = "NetPackCommon" g_rootPath = ChConfig.GetAppPath() # ÊÕ°ü×Öµä RecievePackDict = ChPyNetPack.ChNetPackDict # ·¢°ü×Öµä SendPackDict = ChPyNetSendPack.ChNetPackDict # Py·â°ü×¢²áÐÅÏ¢ PyPackTable = {} ## Ìæ»»×Ö·û´®ASCIIÂë #IsRelpace = False #ReplaceChar = chr(0xFF) #------------------------------------------------------------------------------- #---PyרÓõ÷ÊÔÊä³öÐÅÏ¢ ## PyרÓã¬Êä³öµ÷ÊÔÐÅÏ¢ # @param msg ÏûÏ¢ # @return ·µ»ØÖµÎÞÒâÒå # @remarks Õý³£Èռǵ÷ÊÔÊä³öÐÅÏ¢ def Log(msg): GameWorld.Log(PY_NAME + "->" + msg) return ## PyרÓã¬Êä³ö´íÎóÐÅÏ¢ # @param msg ÏûÏ¢ # @return ·µ»ØÖµÎÞÒâÒå # @remarks Õý³£Èռǵ÷ÊÔÊä³öÐÅÏ¢ def ErrLog(msg): GameWorld.ErrLog(PY_NAME + "->" + msg) return #------------------------------------------------------------------------------- ## ½âÎöPy·â°ü×¢²áÐÅÏ¢ # @param tableName ±íÃû # @return ½âÎö½á¹û # @remarks def ReadPyPackTable(tableName): tDict = {} # scriptPath = g_rootPath + "\\Script\\" curPath = g_rootPath + "%s.ini"%(tableName) config = ConfigParser.ConfigParser() config.read(curPath) for section in config.sections(): if config.getint(section, "RegType") != 0: continue regCnt = config.getint(section, "RegisterPackCount") scriptName = config.get(section, "ScriptName") moudle = __import__(scriptName.split("\\")[-1].split(".")[0]) reload(moudle) # Log("ReadPyPackTable: moudle: %s"%dir(moudle)) for index in range(regCnt): if not config.has_option(section, "PacketCMD_%s"%(index + 1)): continue cmd = config.get(section, "PacketCMD_%s"%(index + 1)) subCmd = config.get(section, "PacketSubCMD_%s"%(index + 1)) callFunc = config.get(section, "PacketCallFunc_%s"%(index + 1)) if not cmd or not subCmd or not callFunc: continue cmd = int(cmd, 16) subCmd = int(subCmd, 16) # Log("ReadPyPackTable: cmd = %s subCmd = %s"%(cmd, subCmd)) evalStr = "moudle.%s"%callFunc # Log("ReadPyPackTable: %s"%evalStr) try: callFunc = eval(evalStr) except: ErrLog("ReadPyPackTable: Error--%s"%traceback.format_exc()) continue if not callable(callFunc): ErrLog("ReadPyPackTable: callFunc = %s is not callable!"%callFunc) continue head = eval("0x%02x%02x"%(cmd, subCmd)) tDict[head] = {"Head": head, "CallFunc": callFunc} # Log("ReadPyPackTable: tDict = %s"%tDict) return tDict ## »ñµÃPy·â°üÊý¾Ý # @param head °üÍ· # @return Py·â°ü # @remarks def GetPyRecievePack(head): if not RecievePackDict.has_key(head): ErrLog("GetPyRecievePack: No PyRecievePack head = %s"%head) return None return RecievePackDict[head] ## »ñµÃPy·â°üÊý¾Ý # @param head °üÍ· # @return Py·â°ü # @remarks def GetPySendPack(head): if not SendPackDict.has_key(head): ErrLog("GetPySendPack: No PySendPack head = %s"%head) return None return SendPackDict[head] #------------------------------------------------------------------------------- def ReadRecPyPackData(packBuff): ## ¸ù¾ÝÊÕµ½µÄpy°übuff¶ÁÈ¡¶ÔÓ¦µÄ°ü½á¹¹ÊµÀý try: if len(packBuff) <= 1: return headData = packBuff[1] + packBuff[0] curPackHead = CommFunc.ReadWORD(headData, 0)[0] clientPack = RecievePackDict.get(curPackHead) if not clientPack: return clientPack.ReadData(packBuff) # ½Ø¶Ï×Ö·û´® for key in dir(clientPack): value = getattr(clientPack, key) if isinstance(value, str): setattr(clientPack, key, value.rstrip(chr(0x0))) return clientPack except Exception: GameWorld.RaiseException("!!!python×Ô¶¨Òå·â°ü½â°üʧ°Ü\r\n%s" % traceback.format_exc()) return ## ½ÓÊÕÍòÄÜ·â°ü # @param index Íæ¼ÒË÷Òý # @param tick ʱ¼ä´Á # @return ÎÞ·µ»ØÖµ # @remarks def RecNetPack(index, tick): try: # Log("½Óµ½Í¨Ó÷â°ü!!!! index = %s"%index) clientPack = IPY_GameWorld.IPY_CFakePack().GetMsg() #ûÓÐPY·â°üÍ· if len(clientPack) <= 1: return #Log("RevieveFakePack: clientPack = %s %d"% (`[clientPack]`, IPY_GameWorld.IPY_CFakePack().GetMsgLen())) #Log("RevieveFakePack: %s %d"%(type(clientPack), len(clientPack))) headData = clientPack[1] + clientPack[0] curPackHead = CommFunc.ReadWORD(headData, 0)[0] # Log("RevieveFakePack: curPackHead = %s"%curPackHead) curPackData = RecievePackDict.get(curPackHead) if not curPackData: return # if IsRelpace: # clientPack = clientPack[:2] + clientPack[2:].replace(ReplaceChar, chr(0x0)) # Log("RevieveFakePack: after replace clientPack = %s"%[clientPack]) # ³¤¶ÈУÑé # if curPackData.GetLength() > len(clientPack): # Log("PyPack Length Error! curLen = %s, normalLen = %s"%(len(clientPack), curPackData.GetLength())) # return curPackData.ReadData(clientPack) # ½Ø¶Ï×Ö·û´® for key in dir(curPackData): value = getattr(curPackData, key) if isinstance(value, str): setattr(curPackData, key, value.rstrip(chr(0x0))) # È¡´Ë°üÍ·×¢²áÐÅÏ¢ curPackHeadRegDict = PyPackTable.get(curPackHead) # ÎÞ´Ë·â°ü×¢²áÐÅÏ¢ if curPackHeadRegDict == None: #Log("RevieveFakePack: No Register curPackHead = %s"%curPackHead) return curPackHeadRegDict["CallFunc"](index, curPackData, tick) except Exception: GameWorld.RaiseException("!!!python×Ô¶¨Òå·â°ü½âÎöʧ°Ü\r\n%s" % traceback.format_exc()) return ## ·¢ËÍÍòÄÜ·â°ü # @param curPlayer Íæ¼ÒʵÀý # @param clientPack Òª°ü×°µÄ·â°ü # @return ÎÞ·µ»ØÖµ # @remarks def SendFakePack(curPlayer, clientPack): if not clientPack: return # Log("SendFakePack: clientPack = %s"%[clientPack.GetBuffer()]) innerPackData = clientPack.GetBuffer() if len(innerPackData) < clientPack.GetLength(): Log("SendFakePack: clientPack Len = %s > %s"%(clientPack.GetLength(), len(innerPackData))) #curPlayer.SendFakePack(innerPackData, len(innerPackData)) curPlayer.SendFakePack(clientPack.GetBuffer(), clientPack.GetLength()) return def SendFackPackOnline(clientPack, parseFunc=None, *args): ## ·¢Ë͸øÈ«·þÔÚÏßÍæ¼Ò # @param parseFunc: Öм䴦ÀíÂß¼­£¬¿ÉÒÔ×öһЩÐ޸İüÊý¾ÝµÄÂß¼­»òÕß¹ýÂËÄ³Ð©Íæ¼Ò²»·¢ËÍ£¬·µ»ØÖµÎªTrueʱ·¢ËÍ # @param args: parseFunc·½·¨²ÎÊý(curPlayer, ...) playerManager = GameWorld.GetPlayerManager() for i in xrange(playerManager.OnlineCount()): curPlayer = playerManager.OnlineAt(i) if not GameWorld.IsNormalPlayer(curPlayer): continue if parseFunc and not parseFunc(curPlayer, *args): continue SendFakePack(curPlayer, clientPack) return #------------------------------------------------------------------------------- #---Py·â°ü×¢²áÐÅÏ¢ PyPackTable = ReadPyPackTable("PyNetPack") #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- #GameServer Py·â°ü×¢²áÐÅÏ¢ GameServerPyPackTable = {} GameServerPyPackTable = ReadPyPackTable("GameServerPyPack") # ÊÕ°ü×Öµä RecGameServerPyPackDict = ChGameToMapPyPack.ChNetPackDict #------------------------------------------------------------------------------- ## ½ÓÊÕGameServerPyPack # @param index Íæ¼ÒË÷Òý # @param tick ʱ¼ä´Á # @return ÎÞ·µ»ØÖµ # @remarks def RecGamePyPack(index, tick): try: gamePack = IPY_GameWorld.IPY_MGeneralPack().GetData() #ûÓÐPY·â°üÍ· if len(gamePack) <= 1: return headData = gamePack[1] + gamePack[0] curPackHead = CommFunc.ReadWORD(headData, 0)[0] #Log("RecGamePyPack: curPackHead = %s"%curPackHead) curPackData = RecGameServerPyPackDict.get(curPackHead) if not curPackData: #Log("RecGamePyPack: not curPackData curPackHead = %s"%curPackHead) return curPackData.ReadData(gamePack) # ½Ø¶Ï×Ö·û´® for key in dir(curPackData): value = getattr(curPackData, key) if isinstance(value, str): setattr(curPackData, key, value.rstrip(chr(0x0))) # È¡´Ë°üÍ·×¢²áÐÅÏ¢ curPackHeadRegDict = GameServerPyPackTable.get(curPackHead) # ÎÞ´Ë·â°ü×¢²áÐÅÏ¢ if curPackHeadRegDict == None: return curPackHeadRegDict["CallFunc"](curPackData, tick) #Log("RecGamePyPack: curPackHead = %s"%curPackHead) except Exception: GameWorld.RaiseException("RecGamePyPack python×Ô¶¨Òå·â°ü½âÎöʧ°Ü\r\n%s" % traceback.format_exc()) return #------------------------------------------------------------------------------- ##·¢ËÍMapµ½GameServerµÄ¹µÍ¨°ü # def SendPyPackToGameServer(sendPack): # if hasattr(sendPack, 'PlayerID'): # if sendPack.PlayerID >= 100000000: # return # routeIndex = GameWorld.GetGameWorld().GetLineNO() # #ÕâÀï±ØÐëÓÃGetRealMapID,GetMapID ʵ¼ÊÈ¡µ½µÄÊÇDataMapID£¬ÔÚÓзÖÏߵĵØÍ¼»áÎÊÌâ # mapID = GameWorld.GetGameWorld().GetRealMapID() # #ÏÈдÈ뵱ǰµØÍ¼±êʶ£¬·½±ãGameServer»Ø°üʱ¿ÉÒÔÕýȷ֪ͨµ½¶ÔÓ¦µØÍ¼ # data = '' # data = CommFunc.WriteBYTE(data, routeIndex) #1 # data = CommFunc.WriteDWORD(data, mapID) #4 # data = CommFunc.WriteString(data, sendPack.GetLength(), sendPack.GetBuffer()) # dataLen = 1 + 4 + sendPack.GetLength() # GameWorld.GetGameWorld().SendGameServerGeneralPack(dataLen, data) return ##ÏòµØÍ¼£¨c++£©·¢ËÍÊý¾Ý # ½á¹¹ÌåÒªÇóµÚÒ»¸öÀàÐÍΪö¾Ù TDataServerToBalanceServer£¬²»ÐèÒª·â°üÍ·£¬ÓÃÀàÐÍ×öÅÐ¶Ï def SendPyPackToMapServerSelf(data, datalen): GameWorld.GetGameWorld().SendPyPackToMapServerSelf(datalen, data) return # ÏòServersRoute·¢ËÍÊý¾Ý def SendPyPackToServersRoute(data, datalen): GameWorld.GetGameWorld().SendPyPackToServersRoute(datalen, data) return #------------------------------------------------------------------------------- # Py¿ç·þ·þÎñÆ÷¼äµÄ·â°ü #¿ç·þ·þÎñÆ÷¼äµÄ·â°ü¼ÈÊÇ·¢°üÒ²ÊÇÊÕ°ü PyCrossServerPackTable = {} PyCrossServerPackTable = ReadPyPackTable("PyCrossServerPack") # ÊÕ°ü×Öµä RecCrossServerPyPackDict = ChServerToServerPyPack.ChNetPackDict ## ½ÓÊÕ¿ç·þÖ®¼ä·â°ü # @param tick ʱ¼ä´Á # @return ÎÞ·µ»ØÖµ # @remarks def RecCrossServerNetPack(netPackBuffer): try: #ûÓÐPY·â°üÍ· if len(netPackBuffer) <= 1: return headData = netPackBuffer[1] + netPackBuffer[0] curPackHead = CommFunc.ReadWORD(headData, 0)[0] curPackData = RecCrossServerPyPackDict.get(curPackHead) if not curPackData: return curPackData.ReadData(netPackBuffer) # ½Ø¶Ï×Ö·û´® for key in dir(curPackData): value = getattr(curPackData, key) if isinstance(value, str): setattr(curPackData, key, value.rstrip(chr(0x0))) # È¡´Ë°üÍ·×¢²áÐÅÏ¢ curPackHeadRegDict = PyCrossServerPackTable.get(curPackHead) # ÎÞ´Ë·â°ü×¢²áÐÅÏ¢ if curPackHeadRegDict == None: #Log("RevieveFakePack: No Register curPackHead = %s"%curPackHead) return curPackHeadRegDict["CallFunc"](curPackData) except Exception: GameWorld.RaiseException("!!!python×Ô¶¨Òå¿ç·þ·â°ü½âÎöʧ°Ü\r\n%s" % traceback.format_exc()) return def GetSSPackDirType(serverType): ## ¸ù¾Ý·þÎñÆ÷ÀàÐÍ»ñÈ¡·¢Ë͵ÄÄ¿±êÀàÐÍ if serverType in [ShareDefine.serverType_Cross, ShareDefine.serverType_CrossCenter]: return ShareDefine.dirType_Cross if serverType in [ShareDefine.serverType_Main, ShareDefine.serverType_Child]: return ShareDefine.dirType_Main if serverType == ShareDefine.serverType_Battle: return ShareDefine.dirType_Battle return ShareDefine.dirType_All def SendCrossServerToServerPack(pack, serverList=None, dirType=None, serverType=None): '''·¢ËÍ¿ç·þ°ü£º·þÎñÆ÷Óë·þÎñÆ÷¼äµÄͨÐÅ @param pack ×Ô¶¨Òå·â°üʵÀý @param serverList ·þÎñÆ÷ÁÐ±í ¸ñʽÈç [(1,10),50,(55,100)] Ô¼¶¨ÄÚ²¿±ØÐëÓÃÔª×é ͬÆäËû¿ç·þÅä±í¹æÔòÒ»Ö @param DirType 0È«¹ã²¥£¬1֪ͨÖ÷·þÎñÆ÷ÅųýºÏ·þ×Ó·þ£¬2֪ͨ·þÎñÆ÷°üº¬ºÏ·þ×Ó·þ£¬ 3֪ͨ¿ç·þ·þÎñÆ÷ @param serverType ¿ÉÖ»´«ÈëÀ´Ô´µÄ·þÎñÆ÷ÀàÐÍ£¬ÊÊÓÃÓÚÒ»¶ÔһͨѶµÄ»Ø°ü ''' if dirType == None and serverType == None: return if dirType == None: dirType = GetSSPackDirType(serverType) if serverList == None: serverList = [] recvPack = MergeServerRecvProtocol.tagLPStringData() recvPack.Type = CommonDefine.gstCrossServerToServerPack recvPack.DirType = dirType recvPack.ServerList = str(serverList) recvPack.ServerLen = len(recvPack.ServerList) recvPack.Data = pack.GetBuffer() recvPack.DataLen = len(recvPack.Data) SendPyPackToServersRoute(recvPack.GetBuffer(), recvPack.GetLength()) return