GM指令:仓库扩容、清空仓库(行会仓库 + 个人仓库,Lua + proto + GMMgr注册)

适配之前 StoreMgr(个人仓库)、行会仓库模块;权限分级,日志埋点,防误删保护

1、新增Proto消息

ini 复制代码
syntax = "proto3";

// GM 仓库操作请求
message GmStoreOpReq {
    uint32 op_type = 1;      // 1:仓库扩容 2:清空仓库
    uint64 target_role_id = 2;
    uint32 store_type = 3;   // 1个人仓库 2行会仓库
    uint32 add_grid = 4;     // op=1时,增加格子数量
    bool force = 5;          // 强制清空(二次确认标记)
}

message GmStoreOpRsp {
    int32 ret = 1;
    string msg = 2;
    uint32 now_grid = 3;
}

2、错误码常量

ini 复制代码
local ERR = {
    SUCCESS = 0,
    PARAM_ERROR = -1,
    NO_PERM = -2,
    ROLE_NOT_EXIST = -3,
    STORE_NOT_OPEN = -4,
    FORCE_REQUIRE = -5,
    GRID_LIMIT = -6, -- 超过仓库最大上限
    GUILD_NOT_EXIST = -7,
}

3、GM指令注册(GMMgr批量注册格式)

ini 复制代码
-- gm_cmd_list.lua
local cmd_list = {
    {
        cmd = "store_expand",
        perm = 3, -- 3=运营GM,1=普通GM,5=超管
        desc = "仓库扩容:store_expand roleid storetype addgrid | storetype:1个人 2行会",
        status = 1,
        func = "gm_store_expand"
    },
    {
        cmd = "store_clear",
        perm = 4, -- 高权限,超管/主运营
        desc = "清空仓库:store_clear roleid storetype force(1确认)",
        status = 1,
        func = "gm_store_clear"
    }
}
return cmd_list

4、核心GM处理函数(gm_store.lua)

lua 复制代码
local StoreMgr = require "store_mgr"
local PlayerMgr = require "player_mgr"
local LogMgr = require "log_mgr"
local EventMgr = require "event_mgr"

local gm_store = {}

-- 仓库扩容
function gm_store.gm_store_expand(gm_role, args)
    -- args: roleid, store_type, add_grid
    local role_id = tonumber(args[1])
    local store_type = tonumber(args[2])
    local add_grid = tonumber(args[3]) or 0

    if not role_id or not store_type or add_grid <= 0 then
        return ERR.PARAM_ERROR, "参数错误!用法: store_expand roleid 1/2 增加格子数"
    end

    local target_player = PlayerMgr:GetPlayer(role_id)
    if not target_player then
        return ERR.ROLE_NOT_EXIST, "目标玩家不存在"
    end

    local ret, msg, new_grid
    if store_type == 1 then
        -- 个人仓库扩容
        ret, msg, new_grid = StoreMgr:GmExpandPersonalStore(target_player, add_grid)
    elseif store_type == 2 then
        -- 行会仓库扩容(取玩家所在行会)
        local guild_id = target_player:GetGuildId()
        if guild_id <= 0 then
            return ERR.GUILD_NOT_EXIST, "该玩家没有行会,无法操作行会仓库"
        end
        ret, msg, new_grid = StoreMgr:GmExpandGuildStore(guild_id, add_grid)
    else
        return ERR.PARAM_ERROR, "store_type只能是1(个人) 2(行会)"
    end

    -- 埋日志
    LogMgr:WriteGMLog(gm_role:GetRoleId(), "store_expand",
        string.format("target:%d,type:%d,add:%d,ret:%d,msg:%s", role_id, store_type, add_grid, ret, msg))
    EventMgr:Fire("GM_STORE_EXPAND", gm_role:GetRoleId(), role_id, store_type, add_grid, ret)

    return ret, msg, new_grid
end

-- 清空仓库(高危!必须带force=1)
function gm_store.gm_store_clear(gm_role, args)
    -- args: roleid, store_type, force
    local role_id = tonumber(args[1])
    local store_type = tonumber(args[2])
    local force = tonumber(args[3]) or 0

    if not role_id or not store_type then
        return ERR.PARAM_ERROR, "参数错误!用法:store_clear roleid 1/2 1"
    end
    if force ~= 1 then
        return ERR.FORCE_REQUIRE, "高危指令!必须追加参数 1 确认清空"
    end

    local target_player = PlayerMgr:GetPlayer(role_id)
    if not target_player then
        return ERR.ROLE_NOT_EXIST, "目标玩家不存在"
    end

    local ret, msg
    if store_type == 1 then
        ret, msg = StoreMgr:GmClearPersonalStore(target_player)
    elseif store_type == 2 then
        local guild_id = target_player:GetGuildId()
        if guild_id <= 0 then
            return ERR.GUILD_NOT_EXIST, "玩家无行会"
        end
        ret, msg = StoreMgr:GmClearGuildStore(guild_id)
    else
        return ERR.PARAM_ERROR, "仓库类型错误"
    end

    LogMgr:WriteGMLog(gm_role:GetRoleId(), "store_clear",
        string.format("target:%d,type:%d,force:%d,ret:%d,msg:%s", role_id, store_type, force, ret, msg))
    EventMgr:Fire("GM_STORE_CLEAR", gm_role:GetRoleId(), role_id, store_type, ret)

    return ret, msg
end

return gm_store

5、StoreMgr内部新增接口实现(store_mgr.lua追加)

lua 复制代码
-- ========== GM扩容 - 个人仓库 ==========
function StoreMgr:GmExpandPersonalStore(player, add_grid)
    local store_data = player:GetStoreData()
    local cfg_max = self.cfg.personal_max_grid -- 配置表上限,防止无限扩
    local new_cnt = store_data.grid_count + add_grid
    if new_cnt > cfg_max then
        return ERR.GRID_LIMIT, "超过仓库最大格子上限", store_data.grid_count
    end
    store_data.grid_count = new_cnt
    self:SavePersonalStore(player:GetRoleId(), store_data)
    -- 同步给客户端
    self:SyncStoreInfo(player, 1)
    return ERR.SUCCESS, "扩容成功", new_cnt
end

-- ========== GM扩容 - 行会仓库 ==========
function StoreMgr:GmExpandGuildStore(guild_id, add_grid)
    local guild_store = self.guild_store_map[guild_id]
    if not guild_store then
        return ERR.STORE_NOT_OPEN, "行会仓库未初始化", 0
    end
    local cfg_max = self.cfg.guild_max_grid
    local new_cnt = guild_store.grid_count + add_grid
    if new_cnt > cfg_max then
        return ERR.GRID_LIMIT, "超过行会仓库格子上限", guild_store.grid_count
    end
    guild_store.grid_count = new_cnt
    self:SaveGuildStore(guild_id, guild_store)
    -- 行会全员同步仓库信息
    self:SyncGuildStoreAllMember(guild_id)
    return ERR.SUCCESS, "行会仓库扩容成功", new_cnt
end

-- ========== GM清空个人仓库 ==========
function StoreMgr:GmClearPersonalStore(player)
    local store_data = player:GetStoreData()
    -- 记录被清掉的物品流水(重要!回查)
    local clear_items = {}
    for _, item in pairs(store_data.items) do
        table.insert(clear_items, item)
    end
    store_data.items = {}
    self:SavePersonalStore(player:GetRoleId(), store_data)
    self:SyncStoreInfo(player,1)
    LogMgr:WriteItemLog(player:GetRoleId(), "gm_clear_store", clear_items)
    return ERR.SUCCESS, "个人仓库已清空"
end

-- ========== GM清空行会仓库 ==========
function StoreMgr:GmClearGuildStore(guild_id)
    local guild_store = self.guild_store_map[guild_id]
    if not guild_store then
        return ERR.STORE_NOT_OPEN, "行会仓库不存在"
    end
    local clear_items = {}
    for _,item in pairs(guild_store.items) do
        table.insert(clear_items, item)
    end
    guild_store.items = {}
    self:SaveGuildStore(guild_id, guild_store)
    self:SyncGuildStoreAllMember(guild_id)
    LogMgr:WriteGuildItemLog(guild_id, "gm_clear_guild_store", clear_items)
    return ERR.SUCCESS, "行会仓库已清空"
end

6、运营使用示例

bash 复制代码
# 给角色10001,个人仓库 +20格
store_expand 10001 1 20

# 给角色10001所在行会,行会仓库+50格
store_expand 10001 2 50

# 清空10001个人仓库(必须最后带1确认)
store_clear 10001 1 1

# 清空10001所在行会仓库
store_clear 10001 2 1

7、安全&运维要点

  1. store_clear 单独拉高权限,强制force参数,防止手滑误清
  2. 清空时把所有被删除物品单独写入物品流水日志,可后台回滚核查
  3. 扩容做配置表上限,GM不能无限扩容
  4. 全部操作落GM日志,带操作人、目标、类型、结果,可导出到运营markdown文档
相关推荐
大哥43091 小时前
不报错 ≠ 生效:三类"静默失效"缺陷与它们的共同指纹
后端
房西杭1 小时前
整理背包 SortBag 完整实现逻辑
后端
Marcus学原理1 小时前
Playwright 入门:让浏览器自动完成重复操作
后端
弦儿1 小时前
后端 Web 实战:部门管理模块全流程(前后端分离 + RESTful + 三层架构 + 日志)
后端·restful
房西杭1 小时前
背包<->仓库转移接口(BagMgr + StoreMgr,Lua)
后端
tntxia1 小时前
设计模式中模板方法的钩子使用
后端
我的div丢了肿么办1 小时前
go语言对路由中的业务逻辑进行抽离
后端·go
leo在掘金1 小时前
纯Rust重写Photoshop,一个月7.2万Star
后端·架构
韩振方1 小时前
Kubernetes 通过资源 requests 决定 Pending Pod 能否找到节点
后端