整理背包 SortBag 完整实现逻辑

核心目标:堆叠同类、按规则排序、空位后置、锁定物品位置不动 ,不修改物品属性(强化、时效、绑定、唯一性) 前置前提:背包是数组结构 items[pos],pos 从 1~最大格子数;格子分【锁定格子】和【普通格子】

一、整体流程总览

markdown 复制代码
输入:player玩家对象 → 取出背包数据
1. 分离锁定物品 和 待排序物品(锁定物品原位保留,不参与排序)
2. 对待排序物品做堆叠合并(满足堆叠条件才合并)
3. 对合并后的物品列表按策划排序规则排序
4. 重建背包格子:先放回锁定物品,再依次往空位填入排序后的物品
5. 落地存库 + 全量同步背包给客户端
6. 返回结果码

二、分步详细逻辑拆解

步骤1:遍历背包,分离锁定物品 & 可排序物品

遍历每一个背包格子(1 ~ 背包最大格子)

  • 如果格子有物品,并且 item.is_lock == true:放入 lock_map,key=格子位置pos,value=物品,这个格子后续不动

    锁定物品一般:穿戴中的装备、绑定锁、限时活动锁定道具、交易挂单物品

  • 如果格子有物品、非锁定 :加入待排序列表 sort_list

  • 空格子直接跳过

判断分支:如果待排序列表是空,直接返回【无需整理】,提前return,节省性能。

步骤2:物品堆叠合并(最容易出bug的环节)

堆叠判定条件必须全部同时满足:

  1. item_id 相同

  2. bind(绑定标记)相同

  3. expire_time(过期时间)相同

    理由:绑定/非绑定不能堆一起;不同到期时间的时效道具不能堆一起

拿到物品配置表 ConfigMgr:GetItemCfg(item_id),读取该物品的 stack_max(最大堆叠数量)

  • 不可堆叠物品(stack_max = 1):直接进入排序列表,跳过合并

  • 可堆叠物品:

    • 用拼接key item_id|bind|expire_time 做字典分组
    • 同key分组内,往已有物品里面加数量,加到 stack_max 上限为止
    • 填满之后剩下的数量生成新物品条目

示例: 物品A,最大堆叠99,已有60,新来50 → 原有变成99,剩余11,新建一条物品A(11)

步骤3:物品排序(策划可配优先级)

合并完成后,对 new_sort 数组执行 table.sort,排序优先级:

  1. 优先按 item_type 物品类型升序(策划配置:装备→消耗→材料→其他)

  2. 同类型下,按 item_id 升序(也可以配品质、等级,按需改)

    这里是配置驱动,想改成【品质优先】只需要修改sort回调

步骤4:回填格子(重点!锁定物品位置优先保留)

  1. 先把背包 items 数组清空

  2. 把 lock_map 里面锁定物品,原样放回原来的 pos 位置

    css 复制代码
    lock_map[5] = 屠龙 → 背包第5格固定放屠龙,不会被挤走
  3. 从头遍历所有格子 1~max_grid,找到空位依次填入排序好的物品

    • 遇到已经有锁定物品的格子:跳过
    • 遇到空位:取排序列表下一个物品填入
    • 排序列表填完,剩下所有格子保持为空

✅ 效果:锁定物品原地不动;所有可排序物品挤到锁定物品之后的空位,全部空格子集中到背包末尾

步骤5:数据持久化 + 客户端同步

  1. 把新的背包数据写入玩家存档(DbMgr落地)
  2. 调用 SyncBagAll(player),下发全量背包协议给客户端,刷新界面
  3. 写操作日志(GM调用写GM日志;玩家自助整理写普通操作日志)

三、关键业务约束(边界规则)

  1. ❌ 整理不会改变:物品uid、强化、幸运、鉴定属性、绑定、过期时间、数量
  2. ❌ 不参与排序:交易中、摆摊上架中的物品(上层加前置判断拦截)
  3. ❌ 唯一性物品(不可堆叠)不会合并
  4. ✅ 只移动格子位置,物品本身数据不变
  5. ✅ 背包最大格子上限不变,整理不会扩容

四、两种模式区分

  1. 玩家自助整理(C2S消息) :玩家点击按钮触发,权限无限制,只写普通操作日志
  2. GM指令整理 bag_sort:运营后台调用,增加角色存在校验、GM审计日志;可扩展高危参数强制忽略锁定

五、对比【仓库整理 StoreMgr:SortStore】

逻辑几乎完全复用这套算法,区别:

  • 数据源换成个人仓库/行会仓库数据
  • 同步对象:个人仓库只同步本人;行会仓库整理后同步给行会全部在线成员

六、常见坑清单(上线必查)

  1. 堆叠key没带上过期时间 → 不同时效道具合并,导致批量过期bug
  2. 锁定物品回填顺序错误 → 锁定物品被挤位置,玩家投诉
  3. 堆叠的时候超过 stack_max 上限
  4. 整理时玩家正在交易/摆摊,物品位置变动引发交易异常
  5. 只改内存数据,忘记持久化,重登变回原来顺序
相关推荐
我不会起名字32234 分钟前
会话缓存失效排查:区分 Redis 失效与节点广播
redis·后端·go·即时通讯·im·故障排查
深入云栈2 小时前
Netty 4.2.x 源码深度解析 (二十三):ByteBuf 核心设计 —— 索引、类型与零拷贝
java·后端·架构
JackJiang2 小时前
IM踩坑:聊天消息ID怎么设计?一个UUID搞不定,我用双ID解决
后端·架构
开心猴爷2 小时前
iOS 上架 App 流程
后端·ios
code_Bo3 小时前
不只命令行:我把跨 Agent 会话同步做成了桌面应用
前端·javascript·后端
用户8356290780513 小时前
使用 Python 控制 Excel 工作表的分页位置
后端·python
用户8356290780513 小时前
Python 如何在 Word 中添加和管理文档变量
后端·python
量化分析码农5 小时前
股票历史数据的复权参数对照:多级别返回的字段与数值差异
java·javascript·后端
程序员cxuan5 小时前
讲真,智能路由这事儿,还得看基元律动
人工智能·后端·程序员
vaskilab6 小时前
Schema 全绿,Agent 却把参数编造了
后端