PWarp+ v1.1
Critical security fixes + 4 new features + UX polish.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Critical security fix — PAID teleport race condition
In v1.0, the PAID teleport flow used
economy.has(player, price) then
withdrawPlayer(player, price) without atomicity. Two simultaneous
/pwarp calls to a paid warp could pass the
has check on both threads, but only one would actually deduct money — letting players double-spend.
Fixed in v1.1: the withdraw call's
EconomyResponse.transactionSuccess() is now the authoritative gate. If the deposit to the owner fails after the withdraw succeeded, the plugin auto-refunds the player and aborts the teleport. New message:
chat.tp-payment-failed.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
New features
TP Cooldown per player
Configurable per-player anti-spam cooldown between teleports.
Code (Text):
# config.yml
cooldown-tp: 10 # seconds. 0 = disabled (default)
- Bypass with pwarp.cooldown.bypass
- Owner of a warp is exempt
- Cooldown only applies after a successful TP — failed TPs don't burn it
Private notes per warp
Each warp owner can attach a private memo (max 200 chars). Visible only to the creator. Perfect for "remember to refill the chest" or "this needs a redstone fix" reminders.
- New button in the Edit Warp GUI (paper material, purple text)
- Stored in DB column private_notes — automatic schema migration via ALTER TABLE, no manual steps
- Type delete/borrar in chat to clear, cancel/cancelar to abort
Top 5 rankings in /pwarpadmin info
The admin info command now shows the top 5 warps by visit count and the top 5 by net votes — useful for spotting popular content and finding hidden gems.
Auto-purge for inactive owners
Optional daily sweep that removes warps whose owners haven't logged in for N days.
Code (Text):
# config.yml
auto-purge:
enabled: false # OFF by default for safety
days: 30 # min 7 (smaller values rejected to prevent accidents)
- Runs 5 minutes after startup, then every 24h
- Uses OffinePlayer.getLastPlayed()
- Players who never logged in are skipped (won't accidentally nuke imported data)
- Every purge is logged to console with the warp name and owner
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Stability fixes
- Async startup — removed .join() that was blocking the main thread during warp load. Also eliminated a redundant double DB query.
- Doorbell task leak — cancelled doorbell timeouts now properly clear when either the visitor or the owner disconnects. Visitor gets a clear "owner disconnected" message.
- Vote race — vote count is updated in the cache only AFTER the DB write confirms. If the write fails, the visual count stays consistent with DB and the player gets a "could not register vote" message.
- Atomic config writes — config.yml is now written to a .tmp file, validated, and atomically renamed. Prevents corrupt configs if the write is interrupted (disk full, server crash, plugin reload mid-write).
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
✨ UX polish
- Hover on PAID teleport button now shows what the owner actually receives (price minus tax)
- Doorbell expired messages include the timeout in seconds: "expired after 30s with no response"
- UUID error messages now show the expected format
- Tab completion of /pwarpadmin delete and /pwarpadmin log warp now includes hidden warps (was only listing public ones — staff couldn't tab-complete a hidden warp's name)
- Custom category icons in gui.yml are now respected by Edit + Detail GUIs (was using default icons before)
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
⬆️ Upgrading from v1.0
- Stop your server
- Replace the old JAR with PWarpPlus-1.1.jar
- Start the server — config gets the cooldown-tp and auto-purge keys added automatically. SQLite gets the private_notes column added automatically. Lang files get the new keys merged automatically (no <placeholder> in chat).
- Existing warps are fully compatible — they just won't have private notes until owners add them.
No breaking changes for existing installations.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Downloads
Tested on Paper 1.21.4 → 1.21.11. Thank you to everyone who downloaded v1.0!
───────────────────────────────────────────────────────────────
SHORT CHANGELOG (for the version description field, <500 chars):
───────────────────────────────────────────────────────────────
v1.1 — Security + Features:
CRITICAL FIX:
• PAID teleport race condition (duplicate-spend exploit) — now atomic with auto-refund
NEW:
• TP cooldown per player (config: cooldown-tp)
• Private notes per warp (owner-only memo, 200 chars)
• Auto-purge inactive warps (opt-in, daily sweep)
• Top 5 by visits / votes in /pwarpadmin info
FIXED:
• Async startup (removed .join() blocking main thread)
• Doorbell task leak on quit
• Vote race condition (cache before DB confirm)
• Atomic config writes (no more corrupt config.yml)
POLISH:
• Owner-take hover on paid TP
• Custom category icons respected
• Tab complete includes hidden warps for admins
• Doorbell expiry messages with timeout