
Q Shop
适用于Forge 1.20.1的灵活服务端商店模组,包含完整的交易GUI、自定义货币、购买/出售/以物易物/命令交易、购买限制、游戏内编辑及KubeJS集成。
Q Shop
Q Shop 是一个适用于 Minecraft Forge 1.20.1 的服务端商店模组。你可以创建一个或多个商店,通过友好的游戏内 GUI(或通过命令 / KubeJS)为商店填充交易,使用基于每位玩家钱包的自定义非物品货币,并让你的玩家购买、出售、以物易物或触发服务器命令——所有功能均支持可配置的数量、购买限制和任务/阶段要求。
没有强制性的模组依赖。 可在纯净的 Forge 1.20.1 服务器上运行。KubeJS、FTB Quests 和 GameStages 是可选模组,仅在需要使用其各自功能(脚本 / 任务门槛 / 阶段门槛)时才需要。
特性



交易 GUI
- 在同一个网格中支持购买、出售、物品对物品的易物和命令交易。
- 对于易物交易,可以选择在物品之外额外收取少量货币费用。
- 命令交易在购买时运行服务器命令——可选择使用物品或货币支付。
- 每笔交易支持自定义显示名称、描述(支持
§颜色代码)以及用于槽位的显示物品。 - 每笔交易数量可配置:可根据你的余额/库存购买任意数量,并实时预览总价。
自定义货币
- 支持任意数量的非物品货币(例如金币、点数、代币),每种货币都有名称和颜色。
- 存储在每位玩家的持久化钱包中——没有物品刷屏,没有箱子。
- 通过
/qshop currency give|take|set、/qshop currency create或 KubeJS 进行管理。 - 在 GUI 中使用 K/M/B 缩写进行大数字安全格式化。
商店与子商店
- 支持多个商店,可通过 ID 或 UUID 识别。
- 每个商店都有一个可滚动的 标签页列表(子商店),并带有图标。
- 每个商店都有一个 默认货币(显示在 GUI 底部的余额)——可在创建商店时设置(命令 / KubeJS)或稍后在 编辑商店 对话框中设置。
- 商店数据存储在每商店的 JSON 文件中(
world/serverconfig/qshop/shops/)——完全可手动编辑。 - 游戏内编辑(创造模式 + OP):通过拖放添加/移除/复制/重新排序条目,使用完整的物品选择器(包括 NBT)编辑物品,重命名标签页,编辑商店信息(名称、图标、默认货币)。
购买限制
- 每个条目有 全局(服务器范围)和 每位玩家 限制,以物品数量计算。
- 重置周期:从不 / 每日 / 每周 / 每月。
要求(门槛)
- 将条目和整个标签页置于 FTB Quests 或 GameStages / KubeJS 阶段之后。
- 这些是 可选的、按交易计算的特性:只有在交易上实际配置了要求时,交易才会受到影响。
- 阶段检测需要安装 GameStages 模组(或 KubeJS 的阶段系统)。
- 如果你配置了要求但未安装相应的模组,该要求将被视为未满足(交易保持锁定)——因此只在安装了这些模组的服务器上设置任务/阶段门槛。
购买时执行命令
- 购买后执行一条或多条命令,支持占位符:
%player%、%player_uuid%、%shop%、%shop_uuid%、%entry%、%units%、%items%、%price%、%currency%、%multiplier%。 - 每条命令可配置 OP 等级(控制台级或玩家级)和静默执行。
细节优化
- 自定义物品提示、彩色文本、淡入淡出遮罩、平滑滚动——GUI 专为易用性而设计。
- 交易反馈消息可以发送到聊天栏或动作栏(statsMessage 区域),以避免聊天栏刷屏——可在服务器配置中切换。
- 编辑模式状态会在关闭界面后保留(创造模式),生存模式始终会强制关闭它。
命令
/qshop open <shop> [player] 打开商店(OP 可为其他玩家打开)
/qshop list 列出所有商店
/qshop balance 显示你的钱包余额
/qshop reload 从磁盘重新加载所有商店配置
/qshop currency list 列出所有货币
/qshop currency create <id> <name> [color]
/qshop currency give|take|set <player> <currency> <amount>
/qshop shop create <id> [displayName] [currency]
/qshop edit <shop> add <type> [price] [currency]
/qshop edit <shop> remove <index>
/qshop edit <shop> setitem <index>
/qshop edit <shop> set <index> <field> <value>
/qshop item 将你手持的物品打印为 Base64(用于配置文件)
/qshop edit add的type可选值:buy、sell、barter、command。编辑命令需要权限等级 2。对于/qshop shop create:省略货币时默认为coins;名称中包含空格时请使用引号,例如/qshop shop create vip "VIP Shop" tokens。
配置
- 商店:
world/serverconfig/qshop/shops/<id>.json— 每个商店一个文件,首次运行时自动生成(包含一个starter商店作为示例)。 - 货币:
world/serverconfig/qshop/currencies.json。 - 服务器设置(
world/serverconfig/qshop-server.toml):切换交易反馈消息并将其移至动作栏。 - 客户端设置(
config/qshop-client.toml):标签页列表的淡入淡出遮罩及其颜色。
配置文件中的物品格式(三种都可接受):"minecraft:diamond"、{"item": "minecraft:oak_log", "count": 8, "nbt": "{...}"} 或 Base64(模组保存的格式,也是 /qshop item 打印的格式)。
KubeJS 集成
安装 KubeJS 后,可以在 server_scripts 中使用 QShop 绑定。完整 API:
// ---- 商店 ----
QShop.open('starter', event.player); // 为玩家打开(通过 ID 或 UUID)
QShop.openByUuid('xxxxxxxx-...', event.player);
QShop.exists('starter'); // boolean
QShop.getShopIds(); // string[]
QShop.getShopUuid('starter');
QShop.createShop('vip', 'VIP Shop', 'coins'); // 显示名称 + 默认货币(空字符串 = 'coins')
QShop.removeShop('vip'); // boolean
QShop.reload();// ---- 货币(钱包) ----
QShop.getBalance(event.player, 'coins'); // double
QShop.giveCurrency(event.player, 'coins', 100);
QShop.takeCurrency(event.player, 'coins', 10);
QShop.setCurrency(event.player, 'points', 50);
QShop.getCurrencies(); // string[]
QShop.createCurrency('tokens', 'Tokens', '55ff55'); // boolean (十六进制颜色)
// ---- 子商店(标签页) ----
QShop.addTab('vip', 'Weapons', 'minecraft:iron_sword'); // 图标可选
QShop.addTab('vip', 'Armor', 'minecraft:diamond_chestplate', 'my-fixed-tab-uuid'); // uuid 可选,为空/省略 = 随机
QShop.updateTab('vip', 0, 'Armor', 'minecraft:diamond_chestplate'); // 按索引
QShop.updateTabByUuid('vip', tabUuid, 'Armor', null); // 按 uuid
QShop.removeTab('vip', 0);
QShop.removeTabByUuid('vip', tabUuid); // 保留至少一个标签页
QShop.getTabCount('vip');
QShop.getShopTabUuid('vip', 0);
// ---- 条目 ----
// 使用 JsonIO.of({...}) 构建条目 JSON(注意:是 JsonIO,不是 JsonUtils!)
QShop.addEntry('vip', JsonIO.of({
type: 'SELL', // BUY | SELL | BARTER | COMMAND
item: 'minecraft:diamond',
price: 100,
currency: 'coins',
globalLimit: 100,
playerLimit: 10,
limitReset: 'DAILY', // NEVER | DAILY | WEEKLY | MONTHLY
uuid: 'my-fixed-entry-uuid' // 可选,为空/省略 = 随机
}));
QShop.addEntry('vip', 1, JsonIO.of({ type: 'BUY', item: {item: 'minecraft:oak_log', count: 8}, price: 2, currency: 'coins' }));
// 2nd argument: Number = tab index (0-based), String = tab uuid
QShop.addEntry('vip', tabUuid, JsonIO.of({ type: 'COMMAND', commands: [{command: 'give %player% diamond 1', op: true, silent: true}] }));
QShop.updateEntry('vip', 0, JsonIO.of({ type: 'SELL', item: 'minecraft:netherite_ingot', price: 500, currency: 'coins' }));
QShop.updateEntryByUuid('vip', tabUuid, entryUuid, JsonIO.of({ type: 'SELL', item: 'minecraft:emerald', price: 50 }));
QShop.removeEntry('vip', 1, 0); // tab 1, index 0
QShop.removeEntryByUuid('vip', tabUuid, entryUuid);
QShop.getEntryCount('vip'); // 默认标签页中的条目数
QShop.getEntryCount('vip', 1);
QShop.getShopEntryUuid('vip', 0, 0);
// ---- 限制清理 ----
QShop.clearEntryLimits('vip', tabUuid, entryUuid);
QShop.clearTabLimits('vip', tabUuid);
QShop.clearShopLimits('vip');
流式构建器(JSON 形式的替代方案)
两种 API 功能等价且经过全面测试——使用你喜欢的那种即可。构建器更易于发现且逐步验证;JSON 形式则与商店配置文件保持一致。
// 交易条目
QShop.entry('vip') // 目标商店(第 2 个参数可选:Number = 标签页索引,String = 标签页 UUID)
.sell('minecraft:diamond') // 或 .buy(...) / .command() / .barter(give, receive)
.price(100, 'coins') // 单价 + 货币
.playerLimit(10, 'DAILY') // 玩家限制 + 重置周期 (NEVER/DAILY/WEEKLY/MONTHLY)
.globalLimit(100)
.description('§aRare material')
.uuid('my-entry-id') // 可选,省略时随机
.add(); // 返回 boolean// 命令条目(cmd() 会自动将类型切换为 COMMAND)
QShop.entry('vip')
.cmd('give %player% minecraft:elytra 1', true, true) // 命令, op, silent
.price(50, 'coins')
.add();
// 易物,使用 JS 对象物品(也接受 {item, count, nbt})
QShop.entry('vip', 0)
.barter({item: 'minecraft:stone', count: 2}, 'minecraft:cobblestone')
.add();
// 子商店(标签页)
QShop.tab('vip')
.name('Weapons')
.icon('minecraft:iron_sword')
.uuid('my-tab-id') // 可选,省略时随机
.add();
构建器中的物品参数接受:物品 ID 字符串('minecraft:diamond')、ItemStack、物品 JSON 或 JS 对象({item, count, nbt})。
事件
// 购买前事件(可取消):在扣费/扣物之前触发
QShopEvents.beforeTrade(event => {
console.log(event.playerName + ' 想买 ' + event.entryName + ' x' + event.units
+ ' 单价 ' + event.price + ' ' + event.currency);
if (event.entryUuid === 'some-entry') {
event.cancel(); // 取消这笔交易
event.player.tell('该条目已下架');
}
});// 购买后事件(只读):成交后触发(含实际数量/实付/是否部分成交)
QShopEvents.afterTrade(event => {
console.log(event.playerName + ' 买了 ' + event.entryName + ' x' + event.tradedUnits
+ ',实付 ' + event.paidPrice + ' ' + event.currency + (event.partial ? ' (部分成交)' : ''));
});
可用字段:player / playerName、shopId / shopUuid、tabIndex / entryIndex / entryUuid、entryType (BUY/SELL/BARTER/COMMAND)、entryName、price / currency、units(购买前)或 tradedUnits / totalItems / paidPrice / partial(购买后)。
实时同步
打开商店 GUI 的玩家会在 约 2 秒内收到修改过的条目/标签页推送 —— 如果另一位管理员或 KubeJS 脚本更改了商店(价格、条目、标签页),打开的 GUI 会自动刷新,同时保留滚动/标签页/编辑模式状态。
示例服务器脚本
// server_scripts/qshop_example.js
// 1) 一次性设置:在服务器完全启动后创建商店
let qshopSetupDone = false;
ServerEvents.tick(event => {
if (qshopSetupDone) return;
qshopSetupDone = true;
if (!QShop.exists('vip')) {
QShop.createShop('vip', 'VIP Shop', 'coins');
QShop.addTab('vip', 'Weapons', 'minecraft:iron_sword');
QShop.addEntry('vip', 0, JsonIO.of({
type: 'SELL',
item: 'minecraft:diamond',
price: 100,
currency: 'coins',
playerLimit: 10,
limitReset: 'DAILY'
}));
QShop.addEntry('vip', 0, JsonIO.of({
type: 'COMMAND',
commands: [{ command: 'give %player% minecraft:elytra 1', op: true, silent: true }]
}));
}
});// 2) 欢迎奖励:每当玩家加入时
PlayerEvents.loggedIn(event => {
QShop.giveCurrency(event.player, 'coins', 50);
});
// 3) 打开商店的命令: /openshop
ServerEvents.commandRegistry(event => {
const { commands } = event;
event.register(
commands.literal('openshop')
.requires(src => src.hasPermission(2))
.executes(ctx => {
QShop.open('vip', ctx.source.entity);
return 1;
})
);
});
提示: 新创建的商店已经包含一个默认子商店,因此
QShop.getTabCount()的初始值为 1,每次QShop.addTab()都会增加一个。建议在玩家触发的事件(PlayerEvents.*、命令、ServerEvents.tick)中进行商店设置——此时服务器的商店管理器已完全加载。
要求
QShop 没有强制性的模组依赖。 它可以在纯净的 Forge 1.20.1 服务器上开箱即用。KubeJS、FTB Quests 和 GameStages 都是 可选的,仅在你需要它们的具体功能时才需要。
- 必需: Minecraft 1.20.1, Forge 47.x
- 可选 — KubeJS: 脚本集成(
QShop绑定)。自动检测,仅在安装时加载。 - 可选 — FTB Quests: 任务门槛。仅在为交易或标签页配置
requiredQuests时需要。 - 可选 — GameStages: 阶段门槛。仅在配置
requiredStages时需要。如果安装了 KubeJS,阶段检查也可以通过 KubeJS 的玩家阶段进行(此时并非严格要求 GameStages),但传统的基于 GameStages 的门槛需要 GameStages 模组(例如GameStages-Forge-1.20.1-15.0.2.jar)。
⚠️ 如果一笔交易配置了任务/阶段要求,但对应的模组缺失,则无法验证这些要求,该交易将被视为锁定。请在已安装 FTB Quests / GameStages(或 KubeJS)的服务器上保留要求配置。
权限
/qshop open(为其他玩家打开)、/qshop reload、/qshop currency、/qshop shop create、/qshop edit:权限等级 2(OP)- 游戏内商店编辑:权限等级 2 + 创造模式
许可证
ARR
正在加载版本记录…

正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。