欢迎光临
我们一直在努力

GMMgr GM指令管理器(Lua MMO 类服务端)

定位:统一注册、权限校验、参数解析、执行、留痕审计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

设计规范 & 避坑清单

  • 强制审计:所有GM操作必须写流水日志,运营查账、出事回溯;
  • 权限分级:刷道具给TEST,封号清数据只开放给SUPER;
  • 高危指令隔离:delplayer、cleardata这类指令,线上默认Disable;
  • 区分两个入口:聊天GM(玩家角色)、后台GM(运营账号,可叠加IP白名单);
  • 参数严格校验,不要直接raw参数丢进SQL,防止注入;
  • 正式服开关:版本上线直接 GMMgr:SetGlobalSwitch(false) 关闭全部GM;
  • GM指令不要写复杂业务,业务复用原有Mgr接口(背包、玩家模块),禁止重复写逻辑。
  • 事件点

    • EVT_GM_CMD_BEFORE:执行前拦截,可以加二次审批、风控
    • EVT_GM_CMD_AFTER:执行后通知,推送后台消息、告警
    赞(0)
    未经允许不得转载:171主机测评 » GMMgr GM指令管理器(Lua MMO 类服务端)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址