CGCreateGuildLeague 是当前版本帮会同盟系统里用于“创建新同盟”的客户端请求包。当前 Game.exe 与当前 Lua 都能确认,这条包固定为 96 字节,包体由一个 32 字节名称槽和一个 64 字节宣言槽组成。
这条请求不是空壳协议。当前 Lua 主链已经接入:msgagent 收到后会交给 ma_guild:CGCreateGuildLeague(),再转发到 .Guildmanager:create_guild_league() 真正完成重名校验、数据库写入、帮会同盟状态更新和在线成员刷新。
包信息
| 项目 |
内容 |
| 封包 ID |
263 |
| 包名 |
CGCreateGuildLeague |
| 方向 |
CG 客户端 -> 游戏服 |
| 固定包长 |
96 |
| 直接回包 |
无专用回包 |
| 当前 Lua 协议定义 |
/home/ubuntu/Game2/services/game/packet.lua |
| 当前消息服入口 |
/home/ubuntu/Game2/services/msgagent.lua |
| 当前帮会模块处理 |
/home/ubuntu/Game2/msgagent_module/ma_guild.lua |
| 当前同盟创建逻辑 |
/home/ubuntu/Game2/services/guild/guildmanager_core.lua |
| 主要作用 |
创建一个新的帮会同盟,并把当前帮会设为该同盟的创建帮会 / 首个成员帮会 |
当前 Game.exe 可直接确认:
GetPacketID() = 263;
GetPacketSize() = 96;
Read() = 0x1405CA6C0;
Write() = 0x1405CA710;
Execute() = 0x1405CA6B0 -> sub_140329060; // 返回 2
包体结构
当前 Game.exe 的 Read() / Write() 明确是两段固定长度字节块;当前 Lua 也按相同长度读取,再做 GBK 转 UTF-8。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x20 |
name |
char[32] |
同盟名称,GBK 编码,尾部可能带 \\0 填充 |
0x20 |
0x40 |
desc |
char[64] |
同盟宣言 / 简介,GBK 编码,尾部可能带 \\0 填充 |
总长度固定为:
32 + 64 = 96
当前服务端真正写库前,还会执行:
updater.name = string.match(updater.name, "([^%z]+)")
updater.desc = string.match(updater.desc, "([^%z]+)")
也就是把固定长度槽里的首个 \\0 之后内容全部裁掉,再把有效字符串写入同盟记录。
当前实际行为
- 当前
msgagent.lua 已接入 request:CGCreateGuildLeague(),收到后直接转给 ma_func:CGCreateGuildLeague(self)。
ma_guild:CGCreateGuildLeague() 会取当前角色的 guild_id,然后调用:
.Guildmanager:create_guild_league(self:get_guid(), guild_id, request)
- 当前
.Guildmanager:create_guild_league() 的前置约束很明确:
- 发起人必须是帮主
- 当前帮会
confederate_id 必须还是 define.INVAILD_ID,也就是尚未加入同盟
- 同盟名称不能与现有同盟重名
- 校验通过后,当前 Lua 会:
- 分配一个新的同盟 ID
- 写入
league.name / league.desc
- 记录盟主 GUID、盟主名字、创建者名字、创建时间
- 把当前帮会作为首个成员帮会写入
league.guilds
- 往 Mongo
leagues 集合插入新记录
- 更新当前帮会的
confederate_id/confederate_name
- 清空同盟预申请数据
- 重载内存中的同盟列表
- 当前成功路径没有专用
GC* / WGC* 成功回包。
- 成功后的可见刷新主要来自内部广播链:
guildmanager_core:update_guild_confederate_id_and_name() 会 multicast(..., "update_confederate_id", ...)
msgagent 里的 CMD.update_confederate_id() 会同步角色当前场景对象的同盟 ID / 名字,并主动触发一次 CGGuild 刷新帮会界面
- 当前失败路径有一个实现细节需要单独说明:
ma_guild:CGCreateGuildLeague() 只要收到 nil,就统一提示 创建同盟失败,名称已存在
- 但
Guildmanager 返回 nil 的原因并不只有重名,也可能是“非帮主”或“当前帮会已经有同盟”
- 因此当前客户端看到的失败提示,并不总能准确反映真实失败原因
服务端落点
- 协议定义:
/home/ubuntu/Game2/services/game/packet.lua
- 请求入口:
/home/ubuntu/Game2/services/msgagent.lua
- MsgAgent 帮会模块:
/home/ubuntu/Game2/msgagent_module/ma_guild.lua
- 同盟创建逻辑:
/home/ubuntu/Game2/services/guild/guildmanager_core.lua
- 创建后同盟状态同步:
/home/ubuntu/Game2/services/msgagent.lua
/home/ubuntu/Game2/services/scene/scenecore.lua
关键代码
当前 Lua 协议定义
packet.CGCreateGuildLeague = {
xy_id = packet.XYID_CG_CREATE_GUILD_LEAGUE,
new = function()
local o = {}
setmetatable(o, { __index = packet.CGCreateGuildLeague })
o:ctor()
return o
end,
ctor = function(self)
end,
bis = function(self, buffer)
local stream = bistream.new()
stream:attach(buffer)
self.name = stream:read(0x20)
self.name = gbk.toutf8(self.name)
self.desc = stream:read(0x40)
self.desc = gbk.toutf8(self.desc)
end
}
当前 Lua 请求入口与中转
function request:CGCreateGuildLeague()
ma_func:CGCreateGuildLeague(self)
end
function ma_guild:CGCreateGuildLeague(request)
local guild_id = self:get_guild_id()
local ret = skynet.call(".Guildmanager", "lua", "create_guild_league", self:get_guid(), guild_id, request)
if ret == nil then
self:notify_tips("创建同盟失败,名称已存在")
end
end
当前同盟创建逻辑
function guildmanager_core:create_guild_league(guid, guild_id, updater)
local guild = self:get_guild_by_id(guild_id)
local chief = self:get_my_guild_info_in_guild(guid, guild_id)
if chief.position ~= define.GUILD_POSITION_CHIEFTAIN then
return
elseif guild.confederate_id ~= define.INVAILD_ID then
return
end
updater.name = string.match(updater.name, "([^%z]+)")
updater.desc = string.match(updater.desc, "([^%z]+)")
if self:check_league_name_dupliate(updater.name) then
return
end
local league = {}
league.id = self:get_empty_league_id()
league.name = updater.name
league.desc = updater.desc
league.chief_guid = chief.guid
league.chief_name = chief.name
league.creator = chief.name
league.founded_time = os.date("%y%m%d%H%M")
league.guilds = { {id = guild.id, join_date = os.date("%y%m%d%H%M") } }
skynet.call(".db", "lua", "safe_insert", { collection = "leagues", doc = league})
self:update_guild_confederate_id_and_name(league, guild)
self:clear_guild_league_prepares(guild, league.id)
self:reload_leagues()
return league
end
当前成功后的状态刷新
function guildmanager_core:update_guild_confederate_id_and_name(league, guild)
guild.confederate_id = league.id
guild.confederate_name = league.name
self:multicast(guild.id, define.INVAILD_ID, "update_confederate_id", league.id, league.name)
self:db_update_guild_confederate_id(league, guild)
end
function CMD.update_confederate_id(confederate_id, confederate_name)
local ret = skynet.call(my_scene, "lua", "update_confederate_id", my_obj_id, confederate_id, confederate_name)
ma_func:set_confederate_id(confederate_id)
ma_func:set_confederate_name(confederate_name)
subscribe_confederate_multicast(confederate_id)
if ret then
local guild_request = { packet_type = 3, type = 3, askid = 0 }
ma_func:CGGuild(guild_request)
end
end
当前 Game.exe 读写结论
Read:
read(name, 32);
read(desc, 64);
Write:
write(name, 32);
write(desc, 64);
GetPacketSize:
96
Execute:
return 2;
结论
CGCreateGuildLeague 的当前包 ID 是 263,固定长度 96 字节。
- 包体结构非常直接,就是
32 字节同盟名称加 64 字节同盟宣言两个固定字符串槽。
- 当前 Lua 主链已经真实接入这条请求,并会把它转交给
.Guildmanager:create_guild_league() 完成创建。
- 当前成功路径没有专用成功回包,而是通过内部
update_confederate_id 广播和后续 CGGuild 刷新来同步客户端状态。
- 当前失败提示存在实现偏差:所有
nil 返回都会显示“名称已存在”,即使真实失败原因可能是“非帮主”或“当前帮会已加入同盟”。