From 8c90814e13ae0495330bcd73451367fe82ac8350 Mon Sep 17 00:00:00 2001 From: quiquelhappy Date: Sun, 21 Jun 2026 20:38:42 +0200 Subject: [PATCH 1/5] fix unvanish crash for regular players --- .../vanishpp/hooks/ProtocolLibManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/net/thecommandcraft/vanishpp/hooks/ProtocolLibManager.java b/src/main/java/net/thecommandcraft/vanishpp/hooks/ProtocolLibManager.java index 82cb5a3..9588b74 100644 --- a/src/main/java/net/thecommandcraft/vanishpp/hooks/ProtocolLibManager.java +++ b/src/main/java/net/thecommandcraft/vanishpp/hooks/ProtocolLibManager.java @@ -236,6 +236,15 @@ public void onPacketSending(PacketEvent event) { // Actions: 0 (Create), 3 (Add Members), 4 (Remove Members) if (action == 0 || action == 3 || action == 4) { + // For the vanish team, non-staff clients never receive ADD packets for + // vanished players, so they must also never receive REMOVE packets — + // otherwise MC crashes with "Player is not on any team" when unvanishing. + String teamName = packet.getStrings().read(0); + if ("Vanishpp_Vanished".equals(teamName) && (action == 3 || action == 4)) { + event.setCancelled(true); + return; + } + Collection players = packet.getSpecificModifier(Collection.class).read(0); if (players != null) { List scrubbed = new ArrayList<>(); From 5c981f06fdaabec65283de8f92958ecf213367d9 Mon Sep 17 00:00:00 2001 From: quiquelhappy Date: Sun, 21 Jun 2026 20:38:51 +0200 Subject: [PATCH 2/5] add missing setStats call --- .../vanishpp/storage/SqlStorage.java | 19 +++++++++++++++++++ .../vanishpp/storage/YamlStorage.java | 9 +++++++++ 2 files changed, 28 insertions(+) diff --git a/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/storage/SqlStorage.java b/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/storage/SqlStorage.java index eb21307..cf6ae4d 100644 --- a/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/storage/SqlStorage.java +++ b/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/storage/SqlStorage.java @@ -569,6 +569,25 @@ public VanishStats getStats(UUID uuid) { return VanishStats.empty(); } + @Override + public void setStats(UUID uuid, VanishStats stats) { + String q = type.equals("postgresql") + ? "INSERT INTO vpp_stats (uuid,total_ms,vanish_count,longest_ms) VALUES(?,?,?,?)" + + " ON CONFLICT (uuid) DO UPDATE SET total_ms=EXCLUDED.total_ms," + + " vanish_count=EXCLUDED.vanish_count, longest_ms=EXCLUDED.longest_ms" + : "INSERT INTO vpp_stats (uuid,total_ms,vanish_count,longest_ms) VALUES(?,?,?,?)" + + " ON DUPLICATE KEY UPDATE total_ms=VALUES(total_ms)," + + " vanish_count=VALUES(vanish_count), longest_ms=VALUES(longest_ms)"; + try (Connection conn = dataSource.getConnection(); + PreparedStatement ps = conn.prepareStatement(q)) { + ps.setString(1, uuid.toString()); + ps.setLong(2, stats.getTotalVanishTimeMs()); + ps.setInt(3, stats.getVanishCount()); + ps.setLong(4, stats.getLongestSessionMs()); + ps.executeUpdate(); + } catch (SQLException e) { handleDatabaseError(e); } + } + @Override public void recordVanishSession(UUID uuid, long durationMs) { if (durationMs <= 0) return; diff --git a/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/storage/YamlStorage.java b/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/storage/YamlStorage.java index de56453..4b930fc 100644 --- a/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/storage/YamlStorage.java +++ b/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/storage/YamlStorage.java @@ -291,6 +291,15 @@ public VanishStats getStats(UUID uuid) { return new VanishStats(total, count, longest); } + @Override + public void setStats(UUID uuid, VanishStats stats) { + String base = "stats." + uuid + "."; + config.set(base + "total-ms", stats.getTotalVanishTimeMs()); + config.set(base + "count", stats.getVanishCount()); + config.set(base + "longest-ms", stats.getLongestSessionMs()); + save(); + } + @Override public void recordVanishSession(UUID uuid, long durationMs) { if (durationMs <= 0) return; From 37fd672018ce0a78ec8ae3742293ae4427557673 Mon Sep 17 00:00:00 2001 From: quiquelhappy Date: Sun, 21 Jun 2026 20:42:38 +0200 Subject: [PATCH 3/5] fix player crashing on unvanish --- .../vanishpp/hooks/ProtocolLibManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/hooks/ProtocolLibManager.java b/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/hooks/ProtocolLibManager.java index 8084761..f512997 100644 --- a/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/hooks/ProtocolLibManager.java +++ b/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/hooks/ProtocolLibManager.java @@ -233,6 +233,15 @@ public void onPacketSending(PacketEvent event) { // Actions: 0 (Create), 3 (Add Members), 4 (Remove Members) if (action == 0 || action == 3 || action == 4) { + // For the vanish team, non-staff clients never receive ADD packets for + // vanished players, so they must also never receive REMOVE packets — + // otherwise MC crashes with "Player is not on any team" when unvanishing. + String teamName = packet.getStrings().read(0); + if ("Vanishpp_Vanished".equals(teamName) && (action == 3 || action == 4)) { + event.setCancelled(true); + return; + } + Collection players = packet.getSpecificModifier(Collection.class).read(0); if (players != null) { List scrubbed = new ArrayList<>(); From 9bf1ac91ce0b688864b564914b9972d602dc4d62 Mon Sep 17 00:00:00 2001 From: quiquelhappy Date: Sun, 21 Jun 2026 20:42:55 +0200 Subject: [PATCH 4/5] fix entity listing scheduler issue --- .../vanishpp/listeners/MobAiManager.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/listeners/MobAiManager.java b/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/listeners/MobAiManager.java index 9e90302..1fbf539 100644 --- a/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/listeners/MobAiManager.java +++ b/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/listeners/MobAiManager.java @@ -26,21 +26,21 @@ public void register() { private void sweepMobTargets() { for (Player p : Bukkit.getOnlinePlayers()) { if (!plugin.isVanished(p)) continue; - - // Only enforce clearing if mob_targeting rule is OFF if (plugin.getRuleManager().getRule(p, RuleManager.MOB_TARGETING)) continue; - // Check all nearby mobs and clear any that have the vanished player as target - for (Entity entity : p.getNearbyEntities(128, 128, 128)) { - if (!(entity instanceof Mob mob)) continue; - - // Clear target if aimed at this vanished player - if (p.equals(mob.getTarget())) { - mob.setTarget(null); - try { - mob.getPathfinder().stopPathfinding(); - } catch (Throwable ignored) {} - } + // getNearbyEntities requires the owning region thread — dispatch per entity. + plugin.getVanishScheduler().runEntity(p, () -> sweepForPlayer(p), null); + } + } + + private void sweepForPlayer(Player p) { + for (Entity entity : p.getNearbyEntities(128, 128, 128)) { + if (!(entity instanceof Mob mob)) continue; + if (p.equals(mob.getTarget())) { + mob.setTarget(null); + try { + mob.getPathfinder().stopPathfinding(); + } catch (Throwable ignored) {} } } } From 95f4355797f6fc42eb8059e894c26be2dd3ec7b4 Mon Sep 17 00:00:00 2001 From: quiquelhappy Date: Sat, 27 Jun 2026 18:54:24 +0200 Subject: [PATCH 5/5] fix mob scheduler --- .../java/net/thecommandcraft/vanishpp/Vanishpp.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/Vanishpp.java b/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/Vanishpp.java index 9f24c53..85fe25c 100644 --- a/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/Vanishpp.java +++ b/vanishpp-paper/src/main/java/net/thecommandcraft/vanishpp/Vanishpp.java @@ -970,10 +970,15 @@ public void applyVanishEffects(Player player) { // ALWAYS clear existing mob targets when vanishing (regardless of mob_targeting rule) // The rule only controls whether new targets can be acquired AFTER vanishing + // Each mob's target access must run on its owning region's thread (Folia safety) for (Entity entity : player.getWorld().getEntities()) { - if (entity instanceof Mob mob && player.equals(mob.getTarget())) { - mob.setTarget(null); - mob.getPathfinder().stopPathfinding(); + if (entity instanceof Mob mob) { + vanishScheduler.runEntity(mob, () -> { + if (player.equals(mob.getTarget())) { + mob.setTarget(null); + mob.getPathfinder().stopPathfinding(); + } + }, null); } }