Compare commits
11 Commits
1.20.2-721
...
1.20.2-744
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c252b863d5 | ||
|
|
54fd31cb6c | ||
|
|
7465ab1daf | ||
|
|
4f43e7845c | ||
|
|
5e62e78720 | ||
|
|
1d4276694e | ||
|
|
3bca6a9846 | ||
|
|
ff831edffa | ||
|
|
b2689cc08c | ||
|
|
ae5a4e8e67 | ||
|
|
d2655c4228 |
4
LICENSE
4
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Era4FunMC
|
||||
Copyright (c) 2024 LuminolMC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
|
||||
@@ -236,7 +236,7 @@ index 0000000000000000000000000000000000000000..baec715e0c20e920ccb99f2f07d84fcb
|
||||
+ Placeholder.component("ping",getPingComponent(player.getPing()))
|
||||
+ ));
|
||||
+ bar.color(barColorFromTps(tps));
|
||||
+ bar.progress((float) Math.max(mspt / 50,0));
|
||||
+ bar.progress((float) Math.min((float)1,Math.max(mspt / 50,0)));
|
||||
+ }
|
||||
+
|
||||
+ private static @NotNull Component getPingComponent(int ping){
|
||||
|
||||
@@ -25,7 +25,7 @@ index d032786938db9725e1be72dae63a1387bcb69d79..dcc52141b34b87a67c3d6070b68b58af
|
||||
if (tpsbarEnabled){
|
||||
initTpsbar();
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 97bfb92e52c3c5ef1cd22afe2b97c204eb45025a..710e87e388095f28af4983a04cb89ddb6be61986 100644
|
||||
index d7a280427442bac8cc8ccb542d24d4e0901df70a..755294e3f5b3fbcfbdc0cc85627b2487663ce591 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -18,6 +18,9 @@ import java.util.Optional;
|
||||
@@ -38,7 +38,7 @@ index 97bfb92e52c3c5ef1cd22afe2b97c204eb45025a..710e87e388095f28af4983a04cb89ddb
|
||||
import net.minecraft.BlockUtil;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.CrashReport;
|
||||
@@ -835,18 +838,7 @@ public class ServerPlayer extends Player {
|
||||
@@ -836,18 +839,7 @@ public class ServerPlayer extends Player {
|
||||
|
||||
Entity entity = this.getCamera();
|
||||
|
||||
@@ -58,7 +58,7 @@ index 97bfb92e52c3c5ef1cd22afe2b97c204eb45025a..710e87e388095f28af4983a04cb89ddb
|
||||
CriteriaTriggers.TICK.trigger(this);
|
||||
if (this.levitationStartPos != null) {
|
||||
CriteriaTriggers.LEVITATION.trigger(this, this.levitationStartPos, this.tickCount - this.levitationStartTime);
|
||||
@@ -855,6 +847,38 @@ public class ServerPlayer extends Player {
|
||||
@@ -856,6 +848,38 @@ public class ServerPlayer extends Player {
|
||||
this.trackStartFallingPosition();
|
||||
this.trackEnteredOrExitedLavaOnVehicle();
|
||||
this.advancements.flushDirty(this);
|
||||
|
||||
77
patches/server/0043-Purpur-use-alternative-keep-alive.patch
Normal file
77
patches/server/0043-Purpur-use-alternative-keep-alive.patch
Normal file
@@ -0,0 +1,77 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
|
||||
Date: Sun, 17 Dec 2023 20:32:49 +0800
|
||||
Subject: [PATCH] Purpur use alternative keep alive
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
index 6edafcdbc188cd6c78e4c4237363e41d927a665e..a62680768068b611fe723fedeb617d42c643e59e 100644
|
||||
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
@@ -64,6 +64,7 @@ public class LuminolConfig {
|
||||
public static int asyncPathProcessingMaxThreads = 0;
|
||||
public static int asyncPathProcessingKeepalive = 60;
|
||||
public static boolean enableAsyncMobSpawning = false;
|
||||
+ public static boolean useAlternateKeepAlive = false;
|
||||
|
||||
public static void init() throws IOException {
|
||||
PARENT_FOLDER.mkdir();
|
||||
@@ -192,6 +193,7 @@ public class LuminolConfig {
|
||||
asyncPathProcessingMaxThreads = 0;
|
||||
enableAsyncMobSpawning = get("optimizations.enable_async_mob_spawning",enableAsyncMobSpawning);
|
||||
RegionizedWorldData.initMobSpawningExecutor();
|
||||
+ useAlternateKeepAlive = get("optimizations.enable_alternative_keep_alive_handling",useAlternateKeepAlive,"Enabling this sends a keepalive packet once per second to a player, and only kicks for timeout if none of them were responded to in 30 seconds. Responding to any of them in any order will keep the player connected. AKA, it won't kick your players because one packet gets dropped somewhere along the lines(From purpur)");
|
||||
}
|
||||
|
||||
public static <T> T get(String key,T def){
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index 2bb944cef9bc8c5e56023ef20921ef13509d4823..9d23285f97ac5d90eb177ddc325281fa197d7f76 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -51,6 +51,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
private long keepAliveTime = Util.getMillis(); // Paper
|
||||
private boolean keepAlivePending;
|
||||
private long keepAliveChallenge;
|
||||
+ private it.unimi.dsi.fastutil.longs.LongList keepAlives = new it.unimi.dsi.fastutil.longs.LongArrayList(); // Purpur
|
||||
private int latency;
|
||||
private volatile boolean suspendFlushingOnServerThread = false;
|
||||
private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit
|
||||
@@ -91,6 +92,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
|
||||
@Override
|
||||
public void handleKeepAlive(ServerboundKeepAlivePacket packet) {
|
||||
+ // Purpur start
|
||||
+ if (me.earthme.luminol.LuminolConfig.useAlternateKeepAlive) {
|
||||
+ long id = packet.getId();
|
||||
+ if (keepAlives.size() > 0 && keepAlives.contains(id)) {
|
||||
+ int ping = (int) (Util.getMillis() - id);
|
||||
+ this.latency = (this.latency * 3 + ping) / 4;
|
||||
+ keepAlives.clear(); // we got a valid response, lets roll with it and forget the rest
|
||||
+ }
|
||||
+ } else
|
||||
+ // Purpur end
|
||||
//PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // CraftBukkit // Paper - This shouldn't be on the main thread
|
||||
if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) {
|
||||
int i = (int) (Util.getMillis() - this.keepAliveTime);
|
||||
@@ -197,6 +208,21 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
long currentTime = Util.getMillis();
|
||||
long elapsedTime = currentTime - this.keepAliveTime;
|
||||
|
||||
+ // Purpur start
|
||||
+ if (me.earthme.luminol.LuminolConfig.useAlternateKeepAlive) {
|
||||
+ if (elapsedTime >= 1000L) { // 1 second
|
||||
+ if (!processedDisconnect && keepAlives.size() * 1000L >= KEEPALIVE_LIMIT) {
|
||||
+ LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName());
|
||||
+ disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT);
|
||||
+ } else {
|
||||
+ keepAliveTime = currentTime; // hijack this field for 1 second intervals
|
||||
+ keepAlives.add(currentTime); // currentTime is ID
|
||||
+ send(new ClientboundKeepAlivePacket(currentTime));
|
||||
+ }
|
||||
+ }
|
||||
+ } else
|
||||
+ // Purpur end
|
||||
+
|
||||
if (this.keepAlivePending) {
|
||||
if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
|
||||
ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName()); // more info
|
||||
579
patches/server/0044-Leaves-Protocol-Core.patch
Normal file
579
patches/server/0044-Leaves-Protocol-Core.patch
Normal file
@@ -0,0 +1,579 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
|
||||
Date: Sun, 17 Dec 2023 20:39:21 +0800
|
||||
Subject: [PATCH] Leaves Protocol Core
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
index 1e3117ccd51be58d988089207a3efdbff02fc374..a28cdeed2a0a2d5194edcfc13cac38f2f2d80489 100644
|
||||
--- a/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
@@ -313,6 +313,8 @@ public final class RegionizedServer {
|
||||
|
||||
// player list
|
||||
MinecraftServer.getServer().getPlayerList().tick();
|
||||
+
|
||||
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleTick(); //Leaves
|
||||
}
|
||||
|
||||
private void tickPlayerSample() {
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java b/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java
|
||||
index af86f752c33a2990405fea058b7c41c437ba9d46..bada9fae1e7178162429e1f5a1608b9c4a680a6c 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java
|
||||
@@ -20,7 +20,12 @@ public record ServerboundCustomPayloadPacket(CustomPacketPayload payload) implem
|
||||
|
||||
private static CustomPacketPayload readPayload(ResourceLocation id, FriendlyByteBuf buf) {
|
||||
FriendlyByteBuf.Reader<? extends CustomPacketPayload> packetdataserializer_a = (FriendlyByteBuf.Reader) ServerboundCustomPayloadPacket.KNOWN_TYPES.get(id);
|
||||
-
|
||||
+ // Leaves start - protocol
|
||||
+ CustomPacketPayload leavesPayload = top.leavesmc.leaves.protocol.core.LeavesProtocolManager.getPayload(id, buf);
|
||||
+ if (leavesPayload != null) {
|
||||
+ return leavesPayload;
|
||||
+ }
|
||||
+ // Leaves end - protocol
|
||||
return (CustomPacketPayload) (packetdataserializer_a != null ? (CustomPacketPayload) packetdataserializer_a.apply(buf) : readUnknownPayload(id, buf));
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index 9d23285f97ac5d90eb177ddc325281fa197d7f76..e1ace2ad411b8d54c56660b41e774a1c998b3ac3 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -127,6 +127,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
|
||||
@Override
|
||||
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
|
||||
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePayload(player, packet.payload()); // Leaves - protocol
|
||||
// Paper start - handle brand payload packet
|
||||
if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.BrandPayload brandPayload) {
|
||||
this.player.clientBrandName = brandPayload.brand();
|
||||
@@ -144,6 +145,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
String channels = payload.toString(com.google.common.base.Charsets.UTF_8);
|
||||
for (String channel : channels.split("\0")) {
|
||||
this.getCraftPlayer().addChannel(channel);
|
||||
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleMinecraftRegister(channel, player); // Leaves - protocol
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t register custom payload", ex);
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 7edaa7558e40942f94c459e9b480ef640146ec6b..3f366ad035ada0ac8170d2925bbfe86b80bd84cb 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -435,6 +435,8 @@ public abstract class PlayerList {
|
||||
//return; // Folia - region threading - must still allow the player to connect, as we must add to chunk map before handling disconnect
|
||||
}
|
||||
|
||||
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); // Leaves - protocol
|
||||
+
|
||||
final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
|
||||
|
||||
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
|
||||
@@ -691,6 +693,7 @@ public abstract class PlayerList {
|
||||
return this.remove(entityplayer, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName())));
|
||||
}
|
||||
public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) {
|
||||
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerLeave(entityplayer); // Leaves - protocol
|
||||
// Paper end
|
||||
ServerLevel worldserver = entityplayer.serverLevel();
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 5fe36cbb14f0f0e9692cfa40381cebdb4e142bbe..ee66241a422acb8920395fd5e41578a966746f5c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -478,6 +478,7 @@ public final class CraftServer implements Server {
|
||||
MapPalette.setMapColorCache(new CraftMapColorCache(this.logger));
|
||||
}
|
||||
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
|
||||
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.init(); // Leaves - protocol
|
||||
}
|
||||
|
||||
public boolean getCommandBlockOverride(String command) {
|
||||
@@ -1114,6 +1115,7 @@ public final class CraftServer implements Server {
|
||||
io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
|
||||
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
|
||||
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
|
||||
+ top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleServerReload(); // Leaves - protocol
|
||||
|
||||
int pollCount = 0;
|
||||
|
||||
diff --git a/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocol.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..64a1d25973b032e8cab64bbffa6824a131676773
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocol.java
|
||||
@@ -0,0 +1,16 @@
|
||||
+package top.leavesmc.leaves.protocol.core;
|
||||
+
|
||||
+import java.lang.annotation.ElementType;
|
||||
+import java.lang.annotation.Retention;
|
||||
+import java.lang.annotation.RetentionPolicy;
|
||||
+import java.lang.annotation.Target;
|
||||
+
|
||||
+@Target(ElementType.TYPE)
|
||||
+@Retention(RetentionPolicy.RUNTIME)
|
||||
+public @interface LeavesProtocol {
|
||||
+
|
||||
+ String namespace() default "minecraft";
|
||||
+
|
||||
+ String[] namespaces() default {};
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocolManager.java b/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocolManager.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..055f044ce6cef4377f6f577efdbfad0ec9a2d57b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/top/leavesmc/leaves/protocol/core/LeavesProtocolManager.java
|
||||
@@ -0,0 +1,340 @@
|
||||
+package top.leavesmc.leaves.protocol.core;
|
||||
+
|
||||
+import net.minecraft.network.FriendlyByteBuf;
|
||||
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import org.apache.commons.lang.ArrayUtils;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+import java.io.File;
|
||||
+import java.io.IOException;
|
||||
+import java.lang.reflect.Constructor;
|
||||
+import java.lang.reflect.InvocationTargetException;
|
||||
+import java.lang.reflect.Method;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+import java.net.JarURLConnection;
|
||||
+import java.net.URL;
|
||||
+import java.net.URLDecoder;
|
||||
+import java.nio.charset.StandardCharsets;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Collections;
|
||||
+import java.util.Enumeration;
|
||||
+import java.util.HashMap;
|
||||
+import java.util.HashSet;
|
||||
+import java.util.LinkedHashSet;
|
||||
+import java.util.List;
|
||||
+import java.util.Map;
|
||||
+import java.util.Set;
|
||||
+import java.util.jar.JarEntry;
|
||||
+import java.util.jar.JarFile;
|
||||
+
|
||||
+public class LeavesProtocolManager {
|
||||
+
|
||||
+ private static final Map<LeavesProtocol, Map<ProtocolHandler.PayloadReceiver, Constructor<? extends CustomPacketPayload>>> KNOWN_TYPES = new HashMap<>();
|
||||
+ private static final Map<LeavesProtocol, Map<ProtocolHandler.PayloadReceiver, Method>> KNOW_RECEIVERS = new HashMap<>();
|
||||
+
|
||||
+ private static final List<Method> TICKERS = new ArrayList<>();
|
||||
+ private static final List<Method> PLAYER_JOIN = new ArrayList<>();
|
||||
+ private static final List<Method> PLAYER_LEAVE = new ArrayList<>();
|
||||
+ private static final List<Method> RELOAD_SERVER = new ArrayList<>();
|
||||
+ private static final Map<LeavesProtocol, Map<ProtocolHandler.MinecraftRegister, Method>> MINECRAFT_REGISTER = new HashMap<>();
|
||||
+
|
||||
+ public static void init() {
|
||||
+ for (Class<?> clazz : getClasses("top.leavesmc.leaves.protocol")) {
|
||||
+ final LeavesProtocol protocol = clazz.getAnnotation(LeavesProtocol.class);
|
||||
+ if (protocol != null) {
|
||||
+ Set<Method> methods;
|
||||
+ try {
|
||||
+ Method[] publicMethods = clazz.getMethods();
|
||||
+ Method[] privateMethods = clazz.getDeclaredMethods();
|
||||
+ methods = new HashSet<>(publicMethods.length + privateMethods.length, 1.0f);
|
||||
+ Collections.addAll(methods, publicMethods);
|
||||
+ Collections.addAll(methods, privateMethods);
|
||||
+ } catch (NoClassDefFoundError e) {
|
||||
+ e.printStackTrace();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ Map<ProtocolHandler.PayloadReceiver, Constructor<? extends CustomPacketPayload>> map = new HashMap<>();
|
||||
+ for (final Method method : methods) {
|
||||
+ if (method.isBridge() || method.isSynthetic() || !Modifier.isStatic(method.getModifiers())) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ method.setAccessible(true);
|
||||
+
|
||||
+ final ProtocolHandler.Init init = method.getAnnotation(ProtocolHandler.Init.class);
|
||||
+ if (init != null) {
|
||||
+ try {
|
||||
+ method.invoke(null);
|
||||
+ } catch (InvocationTargetException | IllegalAccessException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final ProtocolHandler.PayloadReceiver receiver = method.getAnnotation(ProtocolHandler.PayloadReceiver.class);
|
||||
+ if (receiver != null) {
|
||||
+ try {
|
||||
+ map.put(receiver, receiver.payload().getConstructor(ResourceLocation.class, FriendlyByteBuf.class));
|
||||
+ } catch (NoSuchMethodException e) {
|
||||
+ e.printStackTrace();
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!KNOW_RECEIVERS.containsKey(protocol)) {
|
||||
+ KNOW_RECEIVERS.put(protocol, new HashMap<>());
|
||||
+ }
|
||||
+
|
||||
+ KNOW_RECEIVERS.get(protocol).put(receiver, method);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final ProtocolHandler.Ticker ticker = method.getAnnotation(ProtocolHandler.Ticker.class);
|
||||
+ if (ticker != null) {
|
||||
+ TICKERS.add(method);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final ProtocolHandler.PlayerJoin playerJoin = method.getAnnotation(ProtocolHandler.PlayerJoin.class);
|
||||
+ if (playerJoin != null) {
|
||||
+ PLAYER_JOIN.add(method);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final ProtocolHandler.PlayerLeave playerLeave = method.getAnnotation(ProtocolHandler.PlayerLeave.class);
|
||||
+ if (playerLeave != null) {
|
||||
+ PLAYER_LEAVE.add(method);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final ProtocolHandler.ReloadServer reloadServer = method.getAnnotation(ProtocolHandler.ReloadServer.class);
|
||||
+ if (reloadServer != null) {
|
||||
+ RELOAD_SERVER.add(method);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final ProtocolHandler.MinecraftRegister minecraftRegister = method.getAnnotation(ProtocolHandler.MinecraftRegister.class);
|
||||
+ if (minecraftRegister != null) {
|
||||
+ if (!MINECRAFT_REGISTER.containsKey(protocol)) {
|
||||
+ MINECRAFT_REGISTER.put(protocol, new HashMap<>());
|
||||
+ }
|
||||
+
|
||||
+ MINECRAFT_REGISTER.get(protocol).put(minecraftRegister, method);
|
||||
+ }
|
||||
+ }
|
||||
+ KNOWN_TYPES.put(protocol, map);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static CustomPacketPayload getPayload(ResourceLocation id, FriendlyByteBuf buf) {
|
||||
+ for (LeavesProtocol protocol : KNOWN_TYPES.keySet()) {
|
||||
+ if (!protocol.namespace().equals(id.getNamespace()) && !ArrayUtils.contains(protocol.namespaces(), id.getNamespace())) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ Map<ProtocolHandler.PayloadReceiver, Constructor<? extends CustomPacketPayload>> map = KNOWN_TYPES.get(protocol);
|
||||
+ for (ProtocolHandler.PayloadReceiver receiver : map.keySet()) {
|
||||
+ if (receiver.ignoreId() || receiver.payloadId().equals(id.getPath()) || ArrayUtils.contains(receiver.payloadIds(), id.getPath())) {
|
||||
+ try {
|
||||
+ return map.get(receiver).newInstance(id, buf);
|
||||
+ } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ public static void handlePayload(ServerPlayer player, CustomPacketPayload payload) {
|
||||
+ for (LeavesProtocol protocol : KNOW_RECEIVERS.keySet()) {
|
||||
+ if (!protocol.namespace().equals(payload.id().getNamespace()) && !ArrayUtils.contains(protocol.namespaces(), payload.id().getNamespace())) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ Map<ProtocolHandler.PayloadReceiver, Method> map = KNOW_RECEIVERS.get(protocol);
|
||||
+ for (ProtocolHandler.PayloadReceiver receiver : map.keySet()) {
|
||||
+ if (payload.getClass() == receiver.payload()) {
|
||||
+ if (receiver.ignoreId() || receiver.payloadId().equals(payload.id().getPath()) ||
|
||||
+ ArrayUtils.contains(receiver.payloadIds(), payload.id().getPath())) {
|
||||
+ try {
|
||||
+ map.get(receiver).invoke(null, player, payload);
|
||||
+ } catch (InvocationTargetException | IllegalAccessException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void handleTick() {
|
||||
+ if (!TICKERS.isEmpty()) {
|
||||
+ try {
|
||||
+ for (Method method : TICKERS) {
|
||||
+ method.invoke(null);
|
||||
+ }
|
||||
+ } catch (InvocationTargetException | IllegalAccessException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void handlePlayerJoin(ServerPlayer player) {
|
||||
+ if (!PLAYER_JOIN.isEmpty()) {
|
||||
+ try {
|
||||
+ for (Method method : PLAYER_JOIN) {
|
||||
+ method.invoke(null, player);
|
||||
+ }
|
||||
+ } catch (InvocationTargetException | IllegalAccessException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void handlePlayerLeave(ServerPlayer player) {
|
||||
+ if (!PLAYER_LEAVE.isEmpty()) {
|
||||
+ try {
|
||||
+ for (Method method : PLAYER_LEAVE) {
|
||||
+ method.invoke(null, player);
|
||||
+ }
|
||||
+ } catch (InvocationTargetException | IllegalAccessException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void handleServerReload() {
|
||||
+ if (!RELOAD_SERVER.isEmpty()) {
|
||||
+ try {
|
||||
+ for (Method method : RELOAD_SERVER) {
|
||||
+ method.invoke(null);
|
||||
+ }
|
||||
+ } catch (InvocationTargetException | IllegalAccessException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void handleMinecraftRegister(String channelId, ServerPlayer player) {
|
||||
+ for (LeavesProtocol protocol : MINECRAFT_REGISTER.keySet()) {
|
||||
+ String[] channel = channelId.split(":");
|
||||
+ if (!protocol.namespace().equals(channel[0]) && !ArrayUtils.contains(protocol.namespaces(), channel[0])) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ Map<ProtocolHandler.MinecraftRegister, Method> map = MINECRAFT_REGISTER.get(protocol);
|
||||
+ for (ProtocolHandler.MinecraftRegister register : map.keySet()) {
|
||||
+ if (register.ignoreId() || register.channelId().equals(channel[1]) ||
|
||||
+ ArrayUtils.contains(register.channelIds(), channel[1])) {
|
||||
+ try {
|
||||
+ map.get(register).invoke(null, player);
|
||||
+ } catch (InvocationTargetException | IllegalAccessException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static Set<Class<?>> getClasses(String pack) {
|
||||
+ Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
|
||||
+ String packageDirName = pack.replace('.', '/');
|
||||
+ Enumeration<URL> dirs;
|
||||
+ try {
|
||||
+ dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
|
||||
+ while (dirs.hasMoreElements()) {
|
||||
+ URL url = dirs.nextElement();
|
||||
+ String protocol = url.getProtocol();
|
||||
+ if ("file".equals(protocol)) {
|
||||
+ String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8);
|
||||
+ findClassesInPackageByFile(pack, filePath, classes);
|
||||
+ } else if ("jar".equals(protocol)) {
|
||||
+ JarFile jar;
|
||||
+ try {
|
||||
+ jar = ((JarURLConnection) url.openConnection()).getJarFile();
|
||||
+ Enumeration<JarEntry> entries = jar.entries();
|
||||
+ findClassesInPackageByJar(pack, entries, packageDirName, classes);
|
||||
+ } catch (IOException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ } catch (IOException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ return classes;
|
||||
+ }
|
||||
+
|
||||
+ private static void findClassesInPackageByFile(String packageName, String packagePath, Set<Class<?>> classes) {
|
||||
+ File dir = new File(packagePath);
|
||||
+ if (!dir.exists() || !dir.isDirectory()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ File[] dirfiles = dir.listFiles((file) -> file.isDirectory() || file.getName().endsWith(".class"));
|
||||
+ if (dirfiles != null) {
|
||||
+ for (File file : dirfiles) {
|
||||
+ if (file.isDirectory()) {
|
||||
+ findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), classes);
|
||||
+ } else {
|
||||
+ String className = file.getName().substring(0, file.getName().length() - 6);
|
||||
+ try {
|
||||
+ classes.add(Class.forName(packageName + '.' + className));
|
||||
+ } catch (ClassNotFoundException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void findClassesInPackageByJar(String packageName, Enumeration<JarEntry> entries, String packageDirName, Set<Class<?>> classes) {
|
||||
+ while (entries.hasMoreElements()) {
|
||||
+ JarEntry entry = entries.nextElement();
|
||||
+ String name = entry.getName();
|
||||
+ if (name.charAt(0) == '/') {
|
||||
+ name = name.substring(1);
|
||||
+ }
|
||||
+ if (name.startsWith(packageDirName)) {
|
||||
+ int idx = name.lastIndexOf('/');
|
||||
+ if (idx != -1) {
|
||||
+ packageName = name.substring(0, idx).replace('/', '.');
|
||||
+ }
|
||||
+ if (name.endsWith(".class") && !entry.isDirectory()) {
|
||||
+ String className = name.substring(packageName.length() + 1, name.length() - 6);
|
||||
+ try {
|
||||
+ classes.add(Class.forName(packageName + '.' + className));
|
||||
+ } catch (ClassNotFoundException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public record EmptyPayload(ResourceLocation id) implements CustomPacketPayload {
|
||||
+
|
||||
+ public EmptyPayload(ResourceLocation location, FriendlyByteBuf buf) {
|
||||
+ this(location);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void write(@NotNull FriendlyByteBuf buf) {
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public record LeavesPayload(FriendlyByteBuf data, ResourceLocation id) implements CustomPacketPayload {
|
||||
+
|
||||
+ public LeavesPayload(ResourceLocation location, FriendlyByteBuf buf) {
|
||||
+ this(new FriendlyByteBuf(buf.readBytes(buf.readableBytes())), location);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void write(FriendlyByteBuf buf) {
|
||||
+ buf.writeBytes(data);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolHandler.java b/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolHandler.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d696f001d2576d1b61cc732c81f22eb52205072b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolHandler.java
|
||||
@@ -0,0 +1,65 @@
|
||||
+package top.leavesmc.leaves.protocol.core;
|
||||
+
|
||||
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
+
|
||||
+import java.lang.annotation.ElementType;
|
||||
+import java.lang.annotation.Retention;
|
||||
+import java.lang.annotation.RetentionPolicy;
|
||||
+import java.lang.annotation.Target;
|
||||
+
|
||||
+public class ProtocolHandler {
|
||||
+
|
||||
+ @Target(ElementType.METHOD)
|
||||
+ @Retention(RetentionPolicy.RUNTIME)
|
||||
+ public @interface Init {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Target(ElementType.METHOD)
|
||||
+ @Retention(RetentionPolicy.RUNTIME)
|
||||
+ public @interface PayloadReceiver {
|
||||
+
|
||||
+ Class<? extends CustomPacketPayload> payload();
|
||||
+
|
||||
+ String[] payloadIds() default {};
|
||||
+
|
||||
+ String payloadId() default "";
|
||||
+
|
||||
+ boolean ignoreId() default false;
|
||||
+ }
|
||||
+
|
||||
+ @Target(ElementType.METHOD)
|
||||
+ @Retention(RetentionPolicy.RUNTIME)
|
||||
+ public @interface Ticker {
|
||||
+ int delay() default 0;
|
||||
+ }
|
||||
+
|
||||
+ @Target(ElementType.METHOD)
|
||||
+ @Retention(RetentionPolicy.RUNTIME)
|
||||
+ public @interface PlayerJoin {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Target(ElementType.METHOD)
|
||||
+ @Retention(RetentionPolicy.RUNTIME)
|
||||
+ public @interface PlayerLeave {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Target(ElementType.METHOD)
|
||||
+ @Retention(RetentionPolicy.RUNTIME)
|
||||
+ public @interface ReloadServer {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Target(ElementType.METHOD)
|
||||
+ @Retention(RetentionPolicy.RUNTIME)
|
||||
+ public @interface MinecraftRegister {
|
||||
+
|
||||
+ String channelId() default "";
|
||||
+
|
||||
+ String[] channelIds() default {};
|
||||
+
|
||||
+ boolean ignoreId() default false;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolUtils.java b/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolUtils.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5282c5ad3d26d06ab685ddaaf6fd9a4d49559717
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/top/leavesmc/leaves/protocol/core/ProtocolUtils.java
|
||||
@@ -0,0 +1,36 @@
|
||||
+package top.leavesmc.leaves.protocol.core;
|
||||
+
|
||||
+import net.minecraft.network.FriendlyByteBuf;
|
||||
+import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
|
||||
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+import java.util.function.Consumer;
|
||||
+
|
||||
+public class ProtocolUtils {
|
||||
+
|
||||
+ public static void sendEmptyPayloadPacket(ServerPlayer player, ResourceLocation id) {
|
||||
+ player.connection.send(new ClientboundCustomPayloadPacket(new LeavesProtocolManager.EmptyPayload(id)));
|
||||
+ }
|
||||
+
|
||||
+ public static void sendPayloadPacket(ServerPlayer player, ResourceLocation id, Consumer<FriendlyByteBuf> consumer) {
|
||||
+ player.connection.send(new ClientboundCustomPayloadPacket(new CustomPacketPayload() {
|
||||
+ @Override
|
||||
+ public void write(@NotNull FriendlyByteBuf buf) {
|
||||
+ consumer.accept(buf);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public ResourceLocation id() {
|
||||
+ return id;
|
||||
+ }
|
||||
+ }));
|
||||
+ }
|
||||
+
|
||||
+ public static void sendPayloadPacket(ServerPlayer player, CustomPacketPayload payload) {
|
||||
+ player.connection.send(new ClientboundCustomPayloadPacket(payload));
|
||||
+ }
|
||||
+}
|
||||
708
patches/server/0045-Leaves-PCA-sync-protocol.patch
Normal file
708
patches/server/0045-Leaves-PCA-sync-protocol.patch
Normal file
@@ -0,0 +1,708 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
|
||||
Date: Sun, 17 Dec 2023 21:01:59 +0800
|
||||
Subject: [PATCH] Leaves PCA sync protocol
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
index 2c3e1b420303a3c3a9315983fbc7e47423f7d9e4..29a8331e498eba333283b41c3e6a87a7ad97747c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
@@ -45,7 +45,7 @@ import org.bukkit.scheduler.BukkitWorker;
|
||||
*/
|
||||
public class CraftScheduler implements BukkitScheduler {
|
||||
|
||||
- static Plugin MINECRAFT = new MinecraftInternalPlugin();
|
||||
+ public static Plugin MINECRAFT = new MinecraftInternalPlugin();
|
||||
/**
|
||||
* The start ID for the counter.
|
||||
*/
|
||||
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
index a62680768068b611fe723fedeb617d42c643e59e..cfe9a8eb705039ee7e2dc9262e1355c4b0f664bb 100644
|
||||
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
@@ -66,6 +66,10 @@ public class LuminolConfig {
|
||||
public static boolean enableAsyncMobSpawning = false;
|
||||
public static boolean useAlternateKeepAlive = false;
|
||||
|
||||
+ public static boolean pcaSyncProtocol = false;
|
||||
+ public static String pcaSyncPlayerEntity = "NOBODY";
|
||||
+
|
||||
+
|
||||
public static void init() throws IOException {
|
||||
PARENT_FOLDER.mkdir();
|
||||
|
||||
@@ -194,6 +198,9 @@ public class LuminolConfig {
|
||||
enableAsyncMobSpawning = get("optimizations.enable_async_mob_spawning",enableAsyncMobSpawning);
|
||||
RegionizedWorldData.initMobSpawningExecutor();
|
||||
useAlternateKeepAlive = get("optimizations.enable_alternative_keep_alive_handling",useAlternateKeepAlive,"Enabling this sends a keepalive packet once per second to a player, and only kicks for timeout if none of them were responded to in 30 seconds. Responding to any of them in any order will keep the player connected. AKA, it won't kick your players because one packet gets dropped somewhere along the lines(From purpur)");
|
||||
+
|
||||
+ pcaSyncProtocol = get("gameplay.enable_pca_sync_protocol",pcaSyncProtocol);
|
||||
+ pcaSyncPlayerEntity = get("gameplay.pca_sync_player_entity",pcaSyncPlayerEntity,"Available values: NOBODY,EVERYBODY,OPS,OPS_AND_SELF");
|
||||
}
|
||||
|
||||
public static <T> T get(String key,T def){
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
||||
index a0628b9d74c29d02bfba583edf7ee6f2cde2cff6..698c7bfddb0d45d088c30fd26eccb86b924fd60a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
||||
@@ -373,6 +373,11 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
|
||||
|
||||
@Override
|
||||
public void containerChanged(Container sender) {
|
||||
+ // Leaves start - pca
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
boolean flag = this.isSaddled();
|
||||
|
||||
this.updateContainerEquipment();
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
index ce728f062794e239d1dfdf842d7d0c725f77fba7..a3200593788525c7f18420036044bfdccfaf40fc 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
@@ -64,6 +64,15 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa
|
||||
super(type, world);
|
||||
this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 16.0F);
|
||||
this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, -1.0F);
|
||||
+ // Leaves start - pca
|
||||
+ if (!this.level().isClientSide()) {
|
||||
+ this.inventory.addListener(inventory -> {
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
||||
index f64edfdb03f99624daf1e05b5dc86d845c3018b6..e98ea5f93a829e232a61eee4564209d1831f8b8d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
||||
@@ -138,7 +138,13 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void setChanged() {}
|
||||
+ public void setChanged() {
|
||||
+ // Leaves start - pca
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
+ }
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
index a18aadbf7ae83713e1f2b21553185d8000bc7699..4b174bed02fb98f798f9444e03fc866baf1e1a07 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -569,6 +569,16 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
|
||||
}
|
||||
|
||||
+ // Leaves start - pca
|
||||
+ @Override
|
||||
+ public void setChanged() {
|
||||
+ super.setChanged();
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
+
|
||||
@Override
|
||||
public boolean stillValid(net.minecraft.world.entity.player.Player player) {
|
||||
return Container.stillValidBlockEntity(this, player);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
index 416aa989ebb18a8741cc9d605a1180ab830f6643..b73c3dc28a95279285e911bfed3bc3d3f038e6db 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
@@ -131,6 +131,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
|
||||
this.items = list;
|
||||
}
|
||||
|
||||
+ // Leaves start - pca
|
||||
+ @Override
|
||||
+ public void setChanged() {
|
||||
+ super.setChanged();
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
+
|
||||
@Override
|
||||
protected Component getDefaultName() {
|
||||
return Component.translatable("container.barrel");
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
||||
index cf09525efd2d53bf884cd6ec3b0b9229715895eb..9c7b5fbec4ec1eb6b39f139a9b16483208249b6f 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
||||
@@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
+import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
@@ -127,6 +128,11 @@ public class BeehiveBlockEntity extends BlockEntity {
|
||||
super.setChanged();
|
||||
}
|
||||
|
||||
+ // Leaves start - pca
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -188,6 +194,12 @@ public class BeehiveBlockEntity extends BlockEntity {
|
||||
this.level.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entity, this.getBlockState()));
|
||||
}
|
||||
|
||||
+ // Leaves start - pca
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
+
|
||||
entity.discard();
|
||||
super.setChanged();
|
||||
}
|
||||
@@ -334,6 +346,11 @@ public class BeehiveBlockEntity extends BlockEntity {
|
||||
if (BeehiveBlockEntity.releaseOccupant(world, pos, state, tileentitybeehive_hivebee, (List) null, tileentitybeehive_releasestatus, flowerPos)) {
|
||||
flag = true;
|
||||
iterator.remove();
|
||||
+ // Leaves start - pca
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(Objects.requireNonNull(world.getBlockEntity(pos)));
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
// CraftBukkit start
|
||||
} else {
|
||||
tileentitybeehive_hivebee.exitTickCounter = tileentitybeehive_hivebee.minOccupationTicks / 2; // Not strictly Vanilla behaviour in cases where bees cannot spawn but still reasonable // Paper - use exitTickCounter to keep actual bee life
|
||||
@@ -385,6 +402,11 @@ public class BeehiveBlockEntity extends BlockEntity {
|
||||
this.maxBees = nbt.getInt("Bukkit.MaxEntities");
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Leaves start - pca
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
||||
index 526d1bfd5ad0de7bcfd0c2da902515f3dec94c54..66758af67aca2c726b2f5b451f3f7197102af22f 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
||||
@@ -333,6 +333,16 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements
|
||||
|
||||
}
|
||||
|
||||
+ // Leaves start - pca
|
||||
+ @Override
|
||||
+ public void setChanged() {
|
||||
+ super.setChanged();
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
+
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
return Container.stillValidBlockEntity(this, player);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
index d66806565770cb03a21794f99e5c4b0f3040b26a..034bc37a8b50a3c9904f4f53c8758b1b02b458b1 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
@@ -220,6 +220,16 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
|
||||
// Pufferfish end
|
||||
}
|
||||
|
||||
+ // Leaves start - pca
|
||||
+ @Override
|
||||
+ public void setChanged() {
|
||||
+ super.setChanged();
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
+
|
||||
@Override
|
||||
public float getOpenNess(float tickDelta) {
|
||||
return this.chestLidController.getOpenness(tickDelta);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
|
||||
index 881379681c39230a00b3a1f11cd87498984396c7..51fae4d72eed9e4224a8abe1a0b6520835857ba5 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
|
||||
@@ -92,6 +92,16 @@ public class DispenserBlockEntity extends RandomizableContainerBlockEntity {
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ // Leaves start - pca
|
||||
+ @Override
|
||||
+ public void setChanged() {
|
||||
+ super.setChanged();
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
+
|
||||
@Override
|
||||
protected Component getDefaultName() {
|
||||
return Component.translatable("container.dispenser");
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index c90d578643490709936545ee9cbd41c8671eeb7a..3527a3cc76d3b1ad1319f1eebe31fd4d9e8aa039 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -155,6 +155,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
|
||||
}
|
||||
|
||||
+ // Leaves start - pca
|
||||
+ @Override
|
||||
+ public void setChanged() {
|
||||
+ super.setChanged();
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
+
|
||||
@Override
|
||||
protected Component getDefaultName() {
|
||||
return Component.translatable("container.hopper");
|
||||
@@ -234,6 +244,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
if (flag) {
|
||||
blockEntity.setCooldown(world.spigotConfig.hopperTransfer); // Spigot
|
||||
setChanged(world, pos, state);
|
||||
+ // Leaves start - pca
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(blockEntity);
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
return true;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
||||
index 1fa22445a4ecc8c08dbcf0cc6bd39dc5003604c4..c1492fce06cdc00a8e82977f0c474a541efa39e8 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
||||
@@ -269,6 +269,16 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl
|
||||
this.itemStacks = list;
|
||||
}
|
||||
|
||||
+ // Leaves start - pca
|
||||
+ @Override
|
||||
+ public void setChanged() {
|
||||
+ super.setChanged();
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - pca
|
||||
+
|
||||
@Override
|
||||
public int[] getSlotsForFace(Direction side) {
|
||||
return ShulkerBoxBlockEntity.SLOTS;
|
||||
diff --git a/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ebd28033ddf0fe6a354585dc2818a9b481d90ed4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
|
||||
@@ -0,0 +1,384 @@
|
||||
+package top.leavesmc.leaves.protocol;
|
||||
+
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.network.FriendlyByteBuf;
|
||||
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.world.entity.player.Player;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.ChestBlock;
|
||||
+import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
+import net.minecraft.world.level.block.state.BlockState;
|
||||
+import net.minecraft.world.level.block.state.properties.ChestType;
|
||||
+import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
+import org.apache.commons.lang3.tuple.MutablePair;
|
||||
+import org.apache.commons.lang3.tuple.Pair;
|
||||
+import org.apache.logging.log4j.LogManager;
|
||||
+import org.bukkit.craftbukkit.scheduler.CraftScheduler;
|
||||
+import org.jetbrains.annotations.Contract;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+import top.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
+import top.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
+import top.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
+
|
||||
+import java.util.HashMap;
|
||||
+import java.util.HashSet;
|
||||
+import java.util.Map;
|
||||
+import java.util.Set;
|
||||
+import java.util.concurrent.locks.ReentrantLock;
|
||||
+
|
||||
+import static org.bukkit.craftbukkit.scheduler.CraftScheduler.MINECRAFT;
|
||||
+import static top.leavesmc.leaves.protocol.core.LeavesProtocolManager.EmptyPayload;
|
||||
+
|
||||
+@LeavesProtocol(namespace = "pca")
|
||||
+public class PcaSyncProtocol {
|
||||
+
|
||||
+ public static final String PROTOCOL_ID = "pca";
|
||||
+
|
||||
+ public static final ReentrantLock lock = new ReentrantLock(true);
|
||||
+ public static final ReentrantLock pairLock = new ReentrantLock(true);
|
||||
+
|
||||
+ // send
|
||||
+ private static final ResourceLocation ENABLE_PCA_SYNC_PROTOCOL = id("enable_pca_sync_protocol");
|
||||
+ private static final ResourceLocation DISABLE_PCA_SYNC_PROTOCOL = id("disable_pca_sync_protocol");
|
||||
+ private static final ResourceLocation UPDATE_ENTITY = id("update_entity");
|
||||
+ private static final ResourceLocation UPDATE_BLOCK_ENTITY = id("update_block_entity");
|
||||
+
|
||||
+ private static final Map<ServerPlayer, Pair<ResourceLocation, BlockPos>> playerWatchBlockPos = new HashMap<>();
|
||||
+ private static final Map<ServerPlayer, Pair<ResourceLocation, Entity>> playerWatchEntity = new HashMap<>();
|
||||
+ private static final Map<Pair<ResourceLocation, BlockPos>, Set<ServerPlayer>> blockPosWatchPlayerSet = new HashMap<>();
|
||||
+ private static final Map<Pair<ResourceLocation, Entity>, Set<ServerPlayer>> entityWatchPlayerSet = new HashMap<>();
|
||||
+ private static final MutablePair<ResourceLocation, Entity> ResourceLocationEntityPair = new MutablePair<>();
|
||||
+ private static final MutablePair<ResourceLocation, BlockPos> ResourceLocationBlockPosPair = new MutablePair<>();
|
||||
+
|
||||
+ @Contract("_ -> new")
|
||||
+ public static @NotNull ResourceLocation id(String path) {
|
||||
+ return new ResourceLocation(PROTOCOL_ID, path);
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.PlayerJoin
|
||||
+ private static void onJoin(ServerPlayer player) {
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ enablePcaSyncProtocol(player);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.ReloadServer
|
||||
+ private static void onServerReload() {
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ enablePcaSyncProtocolGlobal();
|
||||
+ } else {
|
||||
+ disablePcaSyncProtocolGlobal();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.PayloadReceiver(payload = EmptyPayload.class, payloadId = "cancel_sync_block_entity")
|
||||
+ private static void cancelSyncBlockEntityHandler(ServerPlayer player, EmptyPayload payload) {
|
||||
+ if (!me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ return;
|
||||
+ }
|
||||
+ PcaSyncProtocol.clearPlayerWatchBlock(player);
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.PayloadReceiver(payload = EmptyPayload.class, payloadId = "cancel_sync_entity")
|
||||
+ private static void cancelSyncEntityHandler(ServerPlayer player, EmptyPayload payload) {
|
||||
+ if (!me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ return;
|
||||
+ }
|
||||
+ PcaSyncProtocol.clearPlayerWatchEntity(player);
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.PayloadReceiver(payload = SyncBlockEntityPayload.class, payloadId = "sync_block_entity")
|
||||
+ private static void syncBlockEntityHandler(ServerPlayer player, SyncBlockEntityPayload payload) {
|
||||
+ if (!me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ return;
|
||||
+ }
|
||||
+ MinecraftServer server = MinecraftServer.getServer();
|
||||
+ BlockPos pos = payload.pos;
|
||||
+ ServerLevel world = player.serverLevel();
|
||||
+
|
||||
+ player.getBukkitEntity().getScheduler().execute(MINECRAFT,() -> {
|
||||
+ BlockState blockState = world.getBlockState(pos);
|
||||
+ clearPlayerWatchData(player);
|
||||
+
|
||||
+ BlockEntity blockEntityAdj = null;
|
||||
+ if (blockState.getBlock() instanceof ChestBlock) {
|
||||
+ if (blockState.getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
|
||||
+ BlockPos posAdj = pos.offset(ChestBlock.getConnectedDirection(blockState).getNormal());
|
||||
+ // The method in World now checks that the caller is from the same thread...
|
||||
+ blockEntityAdj = world.getChunk(posAdj).getBlockEntity(posAdj);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (blockEntityAdj != null) {
|
||||
+ updateBlockEntity(player, blockEntityAdj);
|
||||
+ }
|
||||
+
|
||||
+ // The method in World now checks that the caller is from the same thread...
|
||||
+ BlockEntity blockEntity = world.getChunk(pos).getBlockEntity(pos);
|
||||
+ if (blockEntity != null) {
|
||||
+ updateBlockEntity(player, blockEntity);
|
||||
+ }
|
||||
+
|
||||
+ Pair<ResourceLocation, BlockPos> pair = new ImmutablePair<>(player.level().dimension().location(), pos);
|
||||
+ lock.lock();
|
||||
+ playerWatchBlockPos.put(player, pair);
|
||||
+ if (!blockPosWatchPlayerSet.containsKey(pair)) {
|
||||
+ blockPosWatchPlayerSet.put(pair, new HashSet<>());
|
||||
+ }
|
||||
+ blockPosWatchPlayerSet.get(pair).add(player);
|
||||
+ lock.unlock();
|
||||
+ },null,1);
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.PayloadReceiver(payload = SyncEntityPayload.class, payloadId = "sync_entity")
|
||||
+ private static void syncEntityHandler(ServerPlayer player, SyncEntityPayload payload) {
|
||||
+ if (!me.earthme.luminol.LuminolConfig.pcaSyncProtocol) {
|
||||
+ return;
|
||||
+ }
|
||||
+ MinecraftServer server = MinecraftServer.getServer();
|
||||
+ int entityId = payload.entityId;
|
||||
+ ServerLevel world = player.serverLevel();
|
||||
+ player.getBukkitEntity().getScheduler().execute(MINECRAFT,() -> {
|
||||
+ Entity entity = world.getEntity(entityId);
|
||||
+ if (entity != null) {
|
||||
+ clearPlayerWatchData(player);
|
||||
+ if (entity instanceof Player) {
|
||||
+ if (me.earthme.luminol.LuminolConfig.pcaSyncPlayerEntity.equals("NOBODY")) {
|
||||
+ return;
|
||||
+ }else if (me.earthme.luminol.LuminolConfig.pcaSyncPlayerEntity.equals("OPS")) {
|
||||
+ if (server.getProfilePermissions(player.getGameProfile()) < 2) {
|
||||
+ return;
|
||||
+ }
|
||||
+ } else if (me.earthme.luminol.LuminolConfig.pcaSyncPlayerEntity.equals("OPS_AND_SELF")) {
|
||||
+ if (server.getProfilePermissions(player.getGameProfile()) < 2 &&
|
||||
+ entity != player) {
|
||||
+ return;
|
||||
+ }
|
||||
+ } else if (!me.earthme.luminol.LuminolConfig.pcaSyncPlayerEntity.equals("EVERYONE")) {
|
||||
+ // wtf????
|
||||
+ LogManager.getLogger().warn("pcaSyncPlayerEntity wtf???");
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ updateEntity(player, entity);
|
||||
+
|
||||
+ Pair<ResourceLocation, Entity> pair = new ImmutablePair<>(entity.level().dimension().location(), entity);
|
||||
+ lock.lock();
|
||||
+ playerWatchEntity.put(player, pair);
|
||||
+ if (!entityWatchPlayerSet.containsKey(pair)) {
|
||||
+ entityWatchPlayerSet.put(pair, new HashSet<>());
|
||||
+ }
|
||||
+ entityWatchPlayerSet.get(pair).add(player);
|
||||
+ lock.unlock();
|
||||
+ }
|
||||
+ },null,1);
|
||||
+ }
|
||||
+
|
||||
+ public static void enablePcaSyncProtocol(@NotNull ServerPlayer player) {
|
||||
+ ProtocolUtils.sendEmptyPayloadPacket(player, ENABLE_PCA_SYNC_PROTOCOL);
|
||||
+ }
|
||||
+
|
||||
+ public static void disablePcaSyncProtocol(@NotNull ServerPlayer player) {
|
||||
+ ProtocolUtils.sendEmptyPayloadPacket(player, DISABLE_PCA_SYNC_PROTOCOL);
|
||||
+ }
|
||||
+
|
||||
+ public static void updateEntity(@NotNull ServerPlayer player, @NotNull Entity entity) {
|
||||
+ CompoundTag nbt = entity.saveWithoutId(new CompoundTag());
|
||||
+ ProtocolUtils.sendPayloadPacket(player, UPDATE_ENTITY, buf -> {
|
||||
+ buf.writeResourceLocation(entity.level().dimension().location());
|
||||
+ buf.writeInt(entity.getId());
|
||||
+ buf.writeNbt(nbt);
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ public static void updateBlockEntity(@NotNull ServerPlayer player, @NotNull BlockEntity blockEntity) {
|
||||
+ Level world = blockEntity.getLevel();
|
||||
+
|
||||
+ if (world == null) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ProtocolUtils.sendPayloadPacket(player, UPDATE_BLOCK_ENTITY, buf -> {
|
||||
+ buf.writeResourceLocation(world.dimension().location());
|
||||
+ buf.writeBlockPos(blockEntity.getBlockPos());
|
||||
+ buf.writeNbt(blockEntity.saveWithId());
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ private static MutablePair<ResourceLocation, Entity> getResourceLocationEntityPair(ResourceLocation ResourceLocation, Entity entity) {
|
||||
+ pairLock.lock();
|
||||
+ ResourceLocationEntityPair.setLeft(ResourceLocation);
|
||||
+ ResourceLocationEntityPair.setRight(entity);
|
||||
+ pairLock.unlock();
|
||||
+ return ResourceLocationEntityPair;
|
||||
+ }
|
||||
+
|
||||
+ private static MutablePair<ResourceLocation, BlockPos> getResourceLocationBlockPosPair(ResourceLocation ResourceLocation, BlockPos pos) {
|
||||
+ pairLock.lock();
|
||||
+ ResourceLocationBlockPosPair.setLeft(ResourceLocation);
|
||||
+ ResourceLocationBlockPosPair.setRight(pos);
|
||||
+ pairLock.unlock();
|
||||
+ return ResourceLocationBlockPosPair;
|
||||
+ }
|
||||
+
|
||||
+ private static @Nullable Set<ServerPlayer> getWatchPlayerList(@NotNull Entity entity) {
|
||||
+ return entityWatchPlayerSet.get(getResourceLocationEntityPair(entity.level().dimension().location(), entity));
|
||||
+ }
|
||||
+
|
||||
+ private static @Nullable Set<ServerPlayer> getWatchPlayerList(@NotNull Level world, @NotNull BlockPos blockPos) {
|
||||
+ return blockPosWatchPlayerSet.get(getResourceLocationBlockPosPair(world.dimension().location(), blockPos));
|
||||
+ }
|
||||
+
|
||||
+ public static boolean syncEntityToClient(@NotNull Entity entity) {
|
||||
+ if (entity.level().isClientSide()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ lock.lock();
|
||||
+ Set<ServerPlayer> playerList = getWatchPlayerList(entity);
|
||||
+ boolean ret = false;
|
||||
+ if (playerList != null) {
|
||||
+ for (ServerPlayer player : playerList) {
|
||||
+ updateEntity(player, entity);
|
||||
+ ret = true;
|
||||
+ }
|
||||
+ }
|
||||
+ lock.unlock();
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ public static boolean syncBlockEntityToClient(@NotNull BlockEntity blockEntity) {
|
||||
+ boolean ret = false;
|
||||
+ Level world = blockEntity.getLevel();
|
||||
+ BlockPos pos = blockEntity.getBlockPos();
|
||||
+ if (world != null) {
|
||||
+ if (world.isClientSide()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ BlockState blockState = world.getBlockState(pos);
|
||||
+ lock.lock();
|
||||
+ Set<ServerPlayer> playerList = getWatchPlayerList(world, blockEntity.getBlockPos());
|
||||
+
|
||||
+ Set<ServerPlayer> playerListAdj = null;
|
||||
+
|
||||
+ if (blockState.getBlock() instanceof ChestBlock) {
|
||||
+ if (blockState.getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
|
||||
+ BlockPos posAdj = pos.offset(ChestBlock.getConnectedDirection(blockState).getNormal());
|
||||
+ playerListAdj = getWatchPlayerList(world, posAdj);
|
||||
+ }
|
||||
+ }
|
||||
+ if (playerListAdj != null) {
|
||||
+ if (playerList == null) {
|
||||
+ playerList = playerListAdj;
|
||||
+ } else {
|
||||
+ playerList.addAll(playerListAdj);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (playerList != null) {
|
||||
+ for (ServerPlayer player : playerList) {
|
||||
+ updateBlockEntity(player, blockEntity);
|
||||
+ ret = true;
|
||||
+ }
|
||||
+ }
|
||||
+ lock.unlock();
|
||||
+ }
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ private static void clearPlayerWatchEntity(ServerPlayer player) {
|
||||
+ lock.lock();
|
||||
+ Pair<ResourceLocation, Entity> pair = playerWatchEntity.get(player);
|
||||
+ if (pair != null) {
|
||||
+ Set<ServerPlayer> playerSet = entityWatchPlayerSet.get(pair);
|
||||
+ playerSet.remove(player);
|
||||
+ if (playerSet.isEmpty()) {
|
||||
+ entityWatchPlayerSet.remove(pair);
|
||||
+ }
|
||||
+ playerWatchEntity.remove(player);
|
||||
+ }
|
||||
+ lock.unlock();
|
||||
+ }
|
||||
+
|
||||
+ private static void clearPlayerWatchBlock(ServerPlayer player) {
|
||||
+ lock.lock();
|
||||
+ Pair<ResourceLocation, BlockPos> pair = playerWatchBlockPos.get(player);
|
||||
+ if (pair != null) {
|
||||
+ Set<ServerPlayer> playerSet = blockPosWatchPlayerSet.get(pair);
|
||||
+ playerSet.remove(player);
|
||||
+ if (playerSet.isEmpty()) {
|
||||
+ blockPosWatchPlayerSet.remove(pair);
|
||||
+ }
|
||||
+ playerWatchBlockPos.remove(player);
|
||||
+ }
|
||||
+ lock.unlock();
|
||||
+ }
|
||||
+
|
||||
+ public static void disablePcaSyncProtocolGlobal() {
|
||||
+ lock.lock();
|
||||
+ playerWatchBlockPos.clear();
|
||||
+ playerWatchEntity.clear();
|
||||
+ blockPosWatchPlayerSet.clear();
|
||||
+ entityWatchPlayerSet.clear();
|
||||
+ lock.unlock();
|
||||
+ for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) {
|
||||
+ disablePcaSyncProtocol(player);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void enablePcaSyncProtocolGlobal() {
|
||||
+ for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) {
|
||||
+ enablePcaSyncProtocol(player);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ public static void clearPlayerWatchData(ServerPlayer player) {
|
||||
+ PcaSyncProtocol.clearPlayerWatchBlock(player);
|
||||
+ PcaSyncProtocol.clearPlayerWatchEntity(player);
|
||||
+ }
|
||||
+
|
||||
+ public record SyncBlockEntityPayload(BlockPos pos) implements CustomPacketPayload {
|
||||
+
|
||||
+ public static final ResourceLocation SYNC_BLOCK_ENTITY = PcaSyncProtocol.id("sync_block_entity");
|
||||
+
|
||||
+ public SyncBlockEntityPayload(ResourceLocation id, FriendlyByteBuf buf) {
|
||||
+ this(buf.readBlockPos());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void write(FriendlyByteBuf buf) {
|
||||
+ buf.writeBlockPos(pos);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull ResourceLocation id() {
|
||||
+ return SYNC_BLOCK_ENTITY;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public record SyncEntityPayload(int entityId) implements CustomPacketPayload {
|
||||
+
|
||||
+ public static final ResourceLocation SYNC_ENTITY = PcaSyncProtocol.id("sync_entity");
|
||||
+
|
||||
+ public SyncEntityPayload(ResourceLocation id, FriendlyByteBuf buf) {
|
||||
+ this(buf.readInt());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void write(FriendlyByteBuf buf) {
|
||||
+ buf.writeInt(entityId);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull ResourceLocation id() {
|
||||
+ return SYNC_ENTITY;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
183
patches/server/0046-Leaves-Bladeren-protocol.patch
Normal file
183
patches/server/0046-Leaves-Bladeren-protocol.patch
Normal file
@@ -0,0 +1,183 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
|
||||
Date: Thu, 21 Dec 2023 19:50:41 +0800
|
||||
Subject: [PATCH] Leaves Bladeren protocol
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
index cfe9a8eb705039ee7e2dc9262e1355c4b0f664bb..a0fd4fec133617893487586fd52e3a3a864871b4 100644
|
||||
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
@@ -68,6 +68,7 @@ public class LuminolConfig {
|
||||
|
||||
public static boolean pcaSyncProtocol = false;
|
||||
public static String pcaSyncPlayerEntity = "NOBODY";
|
||||
+ public static boolean bladerenLeavesProtocol = false;
|
||||
|
||||
|
||||
public static void init() throws IOException {
|
||||
@@ -201,6 +202,7 @@ public class LuminolConfig {
|
||||
|
||||
pcaSyncProtocol = get("gameplay.enable_pca_sync_protocol",pcaSyncProtocol);
|
||||
pcaSyncPlayerEntity = get("gameplay.pca_sync_player_entity",pcaSyncPlayerEntity,"Available values: NOBODY,EVERYBODY,OPS,OPS_AND_SELF");
|
||||
+ bladerenLeavesProtocol = get("gameplay.bladeren_leaves_protocol",bladerenLeavesProtocol);
|
||||
}
|
||||
|
||||
public static <T> T get(String key,T def){
|
||||
diff --git a/src/main/java/top/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..cf344ad5e928f1bf23953d7b25c4636734da69e6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/top/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java
|
||||
@@ -0,0 +1,151 @@
|
||||
+package top.leavesmc.leaves.protocol.bladeren;
|
||||
+
|
||||
+import com.google.common.collect.Maps;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.network.FriendlyByteBuf;
|
||||
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import org.jetbrains.annotations.Contract;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import me.earthme.luminol.LuminolConfig;
|
||||
+import top.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
+import top.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
+import top.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
+
|
||||
+import java.util.HashMap;
|
||||
+import java.util.Map;
|
||||
+import java.util.function.BiConsumer;
|
||||
+
|
||||
+@LeavesProtocol(namespace = "bladeren")
|
||||
+public class BladerenProtocol {
|
||||
+
|
||||
+ public static final String PROTOCOL_ID = "bladeren";
|
||||
+ public static final String PROTOCOL_VERSION = "1.0.0";
|
||||
+
|
||||
+ private static final ResourceLocation HELLO_ID = id("hello");
|
||||
+ private static final ResourceLocation FEATURE_MODIFY_ID = id("feature_modify");
|
||||
+
|
||||
+ private static final Map<String, BiConsumer<ServerPlayer, CompoundTag>> registeredFeatures = Maps.newConcurrentMap();
|
||||
+
|
||||
+ @Contract("_ -> new")
|
||||
+ public static @NotNull ResourceLocation id(String path) {
|
||||
+ return new ResourceLocation(PROTOCOL_ID, path);
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.PayloadReceiver(payload = BladerenHelloPayload.class, payloadId = "hello")
|
||||
+ private static void handleHello(@NotNull ServerPlayer player, @NotNull BladerenHelloPayload payload) {
|
||||
+ if (LuminolConfig.bladerenLeavesProtocol) {
|
||||
+ String clientVersion = payload.version;
|
||||
+ CompoundTag tag = payload.nbt;
|
||||
+
|
||||
+ if (tag != null) {
|
||||
+ CompoundTag featureNbt = tag.getCompound("Features");
|
||||
+ for (String name : featureNbt.getAllKeys()) {
|
||||
+
|
||||
+ final BiConsumer<ServerPlayer,CompoundTag> target = registeredFeatures.get(name);
|
||||
+
|
||||
+ if (target != null){
|
||||
+ target.accept(player, featureNbt.getCompound(name));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.PayloadReceiver(payload = BladerenFeatureModifyPayload.class, payloadId = "feature_modify")
|
||||
+ private static void handleModify(@NotNull ServerPlayer player, @NotNull BladerenFeatureModifyPayload payload) {
|
||||
+ if (LuminolConfig.bladerenLeavesProtocol) {
|
||||
+ String name = payload.name;
|
||||
+ CompoundTag tag = payload.nbt;
|
||||
+
|
||||
+ final BiConsumer<ServerPlayer,CompoundTag> target = registeredFeatures.get(name);
|
||||
+
|
||||
+ if (target != null){
|
||||
+ target.accept(player, tag);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.PlayerJoin
|
||||
+ public static void onPlayerJoin(@NotNull ServerPlayer player) {
|
||||
+ if (LuminolConfig.bladerenLeavesProtocol) {
|
||||
+ CompoundTag tag = new CompoundTag();
|
||||
+ LeavesFeatureSet.writeNBT(tag);
|
||||
+ ProtocolUtils.sendPayloadPacket(player, new BladerenHelloPayload(PROTOCOL_VERSION, tag));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void registerFeature(String name, BiConsumer<ServerPlayer, CompoundTag> consumer) {
|
||||
+ registeredFeatures.put(name, consumer);
|
||||
+ }
|
||||
+
|
||||
+ public static class LeavesFeatureSet {
|
||||
+
|
||||
+ private static final Map<String, LeavesFeature> features = new HashMap<>();
|
||||
+
|
||||
+ public static void writeNBT(@NotNull CompoundTag tag) {
|
||||
+ CompoundTag featureNbt = new CompoundTag();
|
||||
+ features.values().forEach(feature -> feature.writeNBT(featureNbt));
|
||||
+ tag.put("Features", featureNbt);
|
||||
+ }
|
||||
+
|
||||
+ public static void register(LeavesFeature feature) {
|
||||
+ features.put(feature.name, feature);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public record LeavesFeature(String name, String value) {
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Contract("_, _ -> new")
|
||||
+ public static LeavesFeature of(String name, boolean value) {
|
||||
+ return new LeavesFeature(name, Boolean.toString(value));
|
||||
+ }
|
||||
+
|
||||
+ public void writeNBT(@NotNull CompoundTag rules) {
|
||||
+ CompoundTag rule = new CompoundTag();
|
||||
+ rule.putString("Feature", name);
|
||||
+ rule.putString("Value", value);
|
||||
+ rules.put(name, rule);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public record BladerenFeatureModifyPayload(String name, CompoundTag nbt) implements CustomPacketPayload {
|
||||
+
|
||||
+ public BladerenFeatureModifyPayload(ResourceLocation location, FriendlyByteBuf buf) {
|
||||
+ this(buf.readUtf(), buf.readNbt());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void write(@NotNull FriendlyByteBuf buf) {
|
||||
+ buf.writeUtf(name);
|
||||
+ buf.writeNbt(nbt);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public ResourceLocation id() {
|
||||
+ return FEATURE_MODIFY_ID;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public record BladerenHelloPayload(String version, CompoundTag nbt) implements CustomPacketPayload {
|
||||
+
|
||||
+ public BladerenHelloPayload(ResourceLocation location, @NotNull FriendlyByteBuf buf) {
|
||||
+ this(buf.readUtf(64), buf.readNbt());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void write(@NotNull FriendlyByteBuf buf) {
|
||||
+ buf.writeUtf(version);
|
||||
+ buf.writeNbt(nbt);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public ResourceLocation id() {
|
||||
+ return HELLO_ID;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
126
patches/server/0047-Leaves-Bladeren-mspt-sync-protocol.patch
Normal file
126
patches/server/0047-Leaves-Bladeren-mspt-sync-protocol.patch
Normal file
@@ -0,0 +1,126 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
|
||||
Date: Thu, 21 Dec 2023 20:06:50 +0800
|
||||
Subject: [PATCH] Leaves Bladeren mspt sync protocol
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
index a0fd4fec133617893487586fd52e3a3a864871b4..d19f423debbeaedf955977c02aaf5f8e0016bea3 100644
|
||||
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
|
||||
@@ -69,6 +69,9 @@ public class LuminolConfig {
|
||||
public static boolean pcaSyncProtocol = false;
|
||||
public static String pcaSyncPlayerEntity = "NOBODY";
|
||||
public static boolean bladerenLeavesProtocol = false;
|
||||
+ public static boolean msptSyncProtocol = false;
|
||||
+ public static int msptSyncTickInterval = 20;
|
||||
+
|
||||
|
||||
|
||||
public static void init() throws IOException {
|
||||
@@ -203,6 +206,8 @@ public class LuminolConfig {
|
||||
pcaSyncProtocol = get("gameplay.enable_pca_sync_protocol",pcaSyncProtocol);
|
||||
pcaSyncPlayerEntity = get("gameplay.pca_sync_player_entity",pcaSyncPlayerEntity,"Available values: NOBODY,EVERYBODY,OPS,OPS_AND_SELF");
|
||||
bladerenLeavesProtocol = get("gameplay.bladeren_leaves_protocol",bladerenLeavesProtocol);
|
||||
+ msptSyncProtocol = get("gameplay.bladeren_mspt_sync_protocol",bladerenLeavesProtocol);
|
||||
+ msptSyncTickInterval = get("gameplay.bladeren_mspt_sync_interval",msptSyncTickInterval);
|
||||
}
|
||||
|
||||
public static <T> T get(String key,T def){
|
||||
diff --git a/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..de92ebdf9d51a4f9a58a7650b09f070e51710ef0
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java
|
||||
@@ -0,0 +1,91 @@
|
||||
+package top.leavesmc.leaves.protocol.bladeren;
|
||||
+
|
||||
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
|
||||
+import io.papermc.paper.threadedregions.TickData;
|
||||
+import io.papermc.paper.threadedregions.TickRegions;
|
||||
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
+import it.unimi.dsi.fastutil.objects.ObjectLists;
|
||||
+import me.earthme.luminol.LuminolConfig;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import org.jetbrains.annotations.Contract;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import top.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
+import top.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
+import top.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
+
|
||||
+import java.util.List;
|
||||
+
|
||||
+@LeavesProtocol(namespace = "bladeren")
|
||||
+public class MsptSyncProtocol {
|
||||
+
|
||||
+ public static final String PROTOCOL_ID = "bladeren";
|
||||
+
|
||||
+ private static final ResourceLocation MSPT_SYNC = id("mspt_sync");
|
||||
+
|
||||
+ private static final List<ServerPlayer> players = ObjectLists.synchronize(new ObjectArrayList<>());
|
||||
+
|
||||
+ private static int tickCounter = 0;
|
||||
+
|
||||
+ @Contract("_ -> new")
|
||||
+ public static @NotNull ResourceLocation id(String path) {
|
||||
+ return new ResourceLocation(PROTOCOL_ID, path);
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.Init
|
||||
+ public static void init() {
|
||||
+ BladerenProtocol.registerFeature("mspt_sync", (player, compoundTag) -> {
|
||||
+ if (compoundTag.getString("Value").equals("true")) {
|
||||
+ onPlayerSubmit(player);
|
||||
+ } else {
|
||||
+ onPlayerLoggedOut(player);
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.PlayerLeave
|
||||
+ public static void onPlayerLoggedOut(@NotNull ServerPlayer player) {
|
||||
+ if (LuminolConfig.msptSyncProtocol) {
|
||||
+ players.remove(player);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.Ticker
|
||||
+ public static void tick() {
|
||||
+ if (LuminolConfig.msptSyncProtocol) {
|
||||
+ if (players.isEmpty()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (tickCounter++ % LuminolConfig.msptSyncTickInterval == 0) {
|
||||
+ for (ServerPlayer player : players){
|
||||
+ final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> region = ((ServerLevel) player.level()).regioniser.getRegionAtUnsynchronised(player.sectionX,player.sectionZ);
|
||||
+
|
||||
+ if (region == null){
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final TickData.TickReportData reportData = region.getData().getRegionSchedulingHandle().getTickReport5s(System.nanoTime());
|
||||
+
|
||||
+ if (reportData != null){
|
||||
+ final TickData.SegmentData tpsData = reportData.tpsData().segmentAll();
|
||||
+ final double mspt = reportData.timePerTickData().segmentAll().average() / 1.0E6;
|
||||
+ final double tps = tpsData.average();
|
||||
+
|
||||
+ ProtocolUtils.sendPayloadPacket(player, MSPT_SYNC, buf -> {
|
||||
+ buf.writeDouble(mspt);
|
||||
+ buf.writeDouble(tps);
|
||||
+ });
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void onPlayerSubmit(@NotNull ServerPlayer player) {
|
||||
+ if (LuminolConfig.msptSyncProtocol) {
|
||||
+ players.add(player);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
2044
patches/server/0048-Leaves-Syncmatica-Protocol.patch
Normal file
2044
patches/server/0048-Leaves-Syncmatica-Protocol.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,74 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <novau233@163.com>
|
||||
Date: Mon, 8 Jan 2024 12:19:29 +0000
|
||||
Subject: [PATCH] Do not process any packet if the leaves protocol supports are
|
||||
disabled
|
||||
|
||||
|
||||
diff --git a/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
|
||||
index ebd28033ddf0fe6a354585dc2818a9b481d90ed4..33c7221a1f33cdb81dfac92fc3332f92cf3cd2d9 100644
|
||||
--- a/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
|
||||
+++ b/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package top.leavesmc.leaves.protocol;
|
||||
|
||||
+import me.earthme.luminol.LuminolConfig;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
diff --git a/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java
|
||||
index de92ebdf9d51a4f9a58a7650b09f070e51710ef0..b309963dcf41f16a7b53e4cc2816975523ccba55 100644
|
||||
--- a/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java
|
||||
+++ b/src/main/java/top/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java
|
||||
@@ -35,6 +35,9 @@ public class MsptSyncProtocol {
|
||||
|
||||
@ProtocolHandler.Init
|
||||
public static void init() {
|
||||
+ if (!LuminolConfig.msptSyncProtocol){
|
||||
+ return;
|
||||
+ }
|
||||
BladerenProtocol.registerFeature("mspt_sync", (player, compoundTag) -> {
|
||||
if (compoundTag.getString("Value").equals("true")) {
|
||||
onPlayerSubmit(player);
|
||||
diff --git a/src/main/java/top/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java b/src/main/java/top/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java
|
||||
index fc229f23076147304754a267bcc345cc836b648b..6325f6441e28d915514e6b0ee9b450610e99b2c2 100644
|
||||
--- a/src/main/java/top/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java
|
||||
+++ b/src/main/java/top/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java
|
||||
@@ -2,6 +2,7 @@ package top.leavesmc.leaves.protocol.syncmatica;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.netty.buffer.Unpooled;
|
||||
+import me.earthme.luminol.LuminolConfig;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@@ -68,6 +69,9 @@ public class CommunicationManager {
|
||||
|
||||
@ProtocolHandler.PlayerJoin
|
||||
public static void onPlayerJoin(ServerPlayer player) {
|
||||
+ if (!LuminolConfig.syncmaticaProtocol){
|
||||
+ return;
|
||||
+ }
|
||||
final ExchangeTarget newPlayer = player.connection.exchangeTarget;
|
||||
final VersionHandshakeServer hi = new VersionHandshakeServer(newPlayer);
|
||||
playerMap.put(newPlayer, player);
|
||||
@@ -78,6 +82,9 @@ public class CommunicationManager {
|
||||
|
||||
@ProtocolHandler.PlayerLeave
|
||||
public static void onPlayerLeave(ServerPlayer player) {
|
||||
+ if (!LuminolConfig.syncmaticaProtocol){
|
||||
+ return;
|
||||
+ }
|
||||
final ExchangeTarget oldPlayer = player.connection.exchangeTarget;
|
||||
final Collection<Exchange> potentialMessageTarget = oldPlayer.getExchanges();
|
||||
if (potentialMessageTarget != null) {
|
||||
@@ -92,6 +99,9 @@ public class CommunicationManager {
|
||||
|
||||
@ProtocolHandler.PayloadReceiver(payload = LeavesProtocolManager.LeavesPayload.class, ignoreId = true)
|
||||
public static void onPacketGet(ServerPlayer player, LeavesProtocolManager.LeavesPayload payload) {
|
||||
+ if (!LuminolConfig.syncmaticaProtocol){
|
||||
+ return;
|
||||
+ }
|
||||
onPacket(player.connection.exchangeTarget, payload.id(), payload.data());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user