diff --git a/build-data/divinemc.at b/build-data/divinemc.at index dda3c44..fdbd156 100644 --- a/build-data/divinemc.at +++ b/build-data/divinemc.at @@ -6,6 +6,7 @@ private-f net.minecraft.world.level.levelgen.NoiseChunk$FlatCache noiseFiller private-f net.minecraft.world.level.levelgen.NoiseChunk$NoiseInterpolator noiseFiller private-f net.minecraft.world.level.levelgen.RandomState router private-f net.minecraft.world.level.levelgen.RandomState sampler +public net.minecraft.server.level.ServerPlayerGameMode gameModeForPlayer public net.minecraft.util.Mth SIN public net.minecraft.world.entity.ai.Brain sensors public net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities lineOfSightTest diff --git a/divinemc-server/minecraft-patches/features/0080-Do-not-send-spectator-change-packet.patch b/divinemc-server/minecraft-patches/features/0080-Do-not-send-spectator-change-packet.patch new file mode 100644 index 0000000..6d27a4d --- /dev/null +++ b/divinemc-server/minecraft-patches/features/0080-Do-not-send-spectator-change-packet.patch @@ -0,0 +1,70 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Sun, 20 Jul 2025 00:09:31 +0300 +Subject: [PATCH] Do not send spectator change packet + + +diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java +index 6e7ed7451a45f4525946563617ccf0a55851449b..6a2f8a798f46b337d611c14556ab5ecc1f2584cd 100644 +--- a/net/minecraft/server/level/ServerPlayerGameMode.java ++++ b/net/minecraft/server/level/ServerPlayerGameMode.java +@@ -75,10 +75,18 @@ public class ServerPlayerGameMode { + // CraftBukkit end + this.setGameModeForPlayer(gameModeForPlayer, this.gameModeForPlayer); // Paper - Fix MC-259571 + this.player.onUpdateAbilities(); +- this.level +- .getServer() +- .getPlayerList() +- .broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player), this.player); // CraftBukkit ++ ++ // DivineMC start - Do not send spectator change packet ++ if (!org.bxteam.divinemc.config.DivineConfig.NetworkCategory.sendSpectatorChangePacket) { ++ this.level.getServer().getPlayerList().broadcastPlayerInfoWithoutSpectatorName(this.player); ++ } else { ++ this.level ++ .getServer() ++ .getPlayerList() ++ .broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player), this.player); ++ } ++ // DivineMC end - Do not send spectator change packet ++ + this.level.updateSleepingPlayerList(); + if (gameModeForPlayer == GameType.CREATIVE) { + this.player.resetCurrentImpulseContext(); +diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java +index 96af2c75b526c59510965665da0b2ca00bf657b3..b59078273bb6214295a448d5607538557d7eb1ee 100644 +--- a/net/minecraft/server/players/PlayerList.java ++++ b/net/minecraft/server/players/PlayerList.java +@@ -1473,4 +1473,32 @@ public abstract class PlayerList { + public boolean isAllowCommandsForAllPlayers() { + return this.allowCommandsForAllPlayers; + } ++ ++ // DivineMC start - Do not send spectator change packet ++ public void broadcastPlayerInfoWithoutSpectatorName(ServerPlayer player) { ++ net.minecraft.world.level.GameType displayMode = player.gameMode.getGameModeForPlayer() == net.minecraft.world.level.GameType.SPECTATOR ? net.minecraft.world.level.GameType.SURVIVAL : player.gameMode.getGameModeForPlayer(); ++ ++ for (ServerPlayer otherPlayer : this.players) { ++ if (otherPlayer != player && otherPlayer.getBukkitEntity().canSee(player.getBukkitEntity())) { ++ ClientboundPlayerInfoUpdatePacket packet = createPlayerInfoPacketWithoutSpectatorName(player, displayMode); ++ otherPlayer.connection.send(packet); ++ } ++ } ++ } ++ ++ private ClientboundPlayerInfoUpdatePacket createPlayerInfoPacketWithoutSpectatorName(ServerPlayer player, net.minecraft.world.level.GameType displayMode) { ++ net.minecraft.world.level.GameType originalMode = player.gameMode.gameModeForPlayer; ++ ++ player.gameMode.gameModeForPlayer = displayMode; ++ ++ ClientboundPlayerInfoUpdatePacket packet = new ClientboundPlayerInfoUpdatePacket( ++ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, ++ player ++ ); ++ ++ player.gameMode.gameModeForPlayer = originalMode; ++ ++ return packet; ++ } ++ // DivineMC end - Do not send spectator change packet + } diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java index 31cae55..3bff625 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/config/DivineConfig.java @@ -767,6 +767,7 @@ public class DivineConfig { public static boolean optimizeNonFlushPacketSending = false; public static boolean disableDisconnectSpam = false; public static boolean dontRespondPingBeforeStart = true; + public static boolean sendSpectatorChangePacket = true; public static boolean playerProfileResultCachingEnabled = true; public static int playerProfileResultCachingTimeout = 1440; @@ -803,6 +804,8 @@ public class DivineConfig { "Prevents players being disconnected by 'disconnect.spam' when sending too many chat packets"); dontRespondPingBeforeStart = getBoolean(ConfigCategory.NETWORK.key("general.dont-respond-ping-before-start"), dontRespondPingBeforeStart, "Prevents the server from responding to pings before the server is fully booted."); + sendSpectatorChangePacket = getBoolean(ConfigCategory.NETWORK.key("general.send-spectator-change-packet"), sendSpectatorChangePacket, + "When disabled, tab list will not show that the player have entered the spectator mode. Otherwise, it will act as normal spectator change packet."); playerProfileResultCachingEnabled = getBoolean(ConfigCategory.NETWORK.key("player-profile-result-caching.enabled"), playerProfileResultCachingEnabled, "Enables caching of player profile results on first join.");