Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.bukkit.plugin.Plugin;

import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -16,6 +17,7 @@ class VanishInvisibleService {

private final Set<UUID> vanishedPlayers = ConcurrentHashMap.newKeySet();
private final Set<String> vanishedPlayerNames = ConcurrentHashMap.newKeySet();
private final Map<UUID, Boolean> previousCollidableStates = new ConcurrentHashMap<>();

private final Plugin plugin;
private final Server server;
Expand All @@ -27,6 +29,9 @@ class VanishInvisibleService {
}

void hidePlayer(Player player) {
this.previousCollidableStates.putIfAbsent(player.getUniqueId(), player.isCollidable());
player.setCollidable(false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore collision states on shutdown

When the plugin is disabled or reloaded while a player is vanished, PlayerQuitController.onQuit is not involved; EternalCore.disable() only publishes EternalShutdownEvent. This new setCollidable(false) state is player state rather than plugin-scoped hide state, but previousCollidableStates is discarded with the service instance and no shutdown subscriber restores it, so online vanished players can remain non-collidable after a reload with no way for /vanish to restore their original value. Please restore the saved collision states during shutdown.

Useful? React with 👍 / 👎.


for (Player online : this.server.getOnlinePlayers()) {
if (online.hasPermission(VanishPermissionConstant.VANISH_SEE_PERMISSION)) {
continue;
Expand All @@ -48,6 +53,11 @@ void showPlayer(Player player) {
}
this.vanishedPlayers.remove(player.getUniqueId());
this.vanishedPlayerNames.remove(player.getName());

Boolean previousCollidableState = this.previousCollidableStates.remove(player.getUniqueId());
if (previousCollidableState != null) {
player.setCollidable(previousCollidableState);
}
}
Comment on lines +57 to 61

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Storing the previous collidable state by UUID in a persistent map can lead to a memory leak if a player disconnects while vanished, as their entry is never removed from previousCollidableStates. Additionally, if the player reconnects, their default collision state in the new session or world might differ, but the outdated state from the previous session will be restored when they unvanish.

To prevent this, we should expose a cleanup method to remove the player's state when they disconnect, which should be called from the player quit listener.

        Boolean previousCollidableState = this.previousCollidableStates.remove(player.getUniqueId());
        if (previousCollidableState != null) {
            player.setCollidable(previousCollidableState);
        }
    }

    void removePreviousCollidableState(UUID uuid) {
        this.previousCollidableStates.remove(uuid);
    }


void hideVanishedPlayersFrom(Player player) {
Expand Down
Loading