# ajdnikov — Minecraft Plugins (full text) > Every page of https://www.ajdnikov-dev.com as plain text, for AI assistants and AI search. Short index: https://www.ajdnikov-dev.com/llms.txt --- # ajdnikov — Minecraft Plugins URL: https://www.ajdnikov-dev.com/ Updated: 2026-11-07 > ajdnikov makes Minecraft server plugins for Paper and Velocity: AnziUtils, SMP-Reconnect, AjdnikovGamemodes, AnziLifesteal, AjdnikovRewards++ and AjdnikovPanel, with full public docs. ## Minecraft plugins you can read before you buy. Eight plugins for Paper and Velocity, built and maintained by one developer. Every command, permission node and config key is published here in full — so you can check the wiring before you spend anything. SET 08 PLUGINS BUS PAPER · VELOCITY MANUALS PUBLIC SUPPORT DISCORD U01 U02 ### AnziUtils Paper 1.21+ Security and utility suite. VPN and proxy detection, GeoIP filtering, alt-account limits, combat tagging with anti-escape, player graves, and network-wide staff tooling. - PacketEvents - SQLite - MySQL - Redis - proxycheck.io - LuckPerms - Vault - PlaceholderAPI - WorldGuard Overview Manual U03 U04 ### SMP-Reconnect Velocity 3.x Keeps players bridged on the proxy while a backend restarts or recovers, then returns them the moment it answers. No database, no dependencies. - Velocity API Overview Manual U05 U06 ### AjdnikovGamemodes Paper 1.20.4+ Seven minigames — Death Swap, Manhunt, Man-Save, Speedrun VS, Achievement Speedrun, PvP Arena and Hide & Seek — plus tournaments, Hunt and Target events with a live events page, parties, a preloaded world pool, chat games, and points leaderboards shared across a network. - FastAsyncWorldEdit - MySQL - Redis - Velocity / Bungee Overview Manual U07 U08 ### AnziLifesteal Paper 1.21+ A full Lifesteal season: heart stealing and withdrawal, progressive ban durations, revive beacons, a rebirth prestige ladder, and anti-alt and anti-spawn-kill protection. - MySQL - PlaceholderAPI - Vault - Discord - Velocity / Bungee Overview Manual U09 U10 ### AjdnikovRewards++ Paper 1.21+ Playtime and AFK tracking, staff moderation-action rewards, streaks and automatic promotions, a Discord bot with account linking, and a GUI admin panel. - SQLite - MySQL - LuckPerms - Vault - PlaceholderAPI - Discord Overview Manual U11 U12 ### AjdnikovPanel Velocity Paper New Network monitoring with a live dashboard in your AnziLock account: topology, TPS and tick time, lag causes in plain words, a world map with player timelines, player inspection, and Discord alerts and a bot. The hub runs inside your proxy — nothing else to host. - Velocity - SQLite - AnziLock relay - Discord - Vault Overview Manual U13 U14 ### AnziZiplines Paper 26.2+ New Rideable ziplines: pick two points with a wand, add bends, and players glide along a particle rope. Speed, look, price and permission are set per rope in a menu. Free — apply on Discord. - LuckPerms - Vault Manual Apply (https://discord.gg/xyjmcjMp4W) U15 U16 ### AnziParkour Paper 26.2+ New Timed parkour courses built with a wand and an in-game editor, with checkpoints, crash-safe inventories, rewards, holograms and leaderboards. Free — apply on Discord. - Vault - PlaceholderAPI Manual Apply (https://discord.gg/xyjmcjMp4W) Patch field 9 RUNS - PacketEvents - SQLite - MySQL - Redis - proxycheck.io - LuckPerms - Vault - PlaceholderAPI - WorldGuard - FastAsyncWorldEdit - Discord - AnziLock relay - Velocity / Bungee Hover or focus a module to trace what it talks to. Apart from the server platform, PacketEvents for AnziUtils and the AnziLock relay for AjdnikovPanel, every run above is optional. ### The manual is the proof A marketplace listing describes a plugin. These pages publish it — every command, every permission node, every config key, with the YAML you will actually paste into your server. None of it sits behind the purchase. Read the wiring first, then decide. Open the AnziUtils manual ajdnikov-dev.com/anziutils/docs Commands Command | Description | Permission `/au lookup [page]` | IP history, clickable linked accounts, and geolocation. `/au ` works too. | `anziutils.command` `/au gui` | Browse online players and their IP data. | `anziutils.gui` `/au panic [on|off|status]` | Network lockdown; `status` lists active restrictions and actions. | `anziutils.admin` plugins/AnziUtils/config.yml Excerpt ``` combat-log: enabled: true timer: 15 # combat duration in seconds graves: combat # always | combat | off # Combat restrictions disable-enderpearls: true disable-golden-apples: true block-server-switch: true ``` ### The set at a glance Plugin | Platform | Storage | Network sync | Optional integrations | Manual AnziUtils | Paper 1.21+ · Java 21 | SQLite or MySQL | Redis | PacketEvents (required), proxycheck.io, LuckPerms, WorldGuard, PlaceholderAPI, Vault | Read SMP-Reconnect | Velocity 3.x · Java 17 | None | Proxy-side | None required | Read AjdnikovGamemodes | Paper / Spigot 1.20.4+ · Java 17 | YAML or MySQL | MySQL + Redis | FastAsyncWorldEdit, Velocity or BungeeCord lobby | Read AnziLifesteal | Paper 1.21+ | data.yml or MySQL | MySQL | PlaceholderAPI, Vault, Discord webhook | Read AjdnikovRewards++ | Paper 1.21+ | SQLite or MySQL | MySQL | Discord bot, LuckPerms, Vault, PlaceholderAPI | Read AjdnikovPanel | Velocity 3.4+ or Paper hub, Paper 1.21.x agents · Java 25 | SQLite (built in) | Agents report to one hub | Discord webhooks and bot, Vault | Read AnziZiplines | Paper 26.2+ · free, apply on Discord | ziplines.yml | None | LuckPerms, Vault | Read AnziParkour | Paper 26.2+ · free, apply on Discord | courses.yml | None | Vault, PlaceholderAPI | Read ### On the bench Some plugins are built and running but not on sale yet: SilentJoinLeave , SMP-Reconnect 1.2 with cross-server chat, Chatting for network-wide chat over Redis, CombatJobs , the Factions core for Paper and Folia, the AnziLook anti-freecam plugin, and the Better Maps client mod. Each has a full manual, and builds are handed out on request in the Discord. See the projects Request a build (https://discord.gg/xyjmcjMp4W) ### Already a customer? The paid plugins run on AnziLock , a licensing system built for them rather than a marketplace bolt-on. Sign in to the licence portal to reach your licences and keys, or claim a key with `/claim` in the Discord after buying. Open the licence portal (https://license.ajdnikov-dev.com) Claim a key in Discord (https://discord.gg/xyjmcjMp4W) How AnziLock works ### Support runs through Discord License keys, bug reports, feature requests and setup help all happen in one place. It is also where you claim your key with `/claim` after buying, and where you can ask for something that does not exist yet. Join the Discord (https://discord.gg/xyjmcjMp4W) Commission something custom --- # AnziUtils — Security & Utility Plugin | ajdnikov URL: https://www.ajdnikov-dev.com/anziutils Updated: 2026-11-08 > AnziUtils is a Paper security and utility plugin for Minecraft servers: VPN and proxy detection, GeoIP, alt limiting, combat tagging, graves, staff profiles and Redis network sync. Skip to content ## AnziUtils Paper 1.21+ Java 21 v 1.7.6 Security and utility suite for Paper. VPN and proxy detection through proxycheck.io, GeoIP filtering, alt-account limits, combat tagging with anti-escape restrictions, player graves, and staff tooling that works across a Redis-linked network. Read the manual Get it on BuiltByBit (https://builtbybit.com/creators/ajdnikov.766669/) Ask in Discord (https://discord.gg/xyjmcjMp4W) ### What it talks to U01 U02 #### Ports PacketEvents is the one required plugin. Everything else is optional: AnziUtils runs standalone on SQLite, and MySQL and Redis are what turn it network-wide. - PacketEvents (required) - SQLite - MySQL - Redis - proxycheck.io - LuckPerms - Vault - PlaceholderAPI - WorldGuard Patch field 9 RUNS - PacketEvents - SQLite - MySQL - Redis - proxycheck.io - LuckPerms - Vault - PlaceholderAPI - WorldGuard ### Key Features A01 #### Professional Staff Suite NEW - Advanced Vanish: Two modes: invisible keeps you in the TAB list, leave sends a fake leave message and hides you from it. Seamless across backend switches. - Vanish Safety: No advancements, always able to fly, ignored by mobs, sculk sensors and wardens, no pressure plates. - Silent Containers: Open chests without animations or sounds. - Silent Movement: Suppresses footsteps and entity sounds. - Stealth Item Pickup: Require sneaking to pick up items. - Persistent States: Vanish and Freeze persist across restarts. - Advanced Freeze: Locks movement, damage, mobs, and commands. A02 #### Staff Account System NEW - Dual Profiles: Instantly switch between a staff and a normal player profile. Running `/au staff` in staff mode acts as `/au back`, so exiting is one command. - Separate Inventories: Each profile keeps its own inventory and ender chest. - Separate Economy: LuckPerms ranks and Vault balance are profile-specific. - Staff Godmode: Automatic damage immunity and combat-tag bypass in staff mode. - Teleport Ghosting: Hides staff position/rotation packets from non-admin players. - Hidden Coordinates: F3 coordinates hidden for all staff, regardless of active profile. - /au back Command: Return to your pre-staff server, location, and gamemode, then auto-exit staff mode. Outside staff mode it takes you back to your last location before a teleport, death, or server switch. - Staff Mode Reminder: A blinking action bar so nobody forgets which profile they are on. - Persistent Sessions: Staff sessions survive reloads and backend switches. - Staff-Only Commands: Restrict powerful commands (e.g., /ban, /tp) to staff mode only. - Command Exceptions: Let chosen people use /tp (or any staff-only command) without staff mode via `/au exempt`. A03 #### Advanced Security & IP Management - VPN & Proxy Detection: Detect and block proxies via proxycheck.io. - Alt-Account Limiter: Restrict maximum accounts per IP address. - Geolocation Tracking: Resolve and log player city and country. - Country Filtering: Restrict access using whitelists or blacklists. - Panic Mode: Emergency lockdown with per-restriction toggles and configurable actions: move players to another backend, kick, title, broadcast, or run commands. - Database Logging: Track IP history via SQLite or MySQL. A04 #### Combat & Gameplay Protection - Combat Tagging: Tag players in PvP with anti-escape restrictions. - Anti-Sustain: Optionally block Golden Apples and Totems. - Health Obfuscation: Hide true health from client-side mods. - Combat Logger NPCs: Spawn an NPC if a player disconnects in combat. - Dupe-Proof on Networks: Logged items are held in the shared database, so they can never exist twice, even across Velocity/BungeeCord backends. - Grace Period: Protect new players from immediate combat. - Safe Zones: WorldGuard integration for safe areas, and tagged players can no longer run into them mid-fight. - Post-Combat Cooldown: Optionally block commands, teleports and server switches for a few seconds after a fight ends. A05 #### Secure Player Graves NEW - Custom Graves: Store lost loot in a Player Head grave. - Grave Modes: Graves on every death, only on combat deaths, or off. - Grave Holograms: Display owner, XP, item count, and a despawn countdown. - Anti-Theft Timers: Temporary protection before public access. - Indestructible: Explosions, liquids, pistons and mobs can't break a grave. - Death Compass: Respawn with a compass pointing to your grave. - History & Restore: Admins can list deaths network-wide, view, teleport to, and restore any grave. - Settings GUI: Tune XP kept, item loss, protection and despawn time in-game. - Persistent Graves: Graves safely persist across restarts. A06 #### Redis Network Sync NEW - Network-Wide Panic Mode: One toggle locks down every backend at once. - Live Player Registry: See and act on every player across the network. - Cross-Server Staff Actions: Freeze, bring, announce, and cleardrops span all backends. - Shared Smart Mutes: A mute follows the player wherever they go. - Cached Lookups: GeoIP and VPN results are shared, cutting API calls. - Local Fallbacks: Everything keeps working when Redis is off or offline. A07 #### Network Staff Panel NEW - Staff GUI: One menu for staff mode, vanish, freeze, bring, panic, and more. - Random Player Spectating: Drop in on a random player with an atomic reservation lock. - Rank Hierarchy: Targeted commands only work on same- or lower-weight LuckPerms groups. - Fail-Closed Safety: Actions are blocked when rank data is unavailable. A08 #### Essential Utilities - Interactive Player GUI: Manage players, IPs, and alt accounts. - Discord Webhooks: Rich alerts for VPNs, combat logs, and panic mode. - Smart Chat Monitor: Auto-mutes and smart @mention system. - Rule Book System: Auto-provide formatted rules to new players. - Item Clearer: Scheduled ground-item cleanup with per-world exclusions. - Redstone Limiter: Throttles runaway redstone per chunk before it costs TPS. - Command Watch: Discord audit trail for sensitive commands like /op and /ban. ### Commands & Permissions #### Commands Command | Description `/au` | Clickable help menu listing only the commands you can use. Everything tab-completes, and typos get a “did you mean…?” hint. Also `/anziutils`, `/anzi`. `/au lookup ` | Looks up a player's IP history, geolocation, and linked alt accounts. `/au ` works too. `/au gui` | Opens the interactive online players GUI. `/au panel` | Opens the network staff panel for staff mode, vanish, freeze, bring, announcements, panic mode, drop clearing, and spectating. `/au staff` | Enters staff mode, swapping your inventory, ranks, balance, and more to the staff profile. While in staff mode it acts exactly like `/au back` and exits staff mode in one step. `/au back` | In staff mode, transfers you back to the server, location, and gamemode you were at before entering staff mode, then exits staff mode. Outside staff mode, teleports you to your last location (before a teleport, death, or server switch). `/au vanish [on|off|leave|invisible|mode]` | Toggles vanish. `leave` sends a fake leave message and hides you from the tab list; `invisible` keeps you listed. `mode` sets your preferred mode. `/au freeze ` | Freezes or unfreezes a target player, anywhere on the network. `/au bring ` | Teleports a target player to your location, across servers. `/au spectate [stop]` | Teleports a vanished staff member to a randomly reserved network player. `stop` releases the reservation. `/au announce [-t ] ` | Network-wide announcement in chat, plus on screen as a title, action bar, and/or boss bar. Long messages are shown line by line. `/au announcements [on|off]` | Lets any player choose on-screen announcements or chat only. The choice follows them across backends. `/au cleardrops` | Immediately clears ground items on every backend, respecting the item-clear filters. `/au graves [list|view|tp|restore]` | Opens the grave settings GUI, or lists recent deaths network-wide so you can view, teleport to, and restore lost graves. `/au panic [on|off|status]` | Network lockdown. Runs your configured panic actions; `status` shows active restrictions and actions. `/au exempt ` | Lets chosen players use staff-only commands such as `/tp` without staff mode. `/au book |reset>` | Gives the rule book to a player, or forces every player to receive the updated book. `/au reload` | Reloads the plugin configuration (config.yml, messages.yml, etc.). `/au debug` | Runs GeoIP, Redis, and database diagnostics. `/au test` | Sends test payloads to the configured Discord Webhook to verify functionality. The old commands still work as shortcuts: `/vanish`, `/freeze`, `/bring`, `/announce`, `/cleardrops`, `/staff`, `/auback`, `/staffgui`, `/randomplayer`, `/anziutilsgui`, `/anziutilsreload`, and the rest. #### Permissions Permission | Description `anziutils.admin` | Grants access to /au vanish, freeze, bring, announce, cleardrops, graves, panic, exempt, debug, and test. Also allows seeing true IPs in placeholders. `anziutils.command` | Grants access to /au lookup and /au reload. `anziutils.gui` | Grants access to /au gui. `anziutils.notify` | Receives in-game broadcast warnings for VPNs, Alt accounts, blocked countries, and IP joins. `anziutils.book` | Grants access to /au book. `anziutils.exempt` | Completely exempts the player from VPN detection, Alt-limit kicks, Country filtering, and Smart Mutes. `anziutils.combatlog.bypass` | Completely bypasses combat tagging and all combat restrictions. `anziutils.combatlog.bypass.enderpearls` | Bypasses the Enderpearl block in combat. `anziutils.combatlog.bypass.goldenapples` | Bypasses the Golden Apple block in combat. `anziutils.combatlog.bypass.chorusfruit` | Bypasses the Chorus Fruit block in combat. `anziutils.combatlog.bypass.totems` | Bypasses the Totem of Undying block in combat. `anziutils.combatlog.bypass.inventory` | Bypasses the inventory/container block in combat. `anziutils.combatlog.bypass.flight` | Bypasses the flight/elytra block in combat. `anziutils.combatlog.bypass.commands` | Bypasses the command block in combat. `anziutils.combatlog.bypass.worldchange` | Allows changing worlds while combat tagged. `anziutils.combatlog.bypass.serverswitch` | Allows switching backend servers while combat tagged. `anziutils.combatlog.bypass.regionentry` | Allows entering blocked WorldGuard regions while combat tagged. `anziutils.combatlog.bypass.cooldown` | Skips the post-combat cooldown. `anziutils.staffaccount` | Grants access to the Staff Account system: /au staff, /au back, staff-only commands, godmode, coordinate hiding, and ghosting. Includes `anziutils.back`. `anziutils.back` | /au back to your last location (before a teleport, death, or server switch), network-wide. `anziutils.staffgui` | Grants access to /au panel. `anziutils.randomplayer` | Grants access to /au spectate. `anziutils.staffaccount.exempt.` | Use that staff-only command (e.g. `.exempt.tp`) without staff mode. `.exempt.*` covers all of them. `anziutils.panic.bypass` | Never moved, kicked, or messaged by panic-mode actions. ### PlaceholderAPI Integration If PlaceholderAPI is installed on the server, AnziUtils provides the following placeholders (useful for Scoreboards and TAB plugins): Placeholder | Returns `%anziutils_combat_time%` | Seconds remaining on the player's combat tag (0 if not in combat) `%anziutils_combat_active%` | Returns true if the player is in combat, false otherwise `%anziutils_pvp_cooldown%` | Seconds remaining on the post-combat cooldown (0 if none) `%anziutils_country%` | Player's last known country `%anziutils_city%` | Player's last known city `%anziutils_ip%` | Player's IP address (Hidden if viewer lacks admin permission) ### Installation & Setup #### Download the Plugin Download the latest AnziUtils JAR file from BuiltByBit. #### Place in Plugins Folder Move the JAR file to your server's `plugins/` directory. #### Restart Server Restart your Minecraft server to generate configuration files. #### Add Your License Paste the key you received via Discord into `license.key` in `plugins/AnziUtils/config.yml`, then restart. #### Configure Settings Edit the generated YAML files in `plugins/AnziUtils/` — `config.yml`, `messages.yml`, `discord.yml`, and `rules.yml`. ### Questions before you commit? Support, licence keys, bug reports and feature requests all run through the Discord. Ask anything about AnziUtils there — including whether it fits the server you already run. Already bought it? Your licence lives in the licence portal (https://license.ajdnikov-dev.com) — sign in there for your keys, or claim one with `/claim` in the Discord. Join the Discord (https://discord.gg/xyjmcjMp4W) Back to all plugins --- # AnziUtils Documentation | ajdnikov URL: https://www.ajdnikov-dev.com/anziutils/docs Updated: 2026-11-08 > AnziUtils documentation: setup guide, commands, permissions and configuration for the Paper security and utility plugin, covering VPN detection, alt limiting, combat tagging and graves. ## AnziUtils Documentation Version 1.7.6 Platform Paper 1.21+ Java 21 Storage SQLite or MySQL Network Redis Welcome to the AnziUtils wiki! AnziUtils is an all-in-one administrative utility and security plugin offering VPN detection, alt-limiting, geolocation filters, combat logging, a custom grave system, dual staff profiles, network-wide staff tooling, and much more. Below you will find a complete breakdown of all modules, commands, permissions, and configuration options required to run the plugin optimally on your server. ### Getting Started AnziUtils runs on a single server out of the box and scales up to a full BungeeCord/Velocity network once you add MySQL and Redis. #### Requirements - Java 21 or higher - Paper (or a Paper fork) running Minecraft 1.21+ — the plugin targets `api-version: '1.21'` - PacketEvents (https://modrinth.com/plugin/packetevents) 2.x installed as its own plugin — a required dependency since 1.4 (see below) - A valid AnziUtils license key (issued in the Discord — see `/claim`) - Outbound internet access for GeoIP, VPN lookups, and license verification #### Optional Integrations (softdepend) Plugin | What it unlocks WorldGuard | Combat-log safe zones via `combat-log.safe-zone-regions` PlaceholderAPI | The `anziutils` placeholder expansion LuckPerms | Staff target hierarchy and staff-profile rank separation Vault | Staff-profile balance separation #### Required: PacketEvents Since 1.4, AnziUtils declares `depend: [packetevents]`, so the server will not load it without PacketEvents. It is used for the packet-level features: hiding vanished staff from other players' clients, ghosting staff-mode teleports, reduced debug info (F3 coordinates) in staff mode, and hiding a combat opponent's health. Built against PacketEvents 2.13.0; install the PacketEvents build for your server version. Everything else is bundled. MySQL and Redis are optional external services used only for network setups. ### Installation & License #### Step 1: Download Download the latest AnziUtils JAR file from the BuiltByBit release page. #### Step 2: Install - Stop your Minecraft server - Navigate to your server's `plugins/` directory - Place the AnziUtils JAR file in this directory, together with the PacketEvents JAR - Start your server once to generate the configuration files #### Step 3: AnziLock License Setup AnziUtils is protected by AnziLock , a signed license client that verifies your key against `license.ajdnikov-dev.com` on startup and then keeps a low-frequency heartbeat running in the background. Insert the key you received via Discord (see the `/claim` command in the Discord server) into `plugins/AnziUtils/config.yml`: ``` license: key: "YOUR_LICENSE_KEY_HERE" ``` AnziLock caches the last signed verification, so a brief outage of the license server will not take your server down — the plugin keeps running on the cached result for the duration of the offline grace period. If the key is missing or invalid, the plugin applies the configured failure action and logs the reason to the console. #### Automatic Updates Since 1.7.4, AnziUtils updates itself. When a new version is released, it checks your license again, downloads the new jar into `plugins/update`, and the server loads it on the next restart. The file is kept only if its size and checksum match the signed license answer. Nothing changes while the server is running. - Turn it off with `auto-update: false` in `config.yml`. - Players with `anziutils.updates` (ops by default) are told on join when a new version is waiting for a restart. - New settings are added to `config.yml`, `messages.yml`, `discord.yml` and `rules.yml` on start, with their comments. Your values stay, and the old file is kept as `.bak`. - Coming from 1.7.3 or older? Install 1.7.4 or newer by hand once. Every later version arrives by itself. How the download is checked: AnziLock → Automatic Updates . #### Support Dumps Since 1.7.6, `/au dump` makes a private link for support. The page shows AnziUtils's own log next to the full server log, and your server's setup: software and version, uptime, TPS, RAM, disk, CPU, Java, worlds, every plugin, and `config.yml` and `discord.yml` with keys, passwords and webhooks blanked out. Only you see the link in chat: click it, or click [Copy] , and send it to whoever helps you on Discord (https://discord.gg/xyjmcjMp4W). - `/au dump 6` covers only the last 6 hours. `/au dump local` uploads nothing and saves the dump in `plugins/AnziUtils/dumps/` as a readable `.txt` and a `.json.gz`. - On the page you can filter and search both logs, show only the lines about AnziUtils (stack traces included), and save everything to your PC as `.txt` or `.json`. A saved `.json` opens again at `license.ajdnikov-dev.com/dump` after the link has expired. - The link works for `dump.link-hours` (24 by default, at most 168). You can remove it sooner on your licence page under Dumps . - IP addresses are replaced with `x.x.x.x` unless you set `dump.hide-ips: false`. - Needs `anziutils.dump` (ops by default). ``` dump: # Hours of AnziUtils's log to keep on disk (dump-logs/) and put in a dump. log-hours: 48 # How long the link works, in hours (at most 168). link-hours: 24 # Replace IP addresses in the logs with x.x.x.x. hide-ips: true ``` What a dump contains and how long it is kept: AnziLock → Support Dumps . #### Step 4: Configuration Edit the generated files in `plugins/AnziUtils/`: - `config.yml` — every module, database, Redis, and staff setting - `messages.yml` — every player-facing message - `discord.yml` — the webhook URL and per-event notification toggles - `rules.yml` — the contents of the automatic rule book Apply changes without a restart using `/au reload`. ### Database AnziUtils stores IP history, geolocation results, alt links, staff profiles, and staff sessions in a database. Two backends are supported. #### SQLite (default) Zero setup. Keep `database.type: sqlite` for a single standalone server. #### MySQL (networks) On a BungeeCord/Velocity network, point every backend server at one shared MySQL database so IP history, alt limits, and staff profiles are tracked network-wide. ``` database: type: mysql mysql: host: mysql.example.com port: 3306 database: anziutils username: anziutils password: "CHANGE_THIS_PASSWORD" use-ssl: false fallback-to-sqlite: false pool: maximum-pool-size: 10 minimum-idle: 2 connection-timeout-ms: 10000 idle-timeout-ms: 600000 max-lifetime-ms: 1800000 ``` Create the database and user first: ``` CREATE DATABASE anziutils CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'anziutils'@'%' IDENTIFIED BY 'CHANGE_THIS_PASSWORD'; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, ALTER ON anziutils.* TO 'anziutils'@'%'; FLUSH PRIVILEGES; ``` Keep `fallback-to-sqlite: false` on networks. If MySQL goes down, a silent fallback would let one backend start writing to a local SQLite file and split your network state. With the fallback disabled the plugin disables itself safely instead. Backend servers must also receive the real player IP from the proxy — set `ip_forward: true` on BungeeCord or configure `player-info-forwarding-mode` on Velocity. ### Redis Network Synchronization Redis is optional on a single server and recommended on a network. It synchronizes: - Network-wide panic mode - Shared smart-mutes - A live online-player registry used by `/au gui` and `/au panel` - Cross-server staff action routing (freeze, bring, back, announce, cleardrops, spectate, panic actions) - Instant return of combat-log items when a logger survives - Cached GeoIP and VPN lookup results - Cross-server security alerts Every backend must share the same Redis host, database, and key prefix — but each needs a unique `server-id`. ``` redis: enabled: true host: redis.example.com port: 6379 username: "" password: "CHANGE_THIS_PASSWORD" database: 0 use-ssl: false timeout-ms: 5000 key-prefix: "anziutils" server-id: "survival-1" # unique on every backend heartbeat-seconds: 10 registry-ttl-seconds: 30 session-grace-seconds: 20 action-timeout-seconds: 30 spectate-lock-seconds: 45 proxy-server-name: "survival-1" # name registered on the proxy cache: geo-ttl-seconds: 86400 vpn-ttl-seconds: 3600 ``` For Velocity, also enable BungeeCord-compatible plugin messaging in `velocity.toml` so the Connect messages used by network transfers work: ``` bungee-plugin-message-channel = true ``` Security: never expose Redis to the public internet. Keep it on a private network, require a password or ACL user, and enable TLS when Redis traffic leaves a trusted network. #### Backend Switches vs. Network Leaves With Redis enabled, moving between backends is recognized as a backend switch rather than a fresh join: rule books, VPN/GeoIP checks, database join rows, and join notifications are not repeated. Staff see a notification for the initial network join, and again only after the player has been gone for the full `session-grace-seconds` window. World-local systems — combat loggers, graves, redstone limiting, and automatic item-clear cycles — always stay on the backend they belong to. #### Local Fallbacks Every Redis-backed feature has a local fallback. If Redis is disabled or offline, the plugin keeps working on a per-server basis. ### Security & Access Control #### VPN / Proxy Detection Connecting IPs are checked against `proxycheck.io`. Results are cached in Redis when it is enabled. ``` vpn-detection: enabled: true # true = kick the player, false = warn staff but let them join kick-on-vpn: true kick-message: "&cVPN/Proxy connections are not allowed on this server." ``` When `kick-on-vpn` is `false`, the player is allowed in but staff with `anziutils.notify` are warned — and, if `smart-mute.mute-on-vpn-warn` is enabled, the player is silently muted for the configured duration. #### Alt Account Limiter Restricts how many distinct accounts may connect from a single IP address, blocking botnets and ban evaders. ``` alt-limit: enabled: true max-accounts-per-ip: 3 kick-message: "&cToo many accounts have connected from your IP address." ``` #### Country Filter (GeoIP) Geolocation is resolved through `ipwho.is`. Use full country names exactly as that service returns them (for example `"Slovenia"` or `"Germany"`) — not two-letter codes. ``` country-filter: # 'disabled', 'whitelist' (only these may join), or 'blacklist' (these are blocked) mode: disabled kick-message: "&cYou are not allowed to join from your country." countries: - "Slovenia" - "Croatia" - "Austria" ``` #### IP Exemptions Two independent exemption paths bypass VPN detection and alt-limit checks entirely. The first is an IP list: ``` exempt-ips: - "127.0.0.1" ``` The second is the `anziutils.exempt` permission, which exempts the player wherever they connect from. ### Panic Mode & Smart Mute #### Panic Mode Turn on an emergency lockdown with `/au panic on` when the server is hit by a bot raid, and lift it with `/au panic off`. With Redis enabled the state is published network-wide, so one toggle locks down every backend. Toggling notifies every online player with `anziutils.notify` or `anziutils.admin`, writes a console warning, and fires a Discord webhook. `/au panic status` shows whether it is on, which restrictions apply, and every configured action. Panic mode has two halves: restrictions that tighten who can join and chat, and actions that do something to players — move them to another backend, kick them, show a title, broadcast, or run console commands. ##### Restrictions Each restriction can be switched on or off on its own: ``` panic-mode: restrictions: country-whitelist: true # only these countries may join allowed-countries: - "Slovenia" alt-limit: true # tighten the alt limit max-accounts-per-ip: 1 mute-new-players: true # mute players who joined recently mute-new-players-minutes: 5 # A player counts as "new" (target: new-players) if their first ever # join on the network was less than this many minutes ago. new-player-minutes: 60 # Players with this permission are never touched by panic actions. bypass-permission: "anziutils.panic.bypass" ``` ##### Actions Actions are listed under three triggers: Trigger | Runs `on-enable` | Once, when panic mode turns on `on-join` | For every player who joins a backend while panic mode is on `on-disable` | Once, when panic mode turns off Type | Does | Keys `send` | Moves the targets to another backend through the proxy | `server:` proxy server name `kick` | Kicks the targets | `message:` kick reason `message` | Chat message to the targets | `message:` `title` | On-screen title for the targets | `title:`, `message:` (subtitle) `broadcast` | Chat message to everyone | `message:` `command` | Console command. With `{player}` it runs once per target | `command:` Options available on every action: Option | Values | Default `target` | `all`, `non-staff`, `new-players`, `staff` | `non-staff` `delay` | Seconds to wait before running | `0` `servers` | Only run on these `server-id`s, e.g. `[lobby-1]` | every server `scope` | `network` — every backend runs it for its own players; `origin` — only the server that toggled panic | `network` (`origin` for `command`) Example — park new players in a limbo server during a raid, kick new players who try to come back to survival, and send everyone in limbo to the lobby once it is over: ``` panic-mode: actions: on-enable: - type: title target: new-players title: "&c&lLOCKDOWN" message: "&7Moving you to a waiting area..." - type: send target: new-players server: limbo delay: 3 on-join: - type: kick target: new-players message: "&cThe server is in lockdown. Please try again in a few minutes." servers: [survival-1] on-disable: - type: send target: all server: lobby servers: [limbo] ``` `send` uses the same proxy messaging as the other network transfers, so on Velocity it needs `bungee-plugin-message-channel = true`. Upgrading: the old flat keys (`panic-mode.allowed-countries`, `panic-mode.max-accounts-per-ip`, `panic-mode.mute-new-players-minutes`) are still read when `panic-mode.restrictions` is missing. #### Smart Mute Suspicious joins are silently muted — blocked from chat and from chat-driven commands — for a limited window, without an obvious kick that tells an attacker what tripped. ``` smart-mute: # Mute players who join on a VPN when kick-on-vpn is false mute-on-vpn-warn: true mute-duration-minutes: 5 ``` Smart mutes are shared across the network through Redis. ### Combat Logging Players are combat-tagged when they enter PvP and see a live action bar timer. Disconnecting while tagged spawns a combat logger NPC that can be killed for the player's loot — safely across a whole BungeeCord/Velocity network, without item duplication. #### Configuration ``` combat-log: enabled: true timer: 15 # combat duration in seconds logger: mode: npc # npc = zombie stand-in, instant-death = kill on logout duration-seconds: 30 # how long the NPC stays (0 = same as timer) network-takeover-seconds: 60 # crash recovery window, see below graves: combat # always | combat | off (see Graves) # Combat restrictions disable-enderpearls: true disable-golden-apples: true disable-chorus-fruit: true disable-totems: false disable-inventory-open: true disable-flying: true block-world-change: true block-server-switch: true post-combat-cooldown: # see Post-Combat Cooldown below enabled: false seconds: 10 block-commands: true allowed-commands: ["msg", "r", "tell", "w", "reply"] block-world-change: true block-teleports: true block-server-switch: true blocked-commands: - "home" - "spawn" - "tp" - "tpa" - "tpaccept" - "warp" - "auback" - "sethome" - "rtp" - "wild" safe-zone-regions: - "spawn" - "safezone" block-region-entry: # keep tagged players out of regions enabled: true regions: [] # empty = use safe-zone-regions knockback: true knockback-strength: 1.0 join-grace-period: 3 # seconds after joining where tagging is impossible grave-protection-minutes: 5 # owner/killer-only looting window (more grave keys: see Graves) ``` #### Hidden Opponent Health While two players are combat-tagged against each other, each one's client is told the other is at full health, so health-indicator mods and resource packs cannot show how close an opponent is to dying. Players who are not fighting each other still see real health. It is on by default and is not in the generated `config.yml`; add the key to turn it off: ``` combat-log: hide-health: false # default: true ``` #### Network Combat Logging (Dupe-Proof) The moment a tagged player disconnects — or switches backend through the proxy — their inventory and XP are moved out of the player and into the shared database (`combat_escrow` table). The items now exist in exactly one place, and each escrow can only be claimed once: - Logger killed: the items go into a grave, and the player dies on their next join — on any backend of the network. - Logger survives (or the player rejoins the same backend in time): the items are given back wherever the player is — instantly over Redis, otherwise within a few seconds. - Backend crashes: the escrow is recovered when that server starts again, or another backend takes it over after `network-takeover-seconds` and returns the items. With `logger.mode: instant-death` no NPC is spawned; the player is treated as killed straight away. Network requirements: every backend must use the same MySQL database and a unique `redis.server-id` — set it even if Redis itself is disabled. If you also run an inventory-sync plugin, make sure it saves after AnziUtils on quit; AnziUtils empties the inventory at `LOWEST` priority. #### Anti-Escape Restrictions Each restriction has its own bypass permission, so you can loosen individual rules for specific ranks: - Enderpearls - Golden Apples - Chorus Fruit - Totems of Undying - Creative flight and elytra gliding - Opening containers and the inventory - Blocked commands such as `/tp`, `/spawn`, `/home` - World changes — portals and plugin teleports (`block-world-change`) - Backend server switches through AnziUtils network transfers (`block-server-switch`) - Entering WorldGuard regions such as spawn (`block-region-entry`, see below) Note on server switches: `block-server-switch` covers AnziUtils' own transfers (`/au back`, `/au bring`, `/au spectate`). A player who leaves the backend another way — a proxy `/server` command, for instance — is still treated as a combat logger, and the NPC spawns on the backend they left. #### WorldGuard Safe Zones Region names listed under `safe-zone-regions` (case-insensitive) never apply a combat tag, so players can move through spawn and protected areas safely. Requires WorldGuard. #### Blocking Region Entry A safe zone is no use if a player can run into it mid-fight. With `block-region-entry`, combat-tagged players cannot enter the listed regions: walking, riding, ender pearls, chorus fruit, and teleports into them are all stopped. Leaving a region is always allowed. Requires WorldGuard. The border works like a wall: a player who reaches it stops and bounces back a little. It never lifts anyone into the air. Players knocked into it by a hit, an explosion or a wind charge only stop, so they are not thrown back at their attacker. Since 1.7.5, a vanilla "Flying is not enabled" kick right after the border stopped someone is not counted as combat logging. - `regions`: region names (case-insensitive). Leave it empty to use your `safe-zone-regions`. - `knockback` / `knockback-strength`: also shove players who walk into the border back out, sideways only. `1.0` is about two blocks, `2.0` about four. - Bypass: `anziutils.combatlog.bypass.regionentry` (or the universal `anziutils.combatlog.bypass`). It is on by default , including on configs from before 1.7.3 that have no `block-region-entry` block. Set `enabled: false` to turn it off. #### Post-Combat Cooldown An optional cooldown that starts when a combat tag ends: the timer ran out, or the opponent died or their combat logger was killed. It stops a player from winning a fight and instantly running `/home`, `/spawn`, or `/server`. The remaining time shows on the action bar. Getting hit again replaces the cooldown with a normal combat tag. ``` combat-log: post-combat-cooldown: enabled: false # off by default seconds: 10 block-commands: true # every command except allowed-commands allowed-commands: - "msg" - "r" - "tell" - "w" - "reply" block-world-change: true # portals and teleports into another world block-teleports: true # /tp, /home, /warp... in the same world (pearls and chorus fruit still work) block-server-switch: true # AnziUtils network transfers (/au back, /au bring, /au spectate, panic moves) ``` Bypass: `anziutils.combatlog.bypass.cooldown` (or `anziutils.combatlog.bypass`). Show the remaining time on a scoreboard with `%anziutils_pvp_cooldown%`. #### Join Grace Period `join-grace-period` blocks combat tagging for the first few seconds after joining, preventing spawn-kill loops. Set it to `0` to disable. ### Secure Player Graves Instead of scattering items on the ground, a death can spawn a player-head grave at the death location. `combat-log.graves` decides which deaths do: Mode | Grave is spawned `always` | On every player death, and when a combat logger is killed `combat` (default) | Only when a player dies while combat-tagged, or a combat logger is killed `off` | Never — items and XP drop on the ground like vanilla Graves work in `always` mode even when combat tagging itself is disabled. #### How It Works - A player dies (in combat, or any death in `always` mode), or their combat logger is killed - Their items and XP are collected into a grave - An interactive player head marks the grave location - Floating holograms above it show the owner, the stored XP and item count, and the grave's age - The player clicks the head to open the grave and retrieve their items - Once the protection timer expires, anyone can loot it #### Anti-Theft Protection For the first `grave-protection-minutes` only the grave's owner or their killer can interact with it. After that it becomes public loot — which keeps grave-raiding in the game without making deaths feel cheap. Set the value to `0` to disable protection entirely. #### Grave Settings ``` combat-log: graves: combat grave-protection-minutes: 5 # owner/killer-only window, 0 = no protection grave-xp-retain-percent: 100 # share of XP kept in the grave (0-100) grave-item-loss: # random share of item stacks destroyed on death min-percent: 0 max-percent: 0 # 0 / 0 = nothing is ever lost grave-despawn-minutes: 0 # 0 = graves never despawn grave-compass: true # compass to the grave on respawn grave-history-days: 14 # how long deaths stay in /au graves list ``` - XP retention: `100` keeps all of it — more than vanilla, which drops at most 100 XP. - Item loss: each death picks a random percentage between `min-percent` and `max-percent`, and that share of item stacks is destroyed instead of going into the grave. - Despawn timer: graves disappear after `grave-despawn-minutes` and the hologram counts down. Admins can still give the items back with `/au graves restore`. - Death compass: on respawn the player is always told where their grave is, and with `grave-compass: true` also gets a compass pointing to it. The compass is removed once the grave is gone. - Indestructible: explosions, flowing water and lava, pistons, and mobs cannot destroy a grave. If the head goes missing anyway, it is put back. Graves persist across server restarts. #### Settings GUI `/au graves` on its own opens a settings menu for the grave mode, XP retention, item loss, protection time, despawn time, and the compass toggle, plus a button for the grave history. Changes are saved to `config.yml`. #### Grave History & Restore Every grave's original items are kept in the plugin database for `grave-history-days` days; graves that still exist are never removed from it. With `database.type: mysql` the history is shared by every backend, so `/au graves list` shows deaths from all servers (with the server name). An old `grave-history.yml` is imported automatically on first start. Command | Description `/au graves list [player] [page]` | Recent deaths with location, item count, and status (standing, looted by…, despawned, restored), with clickable [TP] [Items] [Restore] buttons. `/au graves view ` | Read-only view of what the grave held at death. `/au graves tp ` | Teleport to the death spot, sending you to the right backend if it was on another server. `/au graves restore [grave] [force]` | Give the items and XP back. Players who are offline or on another backend get them as soon as they are on any server of the network, and each restore is delivered only once. Add `grave` to place a new grave at the death spot instead (run it on the server where the grave was). Graves the owner already looted, or that were already restored, need `force` so items are not duplicated by accident. All `/au graves` commands need `anziutils.admin`. ### Staff Account System The Staff Account system lets staff members operate two completely separated player profiles: a normal profile (the one they play on as a regular player) and a staff profile (used when actively moderating). Switching is instant, and nearby players are not told who is staff. #### How It Works - A staff member runs `/au staff` (shortcut `/staff`) to enter staff mode. - Their backend server, world, coordinates, yaw/pitch, and gamemode are saved to the database as the `/auback` target. - Inventory, ender chest, statistics, balance, and LuckPerms groups swap to the staff profile, according to `staff-account.separate`. - Staff godmode activates — no damage, and no combat tags. - When they teleport, position/rotation/sound packets are hidden from non-admin players (ghosting). - Running `/au back` (shortcut `/auback`) returns them to the saved location and gamemode and exits staff mode. Running `/au staff` again while in staff mode does the same thing — it acts as `/au back`, so leaving staff mode is always a single command. Because the session is stored centrally, a reload or a backend switch restores the correct session instead of stranding the staff member without a valid `/auback` target. Ranks are applied additively. Entering or leaving staff mode never removes a player's existing LuckPerms groups. While in staff mode, an action bar reminder is shown (and briefly blinks every few seconds) so staff do not forget which profile they are on. The text lives in `messages.yml` under `staff-mode-actionbar` and `staff-mode-actionbar-blink`. #### Configuration ``` staff-account: enabled: true separate: inventory: true # main inventory, armor, offhand ender-chest: true stats: true # vanilla statistics (playtime, kills, deaths, ...) ranks: true # requires LuckPerms currency: true # requires Vault + an economy plugin block-in-combat: true # no escaping combat via a profile swap block-while-frozen: true godmode: true # invulnerable in staff mode, also blocks combat tags ghost-on-teleport: true # hide position/rotation/sound packets from non-admins teleport-view-distance: 3 # view distance after a staff teleport (0 = don't change) require-back-to-exit: true # leaving staff mode always returns you to the saved location actionbar: # reminder shown while in staff mode enabled: true blink: true # briefly flash it so it's hard to forget blink-interval-seconds: 10 blink-duration-seconds: 1.5 # Players allowed to use some staff-only commands without staff mode. # Easiest to manage in-game with /au exempt. command-exceptions: Notch: - tp - tphere staff-only-commands: - "ban" - "tempban" - "ipban" - "kick" - "mute" - "tempmute" - "warn" - "vanish" - "v" - "freeze" - "bring" - "tp" - "tpo" - "tphere" - "teleport" ``` #### Staff-Only Commands Commands listed under `staff-only-commands` are blocked for anyone holding `anziutils.staffaccount` while they are on their normal profile. This stops staff from moderating while playing as a regular player. #### Command Exceptions (e.g. /tp without staff mode) Some people — a builder, an event host, the owner — need `/tp` on their normal profile. Give them an exception instead of removing the command from the list: Command | Effect `/au exempt add Steve` | Steve can use `/tp` (and `/teleport`) without staff mode `/au exempt add Alex tp tphere` | Specific commands only `/au exempt add Admin all` | Every staff-only command `/au exempt remove Steve [commands]` | Remove some or all of Steve's exceptions `/au exempt list` | Show everyone with an exception Exceptions are saved under `staff-account.command-exceptions` in `config.yml` (player name or UUID → list of commands, `*` for all). `tp` also covers `teleport`. If you prefer permissions, grant `anziutils.staffaccount.exempt.` (for example `anziutils.staffaccount.exempt.tp`) or `anziutils.staffaccount.exempt.*`. #### Commands Command | Permission | Description `/au staff` (shortcuts `/staff`, `/staffaccount`) | `anziutils.staffaccount` | Enters staff mode. While in staff mode, it acts exactly like `/au back`: returns you to your saved location and exits staff mode in one step. `/au back` (shortcuts `/auback`, `/staffback`) | `anziutils.back` (included in `anziutils.staffaccount`) | In staff mode: returns to your pre-staff backend, location, and gamemode, then exits staff mode. Outside staff mode: teleports to your last location . `/au exempt [player] [commands]` | `anziutils.admin` | Manage staff-only command exceptions. ### Network Staff Tools With Redis enabled, the staff commands work across the whole network rather than one backend. #### Staff Panel `/au panel` (shortcut `/staffgui`) opens the AnziUtils — Staff Panel , a single inventory menu for staff mode, vanish, freeze, bring, announcements, panic mode, drop clearing, and spectating. Targeted actions open a player picker listing everyone online across the network, with their current backend shown in the lore. #### Cross-Server Commands Every command below is a `/au` subcommand; the short form in brackets works too. Command | Behaviour `/au freeze ` (`/freeze`) | Toggles freeze on whichever backend the player is online on. The freeze persists through server switches. `/au bring ` (`/bring`) | Transfers the remote player to the admin's backend, then teleports them to the admin. `/au back` (`/auback`) | In staff mode, transfers staff back to the backend where staff mode started and restores the saved coordinates. Outside staff mode, returns the player to their last location, transferring them to the right backend first. `/au announce [-t ] ` (`/announce`) | Broadcast to every backend: always in chat, plus on screen as a title, action bar, and/or boss bar. See Network Announcements . `/au cleardrops` (`/cleardrops`) | Clears ground items on every backend, respecting the item-clear filters. `/au spectate [stop]` (`/randomplayer`, `/rp`) | Spectates a random network player while vanished. Each admin reserves one target through an atomic Redis lock, so two admins never land on the same player. `stop` releases the reservation. #### Staff Target Hierarchy Targeted staff commands (freeze, bring, spectate) respect a rank hierarchy, so moderators cannot act on admins — and no staff member can target themselves. ``` staff-hierarchy: enabled: true require-luckperms: true ``` - The target's highest LuckPerms group weight must be the same as or lower than the actor's. - Console and server operators (op) bypass the check entirely. - With `require-luckperms: true` the check fails closed — if LuckPerms or a user's rank data is unavailable, the action is blocked rather than allowed. #### Vanish `/au vanish` (shortcut `/vanish`) hides the staff member from other players. Sounds they generate are suppressed for nearby observers, and entity visibility is handled at the packet level so they do not give themselves away. Vanish has two modes: Mode | Behaviour `invisible` | Hidden in the world, but still listed in the tab list. `leave` | Sends a fake leave message and hides you from the tab list too. Un-vanishing sends a fake join message. Usage: `/vanish [on|off|leave|invisible]`. `/vanish mode [leave|invisible]` sets (or toggles) your preferred mode, which is remembered. ``` vanish: default-mode: invisible # mode used until a player picks one fake-messages: true # fake leave/join messages in leave mode fake-message-style: vanilla # vanilla = same as the real join/leave line, custom = messages.yml fake-messages-scope: network # network = every backend (needs Redis), server = this backend only ``` Keep `fake-message-style: vanilla` unless another plugin changes your real join/leave messages — hacked clients compare the two. With `custom`, match that plugin's format in `vanish-fake-quit` / `vanish-fake-join` in `messages.yml`. Vanish state and the preferred mode follow the player across backends. Vanish is applied before the join completes, so server switches never show join/leave messages or tab entries. Vanished players never earn advancements, can always fly (including after gamemode and world changes), are ignored by mobs, sculk sensors, and wardens, and do not trigger pressure plates. #### Last Location (/au back) Outside staff mode, `/au back` (shortcut `/auback`) teleports a player to their last location: where they were before their last teleport, death, or server switch. With Redis the location is shared, so the player is first sent to the right backend. It needs `anziutils.back`, which `anziutils.staffaccount` includes. ``` back: on-death: true # record the death location on-server-leave: true # record the location when leaving a backend, so /auback undoes a server switch expire-minutes: 1440 # forget the last location after this long (Redis only) ``` In staff mode, `/au back` always returns to where staff mode was entered instead. `auback` is in the default combat `blocked-commands` list, so it cannot be used to escape a fight. #### Network Announcements `/au announce [-t ] ` (shortcut `/announce`) sends a message to every backend. It always goes to chat, and can also show on screen as a title, action bar, and/or boss bar. - Long messages are split into lines shown one after another. Lines break between words, so a word is only cut when it is longer than a whole line. Color codes carry over to the next line. - The heading (“Announcement”) only shows with the first line; the remaining lines appear underneath on their own. - Display time is set per line with `stay-seconds`, or for one announcement with `-t` — e.g. `/announce -t 10 Restart in 5 minutes`. - `/announcements [on|off]` lets any player choose chat only (`off`) or on-screen again (`on`). The choice is saved and, with Redis, follows the player across backends. - Chat tip: a clickable tip under announcements tells players about `/announcements off`. Each player sees it at most once per `hint.interval-minutes`. ``` announcements: # Where it shows on screen: any of title, actionbar, bossbar. Use [] for chat only. display: [title] # How long each line stays on screen (override per announcement with -t) stay-seconds: 5.0 # Longer messages are split into lines of at most this many characters max-line-length: 40 title: heading: "&6&lAnnouncement" # shown above the first line only fade-in-seconds: 0.5 fade-out-seconds: 1.0 bossbar: color: YELLOW # PINK, BLUE, RED, GREEN, YELLOW, PURPLE, WHITE style: PROGRESS # PROGRESS, NOTCHED_6, NOTCHED_10, NOTCHED_12, NOTCHED_20 hint: enabled: true interval-minutes: 30 # 0 = tip under every announcement ``` Display | Behaviour `title` | The line appears as the subtitle under the heading. A title holds only one line, which is why long messages are paged. `actionbar` | The line shows above the hotbar and is refreshed every second so it stays for the full time. `bossbar` | The line shows at the top of the screen and the bar drains over the whole announcement. Displays can be combined, e.g. `display: [title, bossbar]`. Players who ran `/announcements off` only get the chat line. The toggle and tip messages are `announce-screen-on`, `announce-screen-off`, and `announce-hint` in `messages.yml`. ### Server Utilities #### Item Clearer Periodically clears ground items to keep entity counts under control. ``` item-clear: enabled: true interval-minutes: 5 excluded-worlds: - "world_the_end" ``` `/au cleardrops` runs an immediate clear using the same filters. #### Redstone Limiter Throttles runaway redstone per chunk so a lag machine cannot tank the server. ``` redstone-limiter: enabled: true max-pulses-per-second: 150 cooldown-seconds: 5 alert-admins: true ``` When a chunk crosses the threshold it is suppressed for `cooldown-seconds`, and players with `anziutils.admin` are notified if `alert-admins` is on. #### Chat @Mention Tagging Mentioning a player's name in chat highlights it and plays a sound for them. ``` chat-mentions: enabled: true sound: ENTITY_EXPERIENCE_ORB_PICKUP color: "YELLOW" ``` #### Command Watch Sends a Discord notification whenever a watched command is executed — an audit trail for the commands that matter. Matching is on the base command, so `op` matches `/op Player`. ``` command-watch: enabled: true commands: - "op" - "deop" - "stop" - "ban" - "ban-ip" - "pardon" - "gamemode" - "whitelist" - "kick" ``` ### Interactive Rule Books New players automatically receive a written book of your server rules the first time they join. The contents live in `rules.yml`, where each list entry is one page: ``` enabled: true book: title: "&6Server Rules" author: "&cServer Administration" pages: - "&lWelcome to the server!&r\n\nPlease read through our rulebook carefully." - "&l1. No Cheating/Hacking&r\nAny use of modified clients will result in a permanent ban." - "&l2. Be Respectful&r\nDo not harass, flame, or dox other players." ``` Use `\n` to start a new line within a page. Command | Description `/au book give ` | Hand the rule book to a specific player. `/au book reset` | Bump the book generation so every player receives the updated book as if they had never joined. With Redis enabled, a player switching backends does not receive a duplicate book. ### Discord Webhook Integration Discord settings live in their own file, `plugins/AnziUtils/discord.yml`. Set the master toggle and your webhook URL, then enable the events you care about. ``` enabled: false webhook-url: "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN" bot-name: "AnziUtils" bot-avatar: "https://mc-heads.net/avatar/MHF_Question/128" notifications: vpn-detection: ... alt-limit: ... combat-log-death: ... combat-log-rejoin: ... panic-mode: ... command-watch: ... ``` #### Available Notifications Event | Fires when `vpn-detection` | A connecting IP is flagged as a VPN or proxy `alt-limit` | An IP exceeds the configured account limit `combat-log-death` | A player disconnects while combat-tagged and the NPC is killed `combat-log-rejoin` | A combat logger returns to the server `panic-mode` | Panic mode is toggled on or off `command-watch` | A watched command from `command-watch.commands` is executed Each event has its own `enabled` flag plus embed title, description, and color, so you can route only the alerts you want into your staff channel. #### Test Your Webhook Run `/au test` to send test payloads and confirm the integration works. ### Commands Everything lives under one command: `/au` (also `/anziutils` and `/anzi`). Run `/au` on its own for a clickable help menu that only lists what you are allowed to use. Every argument tab-completes, and a mistyped subcommand gets a did you mean…? suggestion. #### Lookup & Administration Command | Description | Permission `/au lookup [page]` | IP history, clickable linked accounts, and geolocation. `/au ` works too. | `anziutils.command` `/au gui` | Browse online players and their IP data. | `anziutils.gui` `/au panic [on|off|status]` | Network lockdown; `status` lists active restrictions and actions. | `anziutils.admin` `/au exempt [player] [commands]` | Let players use staff-only commands (e.g. `/tp`) without staff mode. | `anziutils.admin` `/au book give ` | Give the rule book to a player. | `anziutils.book` `/au book reset` | Regenerate rule books for all players. | `anziutils.book` `/au reload` | Reload `config.yml` and `messages.yml`. | `anziutils.command` `/au dump [hours] [local]` | A private link with AnziUtils' log, the full server log and your server's setup, for support. See Support Dumps . | `anziutils.dump` `/au debug` | GeoIP, Redis, and database diagnostics. | `anziutils.admin` `/au test` | Send test payloads to the Discord webhook. | `anziutils.admin` #### Staff Tools Command | Description | Permission `/au panel` | Open the network staff action panel. | `anziutils.staffgui` `/au staff` | Enter staff mode. In staff mode it acts as `/au back` and exits. | `anziutils.staffaccount` `/au back` | Teleport to your last location (before a teleport, death, or server switch). In staff mode, return to where you entered it and exit staff mode. | `anziutils.back` `/au vanish [on|off|leave|invisible|mode]` | Toggle vanish. `leave` sends a fake leave message and hides you from the tab list; `invisible` keeps you in it. `mode` sets your preferred mode. | `anziutils.admin` `/au freeze ` | Freeze or unfreeze a player, anywhere on the network. | `anziutils.admin` `/au bring ` | Transfer and teleport a player to you. | `anziutils.admin` `/au spectate [stop]` | Spectate a random network player while vanished. | `anziutils.randomplayer` `/au announce [-t ] ` | Network-wide announcement in chat and on screen. Long messages are shown line by line; `-t` sets how long each line stays. | `anziutils.admin` `/au announcements [on|off]` | Choose whether announcements show on your screen or only in chat (`/announcements` and `/togglebroadcast` work too). | `anziutils.announcements` (everyone) `/au cleardrops` | Immediately clear ground items (respects filters). | `anziutils.admin` #### Graves Command | Description | Permission `/au graves` | Open the grave settings GUI. | `anziutils.admin` `/au graves list [player] [page]` | Recent deaths across the network, with TP / Items / Restore buttons. | `anziutils.admin` `/au graves view ` | Read-only view of a grave's original items. | `anziutils.admin` `/au graves tp ` | Teleport to the death spot, on any backend. | `anziutils.admin` `/au graves restore [grave] [force]` | Give the items and XP back, or place a new grave. See Grave History . | `anziutils.admin` #### Shortcuts The short commands still work, so existing habits and scripts keep working: `/vanish`, `/freeze`, `/bring`, `/announce`, `/announcements`, `/cleardrops`, `/staff` (`/staffaccount`), `/auback` (`/staffback`), `/staffgui` (`/staffpanel`), `/randomplayer` (`/rp`), and the older `/anziutilsgui`, `/anziutilsreload`, `/anziutilsdebug`, `/anziutilstest`, `/anziutilsbook`, `/anziutilsbooksreset`. ### Permissions #### Administrative Permission | Description | Default `anziutils.admin` | Staff tools (vanish, freeze, bring, announce, cleardrops), grave settings and history (`/au graves`), panic mode, command exceptions, debug, and test. Also allows seeing true IPs in placeholders. | OP `anziutils.command` | `/au lookup` and `/au reload`. | OP `anziutils.gui` | Access to `/au gui`. | OP `anziutils.notify` | Receives VPN, alt, country, and suspicious-join alerts in chat. | OP `anziutils.book` | Access to `/au book`. | OP `anziutils.staffaccount` | Access to `/au staff` and the staff-mode `/au back`, plus staff godmode, ghosting, and staff-only command enforcement. Includes `anziutils.back`. | OP `anziutils.back` | `/au back` to your last location (before a teleport, death, or server switch), network-wide. | OP `anziutils.staffgui` | Access to `/au panel`. | OP `anziutils.randomplayer` | Access to `/au spectate`. | OP `anziutils.announcements` | Use `/announcements` to show announcements on screen or only in chat. | everyone `anziutils.updates` | Told on join when a new version has been downloaded and is waiting for a restart. See Automatic Updates . | OP `anziutils.dump` | Use `/au dump`. See Support Dumps . | OP Server operators always pass these staff and admin checks, whether or not the permission is set. #### Bypasses Permission | Description | Default `anziutils.exempt` | Exempts the player from VPN detection, alt limits, country filtering, and smart mutes. | false `anziutils.combatlog.bypass` | Universal bypass — the player is never combat tagged. | false `anziutils.combatlog.bypass.enderpearls` | Can throw enderpearls while in combat. | false `anziutils.combatlog.bypass.goldenapples` | Can eat golden apples in combat. | false `anziutils.combatlog.bypass.chorusfruit` | Can eat chorus fruit in combat. | false `anziutils.combatlog.bypass.totems` | Can trigger totems in combat. | false `anziutils.combatlog.bypass.inventory` | Can open containers and the inventory in combat. | false `anziutils.combatlog.bypass.flight` | Can fly or use an elytra in combat. | false `anziutils.combatlog.bypass.commands` | Can use blocked commands in combat. | false `anziutils.combatlog.bypass.worldchange` | Can change worlds while in combat. | false `anziutils.combatlog.bypass.serverswitch` | Can switch backend servers while in combat. | false `anziutils.combatlog.bypass.regionentry` | Can enter blocked WorldGuard regions while in combat. | false `anziutils.combatlog.bypass.cooldown` | Skips the post-combat cooldown. | false `anziutils.staffaccount.exempt.` | Use that staff-only command without staff mode (e.g. `.exempt.tp`). `.exempt.*` covers all of them. | false `anziutils.panic.bypass` | Never moved, kicked, or messaged by panic-mode actions. | false ### PlaceholderAPI When PlaceholderAPI is installed, AnziUtils registers the `anziutils` expansion automatically. It persists across `/papi reload`. Placeholder | Returns `%anziutils_combat_time%` | Seconds remaining on the player's combat tag (`0` when not in combat) `%anziutils_combat_active%` | `true` or `false` — whether the player is combat tagged `%anziutils_pvp_cooldown%` | Seconds remaining on the player's post-combat cooldown (`0` when none) `%anziutils_country%` | The player's last known country `%anziutils_city%` | The player's last known city `%anziutils_ip%` | The player's IP address — returns `Hidden` unless the player has `anziutils.admin` ### Full config.yml The complete default configuration, for reference: ``` # ======================================= # AnziUtils Configuration # ======================================= # AnziLock License Configuration license: # Insert the license key you received via Discord here (see /claim). key: "" # Download new versions of AnziUtils automatically when they are released. # They are checked against your license and load on the next restart. # Players with anziutils.updates (ops by default) are told when one is waiting. auto-update: true # /au dump makes a private link with AnziUtils's log, the full server log and the server's setup # to share with support. "dump local" only saves it in plugins/AnziUtils/dumps/. dump: # Hours of AnziUtils's log to keep on disk (dump-logs/) and put in a dump. log-hours: 48 # How long the link works, in hours (at most 168). link-hours: 24 # Replace IP addresses in the logs with x.x.x.x. hide-ips: true # Database Configuration # Supported types: sqlite, mysql # # Single server: keep type 'sqlite' (default, zero setup). # Network (BungeeCord/Velocity): use ONE shared MySQL database on every # backend server so IP history, alt limits and staff profiles are tracked # network-wide. Make sure your proxy forwards the real player IP # (BungeeCord: ip_forward: true; Velocity: player-info-forwarding-mode). database: type: sqlite # MySQL settings (only used when type is 'mysql') mysql: host: localhost port: 3306 database: anziutils username: root password: "" use-ssl: false # If true, a failed MySQL connection silently falls back to local SQLite. # Networks should keep this FALSE so a broken MySQL never splits player # data across per-server SQLite files (the plugin disables safely instead). fallback-to-sqlite: false # HikariCP connection pool tuning (safe defaults for small servers) pool: maximum-pool-size: 10 minimum-idle: 2 connection-timeout-ms: 10000 idle-timeout-ms: 600000 max-lifetime-ms: 1800000 # Redis Synchronization (optional, for multi-server networks) # Enables: network-wide panic mode, shared smart-mutes, a live online-player # registry (network GUI), GeoIP/VPN result caching and cross-server alerts. # Point every backend at the SAME Redis instance and give every backend a # UNIQUE server-id. Local fallbacks keep the plugin fully working when # Redis is offline or disabled. redis: enabled: false host: localhost port: 6379 username: "" password: "" database: 0 use-ssl: false timeout-ms: 5000 # Namespace for all keys this plugin writes. key-prefix: "anziutils" # MUST be unique per backend server (e.g. "lobby-1", "survival-1"). # Also used by the combat-log escrow, so set it even when Redis is disabled. server-id: "survival-1" # How often this server refreshes its online-player registry entry. heartbeat-seconds: 10 # Registry entries expire after this many seconds without a heartbeat. registry-ttl-seconds: 30 # Grace period used to distinguish a backend switch from a true network leave. session-grace-seconds: 20 # Expiry for pending cross-server teleports/actions. action-timeout-seconds: 30 # Expiry for /randomplayer target reservations (refreshed while spectating). spectate-lock-seconds: 45 # Optional proxy-registered backend name used by BungeeCord-compatible Connect # messages. Leave empty to use server-id. Velocity requires # bungee-plugin-message-channel: true in velocity.toml. proxy-server-name: "" cache: # How long successful GeoIP lookups are cached (seconds). geo-ttl-seconds: 86400 # How long successful VPN/proxy checks are cached (seconds). vpn-ttl-seconds: 3600 # VPN / Proxy Detection # Uses ip-api.com to check if a connecting IP is a VPN or proxy. vpn-detection: enabled: true # If true, players connecting via VPN/proxy will be kicked. # If false, ops will be warned but the player can still join. kick-on-vpn: true kick-message: "&cVPN/Proxy connections are not allowed on this server." # Alt Account Limiter # Limits how many distinct accounts can connect from the same IP address. alt-limit: enabled: true max-accounts-per-ip: 3 kick-message: "&cToo many accounts have connected from your IP address." # Exempt IPs # IPs listed here bypass VPN detection and alt-limit checks entirely. exempt-ips: - "127.0.0.1" # Country Filter # Restrict access based on player country (resolved via GeoIP). # mode: 'disabled', 'whitelist', or 'blacklist' # whitelist = ONLY listed countries can join # blacklist = listed countries are BLOCKED # Use full country names as returned by ipwho.is (e.g. "Slovenia", "Germany"). country-filter: mode: disabled kick-message: "&cYou are not allowed to join from your country." countries: - "Slovenia" - "Croatia" - "Austria" # Panic Mode # A network-wide lockdown against bot raids. Toggle it with: # /au panic on | off | status # With Redis enabled, toggling on one server applies to EVERY backend, and # each backend runs the actions below for its own players. panic-mode: # --- Join restrictions while panic mode is ON --- restrictions: # Only let players from these countries join country-whitelist: true allowed-countries: - "Slovenia" # Lower the alt limit alt-limit: true max-accounts-per-ip: 1 # Mute players who joined less than X minutes ago mute-new-players: true mute-new-players-minutes: 5 # A player counts as "new" (target: new-players) if their first ever join # on the network was less than this many minutes ago. new-player-minutes: 60 # Players with this permission are never touched by panic actions. bypass-permission: "anziutils.panic.bypass" # --- Actions --- # on-enable : runs once when panic mode turns ON # on-join : runs for every player who joins while panic mode is ON # on-disable: runs once when panic mode turns OFF # # Action types: # send - move players to another backend (server: ) # kick - kick players (message: ) # message - chat message to the targets (message: ...) # title - title on screen (title: ..., message: ) # broadcast - chat message to everyone (message: ...) # command - console command; {player} = run once per target (command: ...) # Options for every action: # target: all | non-staff (default) | new-players | staff # delay: seconds to wait before running (default 0) # servers: only run on these server-ids, e.g. [lobby-1] (default: every server) # scope: network (every backend runs it) | origin (only the server that toggled) # default: network, except 'command' which defaults to origin # # Example - move new players into a limbo server and kick them if they come back: # on-enable: # - type: title # target: new-players # title: "&c&lLOCKDOWN" # message: "&7Moving you to a waiting area..." # - type: send # target: new-players # server: limbo # delay: 3 # on-join: # - type: kick # target: new-players # message: "&cThe server is in lockdown. Please try again in a few minutes." # servers: [survival-1] # on-disable: # - type: send # target: all # server: lobby # servers: [limbo] actions: on-enable: - type: broadcast message: "&c&l[!] &cThe server is in lockdown mode. New connections are restricted." on-join: - type: message target: new-players message: "&c&l[!] &7The server is in lockdown - chat is limited for new players." on-disable: - type: broadcast message: "&a&l[!] &aLockdown lifted. Thanks for your patience!" # Smart Mute # Automatically mutes suspicious players for 5 minutes (blocks chat and commands). smart-mute: # Mute player if they join with a VPN but kick-on-vpn is false mute-on-vpn-warn: true # Mute player if they join from a blacklisted/unwhitelisted country but aren't kicked (if we ever decide to warn instead of block) # (Currently country filter only blocks, but good for future proofing) mute-duration-minutes: 5 # Combat Log Module combat-log: enabled: true timer: 15 # Combat duration in seconds # What happens when a combat-tagged player disconnects (including switching # backend servers through the proxy). Their inventory and XP are moved into # the database the moment they leave, so the items exist in exactly one # place - this is what makes combat logging dupe-proof on Velocity/Bungee # networks (use the shared MySQL database on every backend). # - If the logger is killed: the items go into a grave and the player dies # on their next join, on ANY server of the network. # - If the logger survives (or the player returns to the same server in # time): the items are given back, on whichever server they are on. # Every backend needs a unique redis.server-id for this to work correctly. logger: # npc = spawn a zombie stand-in that others can kill # instant-death = kill the player immediately (items go to a grave) mode: npc # How long the NPC stays (seconds). 0 = same as the combat timer. duration-seconds: 30 # If the server that owns a logger crashes, other servers take over its # escrow after this many extra seconds and give the items back. network-takeover-seconds: 60 # When a player head grave (with loot GUI) is spawned instead of vanilla drops: # always = on every player death, and when a combat logger is killed # combat = only when a player dies while combat-tagged, or a combat logger is killed # off = never; items and XP drop on the ground like vanilla # (Replaces the old "graves-enabled" option: true = combat, false = off.) graves: combat # Combat Restrictions disable-enderpearls: true disable-golden-apples: true disable-chorus-fruit: true disable-totems: false disable-inventory-open: true disable-flying: true # Block players in combat from crossing into another world # (portals, plugin teleports, etc.). block-world-change: true # Block players in combat from crossing to another backend server via # AnziUtils network transfers (/auback, /bring, /randomplayer, panic moves). # Switching away via proxy commands (e.g. /server) counts as combat logging. block-server-switch: true # Optional cooldown that starts when a combat tag ends (timer ran out, or the # opponent died / their combat logger was killed). While it runs the player # can't use commands, change worlds, be teleported, or switch servers - so # nobody can win a fight and instantly /home, /spawn or /server away. # Getting hit again replaces the cooldown with a normal combat tag. # Bypass: anziutils.combatlog.bypass or anziutils.combatlog.bypass.cooldown post-combat-cooldown: enabled: false seconds: 10 # Block every command except the ones in allowed-commands. block-commands: true allowed-commands: - "msg" - "r" - "tell" - "w" - "reply" # Portals and any teleport into another world. block-world-change: true # Command and plugin teleports inside the same world (/tp, /home, /warp...). # Ender pearls and chorus fruit are not affected. block-teleports: true # AnziUtils network transfers (/auback, /bring, /randomplayer, panic moves). block-server-switch: true # Commands that are blocked while a player is in combat. # Use lowercase. Players with anziutils.combatlog.bypass skip this. blocked-commands: - "home" - "spawn" - "tp" - "tpa" - "tpaccept" - "warp" - "auback" - "sethome" - "rtp" - "wild" # WorldGuard Integration — region names where combat tagging is disabled. # Requires WorldGuard to be installed. Case-insensitive. safe-zone-regions: - "spawn" - "safezone" # Stop combat-tagged players from entering WorldGuard regions - walking, # riding, ender pearls, chorus fruit and teleports are all blocked, so # nobody can run into spawn mid-fight to escape. Leaving a region is always # allowed. Requires WorldGuard. # Bypass: anziutils.combatlog.bypass or anziutils.combatlog.bypass.regionentry block-region-entry: enabled: true # Region names (case-insensitive). Leave empty to use safe-zone-regions. regions: [] # The border works like a wall: the player is stopped and bounces back a # little. With knockback on, players who walk into it on the ground also get # shoved back out. Anyone knocked into it by a hit, explosion or wind charge # only stops, so they aren't thrown back at their attacker. Nobody is ever # lifted into the air. knockback: true # How hard walking players get shoved back (sideways only). 1.0 = about two # blocks, 2.0 = about four. knockback-strength: 1.0 # Grace period (seconds) after joining where players can't be combat-tagged. # Prevents spawn-killing loops. Set to 0 to disable. join-grace-period: 3 # Grave protection (minutes) — only the owner or their killer can loot. # After this time, anyone can loot the grave. Set to 0 to disable. grave-protection-minutes: 5 # How much of a player's XP is kept in their grave (0-100). # 100 = all of it (more than vanilla, which drops at most 100 XP). # Admins can also change these grave settings in-game with /au graves. grave-xp-retain-percent: 100 # Random item loss on death. Each death picks a random percentage between # min and max, and that share of the item stacks is destroyed instead of # going into the grave. 0 / 0 = nothing is ever lost. grave-item-loss: min-percent: 0 max-percent: 0 # Graves despawn this many minutes after the death and their items are lost. # Admins can still give them back with /au graves restore . 0 = never. grave-despawn-minutes: 0 # Give players a compass pointing to their grave when they respawn # (they are always told the grave's coordinates). grave-compass: true # How many days deaths stay in the admin grave history (/au graves list), # which keeps a copy of every grave's items for restoring. Graves that # still exist are never removed from it. Stored in the database, so with # database.type: mysql every server shares it and restores reach players # on whichever server they join. grave-history-days: 14 # Chat @Mention Tagging chat-mentions: enabled: true sound: ENTITY_EXPERIENCE_ORB_PICKUP color: "YELLOW" # Item Clearer # Periodically clears ground items to reduce lag. item-clear: enabled: true # Interval between automatic clears (in minutes) interval-minutes: 5 # Worlds to exclude from clearing excluded-worlds: - "world_the_end" # Redstone Limiter # Throttles excessive redstone activity per chunk to prevent lag machines. redstone-limiter: enabled: true # Maximum redstone pulses per chunk per second before throttling max-pulses-per-second: 150 # How long (seconds) a throttled chunk stays suppressed cooldown-seconds: 5 # Notify players with anziutils.admin when a chunk is throttled alert-admins: true # Command Watch (Discord Broadcast) # Sends a Discord notification when a player executes a watched command. command-watch: enabled: true # Commands to monitor (without leading /). # Matches the base command only (e.g. "op" matches "/op Player"). commands: - "op" - "deop" - "stop" - "ban" - "ban-ip" - "pardon" - "gamemode" - "whitelist" - "kick" # Staff Target Hierarchy # Targeted staff commands (freeze, bring, randomplayer) can only be used on # players whose highest LuckPerms group weight is the same as or lower than # the actor's. Console and server operators (op) bypass this check. With require-luckperms true, targeted commands # fail closed when LuckPerms or one of the users is unavailable. staff-hierarchy: enabled: true require-luckperms: true # Staff Dual Accounts # Lets staff run /staffaccount to swap between a "staff" profile and a # "normal" player profile. Each profile keeps its own separated data. staff-account: enabled: true separate: # Inventory contents (main, armor, offhand) inventory: true # Ender chest contents ender-chest: true # Vanilla statistics (playtime, kills, deaths, etc.) stats: true # Apply saved profile groups additively (requires LuckPerms). Existing # player ranks are never removed when entering or leaving staff mode. ranks: true # Money balance (requires Vault + an economy plugin) currency: true # Block switching while combat-tagged (prevents escaping combat via profile swap) block-in-combat: true # Block switching while frozen by an admin block-while-frozen: true # Invulnerable while in staff mode (also prevents combat tags) godmode: true # After teleporting in staff mode, hide position/rotation/sound packets from # non-admin players so the staff member can't be tracked ghost-on-teleport: true # View distance applied when teleporting in staff mode (restored on /auback). 0 = don't change teleport-view-distance: 3 # Leaving staff mode (/auback or /staffaccount) returns you to the saved location require-back-to-exit: true # Actionbar reminder shown while in staff mode (text in messages.yml: # staff-mode-actionbar / staff-mode-actionbar-blink) actionbar: enabled: true # Briefly flash the actionbar so it's harder to forget you're in staff mode blink: true # How often to blink, and how long each blink lasts blink-interval-seconds: 10 blink-duration-seconds: 1.5 # Players who may use some staff-only commands WITHOUT staff mode active. # Key = player name or UUID, value = list of commands ("*" = all of them). # "tp" also covers "teleport". Easiest way to manage this in-game: # /au exempt add [commands...] (no commands = tp) # /au exempt remove [commands...] # /au exempt list # You can also grant the permission anziutils.staffaccount.exempt. # (e.g. anziutils.staffaccount.exempt.tp) or anziutils.staffaccount.exempt.* command-exceptions: # Notch: # - tp # - tphere # Commands that only work while in staff mode (for players with anziutils.staffaccount) staff-only-commands: - "ban" - "tempban" - "ipban" - "kick" - "mute" - "tempmute" - "warn" - "vanish" - "v" - "freeze" - "bring" - "tp" - "tpo" - "tphere" - "teleport" # Vanish (/vanish) vanish: # Mode used by /vanish until a player picks one with /vanish mode: # invisible - hidden in the world, still listed in the tab list # leave - fake leave message and hidden from the tab list too default-mode: invisible # Send fake leave/join messages (messages.yml: vanish-fake-quit / vanish-fake-join) fake-messages: true # vanilla - identical to the server's real join/leave line (recommended; hacked clients compare them) # custom - use messages.yml; only if another plugin changes real join/leave messages, then match its format fake-message-style: vanilla # network = every backend shows them (needs Redis), server = only this backend fake-messages-scope: network # /auback outside staff mode (last location). Shared across backends with Redis. back: # Record the death location on-death: true # Record the location when leaving a backend, so /auback undoes a server switch on-server-leave: true # Forget the last location after this many minutes (Redis only) expire-minutes: 1440 # /announce — the chat line is always sent. Players can turn the on-screen part off # for themselves with /announcements off (chat only) and back on with /announcements on. announcements: # Where it shows on screen: any of title, actionbar, bossbar. Use [] for chat only. display: [title] # How long each line stays on screen. Override per announcement: /announce -t 10 stay-seconds: 5.0 # Long messages are split into lines (breaking between words) shown one after another max-line-length: 40 title: # Big text shown above the first line only heading: "&6&lAnnouncement" fade-in-seconds: 0.5 fade-out-seconds: 1.0 bossbar: # PINK, BLUE, RED, GREEN, YELLOW, PURPLE, WHITE color: YELLOW # PROGRESS, NOTCHED_6, NOTCHED_10, NOTCHED_12, NOTCHED_20 style: PROGRESS # Chat tip under announcements telling players about /announcements off (clickable) hint: enabled: true # Each player sees it at most once per this many minutes (0 = under every announcement) interval-minutes: 30 ``` ### Troubleshooting #### Q: The plugin disables itself on startup A: Check the console for an `[AnziLock]` line. `NO_KEY` means `license.key` is still empty; a network error means the server could not reach `license.ajdnikov-dev.com`. Also confirm you are on Java 21 and Paper 1.21+. #### Q: The server says AnziUtils is missing a dependency A: Install PacketEvents (https://modrinth.com/plugin/packetevents). Since 1.4 it is a required dependency, and the server refuses to load AnziUtils without it. #### Q: Every player is flagged as a VPN, or none are A: VPN checks go to `proxycheck.io` and geolocation to `ipwho.is`. Make sure the server has outbound internet access, then run `/au debug` to see live API results and rate-limit status. If you are behind a proxy, confirm the real player IP is being forwarded (`ip_forward` on BungeeCord, `player-info-forwarding-mode` on Velocity) — otherwise every player appears to come from the proxy's IP. #### Q: The alt limiter counts everyone as the same player A: This is the proxy-forwarding problem above. Without forwarding, all connections share the proxy's IP. #### Q: Combat logging is not triggering A: Verify `combat-log.enabled: true`, that the players are not inside a region listed in `safe-zone-regions`, that they are past the `join-grace-period`, and that they do not hold `anziutils.combatlog.bypass`. #### Q: A combat logger kept their items, or items were duplicated A: On a network every backend must point at the same MySQL database and have a unique `redis.server-id` — two backends sharing an id will treat each other's escrows as their own. If you run an inventory-sync plugin, it must save the inventory after AnziUtils has emptied it on quit. #### Q: Someone needs /tp without entering staff mode A: Run `/au exempt add `. See Command Exceptions . #### Q: Graves are not spawning A: Check `combat-log.graves`. With `combat` (the default) only combat deaths and killed loggers make a grave; use `always` for every death. With `off`, items and XP drop on the ground like vanilla. #### Q: A player lost their grave A: Run `/au graves list `, find the death, and click [Restore] (or run `/au graves restore `). Deaths stay in the history for `grave-history-days` days. #### Q: Staff data is split between servers A: Every backend must point at the same MySQL database with `fallback-to-sqlite: false`, and each backend needs a unique `redis.server-id`. #### Q: /au bring, /au back, or a panic send does not transfer across servers A: Cross-server transfers need Redis enabled on every backend, a correct `proxy-server-name` (or a `server-id` matching the proxy's registered name), and — on Velocity — `bungee-plugin-message-channel = true`. #### Q: Discord webhook not working A: Check `discord.yml`: the master `enabled` flag, the webhook URL, and the individual event toggle. Then run `/au test`. #### Q: Need more help? A: Join our Discord server (https://discord.gg/xyjmcjMp4W) for support and bug reports. ### Upgrading from an Older Version - Commands: everything lives under `/au`. The old commands (`/anziutilsgui`, `/staffgui`, `/randomplayer`, …) still work as shortcuts, so habits and scripts keep working. - Panic mode: the old flat keys (`panic-mode.allowed-countries`, `panic-mode.max-accounts-per-ip`, `panic-mode.mute-new-players-minutes`) are still read when `panic-mode.restrictions` is missing. To get the on/off toggles and actions, copy the `panic-mode` block from a freshly generated `config.yml`. - Combat logging: set a unique `redis.server-id` on every backend (even with Redis disabled) and point all backends at one MySQL database. The `combat_escrow` table is created automatically. Escrows left over from a crash are recovered when the owning server starts again, or by another server after `network-takeover-seconds`. - Graves (1.7): `combat-log.graves-enabled` is replaced by `combat-log.graves` (`always` / `combat` / `off`). Old configs keep working: `true` maps to `combat`, `false` to `off`. An existing `grave-history.yml` is imported into the database on first start. - /au back (1.7): now also works outside staff mode, with its own permission `anziutils.back` (included in `anziutils.staffaccount`). See the new `vanish` and `back` sections in the default `config.yml`. - Announcements (1.7.1): copy the `announcements` block from a freshly generated `config.yml` to get the display modes, heading, and chat tip. Without it, announcements still show as a title with the default timing. Players get the new `/announcements` command automatically (`anziutils.announcements`, default: everyone). - Combat (1.7.3): combat-tagged players can no longer walk, pearl, or teleport into WorldGuard regions. This is on by default even without the new `block-region-entry` block, and uses your `safe-zone-regions`; set `block-region-entry.enabled: false` to keep the old behaviour. The new post-combat cooldown is off until you add `post-combat-cooldown.enabled: true`. - Automatic updates (1.7.4): install 1.7.4 or newer by hand once; after that new versions download by themselves and load on the next restart (`auto-update` in `config.yml`). From this version on, new settings are added to your config files automatically, so you no longer need to copy blocks from a fresh `config.yml`. See Automatic Updates . - Region border (1.7.5): the combat region border now stops players like a wall and never lifts them; `knockback` only shoves players who walk into it, sideways. No new settings or permissions. --- # SMP-Reconnect — Auto-Reconnect for Velocity | ajdnikov URL: https://www.ajdnikov-dev.com/smp-reconnect Updated: 2026-11-07 > SMP-Reconnect is a lightweight Velocity plugin that keeps players connected while backend Minecraft servers restart or crash, then sends them back automatically. Source on GitHub. Skip to content ## SMP-Reconnect Velocity 3.x Java 17 Keeps players bridged on the Velocity proxy while a backend restarts or recovers, then returns them the moment it answers. No database, and nothing to install beyond the proxy itself. Read the manual Source on GitHub (https://github.com/ajdnikov/SMPReconnect) Ask in Discord (https://discord.gg/xyjmcjMp4W) ### Restarts without the kick When a backend server crashes or restarts, Velocity normally sends its players back to the lobby, or drops them from the network altogether. SMP-Reconnect sends them to their fallback server instead (or keeps them on the proxy), pings the server that went down, and moves everyone back the moment it answers . Players who were kicked or banned are left alone. ### What it talks to U01 U02 #### Ports One run, and it is the platform. SMP-Reconnect stores nothing and depends on nothing else. - Velocity API Patch field 1 RUN - Velocity API ### Exclusive Features A01 #### Zero-Latency Performance - All pings and reconnection logic are handled asynchronously - Your proxy remains completely lag-free - Designed for networks of any size A02 #### Advanced Server Pinging - Uses the Velocity internal ping API - Accurately detects when a server is accepting players - Configurable ping frequency A03 #### Smart Reconnect Logic - Intelligently remembers where each player was - No more "lost" players wandering the lobby - Automatic return to the original server A04 #### Fail-Safe Protection - Detects if a player was banned or kicked - Will NOT reconnect banned/kicked players - Prevents abuse of the reconnect system A05 #### Dynamic Fallback Mapping - Map source servers to specific fallback destinations - e.g. Survival → Survival-Lobby - Full control over reconnect routing A06 #### Customizable Notifications - Full control over hex-colors - Configurable reconnect message frequency - Keep players informed while they wait ### Commands & Admin Control Command | Description | Permission `/reconnectreload` | Reloads the config.yml without restarting the proxy | `smpreconnect.admin` `/reconnectdebug` | Toggles verbose logging in the console for troubleshooting | `smpreconnect.admin` `/vforward ` | Forwards a command to be executed by the backend server console. Requires the Bridge plugin installed on the target server. | `smpreconnect.forward` ### Technical Configuration Guide plugins/smp-reconnect/config.yml Example ``` # Servers that should NEVER trigger reconnect logic blacklisted_servers: - lobby - login # Map source servers to specific fallback destinations fallback_servers_map: survival: lobby skyblock: skyblock_lobby # Frequency (in seconds) to check if a server is back online ping_delay_seconds: 5 # What do the players see while waiting? reconnecting_message: "&aThe server is still starting up! You will be connected shortly..." ``` ### Quick Installation #### Download Download the SMP-Reconnect Proxy & Bridge plugins from GitHub or BuiltByBit. #### Install Proxy Place the main plugin into your Velocity `/plugins` folder. #### Install Bridge Place the Bridge plugin into your Spigot/Paper `/plugins` folder (optional, for /vforward). #### Done! Configure the fallback mapping. Your players are now protected from restarts! ### Questions before you commit? Support, licence keys, bug reports and feature requests all run through the Discord. Ask anything about SMP-Reconnect there — including whether it fits the server you already run. Already bought it? Your licence lives in the licence portal (https://license.ajdnikov-dev.com) — sign in there for your keys, or claim one with `/claim` in the Discord. Join the Discord (https://discord.gg/xyjmcjMp4W) Back to all plugins --- # SMP-Reconnect Documentation | ajdnikov URL: https://www.ajdnikov-dev.com/smp-reconnect/docs Updated: 2026-11-07 > SMP-Reconnect Documentation - Setup guide, configuration, and troubleshooting for the Velocity auto-reconnect plugin ## SMP-Reconnect Documentation Platform Velocity 3.x Java 17 Storage None Dependencies None Welcome to the SMP-Reconnect documentation! This plugin is a lightweight auto-reconnect solution for Velocity proxies that keeps players bridged during server restarts and crashes. Below you will find a complete guide to installation, configuration, and troubleshooting. ### Getting Started SMP-Reconnect is designed to solve one critical problem: player loss during server restarts . When a backend server goes down, instead of kicking players to the lobby or disconnecting them, the plugin holds them on the proxy and automatically reconnects them when the server is back online. #### Requirements - Java 17 or higher - Velocity Proxy 3.x+ - At least one backend server configured in Velocity #### Key Benefits - Zero player loss during scheduled restarts - Async architecture — no proxy lag - Smart detection — won't reconnect banned/kicked players - Flexible routing — map servers to specific fallbacks ### Installation #### Step 1: Download Download the latest `SMP-Reconnect.jar` from GitHub Releases (https://github.com/ajdnikov/SMPReconnect) or BuiltByBit (https://builtbybit.com/creators/ajdnikov.766669/). #### Step 2: Install ##### Proxy Plugin (Velocity) - Stop your Velocity proxy (recommended but not required) - Navigate to your Velocity `plugins/` directory - Place the `smp-reconnect-velocity.jar` (or normal jar) in this directory - Start (or restart) your Velocity proxy ##### Bridge Plugin (Spigot/Paper) - Optional If you want to use the `/vforward` command, install the bridge plugin on your backend servers: - Navigate to your backend server's `plugins/` directory - Place the `smp-reconnect-bridge.jar` file in this directory - Start (or restart) your backend server #### Step 3: Configure After the first startup, SMP-Reconnect will generate a `config.yml` inside `plugins/smp-reconnect/`. Edit this file to customize the plugin behavior for your network. ### Configuration Guide The configuration file is located at `plugins/smp-reconnect/config.yml`. Below is a breakdown of every option: #### Blacklisted Servers Servers listed here will never trigger the reconnect logic. Use this for lobby servers, login servers, or any server where you want standard Velocity disconnect behavior. ``` # Servers that should NEVER trigger reconnect logic blacklisted_servers: - lobby - login - auth ``` #### Fallback Server Map Define where players should wait while their original server restarts. If a player was on a server listed as a key, they will be sent to the corresponding fallback server to wait. ``` # Map source servers to specific fallback destinations fallback_servers_map: survival: lobby skyblock: skyblock_lobby creative: lobby ``` Example: If a player is on `survival` and it crashes, they will be sent to `lobby` and automatically reconnected to `survival` once it's back online. #### Ping Settings Controls how frequently the plugin checks if a downed server is accepting connections again. ``` # Frequency (in seconds) to check if a server is back online ping_delay_seconds: 5 ``` Recommendation: 5 seconds is a good default. Lower values mean faster reconnection but slightly more network activity. Higher values reduce overhead but delay reconnection. #### Reconnecting Message The message displayed to players while they are waiting to be reconnected. Supports Minecraft color codes including hex colors. ``` # What do the players see while waiting? reconnecting_message: "&aThe server is still starting up! You will be connected shortly..." ``` #### Full Example Config ``` # SMP-Reconnect Configuration # Plugin by ajdnikov # Servers that should NEVER trigger reconnect logic blacklisted_servers: - lobby - login # Map source servers to specific fallback destinations # Format: source_server: fallback_server fallback_servers_map: survival: lobby skyblock: skyblock_lobby # Frequency (in seconds) to check if a server is back online ping_delay_seconds: 5 # What do the players see while waiting? reconnecting_message: "&aThe server is still starting up! You will be connected shortly..." ``` ### How It Works Understanding the reconnect flow helps you configure the plugin optimally: #### Reconnect Flow - Server goes down — A backend server crashes or restarts - Player detection — The plugin detects all players who were on that server - Kick analysis — Checks if the disconnect was a ban/kick (these players are NOT reconnected) - Fallback routing — Players are sent to their mapped fallback server (or stay on proxy) - Async pinging — The plugin begins pinging the downed server at the configured interval - Notification — Players see the reconnecting message while waiting - Reconnection — Once the server responds to pings, all waiting players are automatically sent back #### Fail-Safe Protection The plugin intelligently distinguishes between different types of disconnections: - Server crash/restart: Player IS reconnected Yes - Player kicked by admin: Player is NOT reconnected No - Player banned: Player is NOT reconnected No - Server on blacklist: Normal Velocity behavior, no reconnect No ### Commands Command | Description | Permission `/reconnectreload` | Reloads the `config.yml` without restarting the proxy. Changes take effect immediately. | `smpreconnect.admin` `/reconnectdebug` | Toggles verbose logging in the console. Useful for troubleshooting reconnect issues. | `smpreconnect.admin` `/vforward ` | Forwards a command to be executed by the backend server console. Requires the Bridge plugin. | `smpreconnect.forward` ### Permissions Permission | Description | Default `smpreconnect.admin` | Access to all administrative commands (`/reconnectreload`, `/reconnectdebug`) | OP `smpreconnect.forward` | Allows using the `/vforward` command to send commands to backend servers | OP ### Fallback Mapping Guide The fallback mapping system is the core of SMP-Reconnect's routing logic. Here are some common network setups: #### Simple Network (1 Lobby) ``` # All servers fall back to the single lobby fallback_servers_map: survival: lobby skyblock: lobby creative: lobby prison: lobby ``` #### Multi-Lobby Network ``` # Each gamemode has its own lobby fallback_servers_map: survival: survival_lobby survival_nether: survival_lobby survival_end: survival_lobby skyblock: skyblock_lobby skyblock_nether: skyblock_lobby ``` #### Hub Network ``` # Everything falls back to the hub fallback_servers_map: smp1: hub smp2: hub minigames: hub # Don't reconnect from the hub itself blacklisted_servers: - hub ``` Important: Make sure your fallback servers are listed in `blacklisted_servers` so they don't trigger their own reconnect chains! ### Troubleshooting #### Q: Players are not being reconnected A: Check the following: - Ensure the server is NOT in the `blacklisted_servers` list - Verify the server has a fallback mapping in `fallback_servers_map` - Enable debug mode with `/reconnectdebug` and check the console logs - Make sure the server is actually accepting connections (check firewall, port binding) #### Q: Players get reconnected even when kicked A: This should not happen — the plugin has built-in kick/ban detection. If it does, enable debug mode and report the issue on our Discord (https://discord.gg/xyjmcjMp4W) with the console logs. #### Q: Reconnect takes too long A: Lower the `ping_delay_seconds` value in your config. The default is 5 seconds, but you can set it to 2-3 for faster detection. #### Q: Config changes aren't applying A: Use `/reconnectreload` to reload the config without restarting the proxy. Check for YAML syntax errors in your config file. #### Q: Need more help? A: Join our Discord server (https://discord.gg/xyjmcjMp4W) for support and bug reports, or open an issue on GitHub (https://github.com/ajdnikov/SMPReconnect). --- # AjdnikovGamemodes — Minigame Suite | ajdnikov URL: https://www.ajdnikov-dev.com/ajdnikovgamemodes Updated: 2026-11-08 > AjdnikovGamemodes is a Paper minigame plugin with seven minigames, a party system, a preloaded world pool, chat games and YAML or MySQL + Redis leaderboards. Skip to content ## AjdnikovGamemodes Paper / Spigot 1.20.4+ Java 17 v 1.3.4 Seven minigames — Death Swap, Manhunt, Man-Save, Speedrun VS, Achievement Speedrun, PvP Arena and Hide & Seek — plus tournaments, Hunt and Target events with a live public events page, parties, a preloaded world pool so a round starts without waiting on generation, chat games, random server-wide events, and points leaderboards that can be shared across a network over MySQL and Redis. Read the manual Get it on BuiltByBit (https://builtbybit.com/creators/ajdnikov.766669/) Ask in Discord (https://discord.gg/xyjmcjMp4W) ### What it talks to U01 U02 #### Ports FastAsyncWorldEdit is needed only for the void-map modes. Points live in YAML by default; MySQL shares them across servers, and Redis makes that instant. - FastAsyncWorldEdit - MySQL - Redis - Velocity / Bungee Patch field 4 RUNS - FastAsyncWorldEdit - MySQL - Redis - Velocity / Bungee ### Seven gamemodes A01 #### Death Swap - Every 2–5 minutes, all players swap positions - A warning shortly before each swap - Set traps — last player alive wins A02 #### Manhunt - One Runner must kill the Ender Dragon - Hunters track them with a compass and respawn - The Runner gets a head start A03 #### Man-Save - One Target must survive for the set time - Protectors respawn and win with the Target - The party leader edits the Protector kit A04 #### Speedrun VS - Race to obtain one random target item - Easy, Medium and Hard item pools - First to get it wins A05 #### Achievement Speedrun - Race to complete the same random advancements - 1–10 targets, picked by difficulty - Real advancement progress is restored afterwards A06 #### PvP Arena - Kit-based PvP on schematic maps - FFA, 2 Teams or 4 Teams - Needs FastAsyncWorldEdit A07 #### Hide & Seek - Invisible, silent hiders and one frozen Seeker - Hiders glow briefly on an interval - Needs FastAsyncWorldEdit ### Server events New in 1.3 B01 #### Tournaments - Free-for-all in a protected arena, last player standing wins - Seven preset kits, or save your own; custom schematic maps - Optional shrinking particle border and reward commands - Players' own items are saved and always given back B02 #### Hunt & Target - Hunt: track any player with a compass, hide with a craftable Hunter's Mask - Target: everyone gets a secret target in one shuffled loop - Kill and winner rewards run as commands B03 #### Live events page - A public events page per server: players, kill feed, winners and leaderboards - Never shows coordinates, IPs or your licence key - Optional Discord posts for starts and results ### Questions before you commit? Support, licence keys, bug reports and feature requests all run through the Discord. Ask anything about AjdnikovGamemodes there — including whether it fits the server you already run. Already bought it? Your licence lives in the licence portal (https://license.ajdnikov-dev.com) — sign in there for your keys, or claim one with `/claim` in the Discord. Join the Discord (https://discord.gg/xyjmcjMp4W) Back to all plugins --- # AjdnikovGamemodes Documentation | ajdnikov URL: https://www.ajdnikov-dev.com/ajdnikovgamemodes/docs Updated: 2026-11-08 > AjdnikovGamemodes Documentation - seven minigames, parties, points and leaderboards, YAML or MySQL + Redis storage, random events, chat games, the world pool and the full config.yml ## AjdnikovGamemodes Documentation Version 1.3.4 Platform Spigot / Paper 1.20.4+ Java 17 Storage YAML or MySQL Network MySQL + Redis Void maps need FAWE AjdnikovGamemodes runs seven minigames on one Spigot or Paper server, and several of them can run at the same time. It also includes tournaments, Hunt and Target events with a public live events page, parties, a points system with leaderboards, random server-wide events, chat minigames and a pool of pre-generated worlds. Points can be stored in YAML or MySQL/MariaDB. On a network, MySQL gives every server one shared leaderboard, and adding Redis makes changes show up on every server instantly. ### Overview #### New in 1.3.2 - Automatic updates — new versions download by themselves after a licence check and load on the next restart. - New settings appear on their own — new options are added to your `config.yml` with their comments, and your values stay. #### What's new in 1.3 - Tournaments — free-for-all fights in protected arenas with preset or custom kits, a shrinking particle border, custom schematic maps and reward commands. - Hunt and Target events — track players with a compass (and hide from trackers with the Hunter's Mask), or hunt a secret target in one shuffled loop. - Public events page — every licensed server gets a live page on ajdnikov-dev.com with players, kill feed, winners and leaderboards, plus optional Discord posts. - Item rescue — items from other plugins (StrengthSMP tokens, AnziLifesteal hearts) are no longer lost when game worlds reset. - Turn gamemodes on or off with `/ag gamemodes`, and `/events gui` for one menu over tournaments, arenas, kits, hunt, target, the web page and Discord. #### New in 1.2 - Achievement Speedrun — a seventh gamemode: race to complete the same random advancements. - Chat games — scramble, math, trivia and quick-type rounds in chat that award points. - MySQL / MariaDB storage for points, with an optional Redis add-on for instant cross-server leaderboards, and `/ag storage migrate` to move existing data. - Queued, crash-safe point writes: database outages are retried, and unsent changes survive a shutdown in `pending-points.yml`. #### Requirements | Server | Spigot or Paper, 1.20.4 or newer (`api-version: 1.21`) Java | 17 or newer Optional | FastAsyncWorldEdit (or WorldEdit). Required for PvP Arena and Hide & Seek, which paste schematic maps. Optional | MySQL 5.7+/8.x or MariaDB 10.3+, if you use `storage.type: MYSQL` Optional | Redis 5+, as an add-on to MySQL for instant cross-server updates (`redis.enabled`) License | A licence key, which you receive in the Discord with `/claim` The server needs internet access on first start. It downloads the database libraries (HikariCP, Jedis and MySQL Connector/J) from Maven Central, checks the licence, and looks for updates. No world-management plugin is needed: worlds are created and managed internally, so Multiverse-Core is not required. ### Installation & License - Put `AjdnikovGamemodes-.jar` in `plugins/`. If you want PvP Arena or Hide & Seek, install FAWE as well. - Start the server once. This creates `plugins/AjdnikovGamemodes/config.yml`. - Paste your licence key into `license.key` and restart. - In the lobby, stand where players should return to and run `/ag setlobby`. - Optionally, switch storage to MySQL, or MySQL + Redis. See Storage . On the first start with `world-pool.enabled: true`, the plugin generates the preloaded survival worlds in the background, which can take a few minutes. Survival gamemodes start instantly once the pool is ready. #### AnziLock License AjdnikovGamemodes is protected by AnziLock . Licence keys are issued through the Discord community — use `/claim` there, then set it in `config.yml`: ``` license: key: "YOUR_LICENSE_KEY_HERE" ``` If the licence is invalid, the plugin stops right after the check and none of the features load. The console says why. #### Automatic Updates Since 1.3.2, AjdnikovGamemodes updates itself. When a new version is released, it checks your licence again, downloads the new jar into `plugins/update`, and the server loads it on the next restart. The file is kept only if its size and checksum match the signed licence answer. Nothing changes while the server is running. - Turn it off with `auto-update: false` in `config.yml`. Admins then get the "new version available" notice instead. - Players with `ajdnikovgamemodes.updates` (ops by default) are told on join when a new version is waiting for a restart. - New settings are added to `config.yml` on every start, with their comments. Your values stay, and the old file is kept as `config.yml.bak`. `messages.yml` fills in new messages by itself; `kits.yml` is never touched. - Coming from 1.3.1 or older? Install 1.3.2 or newer by hand once. Every later version arrives by itself. How the download is checked: AnziLock → Automatic Updates . #### Support Dumps Since 1.3.4, `/ag dump` makes a private link for support. The page shows AjdnikovGamemodes's own log next to the full server log, and your server's setup: software and version, uptime, TPS, RAM, disk, CPU, Java, worlds, every plugin, and `config.yml` with keys, passwords and webhooks blanked out. Only you see the link in chat: click it, or click [Copy] , and send it to whoever helps you on Discord (https://discord.gg/xyjmcjMp4W). - `/ag dump 6` covers only the last 6 hours. `/ag dump local` uploads nothing and saves the dump in `plugins/AjdnikovGamemodes/dumps/` as a readable `.txt` and a `.json.gz`. - On the page you can filter and search both logs, show only the lines about AjdnikovGamemodes (stack traces included), and save everything to your PC as `.txt` or `.json`. A saved `.json` opens again at `license.ajdnikov-dev.com/dump` after the link has expired. - The link works for `dump.link-hours` (24 by default, at most 168). You can remove it sooner on your licence page under Dumps . - IP addresses are replaced with `x.x.x.x` unless you set `dump.hide-ips: false`. - Needs `ajdnikovgamemodes.dump` (ops by default). ``` dump: # Hours of AjdnikovGamemodes's log to keep on disk (dump-logs/) and put in a dump. log-hours: 48 # How long the link works, in hours (at most 168). link-hours: 24 # Replace IP addresses in the logs with x.x.x.x. hide-ips: true ``` What a dump contains and how long it is kept: AnziLock → Support Dumps . ### Quick Start ``` /party create friends # you become the leader (invite-only by default) /party invite Steve # Steve gets a clickable invite /party settings # optional: choose roles, PvP mode, difficulty... /game start manhunt # starts Manhunt with every online party member ``` When a game ends, players see a scoreboard of the points they earned. Their inventory, XP, health, effects, gamemode, location and respawn point are then restored to what they had before the game. ### Gamemodes Every game needs at least 2 players. Each one ends when its own win condition is met or when its time limit runs out. Turning gamemodes off. `/ag gamemodes` opens a menu where you click a gamemode to enable or disable it (`/ag gamemodes enable|disable ` and `/ag gamemodes list` work from the console). This sets `games..enabled` in config.yml. A disabled mode can't be started with `/game start`, is hidden from tab completion and never comes up as a random event. Gamemode | `/game start …` | World | How it works Death Swap | `deathswap` | Survival | Every 2–5 minutes (random) all players swap positions, with a warning shortly before. Set traps so whoever lands in your spot dies. Last player alive wins. Manhunt | `manhunt` | Survival | One Runner gets a head start and must kill the Ender Dragon. Hunters get a tracking compass (right-click to update it, with a cooldown) and win by killing the Runner. Hunters respawn when they die. Man-Save | `mansave` | Survival | One Target must survive for `survive-time`. Everyone else is a Protector . Protectors respawn and win together with the Target if the Target survives. If the Target dies, nobody wins. The party leader can edit the Protector starting kit. Speedrun VS | `speedrunvs` | Survival | Everyone races to obtain one random target item. The party leader picks the difficulty pools: Easy (dirt, logs, coal…), Medium (iron, diamonds, blaze rods…), Hard (netherite, elytra, dragon egg…) or All. First to get it wins. Achievement Speedrun | `achievementspeedrun` | Survival | Everyone races to complete the same randomly chosen advancements (`target-count`, 1–10). First to finish all of them wins. At the time limit, the player with the most wins, and ties go to whoever got there first. Real advancement progress is reset for the race and restored afterwards. PvP Arena | `pvparena` | Schematic map | Kit-based PvP on a random map from `PvPArenaMaps/`. Modes: FFA (last player standing), 2 Teams or 4 Teams (last team standing). The leader picks the mode and can assign teams; otherwise teams are balanced at random. Hide & Seek | `hideandseek` | Schematic map | One Seeker is frozen and blinded while the Hiders , who are invisible and silent, hide during `hide-time`. Then the Seeker is released for `seek-time`, and a hit finds (eliminates) a hider. Hiders glow briefly every `hider-glow-interval` seconds. Seekers win if they find everyone; hiders win if anyone survives. - Roles (Runner, Target, Seeker) are random unless the party leader picks a player in `/party settings`. - Nether and End: survival games use the server's normal Nether and End. The plugin keeps track of which players and dragon belong to which game, so games running at the same time don't interfere. - During a game , players are frozen and can't take damage while the countdown runs. Everyone gets their own scoreboard. Players who disconnect are removed from the game and their items are restored. If the server crashes mid-game, players get their items back the next time they join. ### Parties Games are started with a party. Every online member who is not already in a game joins the game. Command | Who | Description `/party create [open]` | anyone | Create a party (name up to 16 characters). With `open`, anyone can join, and a clickable join message is sent to everyone online. `/party invite ` | leader | Send a clickable invite. `/party join ` | anyone | Join an open party or one that invited you. `/party leave` | member | Leave the party. If the leader leaves, the next member becomes leader. `/party kick ` | leader | Remove a member. `/party disband` | leader | Delete the party. `/party list`, `/party info [name]` | anyone | Show the members and who is online. `/party settings` | leader | Open the settings GUI. #### Settings GUI One page per gamemode: - PvP Arena: cycle the mode (FFA / 2 Teams / 4 Teams) and assign players to teams. - Manhunt / Man-Save / Hide & Seek: choose the Runner, Target or Seeker, or leave it on Random . - Man-Save: edit the Protector kit. Click items in your inventory to copy them in, and click kit items to remove them. - Speedrun VS: toggle the Easy, Medium and Hard item pools, or All. Easy is the default. - Achievement Speedrun: toggle the advancement difficulties and cycle how many advancements to complete. Disconnects: a member who disconnects stays in the party for 5 minutes, and the party is told so. If they reconnect within that time they are simply back in the party; otherwise they are removed. Admins can put anyone into a party with `/ag partyadd `. If the party doesn't exist yet, it is created. ### Points & Leaderboards Players earn points for playing. The amounts come from the `points:` section of the config: Key | Default | When `participation` | 1 | Every player, when the game starts `win` | 10 | Each winner (every member of the winning team) `kill` | 2 | Killing another player in a game `survive` | 5 | Reserved. Not awarded by any gamemode yet. `advancement` | 1 | Each target advancement completed in Achievement Speedrun `chat-game` | 3 | Being first to answer a chat game Games started as a random event multiply every award by `random-events.points-multiplier`. - `/ag stats [player]` shows a player's total, and `/ag top` shows the top 10. - Admins can change totals with `/ag points `. Totals never go below 0. #### Holographic leaderboards Place an armor stand, look at it and run `/ag setleaderboard`. The stand becomes an invisible marker and a hologram with the top 3 players appears above it, refreshing every `leaderboard.update-interval` seconds. `/ag removeleaderboard` removes the nearest one (within 5 blocks), and `/ag purgeleaderboards` removes all of them. Breaking the anchor stand also removes its hologram. ### Storage: YAML, MySQL, Redis Choose one of three setups. Settings are read at start-up, so restart after changing them — `/ag reload` does not switch storage. Setup | Config | Best for | Shared between servers YAML (default) | `storage.type: YAML` | A single server, no setup | No — it uses `playerdata.yml` MySQL | `storage.type: MYSQL` | Networks and backups; also works with MariaDB | Yes. Other servers pick up changes within `top-refresh-seconds`, or when the player joins. MySQL + Redis | `storage.type: MYSQL` + `redis.enabled: true` | Networks that want live leaderboards | Yes, instantly MySQL is always where points are stored. Redis doesn't store any points — it only tells the other servers about each change as it happens, so if Redis goes down nothing is lost and servers go back to refreshing from MySQL. Only points are stored in the backend: the lobby spawn, hologram positions, map spawns and crash-recovery inventory snapshots are per-server and stay in local files. #### How writes work - Reads (scoreboards, `/ag stats`, holograms) come from memory and never wait on the database. - Every change updates memory at once and is written by a single background thread, in order. MySQL applies increments atomically (`points = points + n`), so two servers awarding points at the same time never overwrite each other. - If the database goes down , changes are queued and retried every 5 seconds. The console logs the outage about once a minute and again when the connection is back. If the server stops while changes are still queued, they are saved to `pending-points.yml` and replayed on the next start. - With MySQL, a player's points are loaded when they join, and the top 10 is re-read every `storage.top-refresh-seconds`. #### MySQL / MariaDB ``` storage: type: MYSQL mysql: host: "db.example.com" port: 3306 database: "ajdnikovgamemodes" # must already exist username: "gamemodes" password: "change-me" table-prefix: "ag_" use-ssl: false ``` Create the database and a user; the plugin creates its table on first connect: ``` CREATE DATABASE ajdnikovgamemodes CHARACTER SET utf8mb4; CREATE USER 'gamemodes'@'%' IDENTIFIED BY 'change-me'; GRANT SELECT, INSERT, UPDATE, CREATE, INDEX ON ajdnikovgamemodes.* TO 'gamemodes'@'%'; ``` The data goes into one table, `players`, with the columns `uuid` (primary key), `name`, `points` and `updated_at`. You can query it directly for websites or Discord bots, e.g. `SELECT name, points FROM ag_players ORDER BY points DESC LIMIT 10;` Pool tuning lives under `storage.mysql.pool`, and extra JDBC driver options under `storage.mysql.properties`: ``` properties: serverTimezone: "UTC" allowPublicKeyRetrieval: true # MySQL 8 with caching_sha2_password and use-ssl: false ``` #### MySQL + Redis With MySQL alone, a server only sees points earned on another server after its next top-list refresh or when the player rejoins. Add Redis to make those changes show up instantly: ``` storage: type: MYSQL mysql: # ... as above redis: enabled: true host: "redis.example.com" port: 6379 password: "change-me" key-prefix: "ag:" server-id: "minigames-1" # optional, but makes logs easier to read ``` Each change is published on the Redis channel `sync`, and every other server updates its scoreboards and holograms right away. Every server must point at the same MySQL database and the same Redis, and use the same `key-prefix`. Redis needs no persistence. Redis 6+ ACL users go in `redis.username`; use `redis.ssl: true` for TLS-only providers. `redis.enabled` has no effect with YAML storage, and the plugin warns if you try. #### Moving your data `/ag storage migrate ` copies every player between `yaml` and `mysql`, in either direction. Players who already exist in the target are overwritten; other records are left alone. Typical switch from YAML to MySQL: - Fill in `storage.mysql` but keep `type: YAML`, then run `/ag reload`. The migration reads the connection details from the loaded config. - Run `/ag storage migrate yaml mysql`. - Set `storage.type: MYSQL` and restart. `/ag storage info` shows the active backend, whether it is connected, how many writes are queued and whether Redis is connected. ### Random Events Every `min-interval-minutes` to `max-interval-minutes`, a random gamemode is announced to everyone with a clickable [CLICK TO JOIN] (or `/game join`). When the countdown (`announcement-countdown-seconds`) ends, the game starts with everyone who joined, as long as at least `min-players-to-start` joined. Event games award `points-multiplier` × points. Set `discord-webhook-url` to also post the announcement to Discord. Command | Description `/ag randomevent toggle` | Turn automatic events on or off. `/ag randomevent start [gamemode]` | Start an event now, optionally for a specific gamemode. `/ag randomevent info` | Scheduler state, countdown and queued players. `re` is a short alias for `randomevent`. ### Chat Games Every `min-interval-minutes` to `max-interval-minutes`, when at least `min-players` players are online, a question is posted in chat. The first correct answer wins `points.chat-game` points. If nobody answers within `answer-time-seconds`, the answer is revealed. Type | Players have to… `scramble` | Unscramble a word from `chat-games.scramble.words` `math` | Solve an arithmetic problem (numbers up to `math.max-number`) `trivia` | Answer a question from `chat-games.trivia.questions`. Several accepted answers are allowed; case and punctuation are ignored. `quicktype` | Type a random code exactly, case-sensitive (`quicktype.length`, 4–20 characters) Admin control: `/ag chatgame start [type]`, `stop`, `toggle` and `info` (`cg` is a short alias). `/ag reload` applies new words, questions and intervals. ``` chat-games: trivia: questions: - question: "Which mob drops blaze rods?" answers: ["blaze", "blazes"] ``` ### Worlds & the World Pool - Survival gamemodes (Death Swap, Manhunt, Man-Save, Speedrun VS, Achievement Speedrun) take a world from the preloaded pool (`ag_preloaded_N`). The chunks around spawn are generated ahead of time, so games start instantly. After the game, the world is restored from a clean backup and goes back into the pool. - Schematic gamemodes (PvP Arena, Hide & Seek) use void worlds (`ag_game_N`, up to `worlds.game-slots` at once). They are created for the game and deleted afterwards. - If no world is free, `/game start` says there are no free game slots. #### Pool settings (world-pool:) - `max-preloaded-worlds` sets how many survival games can run at once. Each world uses disk space. - `preload-radius` plus `preload-performance` control how fast generation runs versus how much it lags the server. Use `chunks-per-tick` around 20 on weak hosts and 100+ on strong ones. - `auto-replenish` generates missing worlds in the background, but only while fewer than `player-threshold` players are online. - `daily-regeneration` replaces every pool world with a fresh seed at `time` (HH:mm). If `kick-players-if-active` is false, it skips the regeneration while games are running. Setting `world-pool.enabled: false` generates survival worlds when a game starts instead, which is slower. ### Map Setup (PvP Arena & Hide & Seek) Both modes need FAWE and at least one map. - Put `.schem` files (or `.litematic`, if your FAWE version supports it) in `plugins/AjdnikovGamemodes/PvPArenaMaps/` or `plugins/AjdnikovGamemodes/HNSmaps/`. - Run `/setup setspawns `. You are put in creative mode in a temporary world with the map pasted in. Your inventory is saved and given back afterwards. - Use the tools in your hotbar: - Hide & Seek: click a block with the blaze rod to set the spawn point. - PvP Arena: use the blaze rod to set the FFA area (left-click corner 1, right-click corner 2), then the wool blocks to set the Red, Blue, Green and Yellow team spawns. Red and Blue are required; Green and Yellow are only needed for 4 Teams. - Run `/setup confirm` to save to `.yml` next to the schematic, or `/setup cancel` to abort. A random map is chosen each game. Maps are pasted at 0, 64, 0. ### Tournaments Free-for-all fights in a protected arena with a kit the admin picks. Last player standing wins. Several tournaments can run at once, one per arena (`tournament.max-concurrent`). Everything below can also be done in `/tournament gui`. #### Admin setup - Create an arena. Run `/tournament wand`, left-click one corner block and right-click the opposite corner (or stand on each corner and use `/tournament pos1` and `/tournament pos2`). Then run `/tournament create `. The region is protected straight away: no breaking, placing, explosions, liquid flow, fire spread, pistons or mob griefing (see `arena-protection`). WorldGuard isn't needed. - Add spawn points. Stand inside the arena and run `/tournament setspawn ` once per spawn. You need at least 2. No spawn is used twice until every one has been used, so spawns are only shared when there are more players than spawns. Manage them with `/tournament listspawns ` and `/tournament removespawn `. - Pick or make a kit. Seven presets ship in `kits.yml`: `dia_smp`, `smp` (netherite), `sword`, `mace` (1.21+), `axe`, `uhc` and `nethpot`. To make your own, fill your inventory and run `/tournament savekit `, or edit kits by drag and drop in `/tournament gui` → Kits (effects, icon and name are set there too). - Set the elimination lobby (optional). By default eliminated players go to the server lobby (`/ag setlobby`). `/tournament setlobby` uses your position instead; `/tournament resetlobby` goes back. - Start. `/tournament start ` broadcasts a clickable join button and the events page link. Players join with `/tournament join`. - Ready. When enough players are in, `/tournament ready` starts the countdown (`countdown-seconds`, default 10). Players are frozen and can't hurt anyone until it reaches 0. #### What happens to players - Joining saves the player's inventory, armour, offhand, XP, health, hunger and effects to `inventory_saves/.yml` before anything is cleared. They are teleported to a spawn and get the kit after `kit-delay-seconds` (everyone gets it at `/tournament ready` at the latest). - Dying eliminates the player. Kit items never drop. They respawn at the elimination lobby with their own items back. - Logging out counts as an elimination; their items are restored before they leave. `/tournament leave` before the fight just gives everything back; during the fight it counts as an elimination. - The end comes when one player is left, or with `/tournament stop`. Everyone still in gets their items back and is sent to the lobby, the winner is announced and `reward-commands` run for them. - A crash or restart never loses items: snapshots stay on disk and are restored the next time each player joins. On a normal shutdown or `/reload`, running tournaments are stopped and everyone is restored first. #### Restrictions during a tournament Participants can't open ender chests (by block or by command), can't use any command in `tournament.restrictions.blocked-commands` (namespaced forms such as `essentials:ec` are caught too), can't walk or pearl out of the arena, and can't drop items. Each rule has a toggle. Ender chests inside arenas are blocked for everyone. `ajdnikovgamemodes.tournament.bypass` ignores the command list. Only the sides of the arena limit players: they can move from bedrock up to the build limit, so they can climb a mountain or go down a cave even if it is above or below the region you selected (`tournament.restrictions.full-height`; turn it off to make the region's height a hard limit). Arena protection covers the same height (`arena-protection.full-height`). #### Mobs While a tournament runs, no mobs spawn anywhere in its arena (`tournament.mobs.block-spawning`), and hostile mobs are removed at the start and every 5 seconds (`tournament.mobs.remove-hostile`; named mobs are kept). Other plugins and `/summon` can still spawn things. #### Shrinking border Set `tournament.border.enabled: true` (or `/tournament gui` → Shrinking border) for a border that closes in during the fight. It is a wall of particles, not the vanilla world border, so the arena can sit in a world where other people are playing; only tournament players see it (`show-to-nearby-players` shows it to everyone in that world). It starts at `start-size` blocks from the arena centre (0 = fit the arena), waits `delay-seconds` after FIGHT, then shrinks to `end-size` over `shrink-seconds`. Players outside take `damage-per-second`. `shape` is `SQUARE` or `CIRCLE`; `particle`, `color`, `view-distance` and `spacing` change how it looks (bigger spacing = less lag). #### Custom maps Put `.schem` or `.litematic` files in `plugins/AjdnikovGamemodes/TournamentMaps/` (WorldEdit or FAWE needed). Then run `/tournament importmap [arena]`, or open `/tournament gui` → Custom maps and click a map. The map is pasted into its own void world (`tournament.maps.world`, no mobs, always day), each map `spacing` blocks apart, and becomes a normal arena around the pasted blocks (plus `margin`). You are teleported there; add spawns with `/tournament setspawn ` and start it like any other arena. - `/tournament savemapspawns ` writes the spawns to `.yml` next to the file, so importing the map again (here or on another server) loads them automatically. PvP Arena maps set up with `/setup` can be copied over with their `.yml`; their team spawns are used. - `/tournament resetmap ` pastes the map again. With `tournament.maps.reset-after-tournament: true` this happens after every tournament on it. - `/tournament maps` lists the files and which arenas use them. ### Hunt Event `/hunt start` and `/hunt end` (both broadcast). While the hunt runs, any player can use `/hunt ` to track someone: they get a compass pointing at the target and the distance in their action bar, updated every second. There is a cooldown (`hunt.cooldown-seconds`). `/hunt stop` stops tracking. Tracking also stops when the event ends or the target logs out. Hunter's Mask. A carved pumpkin crafted with the shaped recipe in `hunt.mask.recipe` (default: leather around an eye of ender and a carved pumpkin). Wearing it makes you impossible to track, including by someone who was already tracking you; they are told the trail is lost. Only a real mask works: it is recognised by hidden item data, not by its name, so renamed pumpkins do nothing. By default it can only be crafted while the hunt runs (`hunt.mask.craft-only-during-event`). It can't be placed or used in other recipes. Admins can hand one out with `/hunt givemask [player]`. Players with `ajdnikovgamemodes.hunt.exempt` can't be tracked. Players in a tournament can't be tracked unless `hunt.allow-in-tournaments` is on. ### Target Event `/target start` gives every online player with `ajdnikovgamemodes.target.join` a secret target (players in a tournament or minigame are left out unless `target.exclude-busy-players` is off). The targets form one shuffled loop, so nobody gets themselves. `/bounty` works as an alias. - Killing your target runs `target.kill-reward-commands`, and you take over your victim's target. - Only a kill by your hunter takes you out. Dying to mobs, falls or other players doesn't. - If a player logs out they leave the loop, and whoever was hunting them gets their target. - The last player left wins and `target.winner-reward-commands` run. With `max-duration-minutes`, the player with the most kills wins when time is up (a tie means no winner). - `/target info` shows your target, your kills and how many players are left. `/target end` stops it with no winner. ### Public Events Page Every licensed server gets a public page on ajdnikov-dev.com/events showing its live and recent tournaments, hunts and targets: players, eliminations, kill feed, countdown, winners, history and wins/kills leaderboards. Players get the link with `/events link`; it is also added to start broadcasts and Discord posts. You'll find it, with a copy button, on your licence page at license.ajdnikov-dev.com (https://license.ajdnikov-dev.com). - The page only shows player names, kills and results. It never shows coordinates (not even during a hunt), IPs or your licence key. The page address is a random id, not your key. - Updates are sent in small batches in the background. If the site can't be reached, events keep working normally; the console shows one warning and updates are retried. - Your licence comes with one page. Staff can allow more (for example one per server on a network). Each server picks its page with `web-events.feed`; servers using the same name share a page. On the licence page you can remove a page or give it a new link if the old one was shared somewhere it shouldn't be. - Turn it off completely with `web-events.enabled: false`. ``` web-events: enabled: true feed: "main" # servers with the same name share a page display-name: "" # page title (empty = the page name) server-name: "" # label on each event, for shared pages flush-interval-seconds: 3 link-in-broadcasts: tournament: true hunt: true target: true event-discord: webhook-url: "" # posts starts, winners and results with the page link tournament: true hunt: true target: true ``` ### Item Rescue Game worlds are deleted or reset after every game, and each player's game inventory is replaced by their saved one. Without help, items from other plugins that were picked up or dropped during a game would be lost. The `item-rescue` section (on by default) keeps them. Out of the box it covers StrengthSMP's Strength Tokens and AnziLifesteal's Heart and Revive Beacon items. - An item dropped when a player dies belongs to the killer. If nobody picks it up, the killer gets it when the game ends (they are told so at the kill). After a natural death (lava, fall, mobs), the last player who hit the victim counts as the killer; with no attacker at all, the dead player gets it back. - Items a player threw on the ground with Q go back to that player. - Matching items in a player's inventory at the end are given back after their normal inventory is restored. - Offline players get them when they next join (stored in `rescued-items.yml`). ``` item-rescue: enabled: true nbt-contains: # all words of an entry must appear in the item's NBT - "paper strength" # StrengthSMP tokens (not vanilla Strength potions) pdc-namespaces: # data tags from these plugins - strengthsmp - anzilifesteal name-contains: [] materials: [] custom-model-data: [] keep-from-inventory: true auto-detect-death-drops: true # custom items another plugin adds on death debug: false ``` If an item is still lost, hold one and run `/ag itemrescue check` to see whether it matches and to see its NBT. Add a few of its words to `nbt-contains`, then `/ag reload`. `debug: true` logs every death drop and how it was handled. Items lying in the shared Nether/End are not touched, and the server must stop normally (not crash) for them to be kept. AnziLifesteal: while a player is in a game, AjdnikovGamemodes marks them with the `ajdnikovgamemodes_in_game` metadata. An up-to-date AnziLifesteal reads it (`minigame-protection`, on by default), so no hearts are lost or stolen in games, including deaths in the shared Nether/End. ### Commands #### Players (ajdnikovgamemodes.play) Command | Description `/game list` | List gamemodes and the number of active games `/game join` | Join the current random-event queue `/party …` | Party commands, see Parties `/tournament join [arena]` · `leave` · `list` | Join, leave or list tournaments (`.tournament.join`). Aliases `/tourney`, `/tourn`. `/hunt ` · `/hunt stop` | Track a player during the hunt (`.hunt.use`) `/target info` | Your target and players left `/events link` | Link to this server's public events page (`.events.link`) #### Game hosts (ajdnikovgamemodes.game) Command | Description `/game start ` | Start a game with your party `/game start all` | Start with every online player who isn't in a game (also needs `.admin`) `/game stop` | Stop your current game. Admins who aren't in a game force-stop the first active game. #### Admins (ajdnikovgamemodes.admin) Command | Description `/ag setlobby` | Set the lobby spawn to your location `/ag setleaderboard` · `removeleaderboard` · `purgeleaderboards` | Manage leaderboard holograms `/ag points ` | Change a player's points `/ag stats [player]` · `/ag top` | Show a player's points, or the top 10 `/ag partyadd ` | Force a player into a party `/ag randomevent ` | Random events (alias `re`) `/ag chatgame ` | Chat games (alias `cg`) `/ag storage info` | Storage backend and connection status `/ag storage migrate ` | Copy points between `yaml` and `mysql` `/ag reload` | Reload config.yml, messages.yml, arenas.yml and kits.yml (storage/Redis changes need a restart) `/ag gamemodes [enable|disable|list] [mode]` | Turn gamemodes on or off (menu without arguments) `/ag dump [hours] [local]` | A private link with the plugin's log, the full server log and your server's setup, for support. See Support Dumps `/ag itemrescue check` | Show whether the item in your hand is kept after games, and its NBT `/setup ` | Map setup, see Map Setup `/events gui` | One menu for tournaments, arenas, kits, hunt, target, web page and Discord #### Tournament admins (ajdnikovgamemodes.tournament.admin) Command | Description `/tournament gui` | Manage everything in a menu `/tournament start ` | Open a tournament and broadcast the join button `/tournament ready [arena]` | Start the countdown; the fight begins at 0 `/tournament stop [arena]` | End it with no winner; everyone gets their items back `/tournament wand` · `pos1` · `pos2` | Select an arena region `/tournament create ` · `redefine ` · `delete ` | Create, resize or delete an arena `/tournament setspawn ` · `removespawn [n|nearest]` · `listspawns ` | Spawn points `/tournament arenas` · `tp ` · `setmax ` | List, visit, per-arena player limit (0 = config) `/tournament savekit ` · `deletekit ` · `kits` | Save your inventory as a kit, delete, list `/tournament kit presets [overwrite]` | Add the shipped preset kits back `/tournament setlobby` · `resetlobby` | Where eliminated players go `/tournament maps` · `importmap [arena]` | List custom maps, import one as an arena `/tournament resetmap ` · `savemapspawns ` | Paste a map again, save its spawns to the map file #### Event admins Command | Permission | Description `/hunt start` · `end` · `givemask [player]` · `gui` | `.hunt.admin` | Run the hunt, hand out a mask, settings `/target start` · `end` · `gui` | `.target.admin` | Run the target event, settings ### Permissions Permission | Default | Grants `ajdnikovgamemodes.play` | everyone | `/game list|join`, `/party` `ajdnikovgamemodes.game` | OP | `/game start`, `/game stop` `ajdnikovgamemodes.admin` | OP | `/ag`, `/setup`, `/events gui`, `/game start … all`, force-stopping other games, and update notifications. Includes every admin permission below. `ajdnikovgamemodes.tournament.admin` | OP | Arenas, kits, `/tournament start|ready|stop|gui` `ajdnikovgamemodes.tournament.join` | everyone | `/tournament join` `ajdnikovgamemodes.tournament.bypass` | OP | Use blocked commands during a tournament `ajdnikovgamemodes.arena.bypass` | OP | Build inside arenas (creative mode, not while playing) `ajdnikovgamemodes.hunt.admin` | OP | `/hunt start|end|givemask|gui`, no `/hunt` cooldown `ajdnikovgamemodes.hunt.use` | everyone | `/hunt ` `ajdnikovgamemodes.hunt.exempt` | nobody | Can't be tracked `ajdnikovgamemodes.target.admin` | OP | `/target start|end|gui` `ajdnikovgamemodes.target.join` | everyone | Takes part when the target event starts `ajdnikovgamemodes.events.link` | everyone | `/events link` `ajdnikovgamemodes.updates` | OP | Told on join when a new version has been downloaded and is waiting for a restart `ajdnikovgamemodes.dump` | OP | `/ag dump` (also needs `ajdnikovgamemodes.admin` for `/ag`) ### Game Settings Every gamemode under `games:` has a `time-limit` in seconds. If it's missing, `games.global.time-limit` (1800) is used. Key | Default | Meaning `deathswap.min-swap-time` / `max-swap-time` | 120 / 300 | Random time between swaps (seconds) `deathswap.warning-time` | 5 | Warning before a swap (seconds) `manhunt.runner-head-start` | 30 | Seconds before hunters are released `manhunt.compass-cooldown` | 30 | Seconds between compass updates `hideandseek.hide-time` / `seek-time` | 60 / 300 | Length of each phase (seconds) `hideandseek.hider-glow-interval` | 30 | Seconds between hider glow pulses `mansave.survive-time` | 600 | How long the Target must survive (seconds) `pvparena.max-time` | 300 | Round length (seconds) `achievementspeedrun.target-count` | 5 | Advancements to race for (1–10). Leaders can override it in the GUI. `achievementspeedrun.allow-pvp` | false | Whether racers can hurt each other `achievementspeedrun.pool.easy|medium|hard` | built-in | Optional custom advancement lists (e.g. `story/mine_stone`) #### Other sections Section | Purpose `auto-update` | Download new versions automatically; they load on the next restart. See Automatic Updates . `proxy` | BungeeCord/Velocity settings (`enabled`, `lobby-server`). Players currently return to where they were before the game, not to another server. `lobby` | Lobby world and spawn — set it in game with `/ag setlobby` `worlds` | `game-slots` (maximum void-world games at once) and `prefix` `leaderboard.update-interval` | How often holograms refresh, in seconds `item-rescue` | Items from other plugins kept after games, see Item Rescue `tournament` | Player limits, countdown, kit delay, sounds, lobby, rewards, `restrictions`, `mobs`, `border` and `maps`, see Tournaments `arena-protection` | What is blocked inside arenas `hunt` | Cooldown, compass, Hunter's Mask name and recipe, see Hunt Event `target` | Players, rewards, time limit, see Target Event `web-events` · `event-discord` | Public events page and its Discord webhook, see Public Events Page Player-facing text for tournaments, hunt, target, arenas and kits is in `messages.yml` (`&` colour codes and hex colours as `&#RRGGBB`; set a message to `""` to turn it off). Kits are in `kits.yml`. Settings changed in a GUI are saved to config.yml straight away. ### Files & Update Checker All of these are in `plugins/AjdnikovGamemodes/`: File / folder | Contents `config.yml` | Configuration `playerdata.yml` | Points, when using YAML storage `pending-points.yml` | Point changes that couldn't reach MySQL before a shutdown. Replayed on the next start, then deleted. `leaderboards.yml` | Hologram positions `inventory_saves/` | Pre-game player snapshots, restored after a crash `PvPArenaMaps/`, `HNSmaps/`, `TournamentMaps/` | Schematics and their `.yml` spawn files `messages.yml` | Text for tournaments, hunt, target, arenas, kits and the events page `arenas.yml` | Tournament arenas: regions, spawns, player limits `kits.yml` | Tournament kits (presets plus your own) `web-events.yml` | Cached link of this server's events page. Safe to delete. `rescued-items.yml` | Kept items waiting for players who were offline when their game ended `dump-logs/` | The plugin's log for support dumps , one file per hour, kept for `dump.log-hours` `dumps/` | Dumps saved with `/ag dump local`, or when an upload failed After an update, `config.yml.bak` holds your config as it was before the new settings were added. #### Update checker With automatic updates on (the default), new versions are downloaded for you and players with `ajdnikovgamemodes.updates` are told when one is waiting for a restart. With `auto-update: false`, the plugin only checks for a newer release on start-up, asynchronously, so it never delays the server. If the running version is outdated, the console says so, and players with `ajdnikovgamemodes.admin` get a clickable download link when they join. ### Full config.yml The default configuration shipped with 1.3.2. Every option carries a comment. ``` # ======================================== # AjdnikovGamemodes Configuration # ======================================== license: # Insert the license key you received via Discord here (see /claim). key: "" # Download new versions of AjdnikovGamemodes automatically when they are released. # They are checked against your license and load on the next restart. # Players with ajdnikovgamemodes.updates (ops by default) are told when one is waiting. auto-update: true # /ag dump makes a private link with the plugin's log, the full server log and the server's setup # to share with support. "dump local" only saves it in plugins/AjdnikovGamemodes/dumps/. dump: # Hours of the plugin's log to keep on disk (dump-logs/) and put in a dump. log-hours: 48 # How long the link works, in hours (at most 168). link-hours: 24 # Replace IP addresses in the logs with x.x.x.x. hide-ips: true # ======================================== # Storage Settings # ======================================== # Where player points are stored. Changes need a server restart (not /ag reload). # YAML - plugins/AjdnikovGamemodes/playerdata.yml (single server, no setup) # MYSQL - MySQL or MariaDB; share points between several servers. # Optionally add Redis (redis.enabled below) for instant cross-server updates. # Copy existing data with: /ag storage migrate e.g. /ag storage migrate yaml mysql storage: type: YAML # MYSQL: how often (seconds) the shared top list is re-read from the database. # With Redis enabled this is only a safety net; changes arrive instantly. top-refresh-seconds: 30 mysql: host: "localhost" port: 3306 database: "ajdnikovgamemodes" username: "root" password: "" # Table name becomes players. Letters, digits and _ only. table-prefix: "ag_" use-ssl: false pool: maximum-pool-size: 4 minimum-idle: 1 connection-timeout-ms: 5000 max-lifetime-ms: 1800000 # Extra JDBC driver properties, e.g. serverTimezone: "UTC" or allowPublicKeyRetrieval: true properties: {} # ======================================== # Redis Settings # ======================================== # Optional add-on for storage.type MYSQL (MySQL + Redis). MySQL stays the only place points # are stored; Redis pub/sub tells every other server about each change, so leaderboards and # scoreboards update instantly across the network. Has no effect with YAML storage. redis: enabled: false host: "localhost" port: 6379 # Leave username empty unless you use Redis 6+ ACL users. username: "" password: "" database: 0 ssl: false timeout-ms: 2000 pool-size: 8 # The sync channel is sync. Servers sharing a database must use the same prefix. key-prefix: "ag:" # Name of this server in sync messages. Empty = random on every start. server-id: "" # Proxy settings for BungeeCord/Velocity proxy: enabled: false lobby-server: "lobby" # Lobby configuration lobby: world: "world" spawn: x: 0.0 y: 64.0 z: 0.0 yaw: 0.0 pitch: 0.0 # World settings (for dynamic game world slots — PvP Arena, HnS, etc.) worlds: game-slots: 3 prefix: "ag_game_" # ======================================== # Preloaded World Pool Settings # ======================================== # The world pool pre-generates survival worlds so gamemodes like Death Swap, # Manhunt, Man-Save, Speedrun VS and Achievement Speedrun can start instantly # without waiting for world generation. After each game, the used # world is restored to its pristine state from a backup. world-pool: # Whether to use the preloaded world pool system. # If false, worlds are generated dynamically on game start (old behavior). enabled: true # Prefix for preloaded world folder names (e.g. ag_preloaded_1, ag_preloaded_2) prefix: "ag_preloaded_" # Total number of survival worlds to keep preloaded and ready. # More worlds = more disk space, but supports more concurrent games. max-preloaded-worlds: 3 # Radius (in blocks) around world spawn to pre-generate chunks. # Higher values = longer initial generation but smoother gameplay. # Set to 0 to disable chunk preloading. # 500 blocks = ~31 chunk radius = ~3000 chunks per world. preload-radius: 500 # Fine-tune how the chunk preloading behaves. preload-performance: # How many chunks to generate per server tick. # Higher = faster preloading, but more lag during generation. # Lower = slower preloading, but smoother server performance. # Recommended: 20 for weak servers, 50 for average, 100+ for powerful hardware. chunks-per-tick: 50 # How many ticks to wait between each batch of chunks. # 1 = process every tick (fastest), 2 = every other tick, etc. # Increase this if you notice TPS drops during world generation. ticks-between-batches: 1 # How often (in chunks) to log progress to the console. # Set to 0 to disable progress logging entirely. # Example: 500 means a log message every 500 chunks processed. log-interval: 500 # Whether to unload chunks from memory immediately after generating them. # true = saves RAM during generation (recommended for large radii). # false = keeps chunks loaded (faster if players join the world soon after). unload-after-generation: true # Auto-replenishment: generates new worlds when available count drops low. auto-replenish: enabled: true # Only generate new worlds when the server has fewer than this many players online. # This prevents lag spikes during busy periods. player-threshold: 10 # If the number of available (unclaimed) worlds drops below this number, # trigger background generation of a new world. min-available: 1 # How often (in seconds) the plugin checks if replenishment is needed. check-interval-seconds: 30 # Daily regeneration: wipes ALL preloaded worlds and regenerates them # with fresh random seeds at a specific time each day. daily-regeneration: enabled: false # Time of day to perform the regeneration (24-hour format, HH:mm). time: "03:00" # If true, any active games on preloaded worlds will be force-stopped # before regeneration. If false, regeneration is skipped if games are active. kick-players-if-active: false # ======================================== # Random Events Settings # ======================================== # The random events system triggers a server-wide random event (gamemode) # where players click a chat message to join the queue. # Games started as a random event award multiplied/greater points. random-events: # Whether scheduled automatic random events are enabled. enabled: true # Time range (in minutes) between automatic events. min-interval-minutes: 30 max-interval-minutes: 60 # Countdown duration (in seconds) during the click-to-join announcement. announcement-countdown-seconds: 60 # Points multiplier applied to games started as random events (e.g. 2.0 = double points). points-multiplier: 2.0 # Minimum number of players in queue required to start the event game. min-players-to-start: 2 # Optional Discord webhook URL to notify when a random event starts. discord-webhook-url: "" # ======================================== # Chat Games Settings # ======================================== # Every few minutes a question is posted in chat. The first player to type the # correct answer wins points (points.chat-game). Admins: /ag chatgame chat-games: enabled: true min-interval-minutes: 5 max-interval-minutes: 10 # Seconds players have to answer before the answer is revealed. answer-time-seconds: 60 # Only start automatic rounds when at least this many players are online. min-players: 2 # Which kinds of rounds can be picked: scramble, math, trivia, quicktype types: [scramble, math, trivia, quicktype] scramble: # Words to unscramble (answers are not case-sensitive). words: [creeper, diamond, obsidian, enchantment, netherite, redstone, villager, skeleton, enderman, beacon, crafting, furnace, pickaxe, elytra, trident, blaze, stronghold, portal, shulker, piglin, axolotl, emerald, lantern, anvil, bastion, fortress, respawn, strider, warden, amethyst] math: # Largest number used in the problems. max-number: 50 quicktype: # Length of the random code to type (case-sensitive), 4-20. length: 8 trivia: # "answers" can hold several accepted answers. Matching ignores case and punctuation. # The first answer is shown when nobody gets it. Questions support & colour codes. questions: - question: "How many blocks of obsidian are needed for a minimal Nether portal?" answers: ["10", "ten"] - question: "Which mob drops blaze rods?" answers: ["blaze", "blazes"] - question: "What block is the body of a Wither built from? (4 needed)" answers: ["soul sand", "soul soil", "soulsand"] - question: "What item do you give a piglin to barter?" answers: ["gold", "gold ingot", "gold ingots"] - question: "How many eyes of ender does it take to fill an End portal frame?" answers: ["12", "twelve"] - question: "Which ore is only found in the Nether and makes netherite?" answers: ["ancient debris"] - question: "What mob explodes and hisses before it does?" answers: ["creeper", "creepers"] - question: "Which tool is needed to collect honeycomb from a bee nest?" answers: ["shears"] - question: "What do you use to tame a wolf?" answers: ["bone", "bones"] - question: "What is the maximum level of Sharpness from an enchanting table?" answers: ["4", "iv", "four", "sharpness 4", "sharpness iv"] # Points awarded for actions points: win: 10 kill: 2 survive: 5 participation: 1 advancement: 1 # Achievement Speedrun: per target advancement completed chat-game: 3 # Chat games: first correct answer # Leaderboard settings leaderboard: update-interval: 60 # Item rescue: keeps items from other plugins (StrengthSMP tokens and AnziLifesteal hearts by default) # when a game ends. Game worlds are deleted or reset after a game and each player's game # inventory is replaced by their saved one, so without this those items would be lost. # - Items dropped when a player dies belong to the killer. If nobody picks them up, the killer # gets them when the game ends. After a natural death (lava, fall, mobs) the last player who # hit them counts as the killer; with no attacker at all, the dead player gets them back. # - Items a player threw on the ground with Q go back to that player. # - Items in a player's inventory at the end of the game are given back after the restore. # - Players who are offline get them the next time they join (stored in rescued-items.yml). # Hold an item and run /ag itemrescue check to see if it matches and to see its NBT. item-rescue: enabled: true # Keep items whose NBT data (material id, name, lore, custom data...) contains ALL words of # an entry. Case and small-caps letters are ignored. "paper strength" = StrengthSMP tokens. nbt-contains: - "paper strength" # Keep items carrying data tags from these plugins (plugin name in lower case) pdc-namespaces: - strengthsmp # StrengthSMP: Strength Tokens - anzilifesteal # AnziLifesteal: Heart and Revive Beacon items # Keep items whose name contains any of these (colours and case ignored) name-contains: [] # Keep every item of these materials (rarely needed) materials: [] # Keep items with these custom model data values custom-model-data: [] # Also keep matching items a player is holding when the game ends keep-from-inventory: true # Also keep custom items that another plugin adds when a player dies (anything with a # custom name, lore or data that wasn't in their inventory), even if not listed above auto-detect-death-drops: true # Log every death drop and how it was handled (for finding out why an item wasn't kept) debug: false # Game-specific settings # Every gamemode has "enabled". Turn modes on/off in game with /ag gamemodes. games: global: time-limit: 1800 # 30 minutes default fallback for all games deathswap: enabled: true # false = can't be started and never picked for random events time-limit: 1800 # 30 minutes min-swap-time: 120 max-swap-time: 300 warning-time: 5 manhunt: enabled: true # false = can't be started and never picked for random events time-limit: 3600 # 60 minutes runner-head-start: 30 compass-cooldown: 30 # Seconds between manual compass clicks hideandseek: enabled: true # false = can't be started and never picked for random events time-limit: 600 # 10 minutes (hide + seek combined) hide-time: 60 seek-time: 300 hider-glow-interval: 30 # Seconds between the 1-second glow that reveals hiders mansave: enabled: true # false = can't be started and never picked for random events time-limit: 1200 # 20 minutes survive-time: 600 pvparena: enabled: true # false = can't be started and never picked for random events time-limit: 300 # 5 minutes max-time: 300 speedrunvs: enabled: true # false = can't be started and never picked for random events time-limit: 3600 # 60 minutes achievementspeedrun: enabled: true # false = can't be started and never picked for random events time-limit: 2400 # 40 minutes — most completed advancements wins when time runs out target-count: 5 # Advancements to race for (1-10). Party leaders can change this in /party settings. allow-pvp: false # Whether racers can hurt each other # Optional: replace the built-in advancement lists per difficulty. # Use vanilla keys such as "story/mine_stone" or "minecraft:story/mine_stone". # pool: # easy: ["story/mine_stone", "story/smelt_iron", "husbandry/plant_seed"] # medium: ["story/mine_diamond", "story/enter_the_nether"] # hard: ["nether/obtain_blaze_rod", "story/enter_the_end"] # ======================================== # Tournaments # ======================================== # Free-for-all fights in protected arenas with a kit chosen by the admin. # Setup: /tournament wand -> select 2 corners -> /tournament create # -> /tournament setspawn (2 or more) -> /tournament start # -> players /tournament join -> /tournament ready # Everything here can also be changed in game with /tournament gui. tournament: # Most players in one tournament. Arenas can override this (/tournament setmax ). max-players: 16 # How many tournaments can run at the same time (one per arena). max-concurrent: 3 # Players needed before /tournament ready works. min-players: 2 # Seconds after joining before the kit is given (everyone gets it at /tournament ready anyway). kit-delay-seconds: 3 # Length of the countdown started by /tournament ready. Players are frozen and can't attack. countdown-seconds: 10 # Bukkit sound names (empty = no sound). countdown-sound: "BLOCK_NOTE_BLOCK_PLING" fight-sound: "ENTITY_ENDER_DRAGON_GROWL" # Skip the death screen for eliminated players. auto-respawn: true # Item used as the arena selection wand (left-click = corner 1, right-click = corner 2). wand-material: "GOLDEN_AXE" # Where eliminated players go. use-server-lobby: true = the lobby from /ag setlobby. # /tournament setlobby stores your position here and switches use-server-lobby off. lobby: use-server-lobby: true world: "world" x: 0.0 y: 64.0 z: 0.0 yaw: 0.0 pitch: 0.0 # Mobs inside arenas while a tournament runs there (whole height of the arena). mobs: # Stop mobs spawning (other plugins and /summon still can). block-spawning: true # Remove hostile mobs at the start and every 5 seconds (named mobs are kept). remove-hostile: true # Shrinking border made of particles (not the vanilla world border, so the world can be shared). # Only tournament players see it. Players outside it take damage. border: enabled: false # SQUARE or CIRCLE, centred on the arena. shape: SQUARE # Distance from the centre to the wall at the start. 0 = fit the arena. start-size: 0 # Distance it shrinks down to. end-size: 10 # Seconds after FIGHT before it starts moving, then how long it takes to reach end-size. delay-seconds: 60 shrink-seconds: 300 # Damage per second outside the border (2 = one heart). damage-per-second: 2.0 # Bukkit particle name. DUST (REDSTONE on older servers) uses the colour below. particle: DUST color: "#FF3030" particle-size: 1.5 # How far away the wall is drawn, and the gap between particles (bigger = less lag). view-distance: 24 spacing: 1.0 # Also show the wall to everyone else in the world. show-to-nearby-players: false # Custom maps: put .schem/.litematic files in plugins/AjdnikovGamemodes/TournamentMaps/ and run # /tournament importmap [arena] (or /tournament gui -> Custom maps). The map is pasted into # its own void world and becomes a normal arena; add spawns with /tournament setspawn. # A .yml next to the file can hold spawns (/tournament savemapspawns writes it). maps: world: "ag_tournament_maps" # Blocks between maps in that world. spacing: 1000 # Y level the map's origin is pasted at. paste-y: 64 # Extra blocks around the map that count as part of the arena. margin: 0 # Paste the map again after every tournament on it (undoes any changes). reset-after-tournament: false # Console commands run for the winner. Placeholders: %player% %arena% %kit% reward-commands: - "give %player% diamond 5" restrictions: # Block opening ender chests (inside arenas, and anywhere for participants). block-ender-chests: true # Participants can't drop items. block-item-drop: true # Ender pearls and chorus fruit can't take participants out of the arena. block-pearls-leaving-arena: true # Participants can't walk out of the arena region. keep-players-in-arena: true # true = only the arena's sides limit players; they can go from bedrock to the build limit # (climb mountains, go into caves). false = the region's height is a hard ceiling and floor. full-height: true # Commands participants can't use (without "/"). "essentials:ec" style forms are caught too. # Players with ajdnikovgamemodes.tournament.bypass ignore this list. blocked-commands: - ec - echest - enderchest - eechest - eenderchest - endersee - enderview - home - homes - sethome - spawn - tpa - tpahere - tpaccept - tpyes - tpo - tp - tphere - back - warp - warps - rtp - wild - kit - kits - fly - god - heal - feed - repair - fix - hat - workbench - wb - craft - anvil - invsee - trash - disposal - suicide # What is blocked inside every arena region (no WorldGuard needed). # Admins with ajdnikovgamemodes.arena.bypass can build in creative mode when not playing. arena-protection: block-break: true block-place: true explosions: true liquid-flow: true fire-spread: true pistons: true mob-griefing: true block-decay: true # Protect the arena from bedrock to the build limit, not only the selected height. full-height: true # ======================================== # Hunt Event # ======================================== # /hunt start and /hunt end (admins). While it runs, players use /hunt to get a # compass pointing at the target and the distance in their action bar. # A player wearing the Hunter's Mask can't be tracked. Also editable with /hunt gui. hunt: # Seconds between /hunt uses (admins skip it). cooldown-seconds: 30 # Ticks between compass/action bar updates (20 = once a second). update-interval-ticks: 20 # Give hunters a tracking compass (otherwise only the action bar distance). give-compass: true # Tell players when someone starts tracking them. notify-target: false # Allow tracking players who are in a tournament (or tracking while in one). allow-in-tournaments: false mask: name: "&6&lHunter's Mask" lore: - "&7Wear it on your head and" - "&7no one can track you with /hunt." # true = only craftable while the hunt runs; false = always craftable. craft-only-during-event: true recipe: enabled: true # Up to 3 rows of up to 3 symbols; a space is an empty slot. shape: - "LEL" - "LPL" - " L " ingredients: L: LEATHER E: ENDER_EYE P: CARVED_PUMPKIN # ======================================== # Target Event # ======================================== # /target start gives every online player with ajdnikovgamemodes.target.join a secret target. # Kill your target and you inherit theirs. Only a kill by your hunter eliminates you. # The last player left wins. Also editable with /target gui. target: min-players: 2 # Leave out players who are in a tournament or a minigame when the event starts. exclude-busy-players: true # Broadcast every successful hit. announce-kills: true # 0 = no limit. When time runs out, the player with the most kills wins (a tie = no winner). max-duration-minutes: 0 # Console commands for each target kill. Placeholders: %killer% %victim% kill-reward-commands: - "give %killer% gold_ingot 3" # Console commands for the winner. Placeholder: %player% winner-reward-commands: - "give %player% diamond 10" # ======================================== # Public Events Web Page # ======================================== # Tournaments, hunts and targets are shown live on a public page on ajdnikov-dev.com. # The page only shows player names, kills and statuses: never coordinates, IPs or your key. # Updates are sent in the background; the plugin works normally if the site is down. # Get the link with /events link, or from your license page on license.ajdnikov-dev.com. web-events: enabled: true # Your license can have several pages (the limit is set by staff). Servers that use the same # name share one page. Letters, digits, - and _. feed: "main" # Title shown at the top of the page (empty = the page name). display-name: "" # Label shown on each event, useful when several servers share a page. server-name: "" # Seconds between batched updates. flush-interval-seconds: 3 # Add a clickable "watch live" link to these start broadcasts. link-in-broadcasts: tournament: true hunt: true target: true # Where the page and the API live. Leave these unless told otherwise. page-url: "https://ajdnikov-dev.com/events/" api-url: "https://license.ajdnikov-dev.com" # Optional Discord webhook for event starts, winners and results (with the page link). event-discord: webhook-url: "" tournament: true hunt: true target: true ``` ### Troubleshooting #### Q: "No available game slots!" A: Every pool world or void slot is in use, or the pool is still generating. Raise `world-pool.max-preloaded-worlds` or `worlds.game-slots`, or wait. #### Q: "Could not connect to MySQL" at start-up A: Check the host, port, database name and credentials, and that the database already exists. With MySQL 8 and `use-ssl: false`, add `allowPublicKeyRetrieval: true` under `storage.mysql.properties`. Points keep working while it retries: they are queued in memory and written once the connection is back. #### Q: ClassNotFoundException for Hikari or Jedis A: The server couldn't download the libraries on first start. Allow outbound access to `repo.maven.apache.org`, or start the server once on a machine that has access. #### Q: Points differ between servers A: Every server must use `storage.type: MYSQL` with the same database and `table-prefix`, and must have been restarted after the change. Without Redis, other servers catch up within `top-refresh-seconds`. Set `redis.enabled: true` (same Redis and `key-prefix` everywhere) for instant updates. #### Q: I changed storage in config.yml and nothing happened A: Storage settings are only read at start-up. Restart the server. #### Q: Players lost their items after a crash A: Their snapshot is restored automatically the next time they join. Snapshots are in `inventory_saves/`. #### Q: Strength Tokens or Lifesteal hearts disappear when a game ends A: Make sure `item-rescue.enabled` is on, then hold the item and run `/ag itemrescue check`. If it doesn't match, add a few words of its NBT to `item-rescue.nbt-contains` and `/ag reload`. See Item Rescue . #### Q: Players lose hearts in minigames (AnziLifesteal) A: Update AnziLifesteal and keep its `minigame-protection` on. It reads the `ajdnikovgamemodes_in_game` marker this plugin sets during games. #### Q: "Could not reach the events site" in the console A: The events page couldn't be updated. Tournaments, hunts and targets keep working, and updates are retried quietly. "The events site refused the update" means the key is wrong, the licence isn't for this plugin, or the licence has used all its event pages (`web-events.feed`); it retries every 5 minutes. #### Q: A tournament won't start: "needs at least 2 spawn points" A: Add spawns with `/tournament setspawn ` while standing inside the arena. #### Q: PvP Arena / Hide & Seek don't start A: Install FAWE, add at least one map and set it up with `/setup setspawns`. #### Q: Need more help? A: Join the Discord server (https://discord.gg/xyjmcjMp4W) for support and bug reports. --- # AnziLifesteal — Lifesteal SMP Plugin | ajdnikov URL: https://www.ajdnikov-dev.com/anzilifesteal Updated: 2026-11-08 > AnziLifesteal is a Lifesteal SMP plugin for Paper: hearts, rebirth prestige, revive beacons, MySQL cross-server sync and anti-alt and anti-spawn-kill protection. Skip to content ## AnziLifesteal Paper 1.21+ v 1.4.3 A full Lifesteal season: heart stealing and withdrawal, progressive ban durations, revive beacons, a rebirth prestige ladder, and anti-alt and anti-spawn-kill protection — synchronised across a network over MySQL. Read the manual Get it on BuiltByBit (https://builtbybit.com/creators/ajdnikov.766669/) Ask in Discord (https://discord.gg/xyjmcjMp4W) ### The whole season in one plugin A heart stolen on every kill, progressive bans at zero hearts, Revive Beacons to bring players back, and a rebirth prestige for the ones who outgrow the cap. Anti-alt and anti-spawn-kill protections stop heart farming, and with MySQL, hearts, rebirths and toggles follow players across every server on your network. ### What it talks to U01 U02 #### Ports MySQL is optional. Without it everything lives in a local data.yml; with it, hearts and rebirths follow players across the network. - MySQL - PlaceholderAPI - Vault - Discord - Velocity / Bungee Patch field 5 RUNS - MySQL - PlaceholderAPI - Vault - Discord - Velocity / Bungee ### Key Features A01 #### Lifesteal Mechanics - Heart Stealing: Kill a player, gain a heart. Die, lose a heart. - Withdraw System: Convert health into physical Heart items. - Configurable Limits: Starting, max, and minimum withdraw hearts. - PvE Heart Loss: Optionally lose hearts to mobs, lava, etc. A02 #### Eliminations & Reviving - Progressive Bans: 1h → 24h → 7d escalating ban durations. - Revive Beacon: Craftable item to bring back eliminated players. - Revive GUI: Beautiful interface to select who to revive. - Ban-on-Zero Toggle: Ban or keep at 1 heart — your choice. - Minimum Hearts: Optionally stop players at the minimum from losing hearts at all. A03 #### Rebirth System - Prestige Mechanic: Reset hearts to gain a higher max cap. - Beautiful GUI: Interactive rebirth menu with live stats. - Configurable Requirements: Percentage-based heart thresholds. - Scaling Rewards: Extra max hearts per rebirth level. A04 #### MySQL Synchronization - Cross-Server Sync: Hearts, rebirths, and toggles sync across servers. - Velocity/BungeeCord: Built for proxy networks of any size. - Connection Pooling: Configurable pool size for performance. - Server ID System: Unique identifiers for multi-server setups. A05 #### Anti-Exploit Protections - Anti-Spawn Kill: Max kills per victim within a time window. - Spawn Radius: Protect players near their respawn point. - Anti-Alt Farming: Prevent heart farming with alt accounts. - Toggle System: Admins can exempt players from lifesteal. - Minigame Protection: No hearts lost or stolen in AjdnikovGamemodes games or listed minigame worlds. A06 #### In-Game Recipe Editor - Interactive GUI: Edit crafting recipes directly in-game. - Heart & Beacon: Fully customizable shaped crafting. - Live Reload: Changes apply immediately without restart. - Config-Backed: All recipes saved to config.yml. A07 #### Discord Webhooks NEW - Live Event Feed: Withdrawals, kills, eliminations, revives, and rebirths. - Per-Event Toggles: Enable only the events your channel needs. - Custom Embeds: Own title, description, color, and footer for every event. - Rich Placeholders: Player names, heart counts, and ban durations in every message. ### Commands #### Player Commands Command | Description `/withdraw ` | Withdraws hearts into physical items `/rebirth` | Opens the rebirth GUI to prestige #### Admin Commands als.admin Command | Description `/als set_hearts ` | Sets a player's current hearts `/als give [amount]` | Gives a custom Heart or Revive Beacon item `/als recipes ` | Opens the in-game Recipe Editor GUI `/als max_hearts ` | Sets and saves the global maximum heart cap `/als hearts_when_revived ` | Sets how many hearts a revived player receives `/als anti_spawn_kill ` | Toggles spawn-kill protection `/als anti_alt ` | Toggles alt-farming prevention `/als min_hearts_protection ` | Toggles the minimum-hearts protection `/als reload` | Reloads config.yml, recipes, and discord.yml `/lstoggle [time]` | Toggles lifesteal for a player (als.toggle) ### PlaceholderAPI If PlaceholderAPI is installed, AnziLifesteal registers the `lifesteal` expansion with 17 placeholders. The most useful ones: Placeholder | Returns `%lifesteal_hearts%` | Player's current hearts `%lifesteal_max_hearts%` | Personal maximum hearts, including rebirth bonuses `%lifesteal_hearts_fraction%` | Current over maximum, e.g. 8/20 `%lifesteal_hearts_percent%` | Current hearts as a percentage `%lifesteal_hearts_display%` | Hearts drawn as icons `%lifesteal_rebirths%` | Total rebirths completed `%lifesteal_can_rebirth%` | Whether the player meets the heart requirement `%lifesteal_is_eliminated%` | Whether the player is at 0 hearts `%lifesteal_ban_count%` | Times the player has been eliminated ### Questions before you commit? Support, licence keys, bug reports and feature requests all run through the Discord. Ask anything about AnziLifesteal there — including whether it fits the server you already run. Already bought it? Your licence lives in the licence portal (https://license.ajdnikov-dev.com) — sign in there for your keys, or claim one with `/claim` in the Discord. Join the Discord (https://discord.gg/xyjmcjMp4W) Back to all plugins --- # AnziLifesteal Documentation | ajdnikov URL: https://www.ajdnikov-dev.com/anzilifesteal/docs Updated: 2026-11-08 > AnziLifesteal documentation: setup guide, commands, configuration and troubleshooting for the Paper Lifesteal SMP plugin. ## AnziLifesteal Documentation Version 1.4.3 Platform Paper 1.21+ Storage data.yml or MySQL Network MySQL Welcome to the AnziLifesteal documentation! AnziLifesteal is a comprehensive, highly configurable plugin for Paper and Spigot servers running a Lifesteal SMP. It features cross-server synchronization, customizable recipes, an in-game recipe editor, rebirth mechanics, spawn-kill and alt protections, Discord webhook notifications, and more. ### Overview AnziLifesteal provides everything you need to run a professional Lifesteal SMP. Players steal hearts from each other on kill, are eliminated when they reach 0 hearts, and can be revived using craftable Revive Beacons. The plugin includes a rebirth prestige system, optional MySQL synchronization for proxy networks, optional Discord notifications, and extensive anti-exploit protections. Detail | Value Current version | `1.4.3` Platform | Paper / Spigot, `api-version: '1.20'` Soft dependencies | PlaceholderAPI (placeholders), Vault (rebirth money cost) Storage | Local `data.yml` by default, optional MySQL ### Features - Lifesteal Mechanics: Steal a heart from every player you kill, lose one when you die. Heart loss on non-player deaths is configurable. - Heart Items: Withdraw hearts into physical items and consume them later. A stolen heart is handed over as a physical Heart item when the killer is already at their personal maximum. - Eliminations & Reviving: Players reaching 0 hearts are banned for a progressively longer duration each time. They can be brought back with a craftable Revive Beacon. - Rebirth System: A prestige system that resets hearts in exchange for a permanently higher personal heart cap. - MySQL Synchronization: Sync hearts, elimination counts, rebirths, and toggle states across a proxy network. - Protections: Built-in anti-spawn-kill, anti-alt-farming, a minimum-hearts floor, and minigame protection so deaths in minigames never cost hearts. - Toggle System: Admins can temporarily or permanently exempt players from lifesteal. - Discord Webhooks: Optional embeds for withdrawals, kills, eliminations, revives, and rebirths. - PlaceholderAPI Integration: 17 placeholders for scoreboards, tab lists, and leaderboards. - Support Dumps: `/als dump` gives you a private link with the plugin's log, the full server log and your server's setup to send to support. See Support Dumps . - Automatic Updates: New versions download by themselves after a license check and load on the next restart. New settings are added to your config files with their comments. See Automatic Updates . - Update Checker: Admins are notified in-game and in console when a new release is available. ### Installation & License - Download the latest AnziLifesteal release. - Place the JAR in your Paper or Spigot `plugins/` folder. - Start the server once so the configuration files are generated. - Open `plugins/AnziLifesteal/config.yml` and paste your license key. - Restart the server and confirm the console reports a successful license check. #### AnziLock License AnziLifesteal is protected by AnziLock . License keys are issued through the Discord community — use the `/claim` command there to receive yours, then set it in `config.yml`: ``` license: key: "YOUR_LICENSE_KEY_HERE" ``` On startup the plugin verifies the key against `license.ajdnikov-dev.com` and then runs a low-frequency heartbeat in the background. The last signed verification is cached, so a short outage of the license server will not take your server down — the plugin continues on the cached result for the offline grace period. Console lines are prefixed with `[AnziLock]` and `[AnziLS]`. #### Automatic Updates Since 1.4.2, AnziLifesteal updates itself. When a new version is released, it checks your license again, downloads the new jar into `plugins/update`, and the server loads it on the next restart. The file is kept only if its size and checksum match the signed license answer. Nothing changes while the server is running. - Turn it off with `auto-update: false` in `config.yml`. - Players with `als.updates` (ops by default) are told on join when a new version is waiting for a restart. - New settings are added to `config.yml` and `discord.yml` on start, with their comments. Your values stay, and the old file is kept as `.bak`. Recipe ingredients stay exactly as you set them. - Coming from 1.4.1 or older? Install 1.4.2 or newer by hand once. Every later version arrives by itself. How the download is checked: AnziLock → Automatic Updates . #### Support Dumps Since 1.4.3, `/als dump` makes a private link for support. The page shows AnziLifesteal's own log next to the full server log, and your server's setup: software and version, uptime, TPS, RAM, disk, CPU, Java, worlds, every plugin, and `config.yml` and `discord.yml` with keys, passwords and webhooks blanked out. Only you see the link in chat: click it, or click [Copy] , and send it to whoever helps you on Discord (https://discord.gg/xyjmcjMp4W). - `/als dump 6` covers only the last 6 hours. `/als dump local` uploads nothing and saves the dump in `plugins/AnziLifesteal/dumps/` as a readable `.txt` and a `.json.gz`. - On the page you can filter and search both logs, show only the lines about AnziLifesteal (stack traces included), and save everything to your PC as `.txt` or `.json`. A saved `.json` opens again at `license.ajdnikov-dev.com/dump` after the link has expired. - The link works for `dump.link-hours` (24 by default, at most 168). You can remove it sooner on your licence page under Dumps . - IP addresses are replaced with `x.x.x.x` unless you set `dump.hide-ips: false`. - Needs `als.dump` (ops by default). ``` dump: # Hours of AnziLifesteal's log to keep on disk (dump-logs/) and put in a dump. log-hours: 48 # How long the link works, in hours (at most 168). link-hours: 24 # Replace IP addresses in the logs with x.x.x.x. hide-ips: true ``` What a dump contains and how long it is kept: AnziLock → Support Dumps . #### Generated Files - `config.yml` — license, heart rules, protections, rebirth, MySQL, recipes, GUI text, and messages - `discord.yml` — the webhook URL and per-event embeds - `data.yml` — local player data, used when MySQL is disabled - `config.yml.bak`, `discord.yml.bak` — your files as they were before an update added new settings - `dump-logs/` — the plugin's log for support dumps, one file per hour - `dumps/` — dumps saved with `/als dump local`, or when an upload failed ### Commands & Permissions #### Player Commands Command | Description | Permission `/withdraw ` | Withdraws the specified number of hearts into physical Heart items. | None `/rebirth` | Opens the rebirth GUI to prestige. | None #### Admin Commands Permission required: `als.admin` (except `/lstoggle`, which requires `als.toggle`). Command | Description `/als set_hearts ` | Sets a player's current hearts. `/als give [amount]` | Gives the specified custom item. Note the item type comes before the player name. `/als recipes ` | Opens the in-game Recipe Editor GUI for that recipe. `/als max_hearts ` | Sets and saves the global maximum heart cap. `/als hearts_when_revived ` | Sets how many hearts a revived player receives. `/als min_withdraw ` | Sets the minimum hearts a player must retain when withdrawing. `/als min_hearts_protection ` | Toggles the minimum-hearts protection . `/als min_hearts ` | Sets the protected minimum heart count (at least 1). `/als min_hearts_killer_heart ` | Whether a killer still gets a heart for killing a player at the minimum. `/als ban_on_zero ` | Toggles whether players are banned at 0 hearts. `/als lose_on_non_player_death ` | Toggles losing hearts to PvE deaths. `/als anti_spawn_kill ` | Toggles spawn-kill protection. `/als anti_alt ` | Toggles alt-farming prevention. `/als link_alt ` | Manually links two players as alts. `/als unlink_alt ` | Removes a manual alt link. `/als toggle [time]` | Admin alias for changing a player's lifesteal state. `/als reload` | Reloads config.yml, recipes, and the Discord webhook config. `/als dump [hours] [local]` | A private link with the plugin's log, the full server log and your server's setup, for support. Also needs `als.dump`. See Support Dumps . `/lstoggle [time]` | Toggles lifesteal for a player — requires `als.toggle`. #### Permissions Permission | Description | Default `als.admin` | Access to all `/als` admin subcommands. | OP `als.toggle` | Access to `/lstoggle`. | OP `als.updates` | Told on join when a new version has been downloaded and is waiting for a restart. | OP `als.dump` | Use `/als dump`. | OP ### Configuration Guide #### Core Settings - `starting-hearts`: Hearts a new player starts with. Default `10`. - `max-hearts`: The absolute maximum hearts a player can reach. Default `20`. - `min-withdraw-hearts`: Prevents withdrawing if it would drop the player below this threshold. - `lose-hearts-on-non-player-death`: If true, dying to mobs, fall damage, or the void costs a heart. #### Elimination Settings - `ban-on-zero`: If true, hitting 0 hearts eliminates (bans) the player. If false they stay at 1 heart but stop giving hearts on death. - `ban-durations`: A progressive list of ban lengths (for example `1h`, `24h`, `7d`). The last value repeats once a player exceeds the list. `-1` means a permanent ban, and an empty list means every elimination is permanent. - `hearts-when-revived`: Hearts given when a ban expires or a player is revived. - `enable-revive-beacon`: Enables or disables the Revive Beacon item and its recipe. Note: with minimum-hearts protection on (the default), players at the minimum stop losing hearts, so they never reach 0 and are never banned. Turn it off with `/als min_hearts_protection false` if you want eliminations. #### Applying Changes Run `/als reload` after editing `config.yml` directly. The reload re-reads the config, reloads player data, re-registers recipes, and reloads `discord.yml`. ### Protections #### Anti-Spawn-Kill ``` anti-spawn-kill: enabled: true max-kills: 3 # max heart steals from the same victim per window time-window: 180 # window length in seconds spawn-radius: 10 # blocks from the victim's respawn point ``` When a kill is blocked, no hearts are transferred in either direction and both players are told why. Toggle at runtime with `/als anti_spawn_kill`. #### Anti-Alt ``` anti-alt: enabled: false ``` Blocks heart transfers between accounts sharing an IP address, and between accounts an admin has manually linked with `/als link_alt`. Toggle at runtime with `/als anti_alt`. #### Minimum Hearts ``` min-hearts: enabled: true amount: 1 # the protected minimum (at least 1) killer-gets-heart: false # does the killer still get a heart? ``` Players at (or below) `amount` hearts don't lose hearts when they die, so they can never drop to 0 hearts and never get banned. Both players are told why. With `killer-gets-heart: true`, the killer still gets a heart (the victim keeps theirs); with `false`, the killer gets nothing. Withdrawing also can't take a player below this minimum. Change it at runtime with `/als min_hearts_protection`, `/als min_hearts` and `/als min_hearts_killer_heart`. It is on by default , including on configs from before 1.4 that have no `min-hearts` section. If you run eliminations with `ban-on-zero`, turn it off. #### Minigame Protection ``` minigame-protection: enabled: true ajdnikov-gamemodes: true # protect players in an AjdnikovGamemodes game worlds: # also protect every death in these worlds; * matches any text - "ag_game_*" - "ag_preloaded_*" ``` Players don't lose or steal hearts when they die in a minigame, so dying in a game (or the game ending) never costs anyone hearts. With `ajdnikov-gamemodes: true`, players in an AjdnikovGamemodes game are protected in every world, including the shared Nether and End during Manhunt or speedruns. Add any other minigame worlds to `worlds`. AjdnikovGamemodes also keeps Heart and Revive Beacon items through games with its item rescue. ### Rebirth System Rebirth is a prestige mechanic. Players who meet the heart, money, and XP requirements can reset their hearts in exchange for a permanently higher personal heart cap. The GUI opens with `/rebirth` and shows live progress against every requirement. ``` rebirth: hearts-after-rebirth: 10 extra-max-hearts-per-rebirth: 1 required-hearts-percentage: 50 max-rebirths: -1 cost-money: 0 cost-money-multiplier: 1.0 cost-xp-levels: 0 ``` - `hearts-after-rebirth`: Hearts the player is reset to. - `extra-max-hearts-per-rebirth`: Permanent increase to their personal heart cap. - `required-hearts-percentage`: Percentage of the range above starting hearts required to rebirth (0–100). - `max-rebirths`: Maximum number of rebirths. `-1` is unlimited. - `cost-money`: Base money cost. Requires Vault and an economy plugin. Set to `0` to disable. - `cost-money-multiplier`: Scales the money cost per rebirth — `1.5` makes each rebirth 50% more expensive, `1.0` keeps it flat. - `cost-xp-levels`: XP levels required. Set to `0` to disable. Formula: `starting-hearts + (max-hearts - starting-hearts) × percentage` Example: starting = 10, max = 20, 50% → 10 + (20−10) × 0.5 = 15 hearts needed ### Toggle System Admins can exempt individual players from lifesteal entirely — useful for content creators, builders, or a temporary truce. While a player is toggled off they neither steal nor lose hearts, and other players cannot steal from them. ``` /lstoggle off 1h # disable for one hour /lstoggle off # disable permanently /lstoggle on # re-enable ``` Durations accept formats such as `10s`, `34m`, `4h`, and `1d`. Omitting the duration disables lifesteal until it is explicitly turned back on. Running `/lstoggle ` with no action reports the player's current state. ``` toggle: sync-interval-seconds: 30 ``` When MySQL is enabled, toggle states are pulled from the database at this interval, so a toggle set on one backend takes effect network-wide. Affected players are notified when their state changes from another server. ### MySQL & Syncing MySQL is optional. With it disabled the plugin stores everything in a local `data.yml`. Enable it to share hearts, elimination counts, rebirths, and toggle states across a Velocity or BungeeCord network. ``` mysql: enabled: true host: "localhost" port: 3306 database: "lifesteal" username: "root" password: "" pool-size: 10 server-id: "server-1" ``` Point every backend server at the same database, and give each one a unique `server-id`. ### Recipe System Recipes are fully customizable in `config.yml` using a shape matrix, or in-game through the Recipe Editor GUI: ``` /als recipes heart /als recipes revive_beacon ``` Changes made in the editor are saved back to `config.yml` and the recipes re-register immediately — no restart needed. Item | Default ingredients Heart | Diamond, Nether Star, Gold Ingot Revive Beacon | Ender Eye, Nether Star, Obsidian, Beacon Each recipe has its own `enabled` flag, so you can remove one from the game entirely. The Revive Beacon also respects the global `enable-revive-beacon` setting. ### Discord Webhooks AnziLifesteal can post rich embeds to a Discord channel for every major lifesteal event. Configuration lives in its own file, `plugins/AnziLifesteal/discord.yml`. ``` # Master toggle - set to false to disable all Discord messages enabled: false # Your Discord webhook URL (Server Settings -> Integrations -> Webhooks) webhook-url: "https://discord.com/api/webhooks/YOUR_WEBHOOK_URL_HERE" # Bot display name and avatar shown in Discord bot-name: "Lifesteal" bot-avatar-url: "" ``` #### Events Each event can be toggled on or off individually and carries its own embed `title`, `description`, `color` (decimal), and `footer`. Event | Fires when | Placeholders `withdraw` | A player withdraws hearts into items | `{player}`, `{amount}`, `{hearts}` `kill` | A player kills another and steals a heart | `{killer}`, `{victim}`, `{killer_hearts}`, `{victim_hearts}` `elimination` | A player loses all hearts and is banned | `{player}`, `{duration}` `revive` | A Revive Beacon brings a player back | `{player}`, `{target}` `rebirth` | A player successfully rebirths | `{player}`, `{rebirths}`, `{max_hearts}` Example event block: ``` events: kill: enabled: true title: "⚔ Player Killed" description: "**{killer}** killed **{victim}** and stole a heart!" color: 16711680 footer: "Anzi Lifesteal" ``` Colors are decimal values — `16711680` red, `65280` green, `16776960` yellow, `16746496` orange, `0` black. Run `/als reload` after editing `discord.yml`. ### PlaceholderAPI Integration When PlaceholderAPI is installed, AnziLifesteal registers the `lifesteal` expansion automatically. It persists across `/papi reload`. #### Hearts Placeholder | Returns `%lifesteal_hearts%` | The player's current hearts `%lifesteal_max_hearts%` | Their personal maximum, including rebirth bonuses `%lifesteal_starting_hearts%` | The configured starting hearts `%lifesteal_hearts_display%` | Hearts drawn as icons, e.g. `❤❤❤` `%lifesteal_hearts_fraction%` | Current over maximum, e.g. `8/20` `%lifesteal_hearts_percent%` | Current hearts as a percentage, e.g. `40%` #### Rebirth Placeholder | Returns `%lifesteal_rebirths%` | Total number of rebirths completed `%lifesteal_rebirth_bonus%` | Extra max hearts gained from rebirths `%lifesteal_can_rebirth%` | `true` / `false` — whether they meet the heart requirement #### Status & Settings Placeholder | Returns `%lifesteal_is_eliminated%` | `true` / `false` — whether the player is at 0 hearts `%lifesteal_ban_count%` | How many times the player has been eliminated `%lifesteal_ban_on_zero%` | `true` / `false` — whether elimination bans are enabled `%lifesteal_min_withdraw%` | Minimum hearts required when withdrawing `%lifesteal_hearts_when_revived%` | Hearts granted on revival `%lifesteal_revive_beacon_enabled%` | `true` / `false` — whether the Revive Beacon is enabled `%lifesteal_lose_on_non_player_death%` | `true` / `false` — whether PvE deaths cost a heart ### Messages & GUI Text Every GUI title, lore line, and chat message is fully customizable with standard Minecraft color codes (`&`) inside the `gui-text` and `messages` sections of `config.yml`. #### GUI Text The `gui-text` section covers the Recipe Editor, the Revive Beacon player picker, and the Rebirth GUI — including separate lore blocks for the ready, not-ready, and maxed-out rebirth states. Rebirth lore supports `{hearts}`, `{required_hearts}`, `{max_hearts}`, `{player_money}`, `{cost_money}`, `{player_xp}`, and `{cost_xp}`. #### Messages The `messages` section covers heart gains and losses, withdrawals, eliminations, revives, rebirths, config changes, protection blocks, and the full toggle-system message set (including notifications sent when a toggle is synced from another server). Note: Run `/als reload` after making direct changes to `config.yml`. ### Full config.yml The default configuration, with the GUI text and message sections abbreviated: ``` # ══════════════════════════════════════════════ # Anzi Lifesteal - Configuration # ══════════════════════════════════════════════ # ─── ANZILOCK LICENSE ─────────────────────────── # Insert the license key you received via Discord here (see /claim). license: key: "" # Download new versions of AnziLifesteal automatically when they are released. # They are checked against your license and load on the next restart. # Players with als.updates (ops by default) are told when one is waiting. auto-update: true # /als dump makes a private link with the plugin's log, the full server log and the server's setup # to share with support. "dump local" only saves it in plugins/AnziLifesteal/dumps/. dump: # Hours of the plugin's log to keep on disk (dump-logs/) and put in a dump. log-hours: 48 # How long the link works, in hours (at most 168). link-hours: 24 # Replace IP addresses in the logs with x.x.x.x. hide-ips: true # Starting hearts for new players (1 heart = 1 full vanilla heart) starting-hearts: 10 # Maximum hearts a player can have max-hearts: 20 # Minimum hearts a player must be left with when withdrawing min-withdraw-hearts: 1 # ─── MINIMUM HEARTS PROTECTION ────────────────── # Players at (or below) the minimum don't lose hearts when they die, # so they can never drop to 0 hearts and never get banned. min-hearts: # Turn the protection on or off enabled: true # The minimum heart count (at least 1) amount: 1 # If true, the killer still gets a heart when killing a player at minimum hearts # (the victim still keeps theirs). If false, the killer gets nothing. killer-gets-heart: false # If true, players are banned when they reach 0 hearts # If false, they stay at 1 heart but don't give hearts on death ban-on-zero: true # How long a player is banned each time they lose all hearts. # Formats: 1m, 1h, 1d, etc. If a value is -1, it's a permanent ban. # The last value is used if they exceed the list length. ban-durations: - "1h" - "24h" - "7d" # How many hearts players have when their ban expires or they are revived. hearts-when-revived: 1 # If true, the revive beacon item can be used and its recipe works. enable-revive-beacon: true # If true, players lose a heart when dying to non-player causes (mobs, lava, etc.) lose-hearts-on-non-player-death: true # ─── MINIGAME PROTECTION ──────────────────────── # Players don't lose or steal hearts when they die in a minigame, so dying in a # game (or the game ending) never costs anyone hearts. minigame-protection: # Turn the protection on or off enabled: true # Protect players while they are in an AjdnikovGamemodes game (works in every # world, including the shared Nether/End during Manhunt or speedruns) ajdnikov-gamemodes: true # Also protect every death in these worlds. * matches any text. # The defaults are the AjdnikovGamemodes game worlds. worlds: - "ag_game_*" - "ag_preloaded_*" # ─── ANTI SPAWN KILL ──────────────────────────── anti-spawn-kill: enabled: true max-kills: 3 time-window: 180 spawn-radius: 10 # ─── ALT DETECTION ────────────────────────────── anti-alt: enabled: false # ─── REBIRTH ──────────────────────────────────── rebirth: hearts-after-rebirth: 10 extra-max-hearts-per-rebirth: 1 required-hearts-percentage: 50 max-rebirths: -1 cost-money: 0 cost-money-multiplier: 1.0 cost-xp-levels: 0 # ─── MYSQL (Velocity Sync) ────────────────────── mysql: enabled: false host: "localhost" port: 3306 database: "lifesteal" username: "root" password: "" pool-size: 10 server-id: "server-1" # ─── TOGGLE SYSTEM ────────────────────────────── toggle: sync-interval-seconds: 30 # ─── RECIPES ──────────────────────────────────── recipes: heart: enabled: true shape: - "DND" - "NGN" - "DND" ingredients: D: DIAMOND N: NETHER_STAR G: GOLD_INGOT revive_beacon: enabled: true shape: - "ENE" - "OBO" - "OOO" ingredients: E: ENDER_EYE N: NETHER_STAR O: OBSIDIAN B: BEACON # ─── GUI TEXT ─────────────────────────────────── # All GUI titles and button labels are configurable here. gui-text: recipe-editor-title: "&6&lRecipe Editor: &e{type}" revive-gui-title: "&b&lRevive Beacon - Select Player" rebirth-gui-title: "&c&lREBIRTH" # ... save/cancel buttons, revive lore, and the full rebirth lore blocks # ─── MESSAGES ─────────────────────────────────── # All chat messages. messages: heart-gained: "&a+1 ❤ You now have &e{hearts}&a hearts!" heart-lost: "&c-1 ❤ You now have &e{hearts}&c hearts!" heart-withdrawn: "&aWithdrawn &e{amount}&a heart(s)!" banned: "&cYou have lost all your hearts and have been eliminated!" revived: "&aYou have been revived with 1 heart!" spawn-kill-blocked: "&cSpawn kill protection! No hearts were transferred." alt-kill-blocked: "&cAlt account detected! No hearts were transferred." rebirth-success: "&a⭐ You have successfully rebirthed!" # ... plus the full toggle-system message set ``` --- # AjdnikovRewards++ — Playtime & Staff Rewards | ajdnikov URL: https://www.ajdnikov-dev.com/ajdnikovrewards Updated: 2026-11-08 > AjdnikovRewards++ is a Paper plugin for playtime and staff-action rewards, with Discord account linking, staff streaks and promotions. Skip to content ## AjdnikovRewards++ Paper 1.21+ v 2.0.2 Playtime and AFK tracking, rewards for staff moderation actions, streaks and automatic promotions, a Discord bot with account linking, and a GUI admin panel for the whole reward flow. Read the manual Get it on BuiltByBit (https://builtbybit.com/creators/ajdnikov.766669/) Ask in Discord (https://discord.gg/xyjmcjMp4W) ### What it talks to U01 U02 #### Ports Vault, LuckPerms and PlaceholderAPI are soft dependencies — the plugin starts without them and switches those features off. - SQLite - MySQL - LuckPerms - Vault - PlaceholderAPI - Discord Patch field 6 RUNS - SQLite - MySQL - LuckPerms - Vault - PlaceholderAPI - Discord ### Key Features A01 #### Playtime Tracking - AFK detection — AFK time can be excluded - All-time, today, this week and this month - `/playtimetop` leaderboards with heads A02 #### Custom Rewards - Playtime, moderation, or both combined - One-time, repeating, or once per day / week / month - Given automatically, or claimed in the `/rewards` menu A03 #### Staff Moderation Tracking - Bans, warns, mutes and kicks from any punishment plugin - Rolling daily, weekly and monthly windows - A Staff Activity view in game A04 #### Staff Streaks - Playtime and points goals per period - Automatic promotion commands per streak level - Only players with `ptr.staff` are evaluated A05 #### Discord Bot Integration - Account linking with a 6-digit code - LuckPerms group to Discord role sync - Reward DMs, announcements and a weekly report A06 #### Everything In Game - `/ptr` edits every reward, setting and message - Create, duplicate and test rewards on yourself - Player profiles with playtime and reward history ### Questions before you commit? Support, licence keys, bug reports and feature requests all run through the Discord. Ask anything about AjdnikovRewards++ there — including whether it fits the server you already run. Already bought it? Your licence lives in the licence portal (https://license.ajdnikov-dev.com) — sign in there for your keys, or claim one with `/claim` in the Discord. Join the Discord (https://discord.gg/xyjmcjMp4W) Back to all plugins --- # AjdnikovRewards++ Documentation | ajdnikov URL: https://www.ajdnikov-dev.com/ajdnikovrewards/docs Updated: 2026-11-08 > AjdnikovRewards++ 2.0 Documentation - in-game editors, rewards, claiming, commands, permissions, PlaceholderAPI placeholders, staff tracking and streaks, Discord linking and the full config.yml ## AjdnikovRewards++ Documentation Version 2.0.2 Platform Paper 1.21+ Storage SQLite or MySQL Bot Discord AjdnikovRewards++ tracks playtime (with AFK detection), monitors staff moderation actions, and grants configurable rewards — automatically, or by letting players claim them. It integrates with Discord for account linking, role sync, reward DMs and announcements, and weekly reports. Everything is configurable in-game: run `/ptr`. ### Overview - Playtime tracking with AFK detection — all-time, today, this week and this month. - Rewards for playtime, for staff moderation actions, or both — one-time or repeating, given automatically or claimed by players. - Staff moderation tracking from any punishment plugin, staff streaks and automatic promotions . - A Discord bot with account linking, role sync, reward DMs, announcements and a weekly report. - In-game editors for every reward, setting and message — no YAML editing needed. - PlaceholderAPI placeholders for playtime, ranks, rewards and streaks. ### What's New in 2.0 #### 2.0.2: Support dumps Since 2.0.2, `/ptr dump` makes a private link for support. The page shows AjdnikovRewards++'s own log next to the full server log, and your server's setup: software and version, uptime, TPS, RAM, disk, CPU, Java, worlds, every plugin, and `config.yml` with keys, passwords and webhooks blanked out. Only you see the link in chat: click it, or click [Copy] , and send it to whoever helps you on Discord (https://discord.gg/xyjmcjMp4W). - `/ptr dump 6` covers only the last 6 hours. `/ptr dump local` uploads nothing and saves the dump in `plugins/AjdnikovRewards/dumps/` as a readable `.txt` and a `.json.gz`. - On the page you can filter and search both logs, show only the lines about AjdnikovRewards++ (stack traces included), and save everything to your PC as `.txt` or `.json`. A saved `.json` opens again at `license.ajdnikov-dev.com/dump` after the link has expired. - The link works for `dump.link-hours` (24 by default, at most 168). You can remove it sooner on your licence page under Dumps . - IP addresses are replaced with `x.x.x.x` unless you set `dump.hide-ips: false`. - Needs `ptr.dump` (ops by default). ``` dump: # Hours of AjdnikovRewards++'s log to keep on disk (dump-logs/) and put in a dump. log-hours: 48 # How long the link works, in hours (at most 168). link-hours: 24 # Replace IP addresses in the logs with x.x.x.x. hide-ips: true ``` What a dump contains and how long it is kept: AnziLock → Support Dumps . #### 2.0.1: Automatic updates AjdnikovRewards++ now updates itself. When a new version is released, it checks your licence again, downloads the new jar into `plugins/update`, and the server loads it on the next restart. The file is kept only if its size and checksum match the signed licence answer. Nothing changes while the server is running. - Turn it off with `auto-update: false` in `config.yml`. - Players with `ptr.updates` (ops by default) are told on join when a new version is waiting for a restart. - New settings are added to `config.yml` with their comments, keeping your values (the old file is kept as `config.yml.bak`). Your promotions, `rewards.yml` and `staff-rewards.yml` are never touched: example promotions and rewards are not added back, even if you deleted them. - Coming from 2.0.0 or older? Install 2.0.1 or newer by hand once. Every later version arrives by itself. How the download is checked: AnziLock → Automatic Updates . #### Upgrading from 1.x Drop in the new jar and restart. Nothing needs to be deleted. - New options are added automatically to your existing `config.yml` — only missing keys; nothing you set or removed is touched. - New database tables are created automatically (`ptr_playtime_daily`, `ptr_pending_rewards`, `ptr_meta`). - Your `rewards.yml` / `staff-rewards.yml` keep working unchanged. New optional keys: `icon`, `permission`, `playtime-period`, `claim-mode`, `minecraft.broadcast`. - Daily/weekly/monthly playtime starts counting from the moment 2.0 is installed (there was no per-day data before). - If you use staff streaks , give your staff the `ptr.staff` permission (default: op). Only players with it are evaluated now. #### Highlights - Full in-game editors : a dashboard, a reward editor for every field, create/duplicate/delete rewards, test a reward on yourself, a settings editor for every `config.yml` option, a messages editor with live preview, a promotions editor, and a player browser with profiles. - `/rewards` is now a menu with status, progress bars, requirements and click-to-claim, plus manual claiming (`claim-mode: MANUAL`). - Calendar-period playtime (`playtime-period: DAILY | WEEKLY | MONTHLY`): "play 1 hour today" rewards that reset each day, week or month. - Leaderboards menu (`/playtimetop`) for all-time, this month, this week and today. - PlaceholderAPI placeholders are now implemented, all served from a cache. - Tab completion everywhere , including offline player names and reward IDs. #### Notable fixes - Discord slash commands, buttons and role sync never fired in the obfuscated release jar — fixed. - AFK time was never actually recorded or excluded, and with `exclude-afk: true` rewards could be granted too early — fixed. - Rewards given to offline players lost their money, commands and ranks. The whole payout is now queued and delivered on next join. - Discord staff commands were usable by anyone when `discord.staff-role-id` was empty. Now Discord administrators only. - Staff streaks were rewritten: they now measure playtime in the period, read points from the right file, and only evaluate staff. - MySQL 8 failed on start-up; repeating rewards could be granted twice; `/ptr reload` did not reload `staff-rewards.yml`; heads in menus no longer block the main thread. ### Quick Start - Put `AjdnikovRewards-2.0.2.jar` in `plugins/` and start the server. - Put your licence key in `plugins/AjdnikovRewards/config.yml` → `license.key` and restart. Keys are issued in the Discord with `/claim`. - In game, run `/ptr` : - Settings → Discord : set the bot token and guild ID (restart after setting these). - Player Rewards / Staff Rewards : edit the bundled rewards or click + Create Reward . - Players use `/rewards` to see their progress and claim rewards. #### AnziLock License AjdnikovRewards++ is protected by AnziLock . Insert the key you received in the Discord into `config.yml`: ``` license: key: "YOUR_LICENSE_KEY_HERE" ``` ### In-Game Editors `/ptr` opens the admin dashboard: Button | What it does Stats | Online/tracked players, linked accounts, rewards today, integration status (Vault, LuckPerms, PlaceholderAPI, Discord, database) Player Rewards / Staff Rewards | Paged reward lists — filter, sort, create, duplicate (Q), toggle (Shift-click), delete (Right-click) Players | Online / recently seen / search → player profiles Leaderboards | All-time, this month, this week, today Staff Activity | Staff ranked by moderation actions (24h / 7d / 30d) Settings | Every `config.yml` option, grouped by category Messages | Every chat message, with preview and reset Reload | Reload all files from disk #### Reward editor Every field of a reward is editable, grouped into rows: - General — display name, description, icon (click with an item on your cursor, or use the item in your hand), enabled, trigger type, one-time/repeating, claim mode - Requirements — playtime required, which playtime counts (all-time/today/this week/this month), repeat interval, cooldown, moderation requirements, required prior reward, permission - Payouts — money, items (drag-and-drop editor that keeps NBT, enchantments and names), commands, LuckPerms groups, broadcast, staff points - Discord — roles, DM message, announcement channel and message - Actions — test on yourself, enable/disable, duplicate, delete Changes save to disk immediately. When a value is typed in chat you get a title prompt, [Insert] to put the current value in your chat box, examples, validation with retry, `cancel` to abort, `clear` to remove optional values, and a 2-minute timeout. Your input is never shown to other players. Durations accept `30m`, `1h 30m`, `1.5h`, `2d`, `1w`, `2 hours 15 minutes`. Money accepts `500`, `2.5k`, `1m`. #### Settings editor Every option shows its current value and a description. Toggles flip on click, numbers use Left/Right (±) or Shift-click to type, choices cycle, text is typed in chat, and lists open a list editor. Q resets an option to its default. Options marked restart required (bot token, guild ID, database) take effect after a restart; everything else applies immediately. #### Player profiles Playtime (total, today, week, month, stored AFK), Discord link (force-link / unlink), rewards received (with revoke), give reward, set/add/remove/reset playtime, moderation stats with recent actions, re-check rewards, and "view their `/rewards` menu" to see exactly what they see. ### Player Experience - `/rewards` — a menu of every reward: ready, a progress bar while in progress, claimed, cooldown until the next period, or locked (with the reason). It shows what each reward gives. Click to claim, or Claim All when several are ready. Staff (`ptr.staff`) can switch to the staff rewards tab. - `/playtime` — total, today, this week, this month and progress to the next milestone. - `/playtimetop [all|month|week|today]` — the leaderboard menu, with player heads. - Rewards play a title, a sound and an optional harmless firework (all configurable), and can broadcast to the server. - `/link` gives a 6-digit code with a click-to-copy button. ### Configuration Files All three files — `config.yml`, `rewards.yml` and `staff-rewards.yml` — can be edited in game. Editing by hand and running `/ptr reload` also works. New options are added to existing configs automatically on start-up. #### config.yml Section | Key | Default | Description License | `license.key` | — | Your AnziLock licence key Updates | `auto-update` | `true` | Download new versions automatically; they load on the next restart (restart) . See Automatic updates . Discord | `bot-token` | — | Discord bot token (restart) | `guild-id` | — | Discord server ID (restart) | `discord.staff-role-id` | — | Role for staff slash commands (empty = Discord administrators only) | `discord.announcement-channel` | — | Default channel for announcements | `discord.bot-status` | `Watching {online} players online` | Bot activity Linking | `linking.require-link` | `false` | Require a Discord link to play (bypass: `ptr.bypasslink`) | `linking.link-code-expiry` | `600` | Link code validity (seconds) | `linking.limbo-world` | `limbo` | World for unlinked players (empty = kick) | `linking.tab-suffix` | `true` | `[Linked]` / `[Unlinked]` in the tab list Playtime | `playtime.afk-detection` | `true` | Detect AFK players | `playtime.afk-threshold` | `300` | Seconds of no movement or looking around before AFK | `playtime.exclude-afk` | `true` | AFK time doesn't count | `playtime.autosave-interval` | `5` | Minutes between saves | `playtime.check-interval` | `60` | Seconds between reward checks | `playtime.timezone` | `""` | Time zone for daily/weekly/monthly playtime, e.g. `Europe/Berlin` (empty = server). Weeks start on Monday. Rewards | `rewards.claim-mode` | `AUTO` | `AUTO` = given instantly, `MANUAL` = players claim in `/rewards` | `rewards.notify-unclaimed` | `true` | Notify players about claimable rewards, and on join | `rewards.effects.title` | `true` | Title on reward | `rewards.effects.sound` | `entity.player.levelup` | Sound key (empty = none) | `rewards.effects.firework` | `false` | Harmless firework on reward Database | `database.*` | `sqlite` | `sqlite` or `mysql`, plus connection and pool settings (restart) Moderation | `moderation-tracking.enabled` | `true` | Track bans/warns/mutes/kicks | `moderation-tracking.track-commands` | `[...]` | Extra command names to track Staff Streaks | `staff-streaks.enabled` | `true` | Enable streaks | `staff-streaks.staff-permission` | `ptr.staff` | Who counts as staff | `staff-streaks.interval-days` | `7` | Period length | `staff-streaks.playtime-goal-seconds` | `72000` | Playtime needed per period (20 hours) | `staff-streaks.points-goal` | `0` | Staff points needed per period (0 = off) | `staff-streaks.promotions` | — | Streak count → commands Weekly Report | `weekly-report.enabled` / `day` / `time` / `channel` | `true` / `SUNDAY` / `00:00` / — | Automatic Discord summary GUI | `gui.click-sounds` | `true` | Menu sounds Messages | `messages.*` | — | All messages (MiniMessage; legacy `&` codes work) #### rewards.yml / staff-rewards.yml ``` rewards: example_reward: enabled: true icon: DIAMOND # Menu icon (optional) type: PLAYTIME # PLAYTIME | MODERATION | COMBINED one-time: true # false = repeating playtime-required: 3600 # Seconds playtime-period: TOTAL # TOTAL | DAILY | WEEKLY | MONTHLY repeat-interval: 0 # Repeating TOTAL rewards: extra playtime between grants (0 = same as requirement) cooldown: 0 # Minimum seconds between grants (repeating) display-name: "Example" description: "Shown to players" value: 0 # Staff points requires: other_reward_id # Must be earned first (optional) permission: rewards.vip # Only players with this permission (optional) claim-mode: DEFAULT # DEFAULT | AUTO | MANUAL moderation: # MODERATION / COMBINED bans: 0 warns: 0 mutes: 0 kicks: 0 period: WEEKLY # DAILY (24h) | WEEKLY (7d) | MONTHLY (30d) - rolling window minecraft: money: 1000 # Vault roles: [vip] # LuckPerms groups commands: # Console; {player}, {uuid}, {reward_id} - "give {player} diamond 5" items: [] # Exact items - use the in-game item editor broadcast: "{player} earned {reward_name}!" discord: roles: ["123456789012345678"] # Role IDs or exact names dm-message: "Congrats!" announcement-channel: "" # Empty = default channel announcement-message: "{discord_mention} earned **{reward_name}**!" ``` Bundled player rewards: `playtime_1h` → `playtime_10h` → `playtime_24h` → `playtime_50h` → `veteran_player` (500h, chained with `requires`), plus `daily_playtime` (1h today , once per day) and `weekly_playtime` (10h this week , once per week). Bundled staff rewards: `active_moderator`, `warning_duty`, `mute_master`, `swift_justice`, `ban_hammer_monthly`, `dedicated_staff` (10h this month + 5 bans), `staff_of_the_month` (50h this month + 15 bans). ### Reward System #### Types Type | Trigger `PLAYTIME` | Playtime reaches the requirement `MODERATION` | Moderation action counts reach the requirements (rolling window) `COMBINED` | Both playtime and moderation requirements #### Which playtime counts `playtime-period` | Counts | Repeats `TOTAL` (default) | All-time playtime | One-time, or every `repeat-interval` of extra playtime `DAILY` | Playtime today | Once per day `WEEKLY` | Playtime this week (Mon–Sun) | Once per week `MONTHLY` | Playtime this month | Once per month Calendar periods use `playtime.timezone`. When `exclude-afk` is on, AFK time doesn't count. #### Claiming - `AUTO` — granted within `check-interval` seconds (and shortly after join). - `MANUAL` — players are notified and click the reward in `/rewards`. Eligibility is re-checked on claim. - A reward's own `claim-mode` overrides the global setting; `DEFAULT` follows it. #### Payouts A reward can pay any combination of Vault money, exact items, console commands (with `{player}`, `{uuid}` and `{reward_id}`), LuckPerms groups, a server broadcast, staff points (`value`), Discord roles, a Discord DM and an announcement. #### Offline players Rewards given to offline players (`/ptr give`) are recorded immediately; the in-game payout (money, items, commands, ranks) is delivered on their next join. Discord payouts happen immediately. #### Prerequisites & permissions `requires` locks a reward until another is earned; `permission` limits it to players with a permission. Locked rewards show the reason in `/rewards`. ### Commands #### Players Command | Description | Permission `/rewards` | Rewards menu (progress, claim). Alias `/reward` | `ptr.rewards` `/rewards claim` | Claim everything that's ready | `ptr.rewards` `/rewards ` | View another player's rewards | `ptr.rewards.others` `/playtime [player]` | Playtime stats. Alias `/pt` | `ptr.playtime` (`ptr.playtime.others` for others) `/playtimetop [all|month|week|today]` | Leaderboards. Aliases `/pttop`, `/ptop` | `ptr.playtime` `/link` · `/unlink` | Discord linking | `ptr.link` #### Admin — /ptr Aliases: `/ptrconfig`, `/playtimerewards`, `/ajdnikovrewards`. Command | Description | Permission `/ptr` | Admin dashboard | `ptr.admin` `/ptr help` | Clickable command list | `ptr.admin` `/ptr rewards [player|staff]` | Reward manager | `ptr.admin` `/ptr create [player|staff]` | Create a reward and open its editor | `ptr.admin` `/ptr edit ` | Open a reward's editor | `ptr.admin` `/ptr give ` | Give a reward (alias `forcepayout`) | `ptr.admin.reward` `/ptr revoke ` | Revoke a reward | `ptr.admin.reward` `/ptr player ` · `/ptr players` | Player profile / browser | `ptr.admin` `/ptr playtime [time]` | Change playtime | `ptr.admin.setplaytime` `/ptr check [player]` | Run the reward check now | `ptr.admin` `/ptr staff` | Staff activity | `ptr.admin` `/ptr settings` · `/ptr messages` | Editors | `ptr.admin` `/ptr link ` | Force-link (also `/stafflink`) | `ptr.admin.link` `/ptr linkrole ` | Link a LuckPerms group to a Discord role | `ptr.admin.linkrole` `/ptr reload` | Reload everything | `ptr.admin.reload` `/ptr dump [hours] [local]` | A private link with the plugin's log, the full server log and your server's setup, for support (see Support dumps ) | `ptr.dump` `/rewardgive` · `/rewardrevoke` | Same as `/ptr give` / `revoke` | `ptr.admin.reward` `/weeklyreport` | Send the weekly report now | `ptr.admin.report` All commands tab-complete subcommands, player names (including offline players) and reward IDs. #### Discord slash commands Command | Who | Description `/link ` | Players | Link your Minecraft account using the 6-digit code `/unlink` | Players | Unlink your Minecraft account `/playtime [username]` | Players | Your or someone's playtime `/rewards [username]` | Players | Earned and pending rewards `/leaderboard` | Players | The playtime leaderboard `/profile` | Players | Your linked profile `/stafflink ` | Staff | Force-link a Minecraft account to a Discord user `/rewardgive` · `/rewardrevoke ` | Staff | Grant or revoke a reward (reward IDs autocomplete) `/setplaytime