找回密码
 registerss
搜索
查看: 18|回复: 0

洱海月 v0-07-0300 封包解析:ID 137 GCGameCommond(天气效果同步命令回包)

[复制链接]
  • 打卡等级:本地老炮
  • 打卡总天数:603
  • 打卡月天数:1
  • 打卡总奖励:600
  • 最近打卡:2026-10-03 06:32:28
Waylee 发表于 2026-4-14 00:47 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?registerss

×

GCGameCommond 在当前 Temp_Release_v0-07-0300 主链中是一条“通用命令壳”式下行包。客户端执行器仍保留多种旧命令分支,但现役 Lua 场景服实际只把它用于天气/场景效果同步:默认发送 command_code = 0、payload_size = 4,并把 payload_value 作为天气效果 ID 下发给客户端。

包信息

项目 内容
封包 ID 137
包名 GCGameCommond
方向 Server -> Client
对应请求 CGGameCommond
当前主要用途 同步当前场景天气/环境效果

包体结构

当前 Game.exe 的 Read() / Write() 明确显示,这条包的协议头固定为前 8 字节,后续是否再跟一个 int32 由第二个字段控制。

偏移 长度 字段 类型 含义
0x00 0x04 command_code int32 通用命令码;当前 Lua 实际保持默认 0
0x04 0x04 payload_size int32 负载长度控制字段;当前 Lua 固定写 4
0x08 0x04 payload_value int32 当 payload_size 在 1..0x100 时才随包发送;当前 Lua 用作天气/效果 ID

Lua 协议层还给这三个字段保留了兼容别名:

  • is_end = command_code
  • type = payload_size
  • effect = payload_value

当前客户端 GetPacketSize() 逻辑为:

if (payload_size > 0x100) {
    return 8;
}
return payload_size + 8;

因此现役 Lua 默认构造 payload_size = 4 时,实际包长为 12 字节。

当前实际行为

  • 当前 Lua 仅定义了 packet.GCGameCommond,默认构造为:
    • command_code = 0
    • payload_size = 4
    • payload_value = 0
  • 当前场景服发送链只有天气同步:
    • /home/ubuntu/Game2/services/scene/scenecore.lua 中 set_weather(id, time) 广播天气效果 ID
    • /home/ubuntu/Game2/services/scene/scenecore.lua 中 send_weather(obj_me) 在玩家进场景时补发当前天气
    • /home/ubuntu/Game2/lualib/script_base.lua 中 LuaFnSetSceneWeather(weather, time) 直接落到 scene:set_weather()
  • 当前发送时只改写 payload_value,command_code 与 payload_size 保持默认值,所以现役主链实际等价于:
    • command_code = 0
    • payload_size = 4
    • payload_value = weather_id
  • 天气结束时,Lua 会调用 self:set_weather(define.INVAILD_ID);当前 define.INVAILD_ID = -1,这与客户端执行器里的“清除当前效果”分支正好对应。
  • 当前客户端 Execute() 仍保留旧分支:
    • command_code == 1:触发一条旧 UI/系统命令
    • command_code == 2:触发另一条旧 UI/系统命令
    • command_code == 3:触发第三条旧逻辑并附带一次额外收尾调用
    • command_code == 0:把 payload_value 当作环境效果 ID 处理
  • 但当前 Lua 主链没有发现对 1/2/3 这些旧命令码的现役发送点,所以本版本真正在线使用的仍是天气/效果同步分支。

服务端落点

  • 协议定义:
    • /home/ubuntu/Game2/services/game/packet.lua
  • 场景天气广播:
    • /home/ubuntu/Game2/services/scene/scenecore.lua
  • 脚本入口:
    • /home/ubuntu/Game2/lualib/script_base.lua

当前关键调用链如下:

  1. 脚本调用 LuaFnSetSceneWeather(weather, time)
  2. script_base 转到 scene:set_weather(id, time)
  3. 场景服构造 packet.GCGameCommond
  4. 只写入 payload_value = weather_id
  5. 广播给场景内玩家,或在玩家进入场景时单独补发

关键代码

Lua 协议定义

packet.GCGameCommond = {
    xy_id = packet.XYID_GC_GAME_COMMOND,
    ctor = function(self)
        self.command_code = 0
        self.payload_size = 4
        self.payload_value = 0
        self.is_end = self.command_code
        self.type = self.payload_size
        self.effect = self.payload_value
    end,
    bis = function(self, buffer)
        local stream = bistream.new()
        stream:attach(buffer)
        self.command_code = stream:readint()
        self.payload_size = stream:readint()
        if self.payload_size > 0 and self.payload_size < 0x100 then
            self.payload_value = stream:readint()
        end
    end,
    bos = function(self)
        local stream = bostream.new()
        stream:writeint(self.command_code)
        stream:writeint(self.payload_size)
        if self.payload_size > 0 and self.payload_size < 0x100 then
            stream:writeint(self.payload_value)
        end
        return stream:get()
    end
}

Lua 现役发送链

function scenecore:set_weather(id, time)
    local msg = packet_def.GCGameCommond.new()
    if id > 0 then
        self.weather = { id = id, time = time}
        msg.payload_value = id
        self:broadcastall(msg)
    else
        self.weather = nil
        msg.payload_value = id
        self:broadcastall(msg)
    end
end

function scenecore:send_weather(obj_me)
    if self.weather then
        local msg = packet_def.GCGameCommond.new()
        msg.payload_value = self.weather.id
        self:send2client(obj_me, msg)
    end
end

当前 Game.exe 结论

GetPacketID() = 137;

GetPacketSize() {
    if (payload_size > 0x100) {
        return 8;
    }
    return payload_size + 8;
}

Read(stream) {
    read_i32(command_code);
    read_i32(payload_size);
    if ((unsigned)(payload_size - 1) <= 0xFF) {
        read_i32(payload_value);
    }
}

Write(stream) {
    write_i32(command_code);
    write_i32(payload_size);
    if ((unsigned)(payload_size - 1) <= 0xFF) {
        write_i32(payload_value);
    }
}

Execute() {
    if (command_code == 0) {
        apply_scene_effect(payload_value);
    } else if (command_code == 1 || command_code == 2 || command_code == 3) {
        run_legacy_client_command(command_code);
    }
}

结论

GCGameCommond 在当前版本里仍保留“通用命令回包”的旧外形,但现役 Lua 主链已经把它收敛成一条天气/环境效果同步包。可以稳定确认的现役语义只有三项:command_code、payload_size、payload_value,其中 Lua 实际固定发送 0 / 4 / weather_id。客户端虽然还保留 command_code = 1/2/3 的旧执行分支,但当前服务端没有发现这些分支的正式发送链,因此本文应以“天气效果同步命令回包”作为当前主用途。

您需要登录后才可以回帖 登录 | registerss

本版积分规则

QQ|手机版|雪舞知识库 ( 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 )|天天打卡

GMT+8, 2026-10-4 11:26 , Processed in 0.064330 second(s), 26 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表