hxp
2025-10-27 6641154f22dbfafdd14f047f7a2491a9bbeae723
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
@@ -30,6 +30,10 @@
import ChPyNetSendPack
import traceback
import ChGameToMapPyPack
from PyMongoDB.DBCommon import CommonDefine
import ObjPool
import ChServerToServerPyPack
from PyMongoDB.Protocol import MergeServerRecvProtocol
#-------------------------------------------------------------------------------
#---全局变量---
@@ -218,19 +222,34 @@
#  @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())
    ObjPool.GetPoolMgr().release(clientPack)
    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")
@@ -286,21 +305,103 @@
##发送Map到GameServer的沟通包
#
def SendPyPackToGameServer(sendPack):
    if hasattr(sendPack, 'PlayerID'):
        if sendPack.PlayerID >= 100000000:
    # 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
    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)
        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
    
    
## 发送跨服包:服务器与服务器间的通信
#  @param DirType  0全广播,1通知主服务器排除合服子服,2通知服务器包含合服子服, 3通知跨服服务器
#  @param serverList 服务器列表 格式如 [(1,10),50,(55,100)] 约定内部必须用元组 同其他跨服配表规则一致
#  @param packBuffer 自定义封包字节字符串
def SendCrossServerToServerPack(dirType, serverList, packBuffer):
    recvPack = MergeServerRecvProtocol.tagLPStringData()
    recvPack.Type = CommonDefine.gstCrossServerToServerPack
    recvPack.DirType = dirType
    recvPack.ServerList = str(serverList)
    recvPack.ServerLen = len(recvPack.ServerList)
    recvPack.Data = packBuffer
    recvPack.DataLen = len(packBuffer)
    SendPyPackToServersRoute(recvPack.GetBuffer(), recvPack.GetLength())