
OPShield
Protects your server from OP/admin abuse with console-only OP (via password) and optional admin command restriction.
38
1
OPShield 1.3.0
release28 марта 2026 г.[1.3.0] — 2026-03-28
🔥 New Security Features
Auto-Punishment (Automatic Punishment)
- Automatically ban-ip or execute punishment command when players attempt sensitive commands too many times
- Config:
auto_punishment.threshold- maximum allowed attempts - Supports multiple modes:
ban-ip,ban,kick,firewall, or custom command - Firewall script: Execute system commands (iptables/ufw) to block IP at network level
- Configurable sensitive commands list:
sensitive_commands
IP-Limit (Multi-account Detection)
- Track number of accounts connecting from the same IP
- Auto-flag and punish if exceeding
max_accountswithin time window - Default: 3 accounts / 5 minutes
- Integrates with Auto-Punishment to automatically block suspicious IPs
Shadow Ban / Fake Success (Deceptive)
- Instead of showing "no permission", display fake success messages
- Attackers think they succeeded but nothing actually happens
- Buys time for admin to investigate and handle attackers
- Fake messages for commands: clear, kill, ban, gamemode, tp, effect, give
Anti-Spam Console Log
- Blocked commands no longer appear in console log
- Only logged to audit.log to prevent server console spam
🛡️ Security Improvements
- Auto-punishment exempt for OP and whitelist-admin
- IP tracking with automatic time window cleanup
- Full audit logging for all auto-punishment actions
OPShield 1.2.1
release16 марта 2026 г.[1.2.1] — 2026-03-16
✨ New Features
- OP Command Restriction — Added ability to restrict specific commands even for OPs. This helps prevent admin abuse and limits potential damage from backdoors.
- New config options:
restrict_op_commands(boolean) andblocked_op_commands(list). - Console remains exempt from these restrictions for emergency recovery.
OPShield 1.2.0
release15 марта 2026 г.[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.1.1
release11 марта 2026 г.[1.1.1] — 2026-03-11
Fixed
- Alias bypass (EssentialsX and other plugins): Non-OPs could use blocked commands via aliases
(
/gm,/gms,/tpa,/tphere, etc.) because the plugin compared only the typed text. Commands are now resolved to their canonical name via Bukkit'sCommandMapbefore checking the block list, so aliases are caught automatically without needing to enumerate them in config. - Non-OP players could not use
/op <player> <password>:"op"was listed inblocked_commands, causingPlayerCommandPreprocessEventto cancel the command before it ever reachedonCommand. Password-based OP now works correctly for non-OP players. - Password exposed in
logs/latest.log:/opand/deopevents were not cancelled before Bukkit logged them, so the password appeared in plain text in console output and log files. The event is now cancelled immediately and dispatched directly toonCommandinternally. getRemainingLockoutTimeshowed inflated minutes: Integer division added an extra minute at every boundary (e.g. 5 seconds remaining showed "1 minute"). Fixed to ceiling division.
OPShield 1.0.4
release7 марта 2026 г.fixed
Совместимость
Создатели
Детали
Лицензия:Apache-2.0
Опубликован:3 недели назад
Обновлён:6 дней назад
