
OPShield
Protects your server from OP/admin abuse with console-only OP (via password) and optional admin command restriction.
38
1
Список изменений
[1.2.0] — 2026-03-15
🐛 Bug Fixes (7 fixes)
BUG-1 — Deprecated ChatColor API replaced with Adventure LegacyComponentSerializer
- Root cause:
getMsg()usedChatColor.translateAlternateColorCodes('&', msg), which is deprecated in Paper 1.21 and produces build warnings. - Fix: Replaced with
LegacyComponentSerializer.legacyAmpersand().deserialize(raw). AllsendMessage()calls now passComponentobjects. Added helper methodssend(sender, key)andsendReplaced(sender, key, ...)to centralise message dispatch.Bukkit.broadcastMessage()replaced withBukkit.broadcast().
BUG-2 — allow_op_reload: false had no effect on console
- Root cause: The reload handler checked
!allowOpReload && sender instanceof Playerfirst, so console senders (who are notinstanceof Player) skipped the check entirely and were always permitted. - Fix: The behaviour is now explicit and documented:
allow_op_reloadintentionally controls in-game players only. Console is always allowed to reload. Added a clear comment in code and updated the README to document this intent. The help message was also updated to reflect the correct usage.
BUG-3 — savePersistentData() blocked the main thread with I/O
- Root cause: Every wrong password attempt triggered
savePersistentData()synchronously on the main server thread, writing todata.ymlvia file I/O which can stall the tick cycle on loaded servers. - Fix:
savePersistentData()now snapshots the maps on the main thread (thread-safe, fast), then dispatches the actual file write viaBukkit.getScheduler().runTaskAsynchronously().onDisable()still saves synchronously because async tasks may not execute during shutdown.
BUG-4 — No way to manually unlock a locked-out player
- Root cause: When a player was locked out there was no command to lift the lockout. Admins had to either wait for the timer or delete
data.ymlentirely. - Fix: Added
/opshield unlock <player|ip>command. Accepts either a player name (matched case-insensitively) or an IP address (dots automatically converted to underscores to match the storage key). ClearsfailedAttempts,lockoutTimestamps, andlockoutCountfor the matching key. Requiresopshield.unlockpermission (default: op). Newunlock_successandunlock_not_foundmessage keys added to all language files.
BUG-5 — Lockout reset allowed infinite brute-force with fixed delay
- Root cause: When a lockout expired,
isLockedOut()cleared bothlockoutTimestampsandfailedAttempts, resetting the counter to zero. An attacker could attemptmax-attempts - 1wrong passwords, wait out the lockout, and repeat indefinitely without ever receiving a longer penalty. - Fix: Introduced
lockoutCount(persisted indata.ymlaslockout_count). Each time a lockout is triggered, the count increments and the duration doubles:lockoutDurationMinutes * 2^(count-1), capped at 24 hours. On successful authentication thefailedAttemptsandlockoutTimestampsare cleared, butlockoutCountis preserved so repeated abuse continues to receive longer lockouts. The unlock command (BUG-4) clears all three maps.
BUG-6 — Command block / server-console bypass is documented (not a code bug)
- Root cause: Lockout and whitelist checks are gated on
sender instanceof Player— command blocks and other plugins dispatching/opbypass these checks by design because they have no IP address. - Fix: Added explicit documentation in README explaining this is intentional. Server administrators are advised to restrict physical/panel access to prevent console-level abuse.
BUG-7 — CommandMap reflection failure was fully silent
- Root cause: If
getCommandMap()reflection failed (e.g., custom server forks, future API changes), the exception was caught by a barecatch (Exception ignored)block with no log output, making diagnosis impossible. - Fix: Replaced
ignoredwith agetLogger().fine(...)call that logs the failure at FINE level with the command name and exception message. This appears in debug logs without spamming the console under normal operation.
✨ New Features
/opshield unlock <player|ip>— manually clear lockout for a player or IP (opshield.unlockpermission)/opshield(no args) — now shows a brief help line instead of an error/opsalias added for/opshield- Exponential backoff: lockout duration doubles per repeat offender (capped at 24 h)
- Language file defaults auto-merged from jar — new keys appear automatically in existing language files without requiring users to recreate them
🔧 Other Changes
pom.xml: version → 1.2.0; switched dependency fromspigot-apitopaper-api(Paper bundles Adventure — no extra shade required); compiler source/target bumped from Java 17 → Java 21 (maven.compiler.release)plugin.yml: version → 1.2.0; addedopshield.unlockpermission; updated descriptions; added/opsalias- All 3 language files (
en,vn,ru): addedunlock_successandunlock_not_foundkeys; updatedlockout_messageto mention increasing duration
Файлы
OPShield-1.2.0.jar(18.17 KiB)
ОсновнойМетаданные
Канал релиза
Release
Номер версии
1.2.0
Загрузчики
BukkitPaperPurpurSpigot
Версии игры
1.21–1.21.11
Загрузок
3
Дата публикации
2 нед. назад
