hShopСкачатьСкачать
ВЕРСИИ (2)
release
hShop 1.0.0 bugfix
1.0.028 мар. 2026 г.127Minecraft: 1.21, 1.21.1, 1.21.2, 1.21.3, 1.21.4, 1.21.5, 1.21.6, 1.21.7, 1.21.8, 1.21.9, 1.21.10, 1.21.11bukkit, paper, purpur, spigot
Что нового
# hShop Changelog
---
## Bug Fixes
### GUI & Inventory
**Item theft via bottom inventory**
Clicking in the player's own inventory while a shop session was active was not fully blocked. Shift-clicking and drag events could move items in and out of the shop GUI. Both are now cancelled unconditionally when a session is active.
**Drag events never cancelled**
`InventoryDragEvent` was not handled at all, allowing players to drag items freely into shop GUI slots. A drag handler is now in place.
**Category icon clicks did nothing**
Main menu icon clicks were matched by comparing the item's display name string against a freshly colorized string — these could produce different `§`-code sequences and silently fail on every click. Icons are now registered in the session by slot at placement time, so clicks resolve by slot lookup instead.
**Shop item clicks did nothing**
Category page clicks rebuilt the available-slot index list and assumed item *i* was at `available[i]`. Items with an explicit `slot:` value broke this completely. Items are now registered in the session by their actual slot at placement time.
**Ghost sessions after closing confirm menu**
Closing a confirm menu left the session alive permanently. The next chest, crafting table, or any inventory the player opened had all its clicks intercepted and cancelled. Sessions are now cleaned up correctly on close.
**Confirm cancel lore passed wrong type**
The cancel item's lore was passed as a bare `String` to a `List<String>` parameter, producing broken lore. Wrapped in `Collections.singletonList()`.
**Filler overwrote category and shop icons**
The decoration filler ran before shop items were placed, filling slots that items were then placed on top of. On certain decoration configs this caused icons to appear hidden. Decoration is now applied last and only fills slots that are genuinely empty.
**Filler showing when `enabled: false`**
Setting `enabled: false` under `filler` in a decoration file had no effect — empty slots were still filled. The enabled state is now properly stored and respected.
**Memory leak on player disconnect**
`PlayerListener.onQuit` was completely empty. Every disconnected player's session remained in the map permanently. Sessions are now removed on quit.
---
### Transactions & Economy
**`hasInventorySpace` false-positive gave items on full inventory**
The check used `containsAtLeast(item, 1)` which returns true if the player has *any* of that item — even a full 64/64 stack. Purchases succeeded when the inventory was completely full. Now uses direct stack-size calculation against `getStorageContents()`.
**`hshop.bypass.buy` permission did nothing**
The permission was defined in `plugin.yml` but was never checked in `buyItem()`. It is now checked before the buy-disabled gate.
**Amount clamped to 0 proceeded as success**
If a player had exactly hit their buy limit, `getRemaining()` returned 0, the amount was clamped to 0, and the transaction continued — withdrawing 0 currency and giving a 0-count item, returning `SUCCESS`. Now returns `LIMIT_REACHED` if amount is 0 after clamping.
**`hshop.bypass.sell` checked but did nothing**
The permission block was present but empty. It now correctly skips the sell-disabled check.
**`shopItem.getAmount()` per-purchase quantity was never applied**
Items configured with `amount: 5` always gave 1 item per purchase. Now correctly gives `purchaseAmount × shopItem.getAmount()`.
**`removeItems()` missing `updateInventory()`**
Without this call the client's inventory could desync, showing ghost items until re-log. Now called after every removal.
**Transaction log directory never created**
If `transaction-log.file` pointed to a subdirectory (e.g. `logs/transactions.log`), `FileWriter` threw an `IOException` on every transaction. `mkdirs()` is now called before writing.
**Global sell multiplier compounded on every reload**
The multiplier was applied to `sell.price` at load time and stored back into the `ShopItem`. Reloading three times with a `0.5` multiplier effectively applied `0.125×`. The raw price is now stored and the multiplier is applied only at transaction time.
**`{sell_price}` in item lore showed raw price instead of multiplied price**
Players saw one price in the lore and received a different amount on sell. Lore now uses the effective sell price after applying the multiplier.
---
### Commands
**`/hshop help` double-printed every line**
Called both `get("help.player")` and iterated `getStringList("help.player")`, printing everything twice.
**`/hshopa reload` used wrong message key**
Referenced `admin.plugin-reloaded` but the key is `general.plugin-reloaded`.
**`resetlimit` / `resetcooldown` only worked for online players**
Used `Bukkit.getPlayer()` which returns null for offline players. Now falls back to `OfflinePlayer`.
**`giveitem` silently lost items on full inventory**
`addItem()` leftovers were discarded. Excess items are now dropped at the player's feet.
**`SellHandCommand` sent "no-permission" for a disabled feature**
When sell-hand was disabled in config, the command sent a misleading no-permission message. Now sends `sell.sellhand-disabled`.
**`SellHandCommand` only handled `SUCCESS` and a generic else**
All other result codes (`SHOP_DISABLED`, `NOT_ENOUGH_ITEMS`, etc.) played a fail sound with no message. Each result code now has a proper message.
**`/hshopa setprice` accepted negative prices**
No validation was in place. Values below 0 are now rejected.
**Sessions not cleared on `/hshopa reload`**
After a reload, players with open menus held sessions pointing at old `ShopCategory` and `ShopItem` objects from before the reload. Sessions are now cleared on reload.
---
### Data & Configuration
**YAML key dot-corruption for cooldowns and limits**
If a category or item ID contained a dot, `YamlConfiguration` treated it as a nested path separator when saving, silently corrupting all cooldown and limit data for those items. Dots in keys are now replaced before writing.
**`slot: AUTO` in category items parsed as slot 0**
`getInt("slot", -1)` returned 0 when the value was the string `"AUTO"`. Every AUTO-slotted item landed at slot 0, overlapping decorations. Now reads the string value first and only parses as int if it is not `"AUTO"`.
**Category file listing order was non-deterministic**
`File[]` from `listFiles()` has undefined order across operating systems, causing category load order to vary between restarts. Files are now sorted alphabetically before parsing.
**Enchantments and flags not written back on save**
`saveCategory()` never included `enchantments` or `flags` in its write-back loop. These keys silently disappeared from the yml after any admin command triggered a save.
**New items added to yml on disk erased on next save**
`saveCategory()` called `yml.set("items", null)` before writing back in-memory items. Any item added to the file manually while the server was running — without a reload — was permanently deleted the next time anything triggered a save. The save method now merges properly instead of wiping and rewriting.
---
### Messages & Formatting
**Placeholder values not colorized before injection**
`get(path, placeholders)` colorized the message template first, then injected raw placeholder values after — so a display name like `&fɢᴇᴀʀ` landed in the already-colorized string and was never processed, showing as literal `&fɢᴇᴀʀ` in chat. Placeholder values are now colorized individually before being injected.
**Hex color codes not working (`&#ffffff`)**
Hex color codes in item names, lore, and titles were not rendering correctly. The color translation has been rewritten to manually build the correct `§x§R§R§G§G§B§B` sequences, fixing support for all 6-digit hex codes in both upper and lowercase.
**`send()` suppressed valid messages with wrong blank-check**
Checked for literal `''` and `""` strings which can never match a parsed Java value after `colorize()` runs. Replaced with `isBlank()`.
**`sellall-success` message had mismatched placeholder**
The message used `{total}` but the code passed `{items}`. Both are now passed and the message updated.
**Missing message keys**
`sell.sellhand-disabled` and `sell.sellall-disabled` were referenced in code but absent from `messages.yml`. Both are now present.
---
## New Features
**Hex color code support (`&#RRGGBB`)**
All text fields in `messages.yml`, `categories/*.yml`, and `decorations/*.yml` now support hex color codes in `&#RRGGBB` format. Can be freely mixed with standard `&` codes — e.g. `&#B45AE8&lPurple Bold`.
**Pin category icons to specific slots (`icon-slot`)**
Each category file now supports an `icon-slot` key to pin its icon to a fixed slot in the main menu. Set it to a slot number (0-indexed) or `AUTO` to fill in sort order as before. Out-of-bounds values, decoration-reserved slots, and duplicates fall back to `AUTO` with a console warning.
```yaml
icon-slot: 13 # pin to centre of a 6-row menu
icon-slot: AUTO # default — fills left-to-right in sort order
```
**Player placeholders in decoration items**
Custom items in decoration files now support dynamic per-player placeholders in their name and lore, resolved fresh for each player when the menu opens:
| Placeholder | Description |
|---|---|
| `{player}` | Player's name |
| `{vault_balance}` | Raw Vault balance |
| `{vault_formatted}` | Vault-formatted balance |
| `{shards}` | Raw hShards balance |
| `{shards_formatted}` | Formatted hShards balance |
**PlaceholderAPI support in decoration items**
Any `%placeholder%` from PlaceholderAPI can now be used in decoration item names and lore. PlaceholderAPI is optional — the plugin functions normally without it.
**`purse.yml` decoration**
A new built-in decoration displaying a gold nugget with the player's Vault and hShards balances. Drop it in `plugins/hShop/decorations/` and set `default-decoration: purse` in `config.yml`.
**hShards balance now resolves correctly**
The hShards hook cached an availability flag at startup that could be set incorrectly due to plugin load timing, causing balances to always show as `0.00`. The hook now checks `HShardsAPI.isAvailable()` live on every call and wraps all API calls in error handling.
beta
hShop 1.0.0
1.0.027 мар. 2026 г.28Minecraft: 1.21, 1.21.1, 1.21.2, 1.21.3, 1.21.4, 1.21.5, 1.21.6, 1.21.7, 1.21.8, 1.21.9, 1.21.10, 1.21.11bukkit, paper, purpur, spigot
Что нового
## [1.0.0] - Initial Release
### Features
* Basic shop system implementation
* Buy and sell item support
* Integration with Vault for economy handling
* PlaceholderAPI support for dynamic values
* Configurable shop setup
### Compatibility
* Supports Paper, Spigot, Bukkit, and possibly Purpur.
* Requires Minecraft 1.21+
### Dependencies
* Vault (for economy)
* PlaceholderAPI (optional)
### Notes
* First public release of **hShop**
* More features and improvements coming soon