Tags
Creators
Details
All versions
1.1.9
Release
Vanish++ 1.1.9 (Velocity)2 days ago 4
Compatibility
Minecraft: Java Edition
26.3
26.2
26.1.x
1.21.x
1.20.6
Platform
Velocity
Changes
[1.1.9] - 2026-10-23
Added
- Statusbot integration (#35): Statusbot reads
getOnlinePlayers()directly and has no vanish support, so vanished players showed up in its Discord bot status, embeds ($amount-of-players$/$player-list$) and join/leave messages. Statusbot has no API, so the newStatusbotHookhooks its internals via reflection: Statusbot's own join/quit handlers are swapped for vanish-aware ones, the two embed variables are overridden with visible-only versions, the bot status is refreshed on every vanish change, and vanishing/unvanishing sends a fake leave/join (followingbroadcast-fake-quit/broadcast-fake-join). Tested against Statusbot 24.0 - if a different version doesn't match, the hook logs a warning and leaves Statusbot untouched, and a failure at runtime disables the hook and restores Statusbot's defaults. Covered byStatusbotHookTestagainst stand-ins mirroring Statusbot's classes, and verified on a real Paper 26.3 server with Statusbot 24.0 and a live Discord bot: vanishing/unvanishing posts the fake leave/join, and joining or leaving while vanished posts nothing. - Multi-language support (#29): Every message, GUI text, action button, rule name, TAB prefix, bossbar title and scoreboard label now lives in per-language files (
languages/messages_<lang>.yml,languages/scoreboards_<lang>.yml), picked with thelanguageoption inconfig.yml. Ships with English (en-us) and Simplified Chinese (zh-cn); missing keys in a translation fall back to English per key. (Thanks @kanseijo, PR #29)
Fixed
- Update checker never found new versions: the Modrinth project slug was renamed, so the old slug in the API URL now only gets a
308redirect (logged as[UpdateChecker] Modrinth returned HTTP 308), which Java'sHttpURLConnectiondoesn't follow. The checker now uses the project ID, which never changes. - Periodic update check ran its HTTP request on the main thread: a slow or unreachable Modrinth could freeze the server long enough to trip the Watchdog. It now runs async, like the startup check. (Thanks @kanseijo, PR #30)
- "Could not save scoreboards.yml" warning on every startup: the default
scoreboards.ymlis now only extracted when it doesn't exist yet.
[1.1.9] - 2026-08-23
Added
vanishpp:vanishedLuckPerms context now works on the Velocity proxy, not just Paper: Paper has had this context (usable in LuckPerms permission conditions) since earlier work, but the proxy side had no equivalent β a permission conditioned on it would only ever evaluate correctly at the backend, never at the proxy. Added a mirroredLuckPermsHookonvanishpp-velocity, sourced from the proxy's own cross-server vanish state (ProxyStateManager, already kept in sync via the existing plugin-messaging protocol) rather than a Paper plugin instance, which doesn't exist on that side. Registration is optional (only if LuckPerms is present on the proxy) and mirrors Paper's exact context key so one permission condition behaves consistently whether it's checked at the proxy or a backend server. Verified end-to-end on a real Velocity proxy + Paper backend + LuckPerms-Velocity: vanishing/unvanishing on the backend flips the proxy-side context value live (false β true β false), no reconnect needed.
Fixed
/vspecaction bar flickered between "you are vanished" and the spectate overlay:/vspecshares its target-tracking with/vfollow, whose periodic task drives the spectate-info action bar β but that raced, uncoordinated, against a completely separate general "you are vanished" heartbeat that had no idea spectate/follow mode existed, so the two kept overwriting each other's action bar text. The generic heartbeat now skips any player currently in an active/vspec//vfollowsession./vspec stopcould leave the player stuck in SPECTATOR gamemode: unlike/vfollow,/vspecsaved the player's gamemode unconditionally on every invocation β so switching/vspectargets twice, using/vfollowthen/vspec, or double-shift-toggling into spectator before/vspec, would each re-save the already-currentSPECTATORgamemode over the real original, permanently losing it. The codebase actually had four independent, uncoordinated places tracking "gamemode to restore" (the shared/vspec+/vfollowmap, plus two separate player-metadata keys for the double-shift toggle and the vanish/unvanish toggle) β consolidated into a single guarded store (Vanishpp.saveGamemodeForRestore()/restoreSavedGamemode(), save-if-absent semantics) used by all four. As part of this, unvanishing while still mid-/vspec//vfollownow also cleanly drops the active follow/spectate session instead of leaving stale tracking state behind (which previously could cause the follower to keep getting silently re-teleported to the target after they'd already unvanished). Verified on a real server:/vfollowβ/vspecβ/vspec stop, two sequential/vspeccalls, and unvanish-mid-spectate on a non-bypass account all correctly restore the real original gamemode.- Vanished player's nametag could leak through a third-party team plugin (e.g. BetterTeams) to a non-seer, as floating text with no player model: a prior fix attempt (already shipped) scrubbed
SCOREBOARD_TEAMpackets but failed open on any exception β if a packet didn't match the expected shape (plausible for a different plugin's team packets), the original, unscrubbed packet was forwarded rather than dropped, which is the worst failure direction for a leak-class bug. That scrub (both the plugin's own team and the generic any-other-team path) now fails closed: cancel the packet rather than forward it if it can't be verified safe. Separately,PLAYER_INFO/PLAYER_INFO_UPDATEpackets were never intercepted at all βhidePlayer()only sends a one-shot removal at the moment visibility changes, so a later tab-list re-sync from another plugin could still re-include a vanished player for a non-seer. Added a backstop listener (VanishPlayerInfoPolicy, unit-tested the same way as the existingVanishTeamPacketPolicy) that strips vanished-player entries from every such packet regardless of what caused it. Known residual risk, not closed by this fix: a client that already cached a third-party team/tab association for a player before they vanished won't have it retroactively retracted β both fixes only filter packets going forward from the moment of vanish. Closing that fully would require Vanish++ to proactively manage third-party team membership on vanish, which is separate, larger scope. Verified on a real server with raw packet capture: a vanished player joining a fresh vanilla team (standing in for a third-party team plugin, same underlying API) never leaks their name to a non-seer observer.
[1.1.9] - 2026-08-21
Fixed
- Client crash "Player is not on any team" still reachable after the previous fix, when an observer was granted
vanishpp.seelive mid-vanish: Thea5436a6fix (thanks again to @quiquelhappy, PR #19, for the original diagnosis and fix this builds on) scrubbed ADD/REMOVEVanishpp_Vanishedteam packets based on the observer's current permission at send time, but a client's actual scoreboard knowledge depends on what it was sent in the past. An observer promoted to staff (e.g. a live LuckPerms grant, no relog) after missing the original ADD would still receive an unfiltered REMOVE once the vanished player unvanished β the client crashed exactly as before, just from the opposite direction of a permission change.ProtocolLibManagernow tracks, per observer, which team member names that specific client has actually been sent (VanishTeamPacketPolicy), and only forwards a REMOVE for names the client is known to have learned about β regardless of the observer's permission at that moment. As a side effect this also fixes a pre-existing (non-crashing) bug in the other direction: a staff member demoted mid-vanish used to have their REMOVE wrongly suppressed, leaving their client's nametag/team state stale forever; it's now correctly delivered since it no longer depends on current permission either. Covered by a new regression test,VanishTeamPacketPolicyTest, exercising both directions. ProtocolLibManagerlistener registration was all-or-nothing: All packet listeners were registered in one unguarded method body β a single unsupportedPacketTypeon a given server/ProtocolLib version (or any other registration-time exception) silently aborted every listener registered after it, including the crash-preventing team-scrub listener above. Each listener is now registered in its own try/catch, logging a warning and continuing instead of taking down the rest of the hook.
[1.1.9] - 2026-08-17
Added
- Copper chest support: Silent-chest suppression and the
CAN_INTERACTrule gate now recognize all 8 copper chest oxidation/waxed variants (1.21+), matching existing chest/barrel/shulker handling. (Thanks @kanseijo, PR #27)
Fixed
- Rules GUI and Admin Dashboard clicks broke under any non-English language: Both GUIs identified which rule/target a click referred to by parsing it back out of the item's display text (the rule's translated name, or a
Β§8UUID: β¦marker line) β which broke the moment GUI text became translatable the day before (messages.ymlgui:section, above), since the parsed-back string was no longer the literal key it used to be. Both now store the rule id / target UUID in an invisible persistent-data (NBT) key set when the item is built, decoupled entirely from whatever text is displayed. (Thanks @kanseijo, PR #27) - Vanish scoreboard could disappear after rejoin with auto-vanish enabled: TAB (or any other packet-modifying plugin) rebuilding the sidebar shortly after join could silently overwrite the vanish scoreboard the same tick it was shown, leaving vanished players without it until manually toggled. Added
VanishScoreboard.forceReshow(), called from both the auto-vanish-on-join path and the multi-stage join reapply loop so every join-time vanish restore re-asserts the scoreboard, not just the auto-vanish-preference case. (Thanks @kanseijo, PR #28)
[1.1.9] - 2026-08-16
Added
- GUI text is now translatable: All in-game GUI text (Rules GUI, Admin Dashboard, Config GUI) was previously hardcoded in Java and is now externalized to a new
gui:section inmessages.yml, the same file chat messages already use β admins/translators can edit it and run/vreloadto see changes instantly, no recompiling or restart needed. Fixes GitHub issue #23.
Fixed
- Silent chest animation leaked to observers on close, and double chests leaked entirely: Two independent bugs in the silent-chest suppression system. (1) The delayed cleanup after closing a container only kept its block registered for 3 ticks, but vanilla's per-tick
ContainerOpenersCounterrecheck independently re-broadcasts the same open-count change on a later tick, arriving after the 3-tick window closed and leaking the close animation to nearby observers (sound suppression was unaffected β it's a separate packet type with no such duplicate rebroadcast). The window is now 60 ticks. (2) Double chests are two independent tile entities that each fire their own animation/sound packets, but only the clicked half's position was ever registered β the unclicked half's animation and sound always leaked, regardless of the close-timing fix. Both halves are now registered together. Verified against a real Purpur server with raw packet capture (issue #25). - Paper 26.2 always logged "this version has NOT been tested with Vanish++" despite being a documented-supported version:
isVersionSupported()parsedmajor,minor, andpatchunconditionally before checking anything, but Paper 26.2 (a patch-less release) reports its runtime version as26.2.build.112β a non-numeric third segment β so parsingpatchthrewNumberFormatExceptionand the whole check fell through to "unsupported," even thoughmajor == 26alone should have been enough. Paper 26.1.2 wasn't affected only because it happens to have a numeric third segment (26.1.2.build.4). The existing unit tests missed this because they only tested idealized version strings ("26.2","26.2.0") that never exercised this path β not the real,.build.N-suffixed stringsBukkit.getBukkitVersion()actually returns.patchis now only parsed when the1.20.xbranch specifically needs it;major == 26and1.21.xreturn immediately without touching it. Verified against real Paper 26.2 and 26.1.2 servers (booted under the Java 25 runtime both now require). Addresses GitHub issue #22. rules:key collision inmessages.ymlsilently broke/vrulesmessages: The file had two separate top-levelrules:sections (rule-command messages, and rule-preset messages) β YAML parses to a map, so the second silently overwrote the first, meaningrules.status-on/status-off/etc. resolved as "missing key" at runtime (visible as aduplicate keys found: ruleswarning in the server log). The rule-preset section is nowrules-preset:./vconfig guisettings mostly did nothing: 20 of the 23 settings exposed in the Config GUI wrote to config keys that either don't exist or were the wrong path β clicking played the success sound and showed "saved," but nothing ever read the value back, so it had zero effect on real plugin behavior (this is almost certainly what looked like "clicking does nothing" β reported separately). Phantom settings with no real backing config value were removed; wrong-path settings with a real underlying feature were corrected to their actual path (vanish-appearance.action-bar.enabled,vanish-gamemodes.enabled/default-spectator,flight-control.vanish-enable-fly,invisibility-features.prevent-sleeping,permissions.default-vanish-level/default-see-level/max-level). Settings whose real path is gated behind/vconfig'sSENSITIVE_PREFIXES+--confirmsafety requirement (storage.type,storage.redis.*,permissions.layered-permissions-enabled) were removed from the GUI entirely rather than given a bypass β the GUI has no confirmation flow, so exposing them there would let a single accidental click do what the text command deliberately requires an extra confirmation step for. Edit those via the text command instead./vconfig guipagination math was off by 4 per page (latent):ITEMS_PER_PAGEwas computed as(rows*9)-2= 25, but the actual per-page rendering capacity isrows*7= 21 (every wrapped row reserves its own indent, not just one indent total). No category has more than 21 settings today so this never surfaced, but a future 22-25-setting category would have silently dropped items off the end of the page with no error. Fixed the constant to match the real capacity.- Admin Dashboard's Close button did nothing: The barrier item's click was cancelled (as intended, to block normal inventory interaction) but never actually closed the inventory β same "I clicked it and nothing happened" failure mode as the Config GUI bug above, just in the other admin GUI.
/vhistorycalledBukkit.getPlayer()off the main thread:resolveUUID()ran inside the command's async lookup task β unsafe on Bukkit/Paper (main-thread-only API) and would break outright on Folia's region-threading model. The online-player lookup now happens synchronously before the async task is dispatched; only the offline-player cache lookup (a plain thread-safe map read) happens inside the async block./vfollowdidn't actually follow a moving target: The camera-lock/re-teleport logic only ran off the follower's own movement β if the follower stood still while the target walked away, nothing re-synced them at all. Added a periodic Folia-safe sweep (dispatched per-follower through the entity's own region scheduler) that keeps the follower's camera glued to the target's current position regardless of whether the follower moves.- Verified, not changed: the silent-container mechanic doesn't have a duplication-risk bug. Re-verified (after a specific concern was raised) that opening a container silently always references the real, live
Inventoryobject directly β never a snapshot/copy that could be written back over concurrent changes from a real player on close. Confirmed with a real two-player concurrent-access test (an admin silently viewing a chest while a survival player removed/added items to the same chest) β the final state exactly matched the survival player's changes, item count conserved exactly, admin's close had zero effect. This class of bug did exist in a much older version of this codebase (pre-1.1.7) and was already fixed before this session; this just re-confirms it stayed fixed. Also broadenedvanishpp.silentchest'splugin.ymldescription, which still said "chests" only despite covering all container types (barrels, shulker boxes, ender chests too).
[1.1.9] - 2026-08-15
Fixed
- Velocity proxy silently ignored MySQL/PostgreSQL storage config:
VelocityConfigManager's storage accessors (getDbHost/getDbPort/getDbName/getDbUser/getDbPass/getDbSsl/getPoolSize) readstorage.*instead ofstorage.mysql.*, so every DB connection field silently fell back to its hardcoded default (localhost:3306, dbvanishpp, userroot, no password, SSL off) regardless of what was actually configured β on Velocity only, Paper'sSqlStoragealready read the correct path. Verified against a real MariaDB + Velocity proxy setup. Fixes GitHub issue #21.
[1.1.9] - 2026-07-30
Fixed
- Vanish chat filter discarded LuckPerms Chat / HoverChat formatting:
applyVanishChatFilter()(used both for the seer-only "vanished" chat relay and for the/vanishchat confirmbypass) unconditionally replaced theAsyncChatEventrenderer with a hardcodedprefix + displayName + ": " + message, throwing away any renderer already installed by a lower-priority chat formatter (prefixes/suffixes, hover text, click events). The renderer is now wrapped instead of replaced β VPP's[VANISHED]tag is prepended in front of whatever LuckPerms Chat, HoverChat, or any other formatter already produced.
[1.1.9] - 2026-07-26
Fixed
- Client crash "Player is not on any team" on unvanish: Non-staff clients never receive the packet that adds a vanished player to the internal
Vanishpp_Vanishedscoreboard team (it's scrubbed), but once the player unvanished they did receive the "Remove Members" packet for it β telling the client to remove an entry it never knew it had, crashing the client.ProtocolLibManagernow unconditionally cancels both Add- and Remove-Members packets for that team for non-staff observers, regardless of the vanished player's current state at packet-send time. - Mob target clearing violated Folia's region-threading model: Both the one-shot clear-on-vanish pass (
applyVanishEffects) and the every-tick combat safety net (MobAiManager.sweepMobTargets) calledMob#setTarget/getPathfinder().stopPathfinding()directly from the caller's thread instead of the mob's owning region thread, andsweepMobTargetscalledPlayer#getNearbyEntitiesthe same way. On Folia this either throws or silently corrupts state depending on the entity's region. Both call sites now dispatch throughVanishScheduler#runEntity, with mob mutations dispatched individually per-mob (a mob near a region boundary can be owned by a different region than the player that triggered the sweep). Thanks to @quiquelhappy (PR #19) for tracking down the crash and the initial fix.
[1.1.9] - 2026-07-14
Changed
- Extended supported Minecraft version range to 1.20.6 β 26.2:
checkPlatformCompatibility()now accepts1.20.xbuilds with patch>= 6in addition to1.21.xand26.x.x, matching what the docs already (inaccurately) claimed. Test docker environment bumped from Paper 26.1.2 to Paper 26.2, which currently ships only on Paper'sexperimentalrelease channel (PAPER_CHANNEL: experimentaladded to the Paper services).
[1.1.9] - 2026-07-11
Fixed
- Vanished players could get stuck visible ("Vanished Uninvisable"): The join-time self-heal added in the previous release only corrected the unvanished-but-invisible direction (
forceEnsureVisible) β if a player'ssetInvisibleflag was ever cleared while the vanished-set and DB still agreed they were vanished (stale state from an old plugin version, a crash, or a plugin conflict),reconcileVanishState()saw "consistent" state and did nothing.resyncVanishEffects()β the method meant to reapply state to an already-vanished player β also never calledplayer.setInvisible(true), so even a manual resync couldn't fix it. Both are now fixed:resyncVanishEffects()reasserts the invisible flag, andreconcileVanishState()calls it whenever DB and memory agree a player is still vanished, making the self-heal symmetric in both directions. Fixes GitHub issue #20.
Added
- 12-hour clock scoreboard placeholders: Added four new built-in scoreboard placeholders alongside the existing 24-hour
%time%:%time_12%(h:mm, e.g.9:41),%time_12_padded%(hh:mm, e.g.09:41),%time_12_ampm%(h:mm a, e.g.9:41 PM), and%time_12_ampm_padded%(hh:mm a, e.g.09:41 PM). All four respect the sametimezoneandtimezone-offset-hourssettings inscoreboards.ymlas%time%.
[1.1.9] - 2026-07-09
Fixed
- Mobs Still Looking At Vanished Players (for real this time): Cancelling
EntityTargetEventonly prevents mobs from attacking a vanished player β it never touches the vanillaLookAtPlayerGoal, which turns a mob's head/body toward nearby players independently of the target field. Previous attempts (v1.1.4-1.1.8) to fix this via a custom PaperMobGoalsinjection were all reverted because of two bugs: (1) the replacement goal was registered at a priority that collided with vanilla attack goals β which also require theLOOKflag β blocking mobs from attacking anyone; (2) the replacement goal'sshouldActivate()conditionally returnedfalsewhen only vanished players were nearby, "leaking" theLOOKslot back to the vanilla goal it was supposed to replace. This rewrite (VanishLookGoal, injected byMobAiManager) fixes both: it's registered at a fixed low-precedence priority (10, below all vanilla attack goals) so it can never block combat, and its activation condition mirrors vanilla exactly (any player in range, vanished or not) β only the actual look target excludes vanished players, so the goal slot is never freed. Injection now covers newly spawned mobs, mobs streamed in on chunk load, and mobs already loaded before the plugin started, closing the "partial injection" gap that caused past leaks. Known limitation: Brain-based mobs (Villagers, Piglins, Wardens, etc.) use a separate AI system (Sensors/Memory) not covered byMobGoalsand are not addressed by this fix. Requires Paper/Purpur/Folia (Spigot/Bukkit only get the combat-target fix, as before). - Redundant mob target clear in
EntityTargetEventhandler: Removed amob.setTarget(null)/stopPathfinding()call inside the cancelled event handler that had been fixed and reverted twice before (it fires a secondaryFORGOT_TARGETevent, puttingNearestAttackableTargetGoalon cooldown and starving nearby non-vanished players of legitimate targeting). Cancelling the event alone is sufficient. - Regression guards added: Both historical mistakes above (the redundant
setTarget(null)call, and aGoalType/priority collision with attack goals) have each been reintroduced multiple times across releases. Added two permanent unit tests (EventListenerTest) that fail loudly if either regresses again:mobTargeting_cancelled_doesNotClearMobTargetFieldandvanishLookGoal_onlyClaimsLookGoalType(also assertsMobAiManager.LOOK_GOAL_PRIORITYstays at/above vanilla's own priority).
[1.1.9] - 2026-07-08
Added
- DB Downgrade Guard: When a downgraded plugin version connects to a database previously written by a newer version, all DB writes are suspended immediately to prevent data corruption. Admins are alerted in-game every 30 seconds and on join (title + styled chat box). New command
/vdowngrade infoshows exactly what data is at stake (row counts per table);/vdowngrade allowlifts the write-suspend (risky);/vdowngrade reset [confirm]wipes all Vanish++ data and starts fresh. Avpp_plugin_versiontable tracks the highest version that has ever written to the DB. - InvSee config toggle: New
invisibility-features.invsee-shift-clickoption (defaulttrue) lets admins disable the shift-right-click inventory inspection feature entirely. Addresses GitHub issue #20. - Self-healing visibility on join: Players who are not vanished now have their visibility forcibly reset on join (
setInvisible(false),setVisibleByDefault(true),showPlayerfor any observer that can't see them). This self-corrects stale invisible state caused by server crashes, plugin downgrades, or other unexpected shutdowns.
[1.1.9] - 2026-06-15
Changed
- Scoreboard config (
scoreboards.yml): Added comments clarifying that the update timer only runs while at least one player has the scoreboard open (zero overhead otherwise), and an admin note at the bottom on how to toggle it with/vsb. - ProtocolLib Missing Warning: Merged the two separate ProtocolLib-missing warnings (duplicate on join for ops) into a single notice that uses the styled red box format and includes both the
[ Download ProtocolLib ]and[Disabled Features βΆ]buttons. The warning respects/vignoredismiss state as before.
Fixed
- InvSee++ Integration Broken: The plugin name lookup used
"InvSee++"but InvSee++ registers itself as"InvSeePlusPlus"β the soft-dependency never resolved and the integration check always fell through to the built-in fallback. Also corrected the permission nodes granted during a session (invseeplusplus.invsee.view/invseeplusplus.invsee.editinstead of the incorrectinvsee.inventory.see/invsee.inventory.edit). Fixes GitHub issue #15.
[1.1.9] - 2026-06-14
Fixed
- LPC/HoverChat Chat Leak: Vanished players' chat messages were visible to all players when using chat plugins like LuckPerms Chat or HoverChat. The
AsyncChatEventhandler was registered atLOWESTpriority, allowing those plugins to process and broadcast the message before VPP could cancel it. Priority raised toHIGHso cancellation takes effect after third-party chat formatters run.
[1.1.9] - 2026-06-13
Fixed
- WorldGuard Hook Fails on 7.0.12+: Custom region flags (
vanishpp-deny-vanish,vanishpp-force-vanish,vanishpp-deny-unvanish) are now registered inJavaPlugin.onLoad()instead ofonEnable(). WorldGuard 7.0.12+ locks the flag registry beforeonEnable()runs, causing the previous "New flags cannot be registered at this time" error and disabling the WorldGuard integration entirely. Fixes GitHub issue #16. - PostgreSQL Schema Migration v3 Crash: The v3 migration (
vpp_history,vpp_stats,vpp_rule_presets,vpp_preferencestables) unconditionally ran the MySQL-syntax block first βAUTO_INCREMENTand inlineINDEXare PostgreSQL syntax errors. Servers using PostgreSQL storage failed to initialize entirely. The migration now runs the correct dialect block exclusively based on the configured database type.
Changed
- Compile dependency WorldGuard:
7.0.9β7.0.17. - Test docker environment: Updated all servers from Minecraft 1.21.11 to 26.1.2 (Paper, Purpur, Folia, Spigot, Bukkit).
[1.1.9] - 2026-05-29
Added
/vconfig gui: A full in-game, category-based, paginated Config GUI (ConfigGUI/ConfigRenderer/ConfigCategory) for editing settings without touching YAML by hand β numerical controls with Β±1/Β±10 buttons and min/max range enforcement, sound feedback, and multi-page navigation.
Changed
(The rest of this section and the Fixed section below are from @CreeperDisco, PR #14 β thanks for the contribution!)
- Non-destructive config updates: Config updates previously overwrote the whole file via
YamlConfiguration.save(), stripping user comments and formatting. A newConfigUpdaternow injects only missing keys line-by-line, preserving everything else. - Permission result caching: High-frequency permission checks (especially
vanishpp.see) during Tab list and action bar refreshes are now cached for 500ms, cutting down repetitive LuckPerms calls and verbose-log spam without hurting responsiveness.
Fixed
- F3+F4 gamemode switcher desynced: ProtocolLib was blocking
ENTITY_STATUSpackets a player sent about themselves, breaking the client's own OP-status UI sync. Self-entity packets are now exempted from that filter. - Night vision wiped on unvanish: Unvanishing unconditionally removed all
NIGHT_VISIONeffects, stripping ones granted by equipment, beacons, or other plugins. Replaced with a soft 1-tick expiry plus a two-tick armor unequip/re-equip cycle so equipment-based effects are correctly re-detected instead of destroyed. - Flight auto-engaged unexpectedly on join: Auto-vanish on join used to force
setFlying(true)directly, taking players airborne the instant they spawned. Players are now just granted fly permission (setAllowFlight(true)) and take off with a normal double-jump. - Hunger regen blocked entirely while vanished:
FoodLevelChangeEventwas cancelled unconditionally, preventing vanished players from ever regaining hunger/saturation from eating. Now only cancelled when hunger is decreasing. - Container blocking ignored the
CAN_INTERACTrule: A regression from this same round of fixes briefly blocked all vanished players from opening any container (chests, barrels, shulkers, hoppers, dispensers, droppers) regardless of their rules. Container blocking now correctly only applies whenCAN_INTERACTis off. - Several smaller bugs from this batch:
/vfollowleft the follower stuck in Spectator if the target disconnected;/vfollow//vspecteleports weren't Folia-safe;/vstats//vhistorybroke on async offline-player lookups;LuckPermsHookcould register duplicate calculators across/vanishreload;/vincognito offwas ambiguous if a player was literally named "off";/vzoneshowed radius values incorrectly.
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:kbKpK1bc:USlbIKTl"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:kbKpK1bc:USlbIKTl"
}

