定位:统一注册、权限校验、参数解析、执行、留痕审计GM指令,支持聊天栏@指令、后台HTTP GM、控制台GM;强审计、分级权限、线上可关闭高危指令。 依赖:PlayerMgr、LogMgr、EventMgr、ConfigMgr
gm_mgr.lua 完整源码
local GMMgr = {}
GMMgr.__index = GMMgr
— 权限等级定义
GM_AUTH = {
NONE = 0,
TEST = 1, — 测试人员:刷道具、看信息
ADMIN = 5, — 运营:发奖励、禁言、查数据
SUPER = 10, — 超管:封号、清数据、热更、全服广播
}
— 指令注册表:key=cmd名字,value={auth, desc, func, enable}
local cmd_reg = {}
— GM白名单:pid -> auth
local gm_white_list = {}
— 全局开关,正式服可以关闭全部GM
local gm_global_switch = true
— 注册GM指令
— @param cmd 指令名,比如 "additem"
— @param min_auth 最低权限
— @param desc 描述(后台展示)
— @param func 回调 function(gm_pid, target_pid, args) return ok,msg
function GMMgr:RegisterCmd(cmd, min_auth, desc, func)
cmd_reg[cmd] = {
auth = min_auth,
desc = desc,
func = func,
enable = true,
}
LogMgr:Info("[GMMgr] register cmd:%s, min_auth:%d", cmd, min_auth)
end
— 设置玩家GM权限(加载自配置/数据库)
function GMMgr:SetGMAuth(pid, auth)
gm_white_list[pid] = auth
LogMgr:Info("[GMMgr] set gm auth pid=%d, auth=%d", pid, auth)
end
— 关闭单条指令(高危指令线上临时禁用)
function GMMgr:DisableCmd(cmd)
local c = cmd_reg[cmd]
if c then
c.enable = false
end
end
— 全局总开关
function GMMgr:SetGlobalSwitch(onoff)
gm_global_switch = onoff
end
— 获取玩家GM权限
function GMMgr:GetAuth(pid)
return gm_white_list[pid] or GM_AUTH.NONE
end
— 检查权限
function GMMgr:CheckAuth(gm_pid, cmd)
if not gm_global_switch then
return false, "GM全局关闭"
end
local cfg = cmd_reg[cmd]
if not cfg then
return false, "GM指令不存在:"..cmd
end
if not cfg.enable then
return false, "该指令已禁用"
end
local auth = self:GetAuth(gm_pid)
if auth < cfg.auth then
return false, "权限不足,需要权限:"..cfg.auth
end
return true
end
— 解析指令字符串(聊天输入:@additem 1001 99 10002)
— 格式:@cmd arg1 arg2 arg3
function GMMgr:ParseCmdStr(str)
str = string.trim(str)
if str:sub(1,1) ~= "@" then
return nil, nil, "不是GM指令"
end
local parts = string.split(str, " ")
local cmd = parts[1]:sub(2)
table.remove(parts,1)
return cmd, parts, nil
end
— 统一执行入口(最核心)
— gm_pid:执行者pid;target_pid:目标玩家;args参数数组
function GMMgr:Run(gm_pid, target_pid, cmd, args)
local ok, err = self:CheckAuth(gm_pid, cmd)
if not ok then
LogMgr:Warn("[GMMgr] run fail pid=%d cmd=%s err=%s", gm_pid, cmd, err)
return false, err
end
local cfg = cmd_reg[cmd]
— 审计日志,强制落流水!
LogMgr:WriteFlow("gm_cmd", {
gm_pid = gm_pid,
target_pid = target_pid,
cmd = cmd,
args = args,
time = os.time(),
})
EventMgr:Fire(EventDef.EVT_GM_CMD_BEFORE, {
gm_pid=gm_pid, target_pid=target_pid, cmd=cmd, args=args
})
— 执行指令
local ret_ok, ret_msg = cfg.func(gm_pid, target_pid, args)
EventMgr:Fire(EventDef.EVT_GM_CMD_AFTER, {
gm_pid=gm_pid, target_pid=target_pid, cmd=cmd, args=args, ok=ret_ok
})
if ret_ok then
LogMgr:Info("[GMMgr] succ pid=%d cmd=%s target=%d args=%s", gm_pid, cmd, target_pid, table.concat(args, ","))
else
LogMgr:Warn("[GMMgr] cmd exec fail pid=%d cmd=%s msg=%s", gm_pid, cmd, ret_msg)
end
return ret_ok, ret_msg
end
— 聊天消息入口:玩家在聊天框发 @xxx
function GMMgr:OnChatGM(gm_pid, content)
local cmd, args, err = self:ParseCmdStr(content)
if not cmd then
return false, err
end
— 默认目标是自己
local target_pid = gm_pid
return self:Run(gm_pid, target_pid, cmd, args)
end
— 后台HTTP GM入口(运营后台),可单独增加IP白名单校验
function GMMgr:OnBackendGM(gm_pid, target_pid, cmd, args)
return self:Run(gm_pid, target_pid, cmd, args)
end
— 获取指令列表,给GM后台展示
function GMMgr:GetAllCmdInfo()
local list = {}
for k,v in pairs(cmd_reg) do
table.insert(list, {
cmd = k,
auth = v.auth,
desc = v.desc,
enable = v.enable,
})
end
return list
end
return GMMgr
配套 proto(客户端GM聊天、后台GM)
message CS_GM_CMD {
string content = 1; // "@additem 1001 10"
}
message SC_GM_RET {
bool ok = 1;
string msg = 2;
}
注册常用GM指令示例(启动时注册)
— gm_init.lua 启动加载
GMMgr:RegisterCmd("additem", GM_AUTH.TEST, "给目标添加道具,参数:item_id,num", function(gm_pid, target_pid, args)
local item_id = tonumber(args[1])
local num = tonumber(args[2])
if not item_id or not num or num <=0 then
return false, "参数错误:@additem item_id num"
end
local player = PlayerMgr:GetPlayer(target_pid)
if not player then
return false, "目标玩家不在线"
end
local cfg = ConfigMgr:GetRow("item", item_id)
if not cfg then
return false, "道具配置不存在"
end
player.bag:AddItem(item_id, num)
return true, string.format("成功发放道具 id=%d num=%d", item_id, num)
end)
GMMgr:RegisterCmd("setlevel", GM_AUTH.ADMIN, "设置等级:@setlevel lv", function(gm_pid, target_pid, args)
local lv = tonumber(args[1])
local p = PlayerMgr:GetPlayer(target_pid)
if not p then return false, "玩家不在线" end
p:SetLevel(lv)
return true, "等级设置成功"
end)
GMMgr:RegisterCmd("reloadcfg", GM_AUTH.SUPER, "热更配置表:@reloadcfg shop_goods", function(gm_pid, target_pid, args)
local tabname = args[1]
local ok = ConfigMgr:ReloadTable(tabname)
if ok then
return true, "热更成功"
else
return false, "热更失败"
end
end)
GMMgr:RegisterCmd("kick", GM_AUTH.SUPER, "踢人下线 @kick pid", function(gm_pid, target_pid, args)
local kick_pid = tonumber(args[1])
PlayerMgr:KickPlayer(kick_pid, "GM踢下线")
return true, "已踢下线"
end)
使用示例
1. 客户端聊天收到GM消息
— 消息分发
function OnRecvCS_GM_CMD(pid, msg)
local ok, ret = GMMgr:OnChatGM(pid, msg.content)
PlayerMgr:SendMsg(pid, "SC_GM_RET", {ok=ok, msg=ret})
end
2. 后台运营调用(HTTP接口)
— 后台调用,给玩家发元宝
local ok,msg = GMMgr:OnBackendGM(gm_admin_pid, target_pid, "addgold", {10000})
3. 加载GM白名单(启动读配置)
— gm_whitelist.lua
local list = {
[10001] = GM_AUTH.SUPER,
[10002] = GM_AUTH.ADMIN,
}
for pid,auth in pairs(list) do
GMMgr:SetGMAuth(pid, auth)
end
设计规范 & 避坑清单
事件点
- EVT_GM_CMD_BEFORE:执行前拦截,可以加二次审批、风控
- EVT_GM_CMD_AFTER:执行后通知,推送后台消息、告警

