找回密码
 registerss
搜索

洱海月 v0-07-0300 封包解析:ID 125 CGExchangeApplyI(发起交易申请请求)

[复制链接]
Waylee 发表于 2026-4-13 10:30 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

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

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

×

CGExchangeApplyI 是旧版客户端里用于向目标玩家发起交易申请的请求包。当前 Game.exe 与当前 Lua 服务端都能确认,这条包固定为 8 字节,包体由两个 int32 字段组成,分别表示交易目标对象 ID 与目标 GUID。

包信息

项目 内容
封包 ID 125
包名 CGExchangeApplyI
方向 Client -> Server
固定包长 8
相关回包 GCExchangeApplyI
相关回包 ID 69
作用 向指定目标玩家发起交易申请

当前 Game.exe 的虚函数结论为:

GetPacketID() = 125;
GetPacketSize() = 8;
Execute() = 2;

包体结构

当前 Game.exe 已直接确认这条包按 4 + 4 顺序读写;当前 Lua 协议与交易申请回包链路也能对齐出字段语义。

偏移 长度 字段 类型 含义
0x00 0x04 target_obj_id int32 目标玩家当前场景对象 ID
0x04 0x04 target_guid int32 目标玩家 GUID

当前实际行为 / 模式说明

  • 当前 Game.exe 中,CGExchangeApplyI::Read() / Write() 都固定处理两个 int32:
    • target_obj_id
    • target_guid
  • 当前 Lua 请求入口 request:CGExchangeApplyI() 在进场景服前会先做两层校验:
    • 检查角色存档版本号是否与当前在线数据一致
    • 检查二级密码是否已解锁
  • 如果存档版本号异常,当前版本会记录 log_save_lv_change 日志,并提示玩家重新登录后再交易。
  • 进入场景服后,char_exchange_apply_I() 会按 target_obj_id 找目标对象,并依次检查:
    • 当前场景是否为死亡场景
    • 双骑交易配对是否合法
    • 当前交易有效性校验是否通过
    • 目标是否开启拒绝交易
    • 发起方是否已在交易中
    • 目标方是否已在交易中
  • 全部通过后,服务端不会立刻建立交易框,而是先向目标玩家发送 GCExchangeApplyI(69),把发起方信息带过去:
    • source_oid
    • source_guid
    • source_name
    • source_level
  • 当前 Lua 场景主链实际使用的是 target_obj_id;target_guid 在现行场景处理里没有继续参与校验。

服务端落点

  • 协议定义:
    • /home/ubuntu/Game2/services/game/packet.lua
  • 请求入口:
    • /home/ubuntu/Game2/services/msgagent.lua
  • 场景处理:
    • /home/ubuntu/Game2/services/scene/scenecore.lua

关键代码

当前 Lua 协议定义

packet.CGExchangeApplyI = {
    xy_id = packet.XYID_CG_EXCHANGE_APPLY_I,
    ctor = function(self)
        self.target_obj_id = 0
        self.target_guid = 0
    end,
    bis = function(self, buffer)
        local stream = bistream.new()
        stream:attach(buffer)
        self.target_obj_id = stream:readint()
        self.target_guid = stream:readint()
    end
}

当前 Lua 请求入口

function request:CGExchangeApplyI()
    local my_data = ma_func:get_my_data()
    if not my_data then
        return
    end
    local guid = my_data.attrib.guid
    local save_lv,game_agent = skynet.call(".gamed", "lua", "check_save_lv", guid)
    if not save_lv or save_lv ~= my_data.game_flag.save_lv then
        ...
        ma_func:notify_tips("角色数据异常,请重新登陆游戏再进行操作。")
        return
    end
    if not ma_func:is_minor_password_is_unlock() then
        ma_func:send_operate_result_msg(define.OPERATE_RESULT.OR_NEED_UNLOCKMINORPASSWORD)
        return
    end
    skynet.call(my_scene, "lua", "char_exchange_apply_I", my_obj_id, self)
end

当前 Lua 场景处理

function scenecore:char_exchange_apply_I(who, ea)
    local obj_me = self:get_obj_by_id(who)
    if not obj_me then
        return
    end
    ...
    local obj_tar = self:get_obj_by_id(ea.target_obj_id)
    if not obj_tar then
        return
    end
    ...
    local msg = packet_def.GCExchangeApplyI.new()
    msg.source_oid = obj_me:get_obj_id()
    msg.source_guid = obj_me:get_guid()
    msg.source_name = obj_me:get_name()
    msg.source_level = obj_me:get_level()
    self:send2client(obj_tar, msg)
end

当前 Game.exe 的读写结论

Read(stream) {
    read_i32(target_obj_id);
    read_i32(target_guid);
}

Write(stream) {
    write_i32(target_obj_id);
    write_i32(target_guid);
}

结论

CGExchangeApplyI 在当前旧版项目中的结论可以直接概括为:

  1. 这条包的封包 ID 是 125。
  2. 它是固定 8 字节请求包,结构为 target_obj_id + target_guid。
  3. 当前请求入口会先做存档版本号校验和二级密码解锁校验。
  4. 当前场景服主要按 target_obj_id 定位交易目标,并完成一系列交易前置检查。
  5. 校验通过后,服务端会向目标玩家下发 GCExchangeApplyI(69),通知其收到交易申请。
您需要登录后才可以回帖 登录 | registerss

本版积分规则

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

GMT+8, 2026-10-24 13:58 , Processed in 0.025370 second(s), 27 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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