AdventureShop
一、简介
AdventureShop —— 一款全随机商品商店系统,冒险商城
AdventureShop 允许您创建全随机刷新的商品商店。每个商品拥有稀有度等级,价格随机浮动,让玩家每次打开商店都有不同的购物体验。支持8种商店类型、6级稀有度、三层定价、三层折扣、多货币支付和邮件发放。
AdventureShop 支持 Paper / Spigot 1.21.4+ 服务器(Java 21),并且会第一时间支持未来版本。
AdventureShop
- 8种商店类型 > 日/周/月/永久 × 出售/收购
- 6级稀有度 > 权重随机抽取,价格系数联动
- 三层定价 > 基础价 × 稀有度系数 × 随机浮动
- 多货币 > Vault / PlayerPoints / 物品货币
- 三层折扣 > 全局 / 商店级 / 商品级,叠加可控
- 4种发放通道 > 背包/邮件 7/30/180 天
- 商品池 > 支持海量商品随机抽取上架
- GUI商店 > 全GUI交互,美观易用
- 数据存储 > 支持 SQLite 本地存储
- 高自定义 > 商品配置、GUI布局、消息文本全部YAML可配
二、插件前置说明
都是非必须(除 AdventureLib)
- AdventureLib — 必需前置库
- Vault — 经济插件(需基础插件例如ess,cmi等)
- PlayerPoints — 点券插件
- PlaceholderAPI — PAPI变量支持
- AdventureManage — 经济联动
- AdventureMail — 邮件系统,背包满时自动邮寄
安装与目录
环境要求
| 项目 | 要求 |
|---|---|
| 服务端 | Spigot / Paper 1.21.4+ |
| Java | 21+ |
| 必需依赖 | AdventureLib |
| 可选依赖 | Vault、PlayerPoints、AdventureManage、AdventureMail、PlaceholderAPI |
安装步骤
- 放入
AdventureLib.jar+AdventureShop-1.2.2.jar - 按需安装 Vault / AdventureManage / AdventureMail
- 启动服务器自动生成配置
- 编辑
config.yml和items/*.yml /ashopadmin reload
目录结构
plugins/AdventureShop/
config.yml # 主配置
messages.yml # 消息文本
gui.yml # GUI 布局
items/
weapons.yml # 武器物品池
blocks.yml # 建材物品池
misc.yml # 杂货物品池
Translations/
items_CN.yml # 物品名中文翻译
data/
adventureshop.db # SQLite 数据库
商店类型
商店由刷新周期和交易方向两个维度组合,共 8 种:
| 类型 | 配置键 | 周期 | 方向 | 说明 |
|---|---|---|---|---|
| 今日热销 | daySell | 每日 | 出售 | 每天自动刷新 |
| 本周热销 | weekSell | 每周 | 出售 | 每周一刷新 |
| 本月热销 | monthSell | 每月 | 出售 | 每月1号刷新 |
| 固定出售 | onlySell | 永久 | 出售 | 不自动刷新 |
| 今日收购 | dayBuy | 每日 | 收购 | 玩家出售给商店 |
| 本周收购 | weekBuy | 每周 | 收购 | 每周一刷新 |
| 本月收购 | monthBuy | 每月 | 收购 | 每月1号刷新 |
| 固定收购 | onlyBuy | 永久 | 收购 | 不自动刷新 |
出售商店:玩家花钱 → 商店给物品
收购商店:玩家交物品 → 商店给钱(收购价 = 出售价 × buy-back-ratio,默认 0.5)
稀有度系统
每件物品必须指定稀有度,影响抽取概率和价格系数。
| 等级 | 显示名 | 默认权重 | 价格系数 |
|---|---|---|---|
| NORMAL | 普通 (白) | 0.80 | ×1.0 |
| ADVANCED | 高级 (蓝) | 0.50 | ×1.2 |
| RARE | 稀有 (紫) | 0.30 | ×1.5 |
| RARER | 罕见 (粉) | 0.20 | ×2.0 |
| EPIC | 史诗 (黄) | 0.10 | ×3.0 |
| MYTHICAL | 神话 (金) | 0.01 | ×5.0 |
权重覆盖
daySell-weapon:
rarity-weights:
normal: 5 # 权重越高越容易出现
advanced: 3
rare: 2
mythical: 0 # 0 = 不出现
物品池
物品池位于 items/ 目录,一个 YAML 文件 = 一个类别。
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
material | Material | Bukkit 物品材质 |
category | String | 所属类别(匹配商店 category) |
rarity | Rarity | 稀有度等级 |
base-price | double | 基础价格 |
price-variance | double | 浮动比例 (0.15 = ±15%) |
currency | String | 货币 ID |
global-stock | int | 全服库存 (0=不限) |
player-limit | int | 每人限购 (0=不限) |
delivery | Channel | 发放通道 |
discount | Section | C 层商品折扣 (可选) |
示例
# items/weapons.yml
iron_sword:
material: IRON_SWORD
category: weapon
rarity: normal
base-price: 50
price-variance: 0.15
currency: vault
global-stock: 10
player-limit: 2
delivery: INVENTORY
diamond_sword:
material: DIAMOND_SWORD
category: weapon
rarity: rare
base-price: 500
price-variance: 0.2
currency: vault
global-stock: 3
player-limit: 1
delivery: INVENTORY
discount:
enabled: true
rate: 0.85
permission: "adventureshop.discount.weapon"
mace:
material: MACE
category: weapon
rarity: mythical
base-price: 10000
currency: gem
global-stock: 1
delivery: MAIL_180D
物品 category 必须与商店定义的 category 匹配。default 类别会从所有物品中抽取。
定价与刷新
三层定价引擎
最终价格 = 基础价 × 稀有度系数 × (1 ± 随机浮动)
例:钻石剑 base-price=500, RARE (×1.5), variance=0.2
最低 = 500 × 1.5 × 0.8 = 600
最高 = 500 × 1.5 × 1.2 = 900
收购价 = 出售价 × buy-back-ratio (默认 0.5)
自动刷新
| 周期 | 刷新时间 | 配置 |
|---|---|---|
| 每日 | daily-time | refresh.daily-time: "00:00" |
| 每周 | weekly-day | refresh.weekly-day: "MONDAY" |
| 每月 | monthly-day | refresh.monthly-day: 1 |
| 永久 | 不自动刷新 | — |
玩家手动刷新
第 N 次费用 = base-cost × cost-increase ^ (N-1)
示例 (base=500, increase=1.5):
第1次: 500 / 第2次: 750 / 第3次: 1125
| 配置 | 默认 | 说明 |
|---|---|---|
cost-type | vault | 费用货币 |
base-cost | 500 | 首次费用 |
cost-increase | 1.5 | 递增倍率 |
max-per-day | 3 | 每日上限 |
adventureshop.refresh.N 覆盖每日上限。如 adventureshop.refresh.5 = 每天 5 次。
物品发放
| 通道 | 值 | 说明 |
|---|---|---|
| 背包直发 | INVENTORY | 放入背包,满了走兜底 |
| 邮件 7 天 | MAIL_7D | AdventureMail 7 天 |
| 邮件 30 天 | MAIL_30D | AdventureMail 30 天 |
| 邮件 180 天 | MAIL_180D | AdventureMail 180 天 |
兜底机制
INVENTORY 通道降级链:
- 放入背包
- 背包满 → 检查 AdventureMail
- AM 可用 → 发邮箱 (默认 3 天)
- 邮件失败 → SafeGiveUtil 安全掉落
高价值物品(史诗/神话)建议配 MAIL_30D 或 MAIL_180D,避免掉落。
多货币与折扣 v1.1.0
多货币系统
| 后端 | 说明 | 依赖 |
|---|---|---|
vault | Vault 经济接口 | Vault |
playerpoints | PlayerPoints 点券 | PlayerPoints |
item | 物品货币 | 无 |
currencies:
vault:
display-name: "银币"
backend: vault
point:
display-name: "金币"
backend: playerpoints
acoin:
display-name: "A币"
backend: item
item-material: GOLD_NUGGET
item-name: "&eA币"
gem:
display-name: "宝石"
backend: item
item-material: EMERALD
三层折扣
| 层级 | 范围 | 配置位置 |
|---|---|---|
| A 层 | 全局 | discount.permission-discounts |
| B 层 | 商店级 | 商店定义 discount |
| C 层 | 商品级 | 物品池 discount |
叠加规则
| 模式 | 值 | 说明 |
|---|---|---|
| 取最优 | best | 三层取最低(默认) |
| 相乘 | multiply | 0.9 × 0.85 = 0.765 |
| 相加 | add | 折扣幅度相加 |
discount:
enabled: true
stack-mode: best
min-rate: 0.5 # 不低于5折
permission-discounts:
vip:
permission: "adventureshop.discount.vip"
rate: 0.9
priority: 10
svip:
permission: "adventureshop.discount.svip"
rate: 0.8
priority: 20
货币抵扣 v1.1.0
主货币不足时按比例用其他货币补差,聊天框弹出 [点击确认抵扣] 按钮。
currency-fallback:
enabled: true
rules:
- from: vault # 银币不足时
to: point # 用金币抵扣
rate: 10.0 # 1金币 = 10银币
max-ratio: 0.5 # 最多抵扣50%
- from: vault
to: gem
rate: 100.0
max-ratio: 1.0
插件联动
AdventureManage 联动
- 金币交易自动走 AM 的
takeMoney/giveMoney - 交易记录带原因字符串
- 出售给收购商店时自动按 AM 扣税
- 未安装 AM 回退到 Vault 直接扣款
AdventureMail 联动
MAIL_7D / 30D / 180D通道直接发送到邮箱INVENTORY背包满时自动转存邮箱 (默认 3 天)- 邮件标题自动标注商城信息
delivery:
inventory-fallback:
enabled: true
mail-expire-days: 3
mail-source: "§6[冒险商城] §7背包已满自动转存"
命令列表
玩家命令 /ashop
| 命令 | 说明 | 权限 |
|---|---|---|
/ashop | 打开分类选择 GUI | adventureshop.use |
/ashop <商店ID> | 直接打开指定商店 | adventureshop.use |
管理命令 /ashopadmin
| 命令 | 说明 | 权限 |
|---|---|---|
/ashopadmin reload | 重载所有配置 | adventureshop.admin |
/ashopadmin refresh <ID|all> | 强制刷新商店 | adventureshop.admin |
/ashopadmin open <玩家> <ID> | 为玩家打开商店 | adventureshop.admin |
/ashopadmin stats | 查看插件状态 | adventureshop.admin |
config.yml
核心设置
core:
timezone: "Asia/Shanghai"
经济设置
economy:
buy-back-ratio: 0.5
rarity-price-multiplier:
normal: 1.0
advanced: 1.2
rare: 1.5
rarer: 2.0
epic: 3.0
mythical: 5.0
刷新设置
refresh:
daily-time: "00:00"
weekly-day: "MONDAY"
monthly-day: 1
player-refresh:
cost-type: vault
base-cost: 500
cost-increase: 1.5
max-per-day: 3
商店定义
shops:
daySell-weapon:
type: daySell
category: weapon
display-name: "今日热销-武器"
item-count: 8
rarity-weights:
normal: 5
advanced: 3
rare: 2
rarer: 1
epic: 0.5
mythical: 0
数据库
database:
type: sqlite # sqlite / mysql
mysql:
host: localhost
port: 3306
database: adventure_shop
username: root
password: ""
pool-size: 5
GUI 与消息配置
gui.yml
# 分类选择界面
category-gui:
title: "§0§l冒险商城 §8| §r§6选择商店"
size: 54
# 商店浏览界面
shop-gui:
title-format: "§0§l冒险商城 §8| §r{shop_name} §7({page}/{total})"
rows: 6
item-slots: 45
prev-page: { slot: 45, material: ARROW }
next-page: { slot: 53, material: ARROW }
refresh-button: { slot: 49, material: SUNFLOWER }
info-button: { slot: 47, material: BOOK }
# 商品 Lore
item-display:
name-format: "{rarity_color}[{rarity_name}] {item_name}"
lore:
sell:
- "§7价格: §e{price} {currency}"
- "§7全服库存: §f{global_stock}"
- "§7个人限购: §f{purchased}/{player_limit}"
- "§a▶ 左键购买"
buy:
- "§7收购价: §e{price} {currency}"
- "§a▶ 左键出售"
messages.yml v1.2.2
所有用户可见消息、GUI 文本、日志、枚举显示名均可自定义。
| 分区 | 用途 |
|---|---|
shop.* | 交易反馈 (购买/出售/刷新/抵扣) |
reason.* | 交易原因 (AM 日志) |
command.* | 命令反馈 |
gui.* | GUI 标题/Lore/按钮 |
delivery.* | 发放结果 |
mail.* | 邮件标题/来源 |
log.* | 控制台日志 |
enum.* | 枚举显示名 |
prefix: "&6[冒险商城] &r"
shop:
buy-success: "{prefix}&a成功购买 &e{item} &a! 花费 &e{price} {currency}"
fallback-prompt: "{prefix}&e{currency}不足! ..."
fallback-confirm-button: "&a&l[点击确认抵扣]"
enum:
shop-type:
day-sell: "今日热销"
rarity:
epic: "史诗"
GUI 界面
分类选择 GUI
/ashop 打开。每个商店一个图标:
| 商店类型 | 图标 |
|---|---|
| 今日热销 | 向日葵 SUNFLOWER |
| 本周热销 | 金苹果 GOLDEN_APPLE |
| 本月精选 | 下界之星 NETHER_STAR |
| 固定出售 | 箱子 CHEST |
| 今日收购 | 漏斗 HOPPER |
| 本周收购 | 漏斗矿车 HOPPER_MINECART |
| 本月收购 | 末影箱 ENDER_CHEST |
| 固定收购 | 木桶 BARREL |
商店浏览 GUI
54 格界面 (6 行):第 1-5 行商品展示,第 6 行控制栏。
| 槽位 | 功能 |
|---|---|
| 45 | 上一页 (箭头) |
| 47 | 商店信息 (书本) |
| 49 | 刷新商店 (向日葵) — 费用+剩余次数 |
| 53 | 下一页 (箭头) |
权限节点
| 权限 | 说明 | 默认 |
|---|---|---|
adventureshop.use | 使用冒险商城 | 所有人 |
adventureshop.admin | 管理员命令 | OP |
adventureshop.refresh.N | 每日刷新 N 次 (1-10) | false |
adventureshop.discount.vip | VIP 折扣 (9折) | false |
adventureshop.discount.svip | SVIP 折扣 (8折) | false |
adventureshop.discount.mvp | MVP 折扣 (7折) | false |
adventureshop.discount.* | 自定义折扣权限 | false |
从 adventureshop.refresh.10 向下检查,使用首个匹配值。无权限时用 max-per-day。
数据库与安全
存储引擎
SQLite (默认,零配置) 或 MySQL (HikariCP 连接池)。
数据表
| 表名 | 用途 |
|---|---|
shop_items | 商品快照 |
player_purchases | 购买记录 (限购追踪) |
player_refreshes | 刷新次数 (每日) |
transactions | 交易日志 |
shop_stats | 商品统计 |
安全机制
GUI 防护
- Shift / NumberKey / DoubleClick / Drop / SwapOffhand / Middle 全部拦截
- InventoryDragEvent 阻止拖入
- 只处理上方 GUI 区域点击
频率限制
| 操作 | 限制 |
|---|---|
| GUI 点击 | 3秒 / 10次 |
| 购买/出售 | 2秒 / 3次 |
| 刷新商店 | 5秒 / 1次 |
库存原子操作
AtomicInteger + CAS 循环,并发安全不扣负。
交易安全
- 购买:扣库存 → 扣钱 → 发物品,失败回滚
- 出售:先给钱 → 成功后扣物品
- 掉落:SafeGiveUtil 避开岩浆/虚空
更新日志
v1.2.2 最新
- NEW 消息外置 — 所有文本移至 messages.yml
- NEW 枚举显示名 — 商店类型/稀有度可自定义名称
v1.1.0
- NEW 多货币系统 — Vault/PlayerPoints/物品货币
- NEW 三层折扣 — 全局/商店级/商品级
- NEW 货币抵扣 — 主货币不足自动补差
- NEW 4 种发放通道 — 背包/邮件 7/30/180 天
- NEW AdventureMail 兜底 — 背包满自动转存
v1.0.0
- NEW 初始发布 — 随机商品、稀有度、GUI、Vault 经济