File Details
Jvips-2.1.0.jar
- R
- Mar 4, 2026
- 2.54 MB
- 29
- Early Access
File Name
Jvips-2.1.0.jar
Supported Versions
- Early Access
JVIPS Changelog
[2.1.0] — Shop UX Update
New Features
Shop: Filter Panel (price + currency)
A new filter panel is now displayed on the right side of the Shop tab, next to the info box:
- BY PRICE button — cycles through: unordered → ascending price (
< to >) → descending price (> to <) - BY CURANCY button — cycles through: All → each currency configured in
config.json
All labels and button texts are fully configurable via the messages JSON:
| Key | Description |
|---|---|
shop.filter.title |
Panel title label |
shop.filter.byPrice |
Label next to the price button |
shop.filter.byCurancy |
Label next to the currency button |
shop.filter.price.default |
Price button — no sort |
shop.filter.price.asc |
Price button — ascending |
shop.filter.price.desc |
Price button — descending |
shop.filter.currency.all |
Currency button — all currencies |
shop.filter.currency.<id> |
Currency button text for a specific currency ID (falls back to symbol in config.json if not defined) |
Shop: Duration shown in info panel
The Shop info panel now displays the voucher duration alongside seller, VIP type, and price — buyers know exactly how long the VIP lasts before confirming the purchase.
New message keys: shop.info.duration, shop.info.duration.empty
Shop: Seller notification on sale
When a player's voucher is purchased, the seller receives an instant chat notification if they are online at the time of the sale.
Message key: shop.chat.sold
Vouchers Tab: 2-click confirmation
Activating a voucher in the Vouchers tab now requires two clicks to prevent accidental activation:
- First click — selects the slot and shows the voucher info
- Second click on the same slot — confirms and activates
Updated message keys: menu.vouchers.hint.activate, menu.vouchers.hint.confirm
Bug Fixes
Fixed: Client crash — "Failed to load updated CustomUI Texture"
Symptom: Players occasionally experienced a client crash with FileNotFoundException: Could not find file 'CachedAssets/...'.
Root cause: A player UUID stored without hyphens (32 hex chars) was not recognized as a UUID by the skin URL resolver, causing it to be forwarded to the skin provider as a username. The provider returned a generic "unknown" skin. Once the CachedAssets directory was cleared, the client's in-memory asset registry still held a stale reference count — any attempt to load that asset again resulted in a crash.
Fixes applied:
isLikelyUsername()now correctly rejects 32-char all-hex strings (dehyphenated UUIDs)resolveTopHeadUrl()returnsnullfor blank or"unknown"player namesupdateTop()hides the DynamicImage slot when the resolved skin URL isnullreleaseDynamicImageSlotsForPlayer()setswithVisible(false)before releasing the slot, as a defense-in-depth measure against stale rebuilds after menu dismiss
Fixed: Player/top skin re-sent on first page refresh
The player avatar (headerPanel) and Top VIPs ranking heads (topPanel) were being re-sent on the first automatic page refresh because DYNAMIC_IMAGE_LAST_SOURCE was not seeded during panel construction. The cache is now populated immediately after the initial skin URL is applied.
[2.0.0] — VIP Shop & Player Marketplace
New Feature: VIP Shop Tab (Player-to-Player Marketplace)
The biggest addition in JVIPS 2.0.0: a fully integrated VIP voucher marketplace built directly into the /vips menu.
How it works
- Players with TAB vouchers can click "Sell" directly from their Vouchers tab
- A listing form opens — the player sets a price and currency (multi-currency supported)
- The voucher is removed from the player's tab and placed as an active listing
- Any other player browsing the Shop tab can see the listing and click "Buy"
- A confirmation HUD shows the price, seller name, VIP type and duration before purchase
- On confirmed purchase: the buyer is charged, the seller is credited (minus tax), and the voucher is re-issued to the buyer with a new UUID and a new HMAC signature
- Players can cancel their own listing at any time — the voucher is returned to their Vouchers tab
- Listings auto-expire after a configurable number of days, returning vouchers to sellers
Admin Shop (Server as Seller)
Admins can list vouchers on behalf of the server — money from purchases goes to the void (useful for official store listings):
/vips sellkey <vip> <currency> <price> [--duration time]— creates a server listing/vips unsellkey <slot>— removes a server listing by its position in the active listings list
Shop Configuration (config.json)
New shop section:
"shop": {
"enabled": true,
"economyProvider": "auto",
"currencies": [
{ "id": "money", "displayName": "Money", "symbol": "$", "taxPercent": 5.0 },
{ "id": "gold", "displayName": "Gold", "symbol": "G", "taxPercent": 0.0 }
],
"listing": {
"expiryDays": 7,
"maxPerPlayer": 3
}
}
| Field | Description |
|---|---|
enabled |
Enable or disable the entire shop system |
economyProvider |
auto, vaultunlocked, or hyvault |
taxPercent |
% taken from seller on each sale (per currency) |
expiryDays |
Days before a listing auto-expires (0 = never) |
maxPerPlayer |
Max active listings per player (0 = unlimited) |
Security
- Vouchers re-issued with a brand new UUID and a new HMAC signature bound to the buyer
- The original voucher ID is invalidated — no duplication possible
- All economy operations are atomic: charge buyer → credit seller → issue voucher (with rollback on failure)
- Drop-blocking applies to all vouchers including shop-purchased ones
New Data File
| File | Description |
|---|---|
data/shop-listings.json |
Persistent storage of all listings (ACTIVE, SOLD, CANCELLED, EXPIRED) |
Bug Fixes
Fixed: "Invalid Voucher" after purchasing or cancelling a Shop listing
Symptom: After buying a voucher from the Shop (or after a seller cancelled their listing and got the voucher back), using the voucher in the Vouchers tab would show [JVIPS] Invalid voucher.
Root cause (Bug 1 — primary): ShopService.rebuildVoucherRecord() generated a new voucherId for the re-issued voucher but never registered it in VouchersStore. When the player tried to activate it, VoucherService.validateVoucher() looked up the ID in the store, got null, and returned "invalidVoucher".
Root cause (Bug 2 — secondary): The original issuedAt and customDurationSeconds were stored in an in-memory ConcurrentHashMap (static field). If the server restarted while a listing was active, those values were lost. On purchase/cancel after restart, the voucher was re-issued with issuedAt = now instead of the original timestamp.
Fix:
rebuildVoucherRecord()now saves the new voucherId toVouchersStoreimmediately after generationissuedAtandcustomDurationSecondsare now persisted as fields (voucherIssuedAt,voucherCustomDuration) directly inShopListing(written toshop-listings.json) — the in-memory cache was removed entirelyShopServicenow receivesVouchersStoreas a constructor dependency
New Commands
| Command | Description | Permission |
|---|---|---|
/vips sellkey <vip> <currency> <price> [--duration time] |
Lists a VIP voucher for sale as the server | jvips.admin |
/vips unsellkey <slot> |
Removes a server shop listing by global slot (1-indexed) | jvips.admin |
Dependencies
- VaultUnlocked or HyVault required for the Shop economy features
- HyUI 0.9.1+ required for the Shop tab and listing/purchase HUDs
[1.x] — Previous Releases
See the plugin page description for a full overview of features introduced before 2.0.0, including:
- Secure HMAC-signed VIP vouchers
- Command Vouchers
- Voucher Stacking
- Custom Duration (
--duration) - TAB Voucher activation
- Virtual Chest (
/vips chest) - Automatic VIP lifecycle (expiry + commands)
- Top VIPs ranking
- PlaceholderAPI integration
- Multi-language support (en_US, pt_BR, es_ES)
- Smart Config Merge
- VIP Broadcast System
- Per-player file storage with atomic writes

