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

洱海月 v0-07-0300 封包解析:ID 107 CGAskChangeScene(切场景确认请求)

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

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

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

×

CGAskChangeScene 是当前项目里用于确认执行切场景的请求包。

它不是一条独立决定目标坐标的封包,正常流程必须先收到 GCNotifyChangeScene,再由客户端发回这条包,服务端才继续完成切场景交接。

包信息

项目 内容
封包 ID 107
包名 CGAskChangeScene
前置通知 GCNotifyChangeScene
前置通知 ID 287
结果回包 GCRetChangeScene
结果回包 ID 515
作用 客户端确认开始切场景,推动旧场景离场、角色存档切换与新场景连接交接

包体结构

按当前 Temp_Release_v0-07-0300 的 Game.exe 与 Lua 服务端,CGAskChangeScene 固定长度为 12 字节。

偏移 长度 字段 类型 含义
0x00 0x02 scene_from uint16 当前所在场景 ID
0x02 0x02 scene_to uint16 目标场景 ID
0x04 0x04 client_memory_mb uint32 客户端当前进程内存占用,单位 MB
0x08 0x04 client_state_float_raw uint32 客户端附带上报的 4 字节浮点状态值原始位模式;当前 Lua 不使用

总长度:

12 字节

补充说明:

  • 当前 Game.exe 发包时,第 4 个字段实际来源是一个 float32 返回值。
  • 当前 Lua 服务端用 readuint() 读入该字段,而且整个主链完全不参与判定。
  • 因为它的具体业务语义在当前版里还不能 100% 精确命名,所以这里按“客户端状态浮点值原始位模式”处理最稳。

当前实际行为

  • 当前切场景主链先由场景服下发 GCNotifyChangeScene。
  • msgagent.lua 收到 GCNotifyChangeScene 后,会先把目标场景号和目标坐标保存到 change_scene_args:
    • sceneid = notify.scene_to
    • world_pos = notify.world_pos
  • 客户端随后发送 CGAskChangeScene,当前 Lua 请求入口 request:CGAskChangeScene() 本身并不使用包内的 scene_from、scene_to、client_memory_mb、client_state_float_raw 做业务判断。
  • 当前 Lua 真正采用的切场景目标数据,来自前一步缓存下来的 change_scene_args,不是来自这条包自身。
  • 进入 request:CGAskChangeScene() 后,服务端会先让角色从旧场景 leave,取回角色存档数据。
  • 然后把存档中的 sceneid 与 world_pos 改成 change_scene_args 里的目标值,再保存为 "change_scene" 或 "leave_scene" 相关交接数据。
  • 最后向 .gamed 取回新场景连接信息,并回发 GCRetChangeScene:
    • result = 1
    • ip
    • port
    • key
  • 这说明当前项目里,CGAskChangeScene 的实际作用更接近“切场景确认触发包”。
  • 如果前置 GCNotifyChangeScene 没有先到,当前 Lua 这条链就不成立;这也是为什么它不能脱离前置通知单独使用。

服务端落点

  • 协议定义:/home/ubuntu/Game2/services/game/packet.lua
  • 切场景前置通知缓存:/home/ubuntu/Game2/services/msgagent.lua
  • 切场景请求入口:/home/ubuntu/Game2/services/msgagent.lua
  • 场景服下发切场景通知:/home/ubuntu/Game2/services/scene/scenecore.lua
  • 角色切场景存档写入:/home/ubuntu/Game2/services/scene/obj/human.lua

关键代码

packet.CGAskChangeScene = {
    xy_id = packet.XYID_CG_ASK_CHANGE_SCENE,
    bis = function(self, buffer)
        local stream = bistream.new()
        stream:attach(buffer)
        self.scene_from = stream:readushort()
        self.scene_to = stream:readushort()
        self.client_memory_mb = stream:readuint()
        self.client_state_float_raw = stream:readuint()
    end
}
local function on_notify_change_scene(notify)
    change_scene_args = {}
    change_scene_args.sceneid = notify.scene_to
    change_scene_args.world_pos = notify.world_pos
    local my_guid = ma_func:get_guid()
    skynet.call(".world", "lua", "char_start_change_scene", my_guid)
end
function request:CGAskChangeScene()
    ...
    data.attrib.sceneid = change_scene_args.sceneid
    data.attrib.world_pos = change_scene_args.world_pos
    ma_func:save_my_data(data, call_name)
    ...
    ret.result = 1
    ret.ip = ma_func:get_game_ip() or server_conf.server_ip
    ret.port = port
    ret.key = my_connect_key
    Net:send(ret)
end
function scenecore:notify_change_scene(obj_id, sceneid, x, y, client_res)
    local ret = packet_def.GCNotifyChangeScene.new()
    ret.scene_from = self.id
    ret.scene_to = sceneid
    ret.world_pos.x = x
    ret.world_pos.y = y
    ret.client_res = client_res or sceneid
    self:send2client(obj_id, ret)
end
// 当前 Game.exe 的发送点
v24 = GetCurrentSceneID();
v25 = dest_scene_id;
v26 = sub_14007AF80();
v27 = (*(float (__fastcall **)(__int64))(*(_QWORD *)qword_140911068 + 1064LL))(qword_140911068);
__int64 sub_14007AF80()
{
    ...
    return LODWORD(ppsmemCounters.PagefileUsage) >> 20;
}

结论

CGAskChangeScene 在当前版里可以直接按下面理解:

  1. 它的包号是 107,固定长度 12 字节。
  2. 它不是“单独决定去哪”的包,而是收到 GCNotifyChangeScene 之后的切场景确认包。
  3. 当前 Lua 真正采用的目标场景号和目标坐标,来自前置 GCNotifyChangeScene 缓存的 change_scene_args。
  4. 包内后 8 字节属于客户端附带上报数据,其中第 1 个可明确为当前进程内存占用 MB,第 2 个当前不参与服务端逻辑。
您需要登录后才可以回帖 登录 | registerss

本版积分规则

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

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

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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