CGExecuteScript 是当前项目里客户端请求执行服务端脚本函数的通用桥接包。
包信息
| 项目 |
内容 |
| 封包 ID |
066 |
| 包名 |
CGExecuteScript |
| 对应回包 |
当前未发现固定专用回包 |
| 回包 ID |
无 |
| 作用 |
客户端请求执行白名单允许的服务端脚本函数 |
包体结构
当前 Game.exe 与 Lua 服务端下,这条包是可变长结构。
| 偏移 |
长度 |
字段 |
类型 |
含义 |
0x00 |
0x04 |
script_id |
uint32 |
脚本 ID |
0x04 |
0x01 |
func_name_size |
uint8 |
函数字符串长度 |
0x05 |
n |
func_name |
char[n] |
目标脚本函数名 |
0x05+n |
0x01 |
param_count |
uint8 |
参数数量 |
0x06+n |
4 * param_count |
params |
int32[param_count] |
传给脚本函数的整型参数列表 |
总长度:
4 + 1 + func_name_size + 1 + 4 * param_count
当前实际行为
- 客户端提交
script_id、函数名和整型参数列表。
- 服务端读取函数名后,会先截断字符串中的
\0。
- 请求进入
request:CGExecuteScript() 后,不会直接执行脚本。
- 服务端会先按
AllowableScriptFunc.txt 白名单检查 script_id + func_name 是否允许。
- 白名单不通过时,会记录
CGExecuteScript blocked 日志,并提示 该功能当前暂未开放,请联系管理员处理。
- 白名单通过后,才会进入场景服
execute_client_script()。
- 场景服还会继续检查脚本是否存在、函数是否存在,不存在同样会拦截并提示。
- 当前项目里,这条包的实际定位是“受白名单限制的客户端脚本调用入口”,不是旧式无限制透传包。
服务端落点
- 协议定义:
/home/ubuntu/Game2/services/game/packet.lua
- 请求入口:
/home/ubuntu/Game2/services/msgagent.lua
- 白名单加载:
/home/ubuntu/Game2/lualib/cfghelper.lua
- 场景执行:
/home/ubuntu/Game2/services/scene/scenecore.lua
关键代码
self.m_ScriptID = stream:readuint()
self.m_uFunNameSize = stream:readuchar()
if self.m_uFunNameSize > 0 and self.m_uFunNameSize <= 0x40 then
self.m_szFunName = stream:read(self.m_uFunNameSize)
local zero_pos = string.find(self.m_szFunName, "\0", 1, true)
if zero_pos then
self.m_szFunName = string.sub(self.m_szFunName, 1, zero_pos - 1)
end
end
self.m_uParamCount = stream:readuchar()
if self.m_uParamCount > 0 then
for i = 1, self.m_uParamCount do
self.m_aParam[i] = stream:readint()
end
end
local allow, reason = check_cg_execute_script_allow(script_id, func_name)
if not allow then
log_cg_execute_script_reject(script_id, func_name, reason)
notify_cg_execute_script_reject(reason)
return
end
skynet.call(my_scene, "lua", "execute_client_script", my_obj_id, script_id, func_name, table.unpack(self.m_aParam))
local configs = read:load("AllowableScriptFunc.txt")
for _, conf in pairs(configs) do
local script_id = conf["script_id"]
local func_name = conf["func_name"]
if script_id and func_name and func_name ~= "" then
transferd[script_id] = transferd[script_id] or {}
transferd[script_id][func_name] = true
end
end
local script = self.scriptenginer.scripts[script_id]
script = script and script or self.scriptenginer:try_load(script_id)
if not script then
human:notify_tips("该功能当前暂未开放,请联系管理员处理")
return
end
if type(script[func]) ~= "function" then
human:notify_tips("该功能当前暂未开放,请联系管理员处理")
return
end
return self.scriptenginer:call(script_id, func, who, table.unpack(args))
结论
CGExecuteScript 的封包 ID 是 066。
- 这条包是可变长结构,包体由脚本 ID、函数名和整型参数列表组成。
- 当前版本里,这条包不会直接透传执行,而是先经过
AllowableScriptFunc.txt 白名单校验。
- 白名单通过后,场景服还会继续校验脚本和函数是否真实存在。
- 这条包没有固定专用回包,最终结果取决于具体脚本函数的执行逻辑。