跳到主要内容

SystemShop

SystemShop 是 MatrixShop 中最接近“传统服务器商店”的模块。它主要依赖 YAML 静态定义商品,不需要像拍卖行或玩家商店那样读取运行时上架数据。

默认文件

  • SystemShop/settings.yml
  • SystemShop/goods/*.yml
  • SystemShop/shops/weapon.yml
  • SystemShop/shops/food.yml
  • SystemShop/shops/material.yml
  • SystemShop/ui/shop.yml
  • SystemShop/ui/confirm.yml
  • SystemShop/ui/goods-browser.yml
  • SystemShop/ui/goods-editor.yml
  • SystemShop/ui/goods-shops.yml

SystemShop/settings.yml

Enabled: true

Bindings:
Commands:
Bindings:
- 'system'
- 'systemshop'
Register: false
Show-In-Help: true
Priority: 100
Condition: 'perm matrixshop.systemshop.use'

Entry:
Open-Main-On-Command: true

Currency:
Key: vault

字段解释:

字段说明
Enabled是否启用系统商店模块。
Bindings.Commands.Bindings模块级候选命令关键字。
Register这里默认不注册独立命令,而是走主命令体系。
Show-In-Help是否在 /ms help 里展示。
Priority系统商店入口命令优先级。
Condition默认需要 matrixshop.systemshop.use 权限。
Entry.Open-Main-On-Commandtrue 时,直接输入系统商店命令会先打开主分类页。
Currency.Key模块级默认货币 key。

SystemShop/ui/shop.yml

这个文件定义的是系统商店“主分类页”,不是具体商品页。

Title:
- '&8系统商店'

layout:
- '#########'
- '#W#F#M#I#'
- '#########'
- '####R####'

icons:
'#':
material: 'STAINED_GLASS_PANE'
name: ' '
'W':
material: 'DIAMOND_SWORD'
name: '&b武器商店'
lore:
- '&7购买武器与战斗用品'
- ''
- '&e左键打开'
actions:
left:
- 'matrixshop system open weapon'
'F':
material: 'COOKED_BEEF'
name: '&6食物商店'
lore:
- '&7购买食物与生存补给'
- ''
- '&e左键打开'
actions:
left:
- 'matrixshop system open food'
'M':
material: 'DIAMOND'
name: '&d材料商店'
lore:
- '&7购买基础材料'
- ''
- '&e左键打开'
actions:
left:
- 'matrixshop system open material'
'I':
material: 'PAPER'
name: '&f个人信息'
lore:
- '&7玩家: &f{player}'
- '&7余额: &e{money}'
'R':
material: 'BARRIER'
name: '&c关闭'
actions:
left:
- 'close'

重点:

  • WFM 分别跳转到 weaponfoodmaterial 三个分类页。
  • I 是纯信息按钮,没有动作。
  • R 关闭菜单。

SystemShop/shops/weapon.yml

分类文件负责页面布局、模板和商品引用。推荐写法如下:

id: weapon

Title:
- '&8武器商店'

layout:
- '#########'
- '#ggggggg#'
- '#ggggggg#'
- '####I####'
- '####R####'

icons:
'#':
material: 'STAINED_GLASS_PANE'
name: ' '
'g':
material: 'AIR'
mode: 'goods'
'I':
material: 'BOOK'
name: '&f商店说明'
lore:
- '&7点击商品进入确认界面'
- '&7第一版仅实现基础购买流程'
'R':
material: 'BARRIER'
name: '&c返回'
actions:
left:
- 'back'

template:
name: '&f{name}'
lore:
- '&7价格: &e{price} {currency}'
- '&7单次上限: &f{limit}'
- '&7余额: &f{has_currency}'
- ''
- '&e左键进入购买确认'

Currency:
Key: vault

goods:
- wooden_sword
- iron_sword
- diamond_sword
- bow
- arrow_bundle

顶层字段解释

字段说明
id文档上可以保留,但真正的 shopId 仍以文件名 weapon.yml 为准。
Title当前分类页面标题。
layoutg 是动态商品槽位,I 是说明,R 是返回。
icons静态图标定义。
template所有动态商品统一使用的名称和 Lore 模板。
Currency.Key当前分类的默认货币 key。
goods当前分类引用的商品 id 列表。

SystemShop/goods/diamond_sword.yml

商品文件负责真正的商品定义:

id: diamond_sword
material: 'DIAMOND_SWORD'
amount: 1
price: 420
buy-max: 8
name: '&b钻石剑'
lore:
- '&7高品质近战武器'

商品字段解释

字段说明
id商品 id,通常与文件名一致。
material商品材质。
item更高保真的物品定义,可覆盖基础材质展示。
amount每次购买给多少个。
price单次交易价格。
buy-max单次购买的最大数量或上限展示值。
name商品显示名。
lore商品说明。
currency商品级货币 key。可选;只有你想覆盖默认货币时才需要写。

price 也可以写成对象:

price:
base: 420
discounts:
- id: vip
percent: 10
condition:
- "perm 'group.vip'"
- id: weekend
amount-off: 20
- id: night-surge
surcharge: 8

当前折扣规则:

  • 支持 percentamount-offsurcharge
  • condition 使用 Kether 条件判断
  • 支持 whitelistblacklist 控制折扣叠加
  • 多条命中的 percent 会相加
  • 最终成交价不会低于最小正价
  • {price} 显示最终价;{base-price}{discount-count}{discount-summary} 可用于自定义 UI

黑名单示例:

price:
base: 420
discounts:
- id: vip
percent: 10
condition:
- "perm 'group.vip'"
- id: svip
percent: 15
blacklist:
- vip
condition:
- "perm 'group.svip'"
- id: mvp
percent: 20
blacklist:
- svip
condition:
- "perm 'group.mvp'"

这个例子里:

  • SVIP 命中后会排斥 VIP
  • MVP 命中后会排斥 SVIP
  • whitelist 则用于反向定义“只允许与哪些折扣叠加”

兼容说明:旧版 SystemShop/shops/*.yml 中直接内联 goods.<id> 的写法仍然可读取,但新配置应优先拆到 SystemShop/goods/*.yml

SystemShop/goods/starter_weapons.yml

商品组用于把多个 goods 组合成一个可复用引用:

id: starter_weapons
Kind: group
entries:
- wooden_sword
- iron_sword
- bow

商店中可直接写:

goods:
- starter_weapons
- arrow_bundle

SystemShop/goods/weapon_refresh_pool_example.yml

随机池用于给刷新区域提供候选商品:

id: weapon_refresh_pool_example
Kind: pool
entries:
iron_sword_offer:
goods: iron_sword
weight: 10
price: 99
buy-max: 3

刷新池条目的 price 同样支持对象结构,并会与商品本体的折扣规则合并。

刷新区域

当前已经有 SystemShop 刷新基础能力,配置位置在 icons.<char>.refresh

最小示例:

icons:
'g':
material: 'AIR'
mode: 'goods'
refresh:
Enabled: true
Cron: '0 0 6 * * ?'
Timezone: 'Asia/Shanghai'
Same-For-Players-In-Group: true
groups:
default:
Enabled: true
Random-Refresh: true
Pick: 2
Pool-Ref: 'weapon_refresh_pool_example'

刷新字段解释

字段说明
CronQuartz 风格 cron 表达式。
Timezone该刷新区域的时区。
Same-For-Players-In-Group同组是否共享同一份刷新结果。
groups.<id>.Match-ScriptKether 脚本,决定玩家是否命中该组。
groups.<id>.Random-Refresh是否从随机池抽取商品。
groups.<id>.Pick随机抽取数量。
groups.<id>.Pool-Ref引用 goods 目录中的随机池。
groups.<id>.goods非随机模式下直接引用静态商品或商品组。

后台命令

  • /matrixshopadmin refresh list [category]
  • /matrixshopadmin refresh run <category> [icon]

当前货币优先级

SystemShop 当前采用:

  1. 商品级 currency
  2. 当前分类文件里的 Currency.Key
  3. SystemShop/settings.yml 里的 Currency.Key
  4. 默认回退 vault

管理员商品维护

当前后台命令流已经拆成两步:

  1. 保存商品定义到 goods 仓库
  2. 把已保存商品挂到某个系统商店分类

命令如下:

  • /matrixshopadmin goods ui [page]
  • /matrixshopadmin goods save <price> [buy-max] [product-id]
  • /matrixshopadmin goods add <category> <product-id>
  • /matrixshopadmin goods select <category> <product-id>
  • /matrixshopadmin goods edit <price|buy-max|currency|name|item|remove> ...

其中:

  • goods save 只写 SystemShop/goods/*.yml
  • goods add 只负责把商品 id 引用进分类文件的 goods:
  • goods edit remove 只会把商品从当前分类下架,不会删除 goods 仓库里的文件

后台 UI 文件

这三份 UI 文件用于后台 goods 维护:

  • SystemShop/ui/goods-browser.yml
    • goods 仓库分页浏览页
  • SystemShop/ui/goods-editor.yml
    • 单个 goods 的价格、限购、上架和主手物品同步页
  • SystemShop/ui/goods-shops.yml
    • 某个 goods 的分类挂载选择页

你应该怎么改

  • 想新增一个分类:复制一份 shops/weapon.yml,改文件名,再把 ui/shop.yml 的按钮指过去。
  • 想新增一个商品:新建 SystemShop/goods/<product-id>.yml,然后把 id 加到对应分类的 goods: 列表里。
  • 想改默认打开的分类:改顶层 config.ymlsystem-shop.default-category

相关文件

  • SystemShop/shops/food.yml
  • SystemShop/shops/material.yml
  • SystemShop/ui/confirm.yml

通常先改 goods/*.ymlshops/*.yml,只有在你想重做分类入口和确认流程时,才需要再动 ui/*.yml