OPShield v1.3.0
Protect your server from OP/admin abuse with advanced security features.
OPShield replaces the default /op and /deop commands with password-protected versions, locks out players who fail too many attempts (with exponential backoff), optionally blocks non-OPs from using admin commands — including all aliases from EssentialsX and other plugins.
NEW in v1.3.0: Auto-Punishment, IP-Limit multi-account detection, Shadow Ban fake success, and anti-spam logging.
❤️ Features
- 🔒 Password-protected
/opand/deop— requires a secret password to grant or revoke OP status - ⏱️ Brute-force lockout with exponential backoff — locks out by name and IP after too many wrong passwords; lockout duration doubles on every repeat offence, up to 24 hours
- 🔓 Manual unlock — admins can instantly lift any lockout via
/opshield unlock <player|ip> - 📋 OP whitelist — optionally restrict which names can ever be opped, regardless of password
- 🚫 Admin command restriction — block non-OPs from using commands like
/gamemode,/give,/tp, etc. - ⚠️ OP command restriction — block even OPs from using dangerous commands like
/stop,/reload, etc. - 🔗 Alias resolution — aliases such as
/gm,/gms,/tpa,/tpherefrom EssentialsX and other plugins are resolved to their canonical names before checking, so they cannot bypass the block list - 🌐 Plugin namespace blocking — block entire namespaces like
essentials:,cmi:,minecraft:,bukkit: - 📝 Audit log — every OP attempt (success or failure) is written to
plugins/OPShield/audit.log - 🌍 Multi-language — ships with English (
en), Vietnamese (vn), and Russian (ru); add more by creating<lang>.ymlin the plugin folder - 🔐 Password leak prevention —
/opand/deopcommands are intercepted before Bukkit logs them, so the password never appears inlogs/latest.log - ⚡ Async data persistence — lockout state is saved asynchronously to avoid stalling the main thread
- 💥 NEW: Auto-Punishment — automatically ban-ip or execute custom punishment after X failed sensitive command attempts
- 💣 NEW: IP-Limit — detect and auto-punish multiple accounts connecting from the same IP
- 👻 NEW: Shadow Ban — fake success messages for blocked commands (attackers think they succeeded)
- 🤫 NEW: Anti-Spam Logging — blocked commands are hidden from console, only logged to audit file
Requirements
- Paper 1.21 or newer
- Java 21+
Installation
- Drop
OPShield-1.3.0.jarinto yourplugins/folder. - Restart the server.
- On first start, if
op_passwordis still the defaultsecure123, a random 16-character password is generated and printed to the console. Save it immediately. - Edit
plugins/OPShield/config.ymlto customise the plugin.
Commands
| Command | Description | Permission |
|---|---|---|
/op <player> <password> |
Grant OP status | — |
/deop <player> <password> |
Revoke OP status | — |
/opshield reload |
Reload configuration | opshield.reload |
/opshield unlock <player|ip> |
Clear lockout for a player or IP | opshield.unlock |
/ops is an alias for /opshield.
Permissions
| Permission | Description | Default |
|---|---|---|
opshield.reload |
Reload plugin configuration | op |
opshield.unlock |
Manually unlock a locked-out player or IP | op |
Configuration
# Password required to /op or /deop someone.
# Stored in plain text here for convenience; hashed with SHA-256 in memory.
op_password: "your_password_here"
# Block non-OPs from using admin commands (see blocked_commands list).
restrict_admin_commands: true
# If true, even the console must provide the password.
# Note: allow_op_reload only restricts in-game players — console is always allowed.
require_password_from_console: false
# Broadcast a server-wide message when someone is opped/deopped.
broadcast_on_op: true
# Allow in-game OPs to run /opshield reload.
# Console can always reload regardless of this setting.
allow_op_reload: true
# Language: en, vn, ru (or any <lang>.yml you create in the plugin folder)
language: "en"
# Commands blocked for non-OPs. Aliases are resolved automatically.
blocked_commands:
- gamemode # also blocks /gm, /gms, /gmc, /gma, /gmsp
- give
- tp # also blocks /tpa, /tphere, /tpall, etc.
- kill
- ban
- kick
- stop
- reload
- plugins
# ...
# Block all commands from these plugin namespaces.
blocked_command_prefixes:
- "essentials:"
- "cmi:"
- "minecraft:"
- "bukkit:"
- "spigot:"
# Commands always allowed for non-OPs.
allowed_commands:
- opshield
security:
lockout:
enabled: true
max-attempts: 3 # wrong passwords before lockout
duration-minutes: 3 # base lockout duration (doubles each repeat, max 24 h)
op-whitelist:
enabled: false # if true, only names below can ever be opped
names:
- "YourAdminName"
How Alias Blocking Works
When a player types /gm creative, OPShield:
- Looks up
/gmin Bukkit'sCommandMapto resolve the canonical name →gamemode - Checks
gamemodeagainstblocked_commands - Cancels the event and shows the restriction message
This means you only need to list canonical command names — all aliases from EssentialsX, CMI, or vanilla are caught automatically. Plugin-namespaced forms (essentials:gamemode) are additionally caught by blocked_command_prefixes.
If CommandMap reflection fails (rare, on custom forks), OPShield falls back to the typed command name and logs a FINE-level debug message.
Exponential Backoff Lockout
Each time a player triggers a lockout, the duration doubles:
| Lockout # | Duration |
|---|---|
| 1st | duration-minutes (e.g. 3 min) |
| 2nd | duration-minutes × 2 (e.g. 6 min) |
| 3rd | duration-minutes × 4 (e.g. 12 min) |
| … | … doubles each time, capped at 24 h |
The lockout count persists across server restarts. Use /opshield unlock <player> to fully reset a player's lockout history.
Note on Console and Command Blocks
Lockout and whitelist checks apply to in-game players only. Console commands and command blocks bypass these checks because they have no IP address. To prevent console-level abuse, restrict physical and panel access to your server.
Adding a Language
Create a file named <lang>.yml in plugins/OPShield/ with all the following keys, then set language: "<lang>" in config.yml and run /opshield reload:
wrong_password: "&cIncorrect password!"
restricted_message: "&cYou cannot use admin commands right now."
op_restricted_message: "&cYou are an OP, but this command is restricted to prevent potential abuse or backdoors."
op_success: "&aSuccessfully opped {player}!"
deop_success: "&aSuccessfully deopped {player}!"
op_broadcast: "&e[Server] {player} has been opped!"
deop_broadcast: "&e[Server] {player} has been deopped!"
reload_success: "&aOPShield configuration reloaded."
no_permission: "&cYou do not have permission to do that."
lockout_message: "&cLocked out! Try again in {minutes} minute(s)."
whitelist_denied: "&cThis player is not in the OP whitelist."
unlock_success: "&aSuccessfully unlocked {player}."
unlock_not_found: "&eNo lockout record found for {player}."
New keys added in future versions are automatically merged from the bundled defaults — existing language files do not need to be recreated.
Bug Fixes in v1.2.0
| ID | Summary |
|---|---|
| BUG-1 | Deprecated ChatColor API replaced with Adventure LegacyComponentSerializer |
| BUG-2 | allow_op_reload: false now correctly documented as player-only; console always permitted |
| BUG-3 | savePersistentData() moved to async thread — no longer stalls main tick on failed attempts |
| BUG-4 | Added /opshield unlock <player|ip> to manually clear lockouts |
| BUG-5 | Exponential backoff — lockout duration doubles per repeat offence, capped at 24 h |
| BUG-6 | Console/command-block bypass documented as intentional design |
| BUG-7 | CommandMap reflection failure now logged at FINE level instead of silently ignored |
License
Apache License 2.0 — see source file headers for details.

