From 252fe38d8fa00d3058f7bcf4d62fb222896dbf40 Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Sun, 23 Nov 2025 23:18:46 -0500 Subject: [PATCH 01/20] Add files via upload --- .../0021-Add-spectator-teleport-node.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 purpur-server/minecraft-patches/features/0021-Add-spectator-teleport-node.patch diff --git a/purpur-server/minecraft-patches/features/0021-Add-spectator-teleport-node.patch b/purpur-server/minecraft-patches/features/0021-Add-spectator-teleport-node.patch new file mode 100644 index 000000000..758b70ac3 --- /dev/null +++ b/purpur-server/minecraft-patches/features/0021-Add-spectator-teleport-node.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Mickey42302 +Date: Sun, 23 Nov 2025 23:10:49 -0500 +Subject: [PATCH] Add spectator teleport node + + +diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index cb8d0109932116776dd3be33986d1e1ef775d121..e7fb8e64321a8001de8024a7c889755361fbb9e1 100644 +--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -2236,7 +2236,7 @@ public class ServerGamePacketListenerImpl + @Override + public void handleTeleportToEntityPacket(ServerboundTeleportToEntityPacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); +- if (this.player.isSpectator()) { ++ if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("minecraft.spectatetp")) { + for (ServerLevel serverLevel : this.server.getAllLevels()) { + Entity entity = packet.getEntity(serverLevel); + if (entity != null) { From 3954084a5a7a85692c29ddd9a5431cc7893a8d6a Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Fri, 1 May 2026 20:59:01 -0400 Subject: [PATCH 02/20] Add files via upload --- ...ation-entry-for-spectatetp-permission.patch | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 purpur-server/minecraft-patches/features/0022-Add-configuration-entry-for-spectatetp-permission.patch diff --git a/purpur-server/minecraft-patches/features/0022-Add-configuration-entry-for-spectatetp-permission.patch b/purpur-server/minecraft-patches/features/0022-Add-configuration-entry-for-spectatetp-permission.patch new file mode 100644 index 000000000..f6744c234 --- /dev/null +++ b/purpur-server/minecraft-patches/features/0022-Add-configuration-entry-for-spectatetp-permission.patch @@ -0,0 +1,18 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Mickey42302 +Date: Fri, 1 May 2026 20:56:12 -0400 +Subject: [PATCH] Add configuration entry for spectatetp permission + + +diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java +index 42841fdc7e64311ba9217789a3dc758a351cf674..63e827ecd01f4c4ca57257790218b519befdf4ff 100644 +--- a/net/minecraft/server/Main.java ++++ b/net/minecraft/server/Main.java +@@ -112,6 +112,7 @@ public class Main { + org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels", true); + org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands + org.purpurmc.purpur.PurpurConfig.registerMinecraftDisabledCommands = purpurConfiguration.getBoolean("settings.register-minecraft-disabled-commands"); // Purpur - register disabled minecraft commands ++ org.purpurmc.purpur.PurpurConfig.requireSpectatorTeleportPermission = purpurConfiguration.getBoolean("settings.require-spectator-teleport-permission"); // Purpur - require spectator teleport permission + // Purpur end - Add toggle for enchant level clamping - load config files early + + io.papermc.paper.plugin.PluginInitializerManager.load(optionSet); // Paper From e26f4dcdff10f540c7dd3a8cd038eb5fca09a417 Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Fri, 1 May 2026 21:24:33 -0400 Subject: [PATCH 03/20] Add to PurpurConfig --- .../src/main/java/org/purpurmc/purpur/PurpurConfig.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java index 5248f28e6..00a91654a 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -604,6 +604,11 @@ private static void registerMinecraftDisabledCommands() { registerMinecraftDisabledCommands = getBoolean("settings.register-minecraft-disabled-commands", registerMinecraftDebugCommands); } + public static boolean requireSpectatorTeleportPermission = false; + private static void requireSpectatorTeleportPermission() { + requireSpectatorTeleportPermission = getBoolean("settings.require-spectator-teleport-permission", requireSpectatorTeleportPermission); + } + public static List startupCommands = new ArrayList<>(); private static void startupCommands() { startupCommands.clear(); From 243689819a9e9c6f8b267083b196cce9768fb310 Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Sat, 2 May 2026 11:35:11 -0400 Subject: [PATCH 04/20] Add files via upload --- ...023-Add-check-for-spectatetp-setting.patch | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 purpur-server/minecraft-patches/features/0023-Add-check-for-spectatetp-setting.patch diff --git a/purpur-server/minecraft-patches/features/0023-Add-check-for-spectatetp-setting.patch b/purpur-server/minecraft-patches/features/0023-Add-check-for-spectatetp-setting.patch new file mode 100644 index 000000000..87f95c545 --- /dev/null +++ b/purpur-server/minecraft-patches/features/0023-Add-check-for-spectatetp-setting.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Mickey42302 +Date: Sat, 2 May 2026 11:33:02 -0400 +Subject: [PATCH] Add check for spectatetp setting + + +diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index e7fb8e64321a8001de8024a7c889755361fbb9e1..b5ec2d667fca64219f179b5cd08e8558e50f2dcb 100644 +--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -2236,12 +2236,24 @@ public class ServerGamePacketListenerImpl + @Override + public void handleTeleportToEntityPacket(ServerboundTeleportToEntityPacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); +- if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("minecraft.spectatetp")) { +- for (ServerLevel serverLevel : this.server.getAllLevels()) { +- Entity entity = packet.getEntity(serverLevel); +- if (entity != null) { +- this.player.teleportTo(serverLevel, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit +- return; ++ if (org.purpurmc.purpur.PurpurConfig.requireSpectatorTeleportPermission) { ++ if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("minecraft.spectatetp")) { ++ for (ServerLevel serverLevel : this.server.getAllLevels()) { ++ Entity entity = packet.getEntity(serverLevel); ++ if (entity != null) { ++ this.player.teleportTo(serverLevel, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit ++ return; ++ } ++ } ++ } ++ } else { ++ if (this.player.isSpectator()) { ++ for (ServerLevel serverLevel : this.server.getAllLevels()) { ++ Entity entity = packet.getEntity(serverLevel); ++ if (entity != null) { ++ this.player.teleportTo(serverLevel, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit ++ return; ++ } + } + } + } From 0f9cfc3b10b8911126b4522362beb3dc103a9990 Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Wed, 1 Jul 2026 11:58:24 -0400 Subject: [PATCH 05/20] Delete purpur-server/minecraft-patches/features/0021-Add-spectator-teleport-node.patch --- .../0021-Add-spectator-teleport-node.patch | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 purpur-server/minecraft-patches/features/0021-Add-spectator-teleport-node.patch diff --git a/purpur-server/minecraft-patches/features/0021-Add-spectator-teleport-node.patch b/purpur-server/minecraft-patches/features/0021-Add-spectator-teleport-node.patch deleted file mode 100644 index 758b70ac3..000000000 --- a/purpur-server/minecraft-patches/features/0021-Add-spectator-teleport-node.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mickey42302 -Date: Sun, 23 Nov 2025 23:10:49 -0500 -Subject: [PATCH] Add spectator teleport node - - -diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index cb8d0109932116776dd3be33986d1e1ef775d121..e7fb8e64321a8001de8024a7c889755361fbb9e1 100644 ---- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2236,7 +2236,7 @@ public class ServerGamePacketListenerImpl - @Override - public void handleTeleportToEntityPacket(ServerboundTeleportToEntityPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); -- if (this.player.isSpectator()) { -+ if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("minecraft.spectatetp")) { - for (ServerLevel serverLevel : this.server.getAllLevels()) { - Entity entity = packet.getEntity(serverLevel); - if (entity != null) { From 7e24aa89147ea2e2a4fbfb4bf025ba93abdcb6e9 Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Wed, 1 Jul 2026 11:58:27 -0400 Subject: [PATCH 06/20] Delete purpur-server/minecraft-patches/features/0022-Add-configuration-entry-for-spectatetp-permission.patch --- ...ation-entry-for-spectatetp-permission.patch | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 purpur-server/minecraft-patches/features/0022-Add-configuration-entry-for-spectatetp-permission.patch diff --git a/purpur-server/minecraft-patches/features/0022-Add-configuration-entry-for-spectatetp-permission.patch b/purpur-server/minecraft-patches/features/0022-Add-configuration-entry-for-spectatetp-permission.patch deleted file mode 100644 index f6744c234..000000000 --- a/purpur-server/minecraft-patches/features/0022-Add-configuration-entry-for-spectatetp-permission.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mickey42302 -Date: Fri, 1 May 2026 20:56:12 -0400 -Subject: [PATCH] Add configuration entry for spectatetp permission - - -diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java -index 42841fdc7e64311ba9217789a3dc758a351cf674..63e827ecd01f4c4ca57257790218b519befdf4ff 100644 ---- a/net/minecraft/server/Main.java -+++ b/net/minecraft/server/Main.java -@@ -112,6 +112,7 @@ public class Main { - org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels", true); - org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands - org.purpurmc.purpur.PurpurConfig.registerMinecraftDisabledCommands = purpurConfiguration.getBoolean("settings.register-minecraft-disabled-commands"); // Purpur - register disabled minecraft commands -+ org.purpurmc.purpur.PurpurConfig.requireSpectatorTeleportPermission = purpurConfiguration.getBoolean("settings.require-spectator-teleport-permission"); // Purpur - require spectator teleport permission - // Purpur end - Add toggle for enchant level clamping - load config files early - - io.papermc.paper.plugin.PluginInitializerManager.load(optionSet); // Paper From d552351be314f0d89f87f06d04fc6186d8d4b00e Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Wed, 1 Jul 2026 11:58:31 -0400 Subject: [PATCH 07/20] Delete purpur-server/minecraft-patches/features/0023-Add-check-for-spectatetp-setting.patch --- ...023-Add-check-for-spectatetp-setting.patch | 41 ------------------- 1 file changed, 41 deletions(-) delete mode 100644 purpur-server/minecraft-patches/features/0023-Add-check-for-spectatetp-setting.patch diff --git a/purpur-server/minecraft-patches/features/0023-Add-check-for-spectatetp-setting.patch b/purpur-server/minecraft-patches/features/0023-Add-check-for-spectatetp-setting.patch deleted file mode 100644 index 87f95c545..000000000 --- a/purpur-server/minecraft-patches/features/0023-Add-check-for-spectatetp-setting.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mickey42302 -Date: Sat, 2 May 2026 11:33:02 -0400 -Subject: [PATCH] Add check for spectatetp setting - - -diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e7fb8e64321a8001de8024a7c889755361fbb9e1..b5ec2d667fca64219f179b5cd08e8558e50f2dcb 100644 ---- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2236,12 +2236,24 @@ public class ServerGamePacketListenerImpl - @Override - public void handleTeleportToEntityPacket(ServerboundTeleportToEntityPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); -- if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("minecraft.spectatetp")) { -- for (ServerLevel serverLevel : this.server.getAllLevels()) { -- Entity entity = packet.getEntity(serverLevel); -- if (entity != null) { -- this.player.teleportTo(serverLevel, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -- return; -+ if (org.purpurmc.purpur.PurpurConfig.requireSpectatorTeleportPermission) { -+ if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("minecraft.spectatetp")) { -+ for (ServerLevel serverLevel : this.server.getAllLevels()) { -+ Entity entity = packet.getEntity(serverLevel); -+ if (entity != null) { -+ this.player.teleportTo(serverLevel, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -+ return; -+ } -+ } -+ } -+ } else { -+ if (this.player.isSpectator()) { -+ for (ServerLevel serverLevel : this.server.getAllLevels()) { -+ Entity entity = packet.getEntity(serverLevel); -+ if (entity != null) { -+ this.player.teleportTo(serverLevel, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -+ return; -+ } - } - } - } From d5052dc3d333707d47e0b53bd91fc687d8f8e86f Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Wed, 1 Jul 2026 11:59:46 -0400 Subject: [PATCH 08/20] Add files via upload --- .../src/main/java/org/purpurmc/purpur/PurpurConfig.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java index 95d45f2bf..0f5659e11 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -606,11 +606,6 @@ private static void registerMinecraftDisabledCommands() { registerMinecraftDisabledCommands = getBoolean("settings.register-minecraft-disabled-commands", registerMinecraftDebugCommands); } - public static boolean requireSpectatorTeleportPermission = false; - private static void requireSpectatorTeleportPermission() { - requireSpectatorTeleportPermission = getBoolean("settings.require-spectator-teleport-permission", requireSpectatorTeleportPermission); - } - public static List startupCommands = new ArrayList<>(); private static void startupCommands() { startupCommands.clear(); From 07a9f6a10f3a62ad19cfdc54adaf73257f89dd30 Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:32:01 -0400 Subject: [PATCH 09/20] Add requireSpectatorTeleportPermission setting --- .../src/main/java/org/purpurmc/purpur/PurpurConfig.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java index 0f5659e11..95d45f2bf 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -606,6 +606,11 @@ private static void registerMinecraftDisabledCommands() { registerMinecraftDisabledCommands = getBoolean("settings.register-minecraft-disabled-commands", registerMinecraftDebugCommands); } + public static boolean requireSpectatorTeleportPermission = false; + private static void requireSpectatorTeleportPermission() { + requireSpectatorTeleportPermission = getBoolean("settings.require-spectator-teleport-permission", requireSpectatorTeleportPermission); + } + public static List startupCommands = new ArrayList<>(); private static void startupCommands() { startupCommands.clear(); From d94d0a192ab764e40f4c0e1f02f3db8e9f9cb2fd Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Wed, 1 Jul 2026 13:19:39 -0400 Subject: [PATCH 10/20] Add files via upload --- .../0022-Add-spectatetp-permission.patch | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 purpur-server/minecraft-patches/features/0022-Add-spectatetp-permission.patch diff --git a/purpur-server/minecraft-patches/features/0022-Add-spectatetp-permission.patch b/purpur-server/minecraft-patches/features/0022-Add-spectatetp-permission.patch new file mode 100644 index 000000000..b5d6a0b8c --- /dev/null +++ b/purpur-server/minecraft-patches/features/0022-Add-spectatetp-permission.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Mickey42302 +Date: Wed, 1 Jul 2026 13:02:43 -0400 +Subject: [PATCH] Add spectatetp permission + + +diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java +index 1862df44a3319e459b547cebffb16972674856d6..2d9106686fd688f24109c75e10129c7fcdb875b2 100644 +--- a/net/minecraft/server/Main.java ++++ b/net/minecraft/server/Main.java +@@ -112,6 +112,7 @@ public class Main { + org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels", true); + org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands + org.purpurmc.purpur.PurpurConfig.registerMinecraftDisabledCommands = purpurConfiguration.getBoolean("settings.register-minecraft-disabled-commands"); // Purpur - register disabled minecraft commands ++ org.purpurmc.purpur.PurpurConfig.requireSpectatorTeleportPermission = purpurConfiguration.getBoolean("settings.require-spectator-teleport-permission"); // Purpur - require spectator teleport permission + // Purpur end - Add toggle for enchant level clamping - load config files early + + io.papermc.paper.plugin.PluginInitializerManager.load(options); // Paper +diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index cc895257b6f0de151c73cbf25d070514f6e78ead..fc6b71892ab827f21694c42871a19c2ef7a094e2 100644 +--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -2327,12 +2327,24 @@ public class ServerGamePacketListenerImpl + @Override + public void handleTeleportToEntityPacket(final ServerboundTeleportToEntityPacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); +- if (this.player.isSpectator()) { +- for (ServerLevel level : this.server.getAllLevels()) { +- Entity entity = packet.getEntity(level); +- if (entity != null) { +- this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit +- return; ++ if (org.purpurmc.purpur.PurpurConfig.requireSpectatorTeleportPermission) { ++ if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("minecraft.spectatetp")) { ++ for (ServerLevel level : this.server.getAllLevels()) { ++ Entity entity = packet.getEntity(level); ++ if (entity != null) { ++ this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit ++ return; ++ } ++ } ++ } ++ } else { ++ if (this.player.isSpectator()) { ++ for (ServerLevel level : this.server.getAllLevels()) { ++ Entity entity = packet.getEntity(level); ++ if (entity != null) { ++ this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit ++ return; ++ } + } + } + } From 8d38b72c02793c8abac267ad26ad649a78b7e01b Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:14:10 -0400 Subject: [PATCH 11/20] Update PurpurPermissions.java --- .../org/purpurmc/purpur/util/permissions/PurpurPermissions.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/purpur-api/src/main/java/org/purpurmc/purpur/util/permissions/PurpurPermissions.java b/purpur-api/src/main/java/org/purpurmc/purpur/util/permissions/PurpurPermissions.java index 50647252e..c9e46891c 100644 --- a/purpur-api/src/main/java/org/purpurmc/purpur/util/permissions/PurpurPermissions.java +++ b/purpur-api/src/main/java/org/purpurmc/purpur/util/permissions/PurpurPermissions.java @@ -44,6 +44,8 @@ public static Permission registerPermissions() { DefaultPermissions.registerPermission(PREFIX + "inventory_totem", "Allows the user to use totem of undying anywhere in their inventory", PermissionDefault.FALSE, purpur); + DefaultPermissions.registerPermission(PREFIX + "spectator-can-teleport-to-players", "Allows the user to teleport to players while in spectator mode", PermissionDefault.TRUE, purpur); + Permission anvil = DefaultPermissions.registerPermission(PREFIX + "anvil", "Allows the user to use all anvil color and format abilities", PermissionDefault.FALSE, purpur); DefaultPermissions.registerPermission(PREFIX + "anvil.color", "Allows the user to use color codes in an anvil", PermissionDefault.FALSE, anvil); DefaultPermissions.registerPermission(PREFIX + "anvil.minimessage", "Allows the user to use minimessage tags in an anvil", PermissionDefault.FALSE, anvil); From cd88d627e8c4d37de6ce04e922ac56ec0a1f7b0b Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:16:25 -0400 Subject: [PATCH 12/20] Add files via upload --- ...r-can-teleport-to-players-permission.patch | 53 +++++++++++++++++++ .../features/0023-Made-code-less-noisy.patch | 31 +++++++++++ 2 files changed, 84 insertions(+) create mode 100644 purpur-server/minecraft-patches/features/0022-Add-spectator-can-teleport-to-players-permission.patch create mode 100644 purpur-server/minecraft-patches/features/0023-Made-code-less-noisy.patch diff --git a/purpur-server/minecraft-patches/features/0022-Add-spectator-can-teleport-to-players-permission.patch b/purpur-server/minecraft-patches/features/0022-Add-spectator-can-teleport-to-players-permission.patch new file mode 100644 index 000000000..0db48f5ad --- /dev/null +++ b/purpur-server/minecraft-patches/features/0022-Add-spectator-can-teleport-to-players-permission.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Mickey42302 +Date: Wed, 1 Jul 2026 13:02:43 -0400 +Subject: [PATCH] Add spectator can teleport to players permission + + +diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java +index 1862df44a3319e459b547cebffb16972674856d6..2d9106686fd688f24109c75e10129c7fcdb875b2 100644 +--- a/net/minecraft/server/Main.java ++++ b/net/minecraft/server/Main.java +@@ -112,6 +112,7 @@ public class Main { + org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels", true); + org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands + org.purpurmc.purpur.PurpurConfig.registerMinecraftDisabledCommands = purpurConfiguration.getBoolean("settings.register-minecraft-disabled-commands"); // Purpur - register disabled minecraft commands ++ org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers = purpurConfiguration.getBoolean("settings.require-permission-spectator-teleport-to-players"); // Purpur - require permission spectator teleport to players + // Purpur end - Add toggle for enchant level clamping - load config files early + + io.papermc.paper.plugin.PluginInitializerManager.load(options); // Paper +diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index cc895257b6f0de151c73cbf25d070514f6e78ead..fc6b71892ab827f21694c42871a19c2ef7a094e2 100644 +--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -2327,12 +2327,24 @@ public class ServerGamePacketListenerImpl + @Override + public void handleTeleportToEntityPacket(final ServerboundTeleportToEntityPacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); +- if (this.player.isSpectator()) { +- for (ServerLevel level : this.server.getAllLevels()) { +- Entity entity = packet.getEntity(level); +- if (entity != null) { +- this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit +- return; ++ if (org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers) { ++ if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("purpur.spectator-can-teleport-to-players")) { ++ for (ServerLevel level : this.server.getAllLevels()) { ++ Entity entity = packet.getEntity(level); ++ if (entity != null) { ++ this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit ++ return; ++ } ++ } ++ } ++ } else { ++ if (this.player.isSpectator()) { ++ for (ServerLevel level : this.server.getAllLevels()) { ++ Entity entity = packet.getEntity(level); ++ if (entity != null) { ++ this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit ++ return; ++ } + } + } + } diff --git a/purpur-server/minecraft-patches/features/0023-Made-code-less-noisy.patch b/purpur-server/minecraft-patches/features/0023-Made-code-less-noisy.patch new file mode 100644 index 000000000..99cd34754 --- /dev/null +++ b/purpur-server/minecraft-patches/features/0023-Made-code-less-noisy.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Mickey42302 +Date: Mon, 20 Jul 2026 13:23:38 -0400 +Subject: [PATCH] Made code less noisy + + +diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index 1805674a6d6df73608e5be6a48d2b8f13d8abb76..d7493ba7267015a86ee9fdace5fe8d4f0d0d6acf 100644 +--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -2327,18 +2327,8 @@ public class ServerGamePacketListenerImpl + @Override + public void handleTeleportToEntityPacket(final ServerboundTeleportToEntityPacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); +- if (org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers) { +- if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("purpur.spectator-can-teleport-to-players")) { +- for (ServerLevel level : this.server.getAllLevels()) { +- Entity entity = packet.getEntity(level); +- if (entity != null) { +- this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit +- return; +- } +- } +- } +- } else { +- if (this.player.isSpectator()) { ++ if (this.player.isSpectator()) { ++ if (!org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers || this.player.getBukkitEntity().hasPermission("purpur.spectator-can-teleport-to-players")) { + for (ServerLevel level : this.server.getAllLevels()) { + Entity entity = packet.getEntity(level); + if (entity != null) { From d32ef394ee21fafa5420cb41d3b1d2f4b43f0b55 Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:16:47 -0400 Subject: [PATCH 13/20] Delete purpur-server/minecraft-patches/features/0022-Add-spectatetp-permission.patch --- .../0022-Add-spectatetp-permission.patch | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100644 purpur-server/minecraft-patches/features/0022-Add-spectatetp-permission.patch diff --git a/purpur-server/minecraft-patches/features/0022-Add-spectatetp-permission.patch b/purpur-server/minecraft-patches/features/0022-Add-spectatetp-permission.patch deleted file mode 100644 index b5d6a0b8c..000000000 --- a/purpur-server/minecraft-patches/features/0022-Add-spectatetp-permission.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mickey42302 -Date: Wed, 1 Jul 2026 13:02:43 -0400 -Subject: [PATCH] Add spectatetp permission - - -diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java -index 1862df44a3319e459b547cebffb16972674856d6..2d9106686fd688f24109c75e10129c7fcdb875b2 100644 ---- a/net/minecraft/server/Main.java -+++ b/net/minecraft/server/Main.java -@@ -112,6 +112,7 @@ public class Main { - org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels", true); - org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands - org.purpurmc.purpur.PurpurConfig.registerMinecraftDisabledCommands = purpurConfiguration.getBoolean("settings.register-minecraft-disabled-commands"); // Purpur - register disabled minecraft commands -+ org.purpurmc.purpur.PurpurConfig.requireSpectatorTeleportPermission = purpurConfiguration.getBoolean("settings.require-spectator-teleport-permission"); // Purpur - require spectator teleport permission - // Purpur end - Add toggle for enchant level clamping - load config files early - - io.papermc.paper.plugin.PluginInitializerManager.load(options); // Paper -diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index cc895257b6f0de151c73cbf25d070514f6e78ead..fc6b71892ab827f21694c42871a19c2ef7a094e2 100644 ---- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2327,12 +2327,24 @@ public class ServerGamePacketListenerImpl - @Override - public void handleTeleportToEntityPacket(final ServerboundTeleportToEntityPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); -- if (this.player.isSpectator()) { -- for (ServerLevel level : this.server.getAllLevels()) { -- Entity entity = packet.getEntity(level); -- if (entity != null) { -- this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -- return; -+ if (org.purpurmc.purpur.PurpurConfig.requireSpectatorTeleportPermission) { -+ if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("minecraft.spectatetp")) { -+ for (ServerLevel level : this.server.getAllLevels()) { -+ Entity entity = packet.getEntity(level); -+ if (entity != null) { -+ this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -+ return; -+ } -+ } -+ } -+ } else { -+ if (this.player.isSpectator()) { -+ for (ServerLevel level : this.server.getAllLevels()) { -+ Entity entity = packet.getEntity(level); -+ if (entity != null) { -+ this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -+ return; -+ } - } - } - } From 82b2fe21d955390ec72ba4548d7355e0248d5361 Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:48:24 -0400 Subject: [PATCH 14/20] Rewriting the original patch file --- ...r-can-teleport-to-players-permission.patch | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100644 purpur-server/minecraft-patches/features/0022-Add-spectator-can-teleport-to-players-permission.patch diff --git a/purpur-server/minecraft-patches/features/0022-Add-spectator-can-teleport-to-players-permission.patch b/purpur-server/minecraft-patches/features/0022-Add-spectator-can-teleport-to-players-permission.patch deleted file mode 100644 index 0db48f5ad..000000000 --- a/purpur-server/minecraft-patches/features/0022-Add-spectator-can-teleport-to-players-permission.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mickey42302 -Date: Wed, 1 Jul 2026 13:02:43 -0400 -Subject: [PATCH] Add spectator can teleport to players permission - - -diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java -index 1862df44a3319e459b547cebffb16972674856d6..2d9106686fd688f24109c75e10129c7fcdb875b2 100644 ---- a/net/minecraft/server/Main.java -+++ b/net/minecraft/server/Main.java -@@ -112,6 +112,7 @@ public class Main { - org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels", true); - org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands - org.purpurmc.purpur.PurpurConfig.registerMinecraftDisabledCommands = purpurConfiguration.getBoolean("settings.register-minecraft-disabled-commands"); // Purpur - register disabled minecraft commands -+ org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers = purpurConfiguration.getBoolean("settings.require-permission-spectator-teleport-to-players"); // Purpur - require permission spectator teleport to players - // Purpur end - Add toggle for enchant level clamping - load config files early - - io.papermc.paper.plugin.PluginInitializerManager.load(options); // Paper -diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index cc895257b6f0de151c73cbf25d070514f6e78ead..fc6b71892ab827f21694c42871a19c2ef7a094e2 100644 ---- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2327,12 +2327,24 @@ public class ServerGamePacketListenerImpl - @Override - public void handleTeleportToEntityPacket(final ServerboundTeleportToEntityPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); -- if (this.player.isSpectator()) { -- for (ServerLevel level : this.server.getAllLevels()) { -- Entity entity = packet.getEntity(level); -- if (entity != null) { -- this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -- return; -+ if (org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers) { -+ if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("purpur.spectator-can-teleport-to-players")) { -+ for (ServerLevel level : this.server.getAllLevels()) { -+ Entity entity = packet.getEntity(level); -+ if (entity != null) { -+ this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -+ return; -+ } -+ } -+ } -+ } else { -+ if (this.player.isSpectator()) { -+ for (ServerLevel level : this.server.getAllLevels()) { -+ Entity entity = packet.getEntity(level); -+ if (entity != null) { -+ this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -+ return; -+ } - } - } - } From fb109cf2e8908e28a8a4a9aa961d685d3a7915cc Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:48:40 -0400 Subject: [PATCH 15/20] Rewriting the original patch file --- .../features/0023-Made-code-less-noisy.patch | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 purpur-server/minecraft-patches/features/0023-Made-code-less-noisy.patch diff --git a/purpur-server/minecraft-patches/features/0023-Made-code-less-noisy.patch b/purpur-server/minecraft-patches/features/0023-Made-code-less-noisy.patch deleted file mode 100644 index 99cd34754..000000000 --- a/purpur-server/minecraft-patches/features/0023-Made-code-less-noisy.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mickey42302 -Date: Mon, 20 Jul 2026 13:23:38 -0400 -Subject: [PATCH] Made code less noisy - - -diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1805674a6d6df73608e5be6a48d2b8f13d8abb76..d7493ba7267015a86ee9fdace5fe8d4f0d0d6acf 100644 ---- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2327,18 +2327,8 @@ public class ServerGamePacketListenerImpl - @Override - public void handleTeleportToEntityPacket(final ServerboundTeleportToEntityPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); -- if (org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers) { -- if (this.player.isSpectator() && this.player.getBukkitEntity().hasPermission("purpur.spectator-can-teleport-to-players")) { -- for (ServerLevel level : this.server.getAllLevels()) { -- Entity entity = packet.getEntity(level); -- if (entity != null) { -- this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -- return; -- } -- } -- } -- } else { -- if (this.player.isSpectator()) { -+ if (this.player.isSpectator()) { -+ if (!org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers || this.player.getBukkitEntity().hasPermission("purpur.spectator-can-teleport-to-players")) { - for (ServerLevel level : this.server.getAllLevels()) { - Entity entity = packet.getEntity(level); - if (entity != null) { From 70963beb9f3940e8ad9419064852ec5b4670a28c Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:04:05 -0400 Subject: [PATCH 16/20] Update PurpurConfig.java --- .../src/main/java/org/purpurmc/purpur/PurpurConfig.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java index d8b1608d7..e2f12a1a5 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -606,9 +606,9 @@ private static void registerMinecraftDisabledCommands() { registerMinecraftDisabledCommands = getBoolean("settings.register-minecraft-disabled-commands", registerMinecraftDisabledCommands); } - public static boolean requireSpectatorTeleportPermission = false; - private static void requireSpectatorTeleportPermission() { - requireSpectatorTeleportPermission = getBoolean("settings.require-spectator-teleport-permission", requireSpectatorTeleportPermission); + public static boolean requirePermissionSpectatorTeleportToPlayers = false; + private static void requirePermissionSpectatorTeleportToPlayers() { + requirePermissionSpectatorTeleportToPlayers = getBoolean("settings.require-spectator-teleport-permission", requireSpectatorTeleportPermission); } public static List startupCommands = new ArrayList<>(); From 922e6898e3f577d758fd583cd3b3bb76c86a4f6d Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:04:44 -0400 Subject: [PATCH 17/20] Fix configuration key for spectator teleport permission --- .../src/main/java/org/purpurmc/purpur/PurpurConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java index e2f12a1a5..ad5af5190 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -608,7 +608,7 @@ private static void registerMinecraftDisabledCommands() { public static boolean requirePermissionSpectatorTeleportToPlayers = false; private static void requirePermissionSpectatorTeleportToPlayers() { - requirePermissionSpectatorTeleportToPlayers = getBoolean("settings.require-spectator-teleport-permission", requireSpectatorTeleportPermission); + requirePermissionSpectatorTeleportToPlayers = getBoolean("settings.require-permission-spectator-teleport-to-players", requireSpectatorTeleportPermission); } public static List startupCommands = new ArrayList<>(); From 01d8d11d931c1a317a55ba419c7baa1856d21eac Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:06:47 -0400 Subject: [PATCH 18/20] Update PurpurConfig.java --- .../src/main/java/org/purpurmc/purpur/PurpurConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java index ad5af5190..2915904e9 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -608,7 +608,7 @@ private static void registerMinecraftDisabledCommands() { public static boolean requirePermissionSpectatorTeleportToPlayers = false; private static void requirePermissionSpectatorTeleportToPlayers() { - requirePermissionSpectatorTeleportToPlayers = getBoolean("settings.require-permission-spectator-teleport-to-players", requireSpectatorTeleportPermission); + requirePermissionSpectatorTeleportToPlayers = getBoolean("settings.require-permission-spectator-teleport-to-players", requirePermissionSpectatorTeleportToPlayers); } public static List startupCommands = new ArrayList<>(); From 159f2e8dddf5427da244d2c35c10925fff0c5c4e Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:56:12 -0400 Subject: [PATCH 19/20] Add files via upload --- ...d-spectator-teleport-permission-node.patch | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 purpur-server/minecraft-patches/features/0022-Add-spectator-teleport-permission-node.patch diff --git a/purpur-server/minecraft-patches/features/0022-Add-spectator-teleport-permission-node.patch b/purpur-server/minecraft-patches/features/0022-Add-spectator-teleport-permission-node.patch new file mode 100644 index 000000000..1f4292a30 --- /dev/null +++ b/purpur-server/minecraft-patches/features/0022-Add-spectator-teleport-permission-node.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Mickey42302 +Date: Mon, 20 Jul 2026 15:12:50 -0400 +Subject: [PATCH] Add spectator teleport permission node + + +diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java +index 1862df44a3319e459b547cebffb16972674856d6..9edf61c70dbf739a4eeee2b238ed7206ec012c37 100644 +--- a/net/minecraft/server/Main.java ++++ b/net/minecraft/server/Main.java +@@ -110,9 +110,16 @@ public class Main { + // Purpur start - Add toggle for enchant level clamping - load config files early + org.bukkit.configuration.file.YamlConfiguration purpurConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) options.valueOf("purpur-settings")); + org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels", true); ++ // Purpur end - Add toggle for enchant level clamping - load config files early ++ ++ // Purpur start - Add settings for enabling commands that are unavailable by default. + org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands + org.purpurmc.purpur.PurpurConfig.registerMinecraftDisabledCommands = purpurConfiguration.getBoolean("settings.register-minecraft-disabled-commands"); // Purpur - register disabled minecraft commands +- // Purpur end - Add toggle for enchant level clamping - load config files early ++ // Purpur end - Add settings for enabling commands that are unavailable by default. ++ ++ // Purpur start - Add setting which can be used to enable a permission node that controls the ability for spectators to teleport to other players. ++ org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers = purpurConfiguration.getBoolean("settings.require-permission-spectator-teleport-to-players"); // Purpur - require permission spectator teleport to players ++ // Purpur end - Add setting which can be used to enable a permission node that controls the ability for spectators to teleport to other players. + + io.papermc.paper.plugin.PluginInitializerManager.load(options); // Paper + Bootstrap.bootStrap(); +diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index d731cea2005dff7be6e8e82d602b11355a143ec7..d7493ba7267015a86ee9fdace5fe8d4f0d0d6acf 100644 +--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -2328,11 +2328,13 @@ public class ServerGamePacketListenerImpl + public void handleTeleportToEntityPacket(final ServerboundTeleportToEntityPacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + if (this.player.isSpectator()) { +- for (ServerLevel level : this.server.getAllLevels()) { +- Entity entity = packet.getEntity(level); +- if (entity != null) { +- this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit +- return; ++ if (!org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers || this.player.getBukkitEntity().hasPermission("purpur.spectator-can-teleport-to-players")) { ++ for (ServerLevel level : this.server.getAllLevels()) { ++ Entity entity = packet.getEntity(level); ++ if (entity != null) { ++ this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit ++ return; ++ } + } + } + } From 5e4d1b3ff502faeb55c5743bce21a8201677694b Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Mon, 20 Jul 2026 21:37:46 -0400 Subject: [PATCH 20/20] Add files via upload --- ...d-spectator-teleport-permission-node.patch | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/purpur-server/minecraft-patches/features/0022-Add-spectator-teleport-permission-node.patch b/purpur-server/minecraft-patches/features/0022-Add-spectator-teleport-permission-node.patch index 1f4292a30..c5d1011c0 100644 --- a/purpur-server/minecraft-patches/features/0022-Add-spectator-teleport-permission-node.patch +++ b/purpur-server/minecraft-patches/features/0022-Add-spectator-teleport-permission-node.patch @@ -1,36 +1,37 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Mickey42302 -Date: Mon, 20 Jul 2026 15:12:50 -0400 +Date: Mon, 20 Jul 2026 21:30:50 -0400 Subject: [PATCH] Add spectator teleport permission node diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java -index 1862df44a3319e459b547cebffb16972674856d6..9edf61c70dbf739a4eeee2b238ed7206ec012c37 100644 +index 1862df44a3319e459b547cebffb16972674856d6..74340c3ae87846b0610d994331916d130aa4274e 100644 --- a/net/minecraft/server/Main.java +++ b/net/minecraft/server/Main.java -@@ -110,9 +110,16 @@ public class Main { - // Purpur start - Add toggle for enchant level clamping - load config files early +@@ -107,12 +107,16 @@ public class Main { + JvmProfiler.INSTANCE.start(Environment.SERVER); + } + +- // Purpur start - Add toggle for enchant level clamping - load config files early ++ // Purpur - Add toggle for enchant level clamping - load config files early org.bukkit.configuration.file.YamlConfiguration purpurConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) options.valueOf("purpur-settings")); org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels", true); -+ // Purpur end - Add toggle for enchant level clamping - load config files early + -+ // Purpur start - Add settings for enabling commands that are unavailable by default. ++ // Purpur - Add settings for enabling commands that are unavailable by default. org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands org.purpurmc.purpur.PurpurConfig.registerMinecraftDisabledCommands = purpurConfiguration.getBoolean("settings.register-minecraft-disabled-commands"); // Purpur - register disabled minecraft commands - // Purpur end - Add toggle for enchant level clamping - load config files early -+ // Purpur end - Add settings for enabling commands that are unavailable by default. + -+ // Purpur start - Add setting which can be used to enable a permission node that controls the ability for spectators to teleport to other players. ++ // Purpur - Add setting which can be used to enable a permission node that controls the ability for spectators to teleport to other players. + org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers = purpurConfiguration.getBoolean("settings.require-permission-spectator-teleport-to-players"); // Purpur - require permission spectator teleport to players -+ // Purpur end - Add setting which can be used to enable a permission node that controls the ability for spectators to teleport to other players. io.papermc.paper.plugin.PluginInitializerManager.load(options); // Paper Bootstrap.bootStrap(); diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index d731cea2005dff7be6e8e82d602b11355a143ec7..d7493ba7267015a86ee9fdace5fe8d4f0d0d6acf 100644 +index d731cea2005dff7be6e8e82d602b11355a143ec7..6858bfce9464251025fddc825f32e686df394f9d 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2328,11 +2328,13 @@ public class ServerGamePacketListenerImpl +@@ -2328,11 +2328,14 @@ public class ServerGamePacketListenerImpl public void handleTeleportToEntityPacket(final ServerboundTeleportToEntityPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); if (this.player.isSpectator()) { @@ -39,6 +40,7 @@ index d731cea2005dff7be6e8e82d602b11355a143ec7..d7493ba7267015a86ee9fdace5fe8d4f - if (entity != null) { - this.player.teleportTo(level, entity.getX(), entity.getY(), entity.getZ(), Set.of(), entity.getYRot(), entity.getXRot(), true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit - return; ++ // Purpur - Check if requiring a permission node for spectators to teleport to players is disabled or if the player has the permission node. + if (!org.purpurmc.purpur.PurpurConfig.requirePermissionSpectatorTeleportToPlayers || this.player.getBukkitEntity().hasPermission("purpur.spectator-can-teleport-to-players")) { + for (ServerLevel level : this.server.getAllLevels()) { + Entity entity = packet.getEntity(level);