{"id":50400500,"url":"https://github.com/synkfr/stuffplus","last_synced_at":"2026-05-30T23:03:29.195Z","repository":{"id":361408434,"uuid":"1254347371","full_name":"synkfr/StuffPlus","owner":"synkfr","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-30T14:59:11.000Z","size":166,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-30T15:09:38.627Z","etag":null,"topics":["admin","admintools","folia","folia-plugin","folia-supported","java","minecraft","minecraft-plugin","paper","paper-plugin","papermc-plugin","plugin","purpur-plugin","stuff","utility"],"latest_commit_sha":null,"homepage":"https://synkfr.github.io/StuffPlus/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/synkfr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-30T13:01:56.000Z","updated_at":"2026-05-30T14:58:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/synkfr/StuffPlus","commit_stats":null,"previous_names":["synkfr/stuffplus"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/synkfr/StuffPlus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synkfr%2FStuffPlus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synkfr%2FStuffPlus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synkfr%2FStuffPlus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synkfr%2FStuffPlus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/synkfr","download_url":"https://codeload.github.com/synkfr/StuffPlus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synkfr%2FStuffPlus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33712582,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admin","admintools","folia","folia-plugin","folia-supported","java","minecraft","minecraft-plugin","paper","paper-plugin","papermc-plugin","plugin","purpur-plugin","stuff","utility"],"created_at":"2026-05-30T23:03:20.310Z","updated_at":"2026-05-30T23:03:29.187Z","avatar_url":"https://github.com/synkfr.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Stuff](https://cdn.modrinth.com/data/cached_images/3d527e1c3549243fb7545c033e4c0106849f1849.png)\n\n\n# Stuff+\n\nStuff+ is an enterprise-grade, high-performance moderation and utility plugin built for modern Minecraft networks. It ships as **two platform-specific JARs** — one for **Paper/Purpur/Folia** backend servers and one for **Velocity** proxies — sharing a unified core engine for consistent punishment management across your entire network.\n\n**Paper Edition** runs on Paper/Purpur/Folia 1.20–1.21+ servers with full Folia multi-threaded region safety, and includes advanced staff tools like vanish, inventory inspection, and spectator monitoring.\n\n**Velocity Edition** runs on Velocity 3.3.0+ proxies and enforces bans, IP-bans, and mutes at the network gateway before players even reach a backend server.\n\nBoth editions share the same database, configs, and migration system — deploy one or both depending on your setup.\n\n---\n\n## Platform Comparison\n\n| Feature | Paper (Paper/Purpur/Folia) | Velocity (Proxy) |\n| :--- | :---: | :---: |\n| Ban / TempBan / Unban | ✅ | ✅ |\n| IP-Ban / TempIP-Ban / UnIP-Ban | ✅ | ✅ |\n| Mute / TempMute / Unmute | ✅ | ✅ |\n| Warn / Warns / Clear | ✅ | ✅ |\n| History / StaffHistory | ✅ | ✅ |\n| Staff Rollback | ✅ | ✅ |\n| IP-Ban Exemption (`/stuffallow`) | ✅ | ✅ |\n| Punishment Migration (`/stuffimport`) | ✅ | ✅ |\n| Discord Webhook Logging | ✅ | ✅ |\n| Warning Escalation Ladder | ✅ | ✅ |\n| Hierarchy Protection | ✅ | ✅ |\n| Alt-Detection (IP Matching) | ✅ | ✅ |\n| SQLite / MySQL Storage | ✅ | ✅ |\n| Vanish System | ✅ | ❌ |\n| Spectator Monitor/Follow | ✅ | ❌ |\n| Inventory Inspector (`/invsee`) | ✅ | ❌ |\n| Gamemode Shortcuts | ✅ | ❌ |\n| Flight Toggle (`/fly`) | ✅ | ❌ |\n| bStats Metrics | ✅ | ✅ |\n| Folia Scheduler Safety | ✅ | N/A |\n| Proxy-Level Ban Enforcement | ❌ | ✅ |\n\n---\n\n## Features\n\n### Cross-Platform Core\n* **Shared Database**: Both Paper and Velocity editions read and write to the same punishment database (SQLite or MySQL), enabling seamless network-wide moderation.\n* **Shared Configs**: `config.yml` and `messages.yml` use identical formats on both platforms via the Okaeri configuration framework.\n* **Unified Migration Engine**: Import punishments from 7+ plugins on either platform.\n\n### Folia Safety (Paper Edition)\n* **Asynchronous Lifecycles**: All commands, database transactions, and packet actions run on Folia-compliant regional or asynchronous schedulers.\n* **Folia Teleportation Safety**: Standard teleports are replaced with safe, non-blocking `teleportAsync` futures, completely preventing thread crashes.\n* **Isolated Packet Loops**: Visually toggling features (like Vanish hide/show packets) are scheduled on each recipient's specific regional thread, guaranteeing thread-safety.\n\n### Proxy Gateway Enforcement (Velocity Edition)\n* **Pre-Login Ban Check**: Intercepts login attempts at the proxy level and rejects banned players before they reach any backend server.\n* **Network-Wide Mute Filter**: Blocks chat messages from muted players across all connected servers.\n* **IP-Ban Gateway**: Enforces IP bans at the proxy gateway, preventing banned IPs from connecting to any server in the network.\n\n### Vanish (Paper Only)\n* **Total Invisibility**: Completely removes the player from the online count, player ping lists, tab completions, and visible lists.\n* **Physical Interaction Bypass**: Vanished staff bypass physical pressure plates and tripwire triggers entirely.\n* **Silent Containers**: Allows opening chest, furnace, and barrel interfaces silently without triggering container animations or audio.\n* **Stealth Suppression**: Prevents mob targeting, item pickups, and suppresses join/quit messages entirely while active.\n* **Visual Action Bar Indicator**: Real-time HUD showing vanished status via safe asynchronous repeating tasks.\n\n### Moderation (Both Platforms)\n* **Comprehensive Actions**: Integrated `/ban`, `/tempban`, `/ip-ban`, `/tempip-ban`, `/mute`, `/tempmute`, and `/warn`.\n* **Warning Profiles**: Track individual warning logs via `/warns \u003cplayer\u003e [list/clear]`.\n* **Dynamic Time Parsing**: Sophisticated time parser supporting complex units (e.g. `1d`, `12h`, `45m`) and infinite duration mappings (`perm`).\n* **Relational Storage**: Backed by a high-performance database manager supporting both local SQLite databases and remote MySQL servers, managed via a shaded, thread-safe HikariCP connection pool.\n* **Linked Account Alt-Detection**: On player login, automatically scans, logs, and broadcasts alternate accounts sharing the IP address, color-coding active (green) and banned (red) profiles.\n* **Dynamic Command \u0026 History Parity**: Multi-threaded `/history \u003cplayer\u003e`, `/staffhistory \u003cstaff\u003e`, and `/staffrollback \u003cstaff\u003e` commands supported by dynamic database-backed name tab completions.\n* **Warning Escalation Ladder**: Scale punishments dynamically (e.g. tempmutes scaling to permanent bans) based on active warning levels. Command dispatches execute safely on each platform's native scheduler.\n* **Non-Blocking Discord Webhook Logs**: Real-time embeds logging all mute, ban, and warning dispatches using modern non-blocking Java 21 `HttpClient` interfaces with zero impact on region ticks.\n* **Administrative Overwrite Hierarchy Protection**: Custom staff weight ranks (`stuff.hierarchy.weight.\u003cnumber\u003e`) blocking junior staff from overriding, deactivating, or removing punishments placed by senior administrators or the Console (`Integer.MAX_VALUE`).\n* **IP-Ban Exemption Bypass**: Whitelist specific accounts (`/stuffallow`) to connect and bypass active IP-bans without lifting the IP ban itself for other accounts sharing the IP.\n\n### Punishment Importer \u0026 Migration (Both Platforms)\n* **7 Supported Platforms**: Seamlessly import mutes, bans, warnings, and IP bans from:\n  * **Vanilla Minecraft**: Direct imports from `banned-players.json` and `banned-ips.json` in the server root.\n  * **Essentials / EssentialsX**: Automated scans of mutes and bans in user profiles under `plugins/Essentials/userdata/*.yml`.\n  * **LiteBans**: Migrates bans, mutes, and warnings from H2/SQLite/MySQL databases. Supports auto-detection of the `litebans.mv.db` H2 file or manual JDBC parameters.\n  * **AdvancedBan**: Integrates and normalizes legacy SQL `Punishments` tables from SQLite or MySQL.\n  * **MaxBans**: Migration of bans, IP bans, mutes, and warnings from SQLite or MySQL.\n  * **BanManager**: Integrates historical player bans, mutes, and warnings with configurable table prefixes.\n  * **BungeeAdminTools (BAT)**: Imports entries from database tables `bat_ban` and `bat_mute`.\n* **Dynamic Auto-Scanning**: Scans your server's active files on command, extracts SQLite paths or remote SQL database credentials, and allows zero-configuration migrations.\n* **Batch Operations**: Commits imported records inside a single transaction using batch inserts, migrating thousands of records instantly.\n* **Non-Blocking Futures**: Runs connection setups, configuration decodes, and database commits fully asynchronously on non-blocking thread pools.\n\n### Spectator Follow (Paper Only)\n* **Cinematic Camera Tracking**: Teleports staff in spectator mode to follow the target seamlessly.\n* **Velocity-Predicted Follow**: Computes target movements and velocity vectors (`target.getVelocity()`) to position the camera slightly ahead of the target, eliminating stutter and rubber-banding.\n* **Throttled Teleports**: Auto-updates run at a throttled 4-tick (200ms) interval with a 400ms cooldown, giving client-side predicted movements and Paper's async teleportation futures time to fully resolve.\n* **Configurable Boundary Tether**: Allows staff to orbit or move freely within a 10-block radius. Going beyond the boundary gently tethers the camera back into offset.\n\n### Inventory Inspector (Paper Only)\n* **54-Slot Live GUI**: View and edit target players' main inventories (0-35), armor slots (helmet, chestplate, leggings, boots), off-hand items, and stats.\n* **Live Stats \u0026 Shortcuts**:\n  * **Golden Apple**: Displays health, food levels, and experience dynamically.\n  * **Potion Bottle**: Shows a live list of active potion effects and durations.\n  * **Ender Chest**: Quick-access shortcut item to inspect their Ender Chest directly.\n* **Unparalleled Folia Safety**: Completely avoids asynchronous block-state reads (which crash under Folia when querying `.getOpenInventory().getTopInventory().getHolder()` on block-based inventories in other regions). Instead, it implements a thread-safe custom session registry that cleanly tracks active inspect views and propagates updates regionally.\n\n### Shortcuts (Paper Only)\n* **Instant Gamemode Shifts**: Rapid commands including creative (`/gmc`), survival (`/gms`), spectator (`/gmsp`), and adventure (`/gma`).\n* **Flight Mode**: Seamless command flight toggles via `/fly`.\n\n---\n\n## Commands \u0026 Permissions\n\n### Network-Wide Commands (Paper \u0026 Velocity)\n\n| Command | Description | Usage | Permission Node |\n| :--- | :--- | :--- | :--- |\n| `/ban` | Bans a player from the server. | `/ban \u003cplayer\u003e [reason]` | `stuff.ban` |\n| `/tempban` | Temporarily bans a player. | `/tempban \u003cplayer\u003e \u003cduration\u003e [reason]` | `stuff.tempban` |\n| `/unban` | Unbans a player. | `/unban \u003cplayer\u003e` | `stuff.unban` |\n| `/ip-ban` | IP-bans a player. | `/ip-ban \u003cplayer\u003e [reason]` | `stuff.ipban` |\n| `/tempip-ban` | Temporarily IP-bans a player. | `/tempip-ban \u003cplayer\u003e \u003cduration\u003e [reason]` | `stuff.tempipban` |\n| `/unip-ban` | Unbans an IP address or player. | `/unip-ban \u003cplayer/IP\u003e` | `stuff.unipban` |\n| `/mute` | Mutes a player in chat. | `/mute \u003cplayer\u003e [reason]` | `stuff.mute` |\n| `/tempmute` | Temporarily mutes a player. | `/tempmute \u003cplayer\u003e \u003cduration\u003e [reason]` | `stuff.tempmute` |\n| `/unmute` | Unmutes a player. | `/unmute \u003cplayer\u003e` | `stuff.unmute` |\n| `/warn` | Warns a player. | `/warn \u003cplayer\u003e [reason]` | `stuff.warn` |\n| `/warns` | View or clear warning history. | `/warns \u003cplayer\u003e [list/clear]` | `stuff.warns` |\n| `/history` | View complete punishment logs (active/inactive) for players. | `/history \u003cplayer\u003e` | `stuff.history` |\n| `/staffhistory` | View all punishments issued by a staff member. | `/staffhistory \u003cstaff\u003e` | `stuff.staffhistory` |\n| `/staffrollback` | Rollback all active punishments placed by a staff member. | `/staffrollback \u003cstaff\u003e [confirm]` | `stuff.staffrollback` |\n| `/stuffallow` | Exempt a player/UUID from active IP bans. | `/stuffallow \u003cplayer\u003e [remove]` | `stuff.stuffallow` |\n| `/stuffimport` | Import punishments from other plugins. | `/stuffimport \u003csource\u003e [params...]` | `stuff.import` |\n\n### Paper-Only Commands\n\n| Command | Description | Usage | Permission Node |\n| :--- | :--- | :--- | :--- |\n| `/vanish` | Toggle complete invisibility. | `/vanish` | `stuff.vanish` |\n| `/invsee` | Inspect a player's inventory live. | `/invsee \u003cplayer\u003e` | `stuff.invsee` |\n| `/monitor` | Spectate and smoothly follow a player. | `/monitor \u003cplayer/leave\u003e` | `stuff.monitor` |\n| `/fly` | Toggle player flight. | `/fly [player]` | `stuff.fly` |\n| `/gmc` | Switch to creative mode. | `/gmc [player]` | `stuff.gmc` |\n| `/gms` | Switch to survival mode. | `/gms [player]` | `stuff.gms` |\n| `/gmsp` | Switch to spectator mode. | `/gmsp [player]` | `stuff.gmsp` |\n| `/gma` | Switch to adventure mode. | `/gma [player]` | `stuff.gma` |\n\n\u003e **Admin Wildcard**: The permission node `stuff.admin` grants access to all capabilities of the plugin by default.\n\u003e **Bypass Node**: Players with the permission `stuff.vanish.see` can see vanished players in-game, in tab lists, and in commands.\n\n---\n\n## Installation\n\n### Paper Edition (Paper / Purpur / Folia)\n1. Download `StuffPlus-Paper-1.0.0.jar` from [Releases](https://github.com/synkfr/StuffPlus/releases).\n2. Place the JAR in your server's `plugins/` folder.\n3. Restart your server.\n4. Edit `plugins/Stuff/config.yml` and `plugins/Stuff/messages.yml` to your liking.\n\n### Velocity Edition (Proxy)\n1. Download `StuffPlus-Velocity-1.0.0.jar` from [Releases](https://github.com/synkfr/StuffPlus/releases).\n2. Place the JAR in your Velocity proxy's `plugins/` folder.\n3. Restart your proxy.\n4. Edit `plugins/stuffplus/config.yml` and `plugins/stuffplus/messages.yml` to your liking.\n\n### Shared Database (Network Mode)\nTo share punishments across your entire network, configure **both** editions to use the same MySQL database:\n\n```yaml\n# config.yml (same on both Paper and Velocity)\nstorage-type: \"mysql\"\nmysql-host: \"your-db-host\"\nmysql-port: 3306\nmysql-database: \"stuffplus\"\nmysql-username: \"your-user\"\nmysql-password: \"your-password\"\n```\n\n---\n\n## Configuration\n\nThe plugin uses Okaeri Config to generate, validate, and auto-update clean YAML configuration structures. Both platforms share identical configuration formats.\n\n### `config.yml`\n```yaml\n# Storage type: SQLITE or MYSQL\nstorage-type: \"sqlite\"\n\n# MySQL Connection Details (only used if storage-type is MYSQL)\nmysql-host: \"localhost\"\nmysql-port: 3306\nmysql-database: \"minecraft\"\nmysql-username: \"root\"\nmysql-password: \"password\"\nmysql-pool-size: 10\nmysql-use-ssl: false\n\n# Vanish settings (Paper only — ignored on Velocity)\nvanish-silent-container-clicks: true\nvanish-ignore-pressure-plates: true\nvanish-disable-mob-targeting: true\nvanish-disable-item-pickup: true\n\n# Warning escalation ladder settings\nwarning-ladder-enabled: true\n\n# Actions to run when a player reaches a specific number of active warnings\nwarning-ladder-actions:\n  1: \"tempmute {player} 1h [Warning Ladder] First warning\"\n  2: \"tempmute {player} 12h [Warning Ladder] Second warning\"\n  3: \"tempban {player} 3d [Warning Ladder] Reached 3 warnings\"\n  4: \"ban {player} [Warning Ladder] Reached 4 warnings\"\n\n# Discord Webhook logging settings\ndiscord-webhook-enabled: false\ndiscord-webhook-url: \"\"\ndiscord-webhook-username: \"Stuff+ Moderation\"\ndiscord-webhook-avatar-url: \"https://i.imgur.com/8Qp49X0.png\"\n\n# Hex color codes for webhook embeds (without the #)\ndiscord-webhook-color-ban: \"FF5555\"\ndiscord-webhook-color-mute: \"FFAA00\"\ndiscord-webhook-color-warn: \"FFFF55\"\n```\n\n### `messages.yml`\nFeatures full Adventure MiniMessage compatibility, enabling gorgeous native text styling, hex colors, and gradients (e.g. `\u003cgradient:#FF5F6D:#FFC371\u003eText\u003c/gradient\u003e`).\n```yaml\n# Prefix for all plugin messages\nprefix: \"\u003ccolor:#A0A0A0\u003e[\u003ccolor:#00E262\u003eStuff+\u003ccolor:#A0A0A0\u003e] \"\n\nno-permission: \"\u003ccolor:#E20000\u003eYou do not have permission to execute this command.\"\nplayer-only: \"\u003ccolor:#E20000\u003eThis command can only be executed by a player.\"\ncannot-overwrite-punishment: \"\u003ccolor:#E20000\u003eYou cannot override a punishment placed by a higher-ranking staff member ({staff}).\"\nplayer-allowed: \"\u003ccolor:#00E262\u003eYou have allowed {player} to bypass IP bans.\"\nplayer-allowed-broadcast: \"\u003ccolor:#00E262\u003e{player} has been exempted from IP bans by {sender}.\"\nplayer-unallowed: \"\u003ccolor:#00E262\u003eYou have removed IP ban exemption for {player}.\"\nplayer-unallowed-broadcast: \"\u003ccolor:#00E262\u003e{player} is no longer exempted from IP bans.\"\nplayer-not-found: \"\u003ccolor:#E20000\u003ePlayer '{player}' has not been found or registered.\"\ninvalid-duration: \"\u003ccolor:#E20000\u003eInvalid duration format! Use e.g. 1d, 12h, 30m or perm.\"\n\n# Mutes\nplayer-muted: \"\u003ccolor:#00E262\u003eYou have muted {player} for {time}. Reason: {reason}\"\nplayer-muted-broadcast: \"\u003ccolor:#E2B700\u003e{player} has been muted by {sender} for {time}. Reason: {reason}\"\nyou-are-muted: \"\u003ccolor:#E20000\u003eYou are muted! Remaining time: {time}. Reason: {reason}\"\n\n# Bans\nplayer-banned: \"\u003ccolor:#00E262\u003eYou have banned {player} for {time}. Reason: {reason}\"\nplayer-banned-broadcast: \"\u003ccolor:#E20000\u003e{player} has been banned by {sender} for {time}. Reason: {reason}\"\nban-kick-message: \"\u003ccolor:#E20000\u003eYou have been banned from the server!\\n\\nReason: {reason}\\nExpiry: {time}\"\n\n# Vanish (Paper only)\nvanish-enabled: \"\u003ccolor:#00E262\u003eYou are now vanished.\"\nvanish-disabled: \"\u003ccolor:#00E262\u003eYou are no longer vanished.\"\nvanish-action-bar: \"\u003ccolor:#00E262\u003e★ YOU ARE VANISHED ★\"\n```\n\n---\n\n## Build \u0026 Compilation\n\nStuff+ is a **multi-module Gradle project** producing two independent shaded JARs.\n\n### Requirements\n* **Java 21** or higher\n* **Gradle** (installed or via wrapper)\n\n### Build Command\nCompile and build both platform JARs:\n```bash\n./gradlew clean build\n```\n\nThe compiled plugins will be located at:\n```\nstuff-paper/build/libs/StuffPlus-Paper-1.0.0.jar    # Paper/Purpur/Folia servers\nstuff-velocity/build/libs/StuffPlus-Velocity-1.0.0.jar  # Velocity proxies\n```\n\n### Project Structure\n```\nStuffPlus/\n├── stuff-core/          # Shared platform-agnostic library\n│   └── src/main/java/   # Database, Punishment model, Configs, Migration, Utils\n├── stuff-paper/         # Paper/Folia backend plugin\n│   └── src/main/java/   # Paper commands, listeners, vanish, monitor, invsee\n├── stuff-velocity/       # Velocity proxy plugin\n│   └── src/main/java/   # Velocity commands, login/chat listeners\n├── build.gradle          # Root configuration\n└── settings.gradle       # Multi-module declaration\n```\n\n*Note: The Gradle shadow configuration automatically relocates `eu.okaeri`, `com.zaxxer.hikari`, `org.h2`, and `org.xerial` libraries to private namespaces (`me.ayosynk.stuff.libs.*`) to prevent conflicts with any other plugins on the classpath.*\n\n---\n\n## Continuous Integration\n\n`Stuff+` implements a fully automated CI/CD pipeline via GitHub Actions to compile, validate, and distribute artifacts for **both platforms**.\n\n### Dev Builds\n* **Frequency**: Built automatically on every `push` to the `master` or `main` branches.\n* **Release Target**: Published under the rolling **[dev-latest](https://github.com/synkfr/StuffPlus/releases/tag/dev-latest)** pre-release tag on GitHub.\n* **Rolling Policy**: The pipeline automatically overwrites the previous `dev-latest` tag on every build, maintaining a clean releases page.\n* **Artifacts**: Both `StuffPlus-Paper` and `StuffPlus-Velocity` JARs are published in every release.\n\n### Stable Releases\n* **Frequency**: Generated whenever a semantic Git version tag matching `v*` (e.g., `v1.0.0`) is pushed to the repository.\n* **Release Target**: Published as a dedicated production release containing formal release notes and both platform-ready shaded JAR assets.\n\n---\n\n## bStats Metrics\n\nBoth editions of Stuff+ integrate with [bStats](https://bstats.org/) to collect anonymous usage statistics. This helps us understand how the plugin is being used and guides future development.\n\n- **Paper Edition**: Uses `bstats-bukkit` for server-side metrics.\n- **Velocity Edition**: Uses `bstats-velocity` (Plugin ID: `31693`) for proxy-side metrics.\n\nIf you wish to opt-out of anonymous metrics collection, you can disable it by navigating to the `plugins/bStats/config.yml` file on your server or proxy and setting `enabled: false`.\n\n---\n\n## Developer Notes\n\nFor developers looking at the source code of Stuff+, here is a summary of the architecture:\n\n### Multi-Module Architecture\n1. **stuff-core**: Platform-agnostic shared library containing the database layer, punishment model, config system, migration engine, and utility classes. Uses `ForkJoinPool.commonPool()` for async operations — no platform-specific scheduler dependencies.\n2. **stuff-paper**: Paper/Folia plugin implementing `StuffPlatform` interface. Contains all Paper-specific commands, listeners, vanish, monitor, invsee, and gamemode shortcuts. Uses Folia-safe regional schedulers.\n3. **stuff-velocity**: Velocity proxy plugin implementing `StuffPlatform` interface. Contains proxy-level commands and login/chat event listeners for network-wide enforcement.\n\n### Folia Threading Rules (Paper)\n1. **Async Teleportation**: Never call `Player#teleport()` on Folia. Always use `Player#teleportAsync()` and queue dependent actions using `.thenRun()` or `.thenAccept()`.\n2. **Recipient Thread Safety**: Action updates (like `recipient.hidePlayer()` or `recipient.showPlayer()`) must execute on the **recipient's** regional thread context. Wrap these calls in `SchedulerUtils.runEntity(plugin, recipient, ...)` to guarantee packet delivery.\n3. **Avoid cross-region block state reads**: Calling `open.getHolder()` on block-based inventories open in other regions throws threading exceptions. Instead, maintain an in-memory, thread-safe registry of `InvseeSession` objects.\n4. **Cinematic Follow Damping**: Use interval checking (≥4 ticks), velocity extrapolation, and a task cooldown to maintain smooth follower views.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynkfr%2Fstuffplus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsynkfr%2Fstuffplus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynkfr%2Fstuffplus/lists"}