From 3507102ce2ddab552c9db5d581bcc75e015d4b5c Mon Sep 17 00:00:00 2001 From: BillyGalbreath Date: Sun, 12 Jan 2025 14:11:28 -0800 Subject: [PATCH] Give bee counts in beehives to Purpur clients --- ...counts-in-beehives-to-Purpur-clients.patch | 184 ------------------ .../server/MinecraftServer.java.patch | 3 +- .../dedicated/DedicatedServer.java.patch | 3 +- .../org/purpurmc/purpur/PurpurConfig.java | 5 + .../network/ClientboundBeehivePayload.java | 27 +++ .../network/ServerboundBeehivePayload.java | 26 +++ .../org/purpurmc/purpur/task/BeehiveTask.java | 67 +++++++ 7 files changed, 129 insertions(+), 186 deletions(-) delete mode 100644 patches/server/0223-Give-bee-counts-in-beehives-to-Purpur-clients.patch create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/network/ClientboundBeehivePayload.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java diff --git a/patches/server/0223-Give-bee-counts-in-beehives-to-Purpur-clients.patch b/patches/server/0223-Give-bee-counts-in-beehives-to-Purpur-clients.patch deleted file mode 100644 index 3229477ef..000000000 --- a/patches/server/0223-Give-bee-counts-in-beehives-to-Purpur-clients.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: BillyGalbreath -Date: Thu, 30 Dec 2021 09:56:43 -0600 -Subject: [PATCH] Give bee counts in beehives to Purpur clients - - -diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 80a8bd2dc32763f8ee2062c2d1b36188f2532523..1dc4476ca1fc41030001d4d23ffff1b810a056cd 100644 ---- a/net/minecraft/server/MinecraftServer.java -+++ b/net/minecraft/server/MinecraftServer.java -@@ -1170,6 +1170,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop STREAM_CODEC = CustomPacketPayload.codec(ClientboundBeehivePayload::write, ClientboundBeehivePayload::new); -+ public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath("purpur", "beehive_s2c")); -+ -+ public ClientboundBeehivePayload(FriendlyByteBuf friendlyByteBuf) { -+ this(friendlyByteBuf.readBlockPos(), friendlyByteBuf.readInt()); -+ } -+ -+ private void write(FriendlyByteBuf friendlyByteBuf) { -+ friendlyByteBuf.writeBlockPos(this.pos); -+ friendlyByteBuf.writeInt(this.numOfBees); -+ } -+ -+ @Override -+ public @NotNull Type type() { -+ return TYPE; -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java b/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java -new file mode 100644 -index 0000000000000000000000000000000000000000..fa72769e06061609e1e658a0250e99c8cb026c0e ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java -@@ -0,0 +1,26 @@ -+package org.purpurmc.purpur.network; -+ -+import net.minecraft.core.BlockPos; -+import net.minecraft.network.FriendlyByteBuf; -+import net.minecraft.network.codec.StreamCodec; -+import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -+import net.minecraft.resources.ResourceLocation; -+import org.jetbrains.annotations.NotNull; -+ -+public record ServerboundBeehivePayload(BlockPos pos) implements CustomPacketPayload { -+ public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(ServerboundBeehivePayload::write, ServerboundBeehivePayload::new); -+ public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath("purpur", "beehive_c2s")); -+ -+ public ServerboundBeehivePayload(FriendlyByteBuf friendlyByteBuf) { -+ this(friendlyByteBuf.readBlockPos()); -+ } -+ -+ private void write(FriendlyByteBuf friendlyByteBuf) { -+ friendlyByteBuf.writeBlockPos(this.pos); -+ } -+ -+ @Override -+ public @NotNull Type type() { -+ return TYPE; -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java -new file mode 100644 -index 0000000000000000000000000000000000000000..664f9d5e1ce5e2787bf699bd11758b9e3aa8ed3a ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java -@@ -0,0 +1,67 @@ -+package org.purpurmc.purpur.task; -+ -+import io.netty.buffer.Unpooled; -+import net.minecraft.network.FriendlyByteBuf; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.level.block.entity.BeehiveBlockEntity; -+import net.minecraft.world.level.block.entity.BlockEntity; -+import org.bukkit.Bukkit; -+import org.bukkit.craftbukkit.entity.CraftPlayer; -+import org.bukkit.entity.Player; -+import org.bukkit.plugin.PluginBase; -+import org.bukkit.plugin.messaging.PluginMessageListener; -+import org.jetbrains.annotations.NotNull; -+import org.purpurmc.purpur.network.ClientboundBeehivePayload; -+import org.purpurmc.purpur.network.ServerboundBeehivePayload; -+import org.purpurmc.purpur.util.MinecraftInternalPlugin; -+ -+public class BeehiveTask implements PluginMessageListener { -+ -+ private static BeehiveTask instance; -+ -+ public static BeehiveTask instance() { -+ if (instance == null) { -+ instance = new BeehiveTask(); -+ } -+ return instance; -+ } -+ -+ private final PluginBase plugin = new MinecraftInternalPlugin(); -+ -+ private BeehiveTask() { -+ } -+ -+ public void register() { -+ Bukkit.getMessenger().registerOutgoingPluginChannel(this.plugin, ClientboundBeehivePayload.TYPE.id().toString()); -+ Bukkit.getMessenger().registerIncomingPluginChannel(this.plugin, ServerboundBeehivePayload.TYPE.id().toString(), this); -+ } -+ -+ public void unregister() { -+ Bukkit.getMessenger().unregisterOutgoingPluginChannel(this.plugin, ClientboundBeehivePayload.TYPE.id().toString()); -+ Bukkit.getMessenger().unregisterIncomingPluginChannel(this.plugin, ServerboundBeehivePayload.TYPE.id().toString()); -+ } -+ -+ @Override -+ public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte[] bytes) { -+ FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.copiedBuffer(bytes)); -+ ServerboundBeehivePayload payload = ServerboundBeehivePayload.STREAM_CODEC.decode(byteBuf); -+ -+ ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); -+ -+ // targeted block info max range specified in client at net.minecraft.client.gui.hud.DebugHud#render -+ if (!payload.pos().getCenter().closerThan(serverPlayer.position(), 20)) return; // Targeted Block info max range is 20 -+ if (serverPlayer.level().getChunkIfLoaded(payload.pos()) == null) return; -+ -+ BlockEntity blockEntity = serverPlayer.level().getBlockEntity(payload.pos()); -+ if (!(blockEntity instanceof BeehiveBlockEntity beehive)) { -+ return; -+ } -+ -+ ClientboundBeehivePayload customPacketPayload = new ClientboundBeehivePayload(payload.pos(), beehive.getOccupantCount()); -+ FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.buffer()); -+ ClientboundBeehivePayload.STREAM_CODEC.encode(friendlyByteBuf, customPacketPayload); -+ byte[] byteArray = new byte[friendlyByteBuf.readableBytes()]; -+ friendlyByteBuf.readBytes(byteArray); -+ player.sendPluginMessage(this.plugin, customPacketPayload.type().id().toString(), byteArray); -+ } -+} diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch index e189da923..2e3d170bc 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch @@ -43,11 +43,12 @@ // CraftBukkit start if (this.server != null) { this.server.spark.disable(); // Paper - spark -@@ -1093,6 +_,7 @@ +@@ -1093,6 +_,8 @@ this.safeShutdown(waitForServer, false); } public void safeShutdown(boolean waitForServer, boolean isRestarting) { + org.purpurmc.purpur.task.BossBarTask.stopAll(); // Purpur - Implement TPSBar ++ org.purpurmc.purpur.task.BeehiveTask.instance().unregister(); // Purpur - Give bee counts in beehives to Purpur clients this.isRestarting = isRestarting; this.hasLoggedStop = true; // Paper - Debugging if (isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch index bcb20f781..d58b511b0 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -47,11 +47,12 @@ // CraftBukkit start // this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); // Spigot - moved up -@@ -350,6 +_,7 @@ +@@ -350,6 +_,8 @@ LOGGER.info("JMX monitoring enabled"); } + org.purpurmc.purpur.task.BossBarTask.startAll(); // Purpur - Implement TPSBar ++ if (org.purpurmc.purpur.PurpurConfig.beeCountPayload) org.purpurmc.purpur.task.BeehiveTask.instance().register(); // Purpur - Give bee counts in beehives to Purpur clients return true; } } 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 7d753a6d3..265b9faf3 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -428,6 +428,11 @@ public class PurpurConfig { allowWaterPlacementInTheEnd = getBoolean("settings.allow-water-placement-in-the-end", allowWaterPlacementInTheEnd); } + public static boolean beeCountPayload = false; + private static void beeCountPayload() { + beeCountPayload = getBoolean("settings.bee-count-payload", beeCountPayload); + } + public static boolean loggerSuppressInitLegacyMaterialError = false; public static boolean loggerSuppressIgnoredAdvancementWarnings = false; public static boolean loggerSuppressUnrecognizedRecipeErrors = false; diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/network/ClientboundBeehivePayload.java b/purpur-server/src/main/java/org/purpurmc/purpur/network/ClientboundBeehivePayload.java new file mode 100644 index 000000000..793a3ea45 --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/network/ClientboundBeehivePayload.java @@ -0,0 +1,27 @@ +package org.purpurmc.purpur.network; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; + +public record ClientboundBeehivePayload(BlockPos pos, int numOfBees) implements CustomPacketPayload { + public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(ClientboundBeehivePayload::write, ClientboundBeehivePayload::new); + public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath("purpur", "beehive_s2c")); + + public ClientboundBeehivePayload(FriendlyByteBuf friendlyByteBuf) { + this(friendlyByteBuf.readBlockPos(), friendlyByteBuf.readInt()); + } + + private void write(FriendlyByteBuf friendlyByteBuf) { + friendlyByteBuf.writeBlockPos(this.pos); + friendlyByteBuf.writeInt(this.numOfBees); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java b/purpur-server/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java new file mode 100644 index 000000000..fa72769e0 --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/network/ServerboundBeehivePayload.java @@ -0,0 +1,26 @@ +package org.purpurmc.purpur.network; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; + +public record ServerboundBeehivePayload(BlockPos pos) implements CustomPacketPayload { + public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(ServerboundBeehivePayload::write, ServerboundBeehivePayload::new); + public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath("purpur", "beehive_c2s")); + + public ServerboundBeehivePayload(FriendlyByteBuf friendlyByteBuf) { + this(friendlyByteBuf.readBlockPos()); + } + + private void write(FriendlyByteBuf friendlyByteBuf) { + friendlyByteBuf.writeBlockPos(this.pos); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java b/purpur-server/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java new file mode 100644 index 000000000..664f9d5e1 --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java @@ -0,0 +1,67 @@ +package org.purpurmc.purpur.task; + +import io.netty.buffer.Unpooled; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.block.entity.BeehiveBlockEntity; +import net.minecraft.world.level.block.entity.BlockEntity; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginBase; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; +import org.purpurmc.purpur.network.ClientboundBeehivePayload; +import org.purpurmc.purpur.network.ServerboundBeehivePayload; +import org.purpurmc.purpur.util.MinecraftInternalPlugin; + +public class BeehiveTask implements PluginMessageListener { + + private static BeehiveTask instance; + + public static BeehiveTask instance() { + if (instance == null) { + instance = new BeehiveTask(); + } + return instance; + } + + private final PluginBase plugin = new MinecraftInternalPlugin(); + + private BeehiveTask() { + } + + public void register() { + Bukkit.getMessenger().registerOutgoingPluginChannel(this.plugin, ClientboundBeehivePayload.TYPE.id().toString()); + Bukkit.getMessenger().registerIncomingPluginChannel(this.plugin, ServerboundBeehivePayload.TYPE.id().toString(), this); + } + + public void unregister() { + Bukkit.getMessenger().unregisterOutgoingPluginChannel(this.plugin, ClientboundBeehivePayload.TYPE.id().toString()); + Bukkit.getMessenger().unregisterIncomingPluginChannel(this.plugin, ServerboundBeehivePayload.TYPE.id().toString()); + } + + @Override + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte[] bytes) { + FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.copiedBuffer(bytes)); + ServerboundBeehivePayload payload = ServerboundBeehivePayload.STREAM_CODEC.decode(byteBuf); + + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + // targeted block info max range specified in client at net.minecraft.client.gui.hud.DebugHud#render + if (!payload.pos().getCenter().closerThan(serverPlayer.position(), 20)) return; // Targeted Block info max range is 20 + if (serverPlayer.level().getChunkIfLoaded(payload.pos()) == null) return; + + BlockEntity blockEntity = serverPlayer.level().getBlockEntity(payload.pos()); + if (!(blockEntity instanceof BeehiveBlockEntity beehive)) { + return; + } + + ClientboundBeehivePayload customPacketPayload = new ClientboundBeehivePayload(payload.pos(), beehive.getOccupantCount()); + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.buffer()); + ClientboundBeehivePayload.STREAM_CODEC.encode(friendlyByteBuf, customPacketPayload); + byte[] byteArray = new byte[friendlyByteBuf.readableBytes()]; + friendlyByteBuf.readBytes(byteArray); + player.sendPluginMessage(this.plugin, customPacketPayload.type().id().toString(), byteArray); + } +}