
Repair Shop
RepairShop, a Minecraft plugin that turns a Citizens NPC into a blacksmith. Players right click the NPC and a menu lists every damaged item they're carrying, each priced on how worn it is, what it's made of, and what's enchanted on it, paid through Vault
Список изменений
Changelog
2.0.0
One jar for Minecraft 1.9 through 26.2
RepairShop used to require Paper 1.21 and refuse to load on anything else. It now runs on any server from 1.9 to 26.2 Spigot or Paper from a single jar, with Paper 1.21.11 still the version it is developed and tuned against.
Nothing about pricing, the GUI, the shop editor or the logs has changed. Existing config.yml,
messages.yml and shops/*.yml files are read exactly as before, and items already carrying a
repair count keep it.
How it works. Everything the Bukkit API moved over the years now sits behind a small interface
in net.repairshop.compat, and the implementation is chosen at startup by asking whether a class
or method exists never by comparing version numbers, which is precisely the thing that broke
when Minecraft's version scheme changed to 26.x. The implementations that need modern APIs live
in compat.modern and are loaded reflectively, so an old server never touches them.
- Text. Full MiniMessage on Paper 1.16.5+; everywhere else a built-in translator renders the
same source into legacy
§codes. Colours, hex and the five decorations survive; gradients collapse to their first colour and hover/click text is dropped, keeping its contents. - Item damage.
Damageableitem meta on 1.13+, theItemStackdurability short below it, and per-item maximum durability where 1.20.5+ supports it. - Material names. Config files are read in both the pre- and post-flattening vocabularies, so
the same file prices
GOLDEN_AXEandGOLD_AXEas one thing. GUI buttons resolve through a preference list per button, so a menu still draws on a version where the icon does not exist. - Enchantment names. Pre-1.13 Bukkit constants (
DIG_SPEED,DURABILITY) are mapped onto modern keys, so oneconfig.ymlprices enchantments identically everywhere. - Chat prompts. Paper's
AsyncChatEventwhere it exists,AsyncPlayerChatEventotherwise. - Adventure 5. Paper 26.2 ships Adventure 5, which dropped previously deprecated API. The Adventure bridge self-checks at startup and falls back to legacy text rather than failing if a future release moves something it needs.
The one real loss on old servers: the work penalty needs somewhere on the item to keep a repair
count, and that is the persistent data container, which arrived in 1.14. On 1.9–1.13 the penalty is
inactive and every repair is priced as a first repair. The console says so at startup and
/repairshop quote says so per item. Everything else degrades cosmetically or not at all.
New: /repairshop compat prints which route the running server took, so a support question
does not need the startup log.
Build changes
maven.compiler.releaseis now 8 rather than 21. Java 8 bytecode loads on every later JVM, so the jar needs nothing of the server that the server did not already need.api-versionis now1.13, not1.21. It is the oldest value any server accepts, and versions before 1.13 ignore the key entirely which is what lets one jar cover the range. Raising it to match your own server would break every older one.build.ps1 -Verifycompiles the version-agnostic core against Spigot 1.9, 1.12.2 and 1.13.2 and Paper 1.21.11 and 26.2, then runs the legacy text translator's checks. That is what keeps the range honest; run it after touching anything incompat/.
Upgrading: delete the old RepairShop-1.3.0.jar before starting, or the server will refuse to
load two plugins with the same name. build.ps1 -Deploy does that for you.
1.3.0
Per-shop repair logs
Every paid repair is now written to shops/<id>/logs/<date>.log, one file per shop per day
the same idea as the dtlTradersPlus shop logs, in a format meant to be read.
# RepairShop repair log
# Shop : city_smith City Smith
# Date : 2026-08-21
#
# One line per paid repair. "worn" is how damaged the item was when it was handed
# in; "nth" counts how many times this plugin had already repaired that same item,
# which is what the work penalty charges for. Amounts are plain numbers.
#
#time | player | item | tier | worn | nth | cost
#---------+------------------+----------------------------------+-----------+------+------+-------------
00:12:04 | Player A | Netherite Axe | NETHERITE | 82% | 3rd | 1,742.50
00:12:44 | Player B | Diamond Pickaxe | DIAMOND | 31% | 1st | 298.00
00:12:46 | Player C | * Repair All (4 items) | - | - | - | 1,204.00
What it does differently from the logs it is modelled on:
- Fixed, pipe-separated columns instead of a sentence, so a day's trade can be scanned down
the page and still
grep-ed or pulled into a spreadsheet. - No leftover colour codes. Names and item names are written as plain text; a
§rnever reaches the file. - No repetition. The date and the shop name are in the path, so they are not on every line.
- A header that explains the columns, written once per file.
- Repair-specific detail: how worn the item was, its tier, and how many times this plugin had repaired that same item before which is the number the work penalty charges for, and the one to look at when a price seems too high.
- A
Repair Everythingclick writes its items individually and then one*summary line, so a batch can be read as a group. A one-item batch skips the summary.
Nothing is created until it is needed. A shop nobody has repaired at has no logs folder;
the day's file appears with the first repair of that day.
Configuration new logging: section in config.yml:
| Key | Default | Meaning |
|---|---|---|
enabled | true | Turn logging off entirely. |
include-uuid | false | Add a UUID column, for auditing across name changes. |
keep-days | 0 | Delete logs older than this on startup. 0 keeps them forever. |
Writes happen off the main thread, and a failure is reported once rather than every repair.
1.2.0
Shops can be created and edited in-game
Until now a new shop meant stopping to copy shops/default.yml by hand, editing YAML, and
running /repairshop reload. The whole cycle is now a GUI, and the file it writes keeps the
same comments a hand-written one has.
/repairshop shopsa browser listing every shop with its title, multiplier, permission, tiers, refusal count and how many NPCs are running it. Click a shop to edit it, shift-click to see it as a customer would, or press New Shop to make another./repairshop create <id>straight into the editor for a new shop./repairshop edit <id>the editor for an existing one. With no id it opens the browser./repairshop delete <id> confirmdeletes a shop and its file from chat. The editor has the same thing as a two-click button.
The editor holds every field of a shop file on one screen:
| Button | Does |
|---|---|
| Menu title | Type a MiniMessage title in chat; the button shows it rendered. Right-click reverts to the global default. |
| Price multiplier | Left/right-click ±0.05, shift for ±0.25, middle-click resets. Shows what a worn-out diamond pickaxe would cost at that rate. |
| Accepted tiers | Sub-screen with every tier from config.yml, click to toggle, shift-click for "only this one". |
| Refused materials | Sub-screen: add the item in your hand, type names in chat, or click an entry to drop it. |
| Assign to selected NPC | Gives your /npc select-ed NPC this shop, saving it first if needed. |
| Preview | Opens the shop as a customer sees it, unsaved changes and all; closing it returns to the editor. |
| Duplicate | Copies the settings into a new shop id. |
| Save / Discard / Delete | Nothing is written until Save. Delete needs two clicks. |
Nothing is written to disk until Save, and a saved shop is live immediately no reload. Closing the editor with unsaved changes says so in chat rather than silently dropping them.
Details
- Shop ids are validated before a file is created: lowercase letters, digits,
-and_, up to 32 characters, not already taken, and not a name Windows reserves (con,aux,lpt1, …). - An empty
allowed-tierslist means "every tier", so the editor refuses to leave it at zero selected tiers that would otherwise silently mean the opposite of what was intended. - Deleting the last remaining shop re-creates the in-memory
default, sogetOrDefaultalways has something to hand back. messages.ymlgained aneditor:section about 130 new keys, all MiniMessage. Existing files keep working; missing keys fall back to the copy bundled in the jar.build.ps1added: builds withjavac/jarfrom JDK 21 directly, for machines with no Maven. It reads the version frompom.xmland filtersplugin.ymlthe same way the pom does.
1.1.0
Help and price discovery
/repairshop helprewritten as a real help page: an explanation of what the plugin does, then commands split into "Everyone" and "Admin" sections. Only shows what the sender has permission to run. Also shown when/repairshopis run with no arguments.- New
/repairshop pricescost of a full repair for every material tier. /repairshop quoteand/repairshop pricesare now player-facing under the newrepairshop.quotepermission (default true) instead of being admin-only.- Help entries and tab completion are generated from the same arrays, so they cannot drift apart.
Price rebalance
The tier ladder was scaled by roughly 1.9x, anchored so that a diamond axe with 500 of 1561 durability damaged costs ~320. Enchantment surcharges were deliberately left unchanged.
| Tier | 1.0.0 | 1.1.0 | Tier | 1.0.0 | 1.1.0 | |
|---|---|---|---|---|---|---|
| Wood | 12 | 24 | Turtle | 270 | 515 | |
| Leather | 14 | 26 | Diamond | 500 | 950 | |
| Stone | 22 | 42 | Netherite | 1000 | 1900 | |
| Gold | 60 | 115 | Elytra | 750 | 1425 | |
| Chainmail | 90 | 170 | Trident | 600 | 1140 | |
| Iron | 140 | 265 | Mace | 700 | 1330 |
item-values for bows, crossbows, shields, fishing rods, shears, flint and steel, carrot on a
stick and brushes were scaled by the same factor.
Fixes
messages.ymlnow falls back to the copy bundled in the jar for any key it is missing. Previously, message keys added by an update rendered as<missing message: ...>until the user deleted their file.
1.0.0
Initial release.
- Citizens
repairshoptrait; right-clicking an NPC opens the repair menu. - Dynamic pricing from material tier, item shape, enchantments and damage ratio, shaped by a configurable curve.
- Paginated 54-slot GUI scanning main inventory, hotbar, armour slots and offhand.
- Per-item repair and "Repair Everything", the latter with optional confirmation and cheapest-first partial repair when funds are short.
- Multiple shops with individual price multipliers, permissions and allowed tiers.
- Permission-based rank discounts.
- Compounding work penalty replacing vanilla's "Too Expensive" cap, tracked per item in its persistent data container.
- Slot-and-snapshot verification on every purchase, with withdraw-before-repair and refund on failure.
- MiniMessage-formatted
messages.yml.
