mirror of
https://github.com/BX-Team/DivineMC.git
synced 2025-12-19 14:59:25 +00:00
upstream leaves protocols
This commit is contained in:
@@ -34,25 +34,6 @@ index fb263fa1f30a7dfcb7ec2656abfb38e5fe88eac9..c3be4c2fd4a544967322a45d3b8c0fe7
|
||||
}
|
||||
};
|
||||
}
|
||||
diff --git a/net/minecraft/network/protocol/common/custom/DiscardedPayload.java b/net/minecraft/network/protocol/common/custom/DiscardedPayload.java
|
||||
index 62b9d9486c15a1ec6527f786df4e9fc483390bcb..36d8b93182cc44e3bea245800ea9e2719333ac65 100644
|
||||
--- a/net/minecraft/network/protocol/common/custom/DiscardedPayload.java
|
||||
+++ b/net/minecraft/network/protocol/common/custom/DiscardedPayload.java
|
||||
@@ -4,12 +4,12 @@ import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
-public record DiscardedPayload(ResourceLocation id, byte[] data) implements CustomPacketPayload { // Paper - store data
|
||||
+public record DiscardedPayload(ResourceLocation id, byte @org.jetbrains.annotations.Nullable [] data) implements CustomPacketPayload { // Paper - store data // DivineMC - Leaves Protocol Core
|
||||
public static <T extends FriendlyByteBuf> StreamCodec<T, DiscardedPayload> codec(ResourceLocation id, int maxSize) {
|
||||
return CustomPacketPayload.codec((value, output) -> {
|
||||
// Paper start
|
||||
// Always write data
|
||||
- output.writeBytes(value.data);
|
||||
+ if (value.data != null) output.writeBytes(value.data); // DivineMC - Leaves Protocol Core
|
||||
}, buffer -> {
|
||||
int i = buffer.readableBytes();
|
||||
if (i >= 0 && i <= maxSize) {
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 89c1fa23b7ce507f86c69c8dcc8f0de38bfa8e99..ce422e12d985a274816abf2841bb3a939568b13b 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
@@ -66,69 +47,67 @@ index 89c1fa23b7ce507f86c69c8dcc8f0de38bfa8e99..ce422e12d985a274816abf2841bb3a93
|
||||
for (int i = 0; i < this.tickables.size(); i++) {
|
||||
this.tickables.get(i).run();
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 963aaef7493e1e281882a9eeca72b1a08fe9cbe8..7f6996e03d7c7d3ecd9a71f9b261a1c0b60ab59c 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -432,6 +432,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
private boolean ramBar = false; // Purpur - Implement rambar commands
|
||||
public boolean smoothWorldTeleport; // DivineMC - Smooth teleport API
|
||||
public boolean hasTickedAtLeastOnceInNewWorld = false; // DivineMC - Parallel world ticking
|
||||
+ public net.minecraft.network.Connection internalConnection; // DivineMC - Leaves Protocol Core
|
||||
|
||||
// Paper start - rewrite chunk system
|
||||
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
|
||||
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index a7c4fad2b1cb0cbac742a18d37d688bb2663944e..b94243d293e805743453adf7b4fc8d852184f460 100644
|
||||
index 2853d8a34038dd521df2a9e5dfe33d50a72cff82..e6e320100fe1609c58215ea8c9e7914cf02ce9a3 100644
|
||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -230,6 +230,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
final String channel = new String(data, from, length, java.nio.charset.StandardCharsets.US_ASCII);
|
||||
if (register) {
|
||||
bridge.addChannel(channel);
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleMinecraftRegister(channel, bridge); // DivineMC - Leaves Protocol Core
|
||||
} else {
|
||||
bridge.removeChannel(channel);
|
||||
}
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 4d37b16adc5491db24fce1ce656f6cde575e10f4..799bb99c4b9403f72eaf30119fd423dd3d80183a 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3680,6 +3680,17 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -61,6 +61,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
public @Nullable String playerBrand;
|
||||
public final java.util.Set<String> pluginMessagerChannels;
|
||||
// Paper end - retain certain values
|
||||
+ public final GameProfile profile; // DivineMC - Leaves Protocol Core
|
||||
|
||||
public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie) {
|
||||
this.server = server;
|
||||
@@ -74,6 +75,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
this.pluginMessagerChannels = cookie.channels();
|
||||
this.keepAlive = cookie.keepAlive();
|
||||
// Paper end
|
||||
+ this.profile = cookie.gameProfile(); // DivineMC - Leaves Protocol Core
|
||||
}
|
||||
|
||||
// Paper start - configuration phase API
|
||||
@@ -165,6 +167,18 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
|
||||
@Override
|
||||
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
|
||||
+ // DivineMC start - Leaves Protocol Core
|
||||
+ if (packet.payload() instanceof org.leavesmc.leaves.protocol.core.LeavesCustomPayload leavesPayload) {
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePayload(player, leavesPayload);
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePayload(org.leavesmc.leaves.protocol.core.ProtocolUtils.createSelector(this), leavesPayload);
|
||||
+ return;
|
||||
+ }
|
||||
+ if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.DiscardedPayload(net.minecraft.resources.ResourceLocation id, byte[] data)) {
|
||||
+ if (org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleBytebuf(player, id, io.netty.buffer.Unpooled.wrappedBuffer(data))) {
|
||||
+ if (org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleBytebuf(org.leavesmc.leaves.protocol.core.ProtocolUtils.createSelector(this), id, io.netty.buffer.Unpooled.wrappedBuffer(data))) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // DivineMC end - Leaves Protocol Core
|
||||
super.handleCustomPayload(packet); // Paper
|
||||
}
|
||||
|
||||
+
|
||||
// Paper start
|
||||
if (!(packet.payload() instanceof final net.minecraft.network.protocol.common.custom.DiscardedPayload discardedPayload)) {
|
||||
return;
|
||||
@@ -230,6 +244,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
final String channel = new String(data, from, length, java.nio.charset.StandardCharsets.US_ASCII);
|
||||
if (register) {
|
||||
bridge.addChannel(channel);
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleMinecraftRegister(channel, org.leavesmc.leaves.protocol.core.ProtocolUtils.createSelector(this)); // DivineMC - Leaves Protocol Core
|
||||
} else {
|
||||
bridge.removeChannel(channel);
|
||||
}
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index e4513af9b89222cec9f9573a053504ec87fc30b8..2b4a87643e4f2d2564597b923a025b432bcf5d23 100644
|
||||
index e4513af9b89222cec9f9573a053504ec87fc30b8..0888ba7853f07909e9915d35f706d39a1c6cf307 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -343,6 +343,11 @@ public abstract class PlayerList {
|
||||
@@ -343,6 +343,8 @@ public abstract class PlayerList {
|
||||
return;
|
||||
}
|
||||
|
||||
+ // DivineMC start - Leaves Protocol Core
|
||||
+ if (player.internalConnection == null) player.internalConnection = connection;
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player);
|
||||
+ // DivineMC end - Leaves Protocol Core
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); // DivineMC - Leaves Protocol Core
|
||||
+
|
||||
final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
|
||||
|
||||
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
|
||||
@@ -516,6 +521,7 @@ public abstract class PlayerList {
|
||||
@@ -516,6 +518,7 @@ public abstract class PlayerList {
|
||||
return this.remove(player, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? player.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(player.getDisplayName())));
|
||||
}
|
||||
public @Nullable net.kyori.adventure.text.Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) {
|
||||
@@ -136,7 +115,7 @@ index e4513af9b89222cec9f9573a053504ec87fc30b8..2b4a87643e4f2d2564597b923a025b43
|
||||
// Paper end - Fix kick event leave message not being sent
|
||||
org.purpurmc.purpur.task.BossBarTask.removeFromAll(player.getBukkitEntity()); // Purpur - Implement TPSBar
|
||||
ServerLevel serverLevel = player.level();
|
||||
@@ -1459,6 +1465,7 @@ public abstract class PlayerList {
|
||||
@@ -1459,6 +1462,7 @@ public abstract class PlayerList {
|
||||
serverPlayer.connection.send(clientboundUpdateRecipesPacket);
|
||||
serverPlayer.getRecipeBook().sendInitialRecipeBook(serverPlayer);
|
||||
}
|
||||
|
||||
@@ -39,10 +39,10 @@ index 02c02314a4a6a7a6da427f0d064dbc61ce92301d..56efd53d22f6d7338ef7d7cc36d612d4
|
||||
+ // DivineMC end - Do not send spectator change packet
|
||||
}
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 2b4a87643e4f2d2564597b923a025b432bcf5d23..a0b7d7046b762e6a3142408051ee327cafe80f45 100644
|
||||
index 0888ba7853f07909e9915d35f706d39a1c6cf307..48a02a25c4fa6f3bacefaccd122694156da1a331 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -359,6 +359,8 @@ public abstract class PlayerList {
|
||||
@@ -356,6 +356,8 @@ public abstract class PlayerList {
|
||||
// CraftBukkit start - sendAll above replaced with this loop
|
||||
ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); // Paper - Add Listing API for Player
|
||||
|
||||
@@ -51,7 +51,7 @@ index 2b4a87643e4f2d2564597b923a025b432bcf5d23..a0b7d7046b762e6a3142408051ee327c
|
||||
final List<ServerPlayer> onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - Use single player info update packet on join
|
||||
for (int i = 0; i < this.players.size(); ++i) {
|
||||
ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i);
|
||||
@@ -367,7 +369,7 @@ public abstract class PlayerList {
|
||||
@@ -364,7 +366,7 @@ public abstract class PlayerList {
|
||||
// Paper start - Add Listing API for Player
|
||||
if (entityplayer1.getBukkitEntity().isListed(bukkitPlayer)) {
|
||||
// Paper end - Add Listing API for Player
|
||||
@@ -60,7 +60,7 @@ index 2b4a87643e4f2d2564597b923a025b432bcf5d23..a0b7d7046b762e6a3142408051ee327c
|
||||
// Paper start - Add Listing API for Player
|
||||
} else {
|
||||
entityplayer1.connection.send(ClientboundPlayerInfoUpdatePacket.createSinglePlayerInitializing(player, false));
|
||||
@@ -383,7 +385,10 @@ public abstract class PlayerList {
|
||||
@@ -380,7 +382,10 @@ public abstract class PlayerList {
|
||||
}
|
||||
// Paper start - Use single player info update packet on join
|
||||
if (!onlinePlayers.isEmpty()) {
|
||||
@@ -72,7 +72,7 @@ index 2b4a87643e4f2d2564597b923a025b432bcf5d23..a0b7d7046b762e6a3142408051ee327c
|
||||
}
|
||||
// Paper end - Use single player info update packet on join
|
||||
player.sentListPacket = true;
|
||||
@@ -1471,4 +1476,69 @@ public abstract class PlayerList {
|
||||
@@ -1468,4 +1473,69 @@ public abstract class PlayerList {
|
||||
public boolean isAllowCommandsForAllPlayers() {
|
||||
return this.allowCommandsForAllPlayers;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.minecraft.world.level.GameRules;
|
||||
import org.bxteam.divinemc.config.DivineConfig;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.protocol.core.Context;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
@@ -16,9 +17,11 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@LeavesProtocol.Register(namespace = "appleskin")
|
||||
public class AppleSkinProtocol implements LeavesProtocol {
|
||||
|
||||
public static final String PROTOCOL_ID = "appleskin";
|
||||
|
||||
private static final ResourceLocation SATURATION_KEY = id("saturation");
|
||||
@@ -31,7 +34,7 @@ public class AppleSkinProtocol implements LeavesProtocol {
|
||||
private static final Map<ServerPlayer, Float> previousExhaustionLevels = new HashMap<>();
|
||||
private static final Map<ServerPlayer, Boolean> previousNaturalRegeneration = new HashMap<>();
|
||||
|
||||
private static final Map<ServerPlayer, Set<String>> subscribedChannels = new HashMap<>();
|
||||
private static final Map<UUID, Set<String>> subscribedChannels = new HashMap<>();
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static ResourceLocation id(String path) {
|
||||
@@ -45,21 +48,24 @@ public class AppleSkinProtocol implements LeavesProtocol {
|
||||
|
||||
@ProtocolHandler.PlayerLeave
|
||||
public static void onPlayerLoggedOut(@NotNull ServerPlayer player) {
|
||||
subscribedChannels.remove(player);
|
||||
subscribedChannels.remove(player.getUUID());
|
||||
resetPlayerData(player);
|
||||
}
|
||||
|
||||
@ProtocolHandler.MinecraftRegister(onlyNamespace = true)
|
||||
public static void onPlayerSubscribed(@NotNull ServerPlayer player, ResourceLocation id) {
|
||||
subscribedChannels.computeIfAbsent(player, k -> new HashSet<>()).add(id.getPath());
|
||||
public static void onPlayerSubscribed(@NotNull Context context, ResourceLocation id) {
|
||||
subscribedChannels.computeIfAbsent(context.profile().getId(), k -> new HashSet<>()).add(id.getPath());
|
||||
}
|
||||
|
||||
@ProtocolHandler.Ticker
|
||||
public static void tick() {
|
||||
for (Map.Entry<ServerPlayer, Set<String>> entry : subscribedChannels.entrySet()) {
|
||||
ServerPlayer player = entry.getKey();
|
||||
FoodData data = player.getFoodData();
|
||||
for (Map.Entry<UUID, Set<String>> entry : subscribedChannels.entrySet()) {
|
||||
ServerPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(entry.getKey());
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FoodData data = player.getFoodData();
|
||||
for (String channel : entry.getValue()) {
|
||||
switch (channel) {
|
||||
case "saturation" -> {
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
|
||||
@LeavesProtocol.Register(namespace = "xaerominimap_or_xaeroworldmap_i_dont_care")
|
||||
public class XaeroMapProtocol implements LeavesProtocol {
|
||||
|
||||
public static final String PROTOCOL_ID_MINI = "xaerominimap";
|
||||
public static final String PROTOCOL_ID_WORLD = "xaeroworldmap";
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.leavesmc.leaves.protocol.core;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.network.Connection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record Context(@NotNull GameProfile profile, Connection connection) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.leavesmc.leaves.protocol.core;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public record IdentifierSelector(@Nullable Context context, @Nullable ServerPlayer player) {
|
||||
|
||||
public Object select(ProtocolHandler.Stage stage) {
|
||||
return stage == ProtocolHandler.Stage.CONFIGURATION ? context : player;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
public interface LeavesCustomPayload extends CustomPacketPayload {
|
||||
|
||||
Type<? extends CustomPacketPayload> LEAVES_TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath("leaves", "custom_payload"));
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
public interface LeavesProtocol {
|
||||
|
||||
boolean isActive();
|
||||
|
||||
default int tickerInterval(String tickerID) {
|
||||
@@ -17,4 +18,4 @@ public interface LeavesProtocol {
|
||||
@interface Register {
|
||||
String namespace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.leavesmc.leaves.protocol.core;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.papermc.paper.connection.PluginMessageBridgeImpl;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
@@ -15,9 +14,6 @@ import org.leavesmc.leaves.protocol.core.invoker.MinecraftRegisterInvokerHolder;
|
||||
import org.leavesmc.leaves.protocol.core.invoker.PayloadReceiverInvokerHolder;
|
||||
import org.leavesmc.leaves.protocol.core.invoker.PlayerInvokerHolder;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
@@ -40,6 +36,7 @@ import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
public class LeavesProtocolManager {
|
||||
|
||||
private static final LeavesLogger LOGGER = LeavesLogger.LOGGER;
|
||||
|
||||
private static final Map<Class<? extends LeavesCustomPayload>, PayloadReceiverInvokerHolder> PAYLOAD_RECEIVERS = new HashMap<>();
|
||||
@@ -101,16 +98,6 @@ public class LeavesProtocolManager {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean active = true;
|
||||
try {
|
||||
Method isActiveMethod = clazz.getDeclaredMethod("isActive");
|
||||
isActiveMethod.setAccessible(true);
|
||||
active = (Boolean) isActiveMethod.invoke(protocol);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.warning("Failed to check isActive for " + clazz.getName() + ": " + e);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (final Method method : clazz.getDeclaredMethods()) {
|
||||
if (method.isBridge() || method.isSynthetic()) {
|
||||
continue;
|
||||
@@ -128,20 +115,6 @@ public class LeavesProtocolManager {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!active) continue;
|
||||
|
||||
final ProtocolHandler.ReloadServer reloadServer = method.getAnnotation(ProtocolHandler.ReloadServer.class);
|
||||
if (reloadServer != null) {
|
||||
RELOAD_SERVER.add(new EmptyInvokerHolder<>(protocol, method, reloadServer));
|
||||
continue;
|
||||
}
|
||||
|
||||
final ProtocolHandler.ReloadDataPack reloadDataPack = method.getAnnotation(ProtocolHandler.ReloadDataPack.class);
|
||||
if (reloadDataPack != null) {
|
||||
RELOAD_DATAPACK.add(new EmptyInvokerHolder<>(protocol, method, reloadDataPack));
|
||||
continue;
|
||||
}
|
||||
|
||||
final ProtocolHandler.PayloadReceiver payloadReceiver = method.getAnnotation(ProtocolHandler.PayloadReceiver.class);
|
||||
if (payloadReceiver != null) {
|
||||
PAYLOAD_RECEIVERS.put(payloadReceiver.payload(), new PayloadReceiverInvokerHolder(protocol, method, payloadReceiver));
|
||||
@@ -186,6 +159,18 @@ public class LeavesProtocolManager {
|
||||
continue;
|
||||
}
|
||||
|
||||
final ProtocolHandler.ReloadServer reloadServer = method.getAnnotation(ProtocolHandler.ReloadServer.class);
|
||||
if (reloadServer != null) {
|
||||
RELOAD_SERVER.add(new EmptyInvokerHolder<>(protocol, method, reloadServer));
|
||||
continue;
|
||||
}
|
||||
|
||||
final ProtocolHandler.ReloadDataPack reloadDataPack = method.getAnnotation(ProtocolHandler.ReloadDataPack.class);
|
||||
if (reloadDataPack != null) {
|
||||
RELOAD_DATAPACK.add(new EmptyInvokerHolder<>(protocol, method, reloadDataPack));
|
||||
continue;
|
||||
}
|
||||
|
||||
final ProtocolHandler.MinecraftRegister minecraftRegister = method.getAnnotation(ProtocolHandler.MinecraftRegister.class);
|
||||
if (minecraftRegister != null) {
|
||||
String key = minecraftRegister.key();
|
||||
@@ -233,27 +218,27 @@ public class LeavesProtocolManager {
|
||||
codec.encode(ProtocolUtils.decorate(buf), payload);
|
||||
}
|
||||
|
||||
public static void handlePayload(ServerPlayer player, LeavesCustomPayload payload) {
|
||||
public static void handlePayload(IdentifierSelector selector, LeavesCustomPayload payload) {
|
||||
PayloadReceiverInvokerHolder holder;
|
||||
if ((holder = PAYLOAD_RECEIVERS.get(payload.getClass())) != null) {
|
||||
holder.invoke(player, payload);
|
||||
holder.invoke(selector, payload);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean handleBytebuf(ServerPlayer player, ResourceLocation location, ByteBuf buf) {
|
||||
public static boolean handleBytebuf(IdentifierSelector selector, ResourceLocation location, ByteBuf buf) {
|
||||
RegistryFriendlyByteBuf buf1 = ProtocolUtils.decorate(buf);
|
||||
BytebufReceiverInvokerHolder holder;
|
||||
if ((holder = STRICT_BYTEBUF_RECEIVERS.get(location.toString())) != null) {
|
||||
holder.invoke(player, buf1);
|
||||
holder.invoke(selector, buf1);
|
||||
return true;
|
||||
}
|
||||
if ((holder = NAMESPACED_BYTEBUF_RECEIVERS.get(location.getNamespace())) != null) {
|
||||
if (holder.invoke(player, buf1)) {
|
||||
if (holder.invoke(selector, buf1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (var holder1 : GENERIC_BYTEBUF_RECEIVERS) {
|
||||
if (holder1.invoke(player, buf1)) {
|
||||
if (holder1.invoke(selector, buf1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -293,39 +278,37 @@ public class LeavesProtocolManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleMinecraftRegister(String channelId, PluginMessageBridgeImpl bridge) {
|
||||
ServerPlayer player = null;
|
||||
if (bridge instanceof CraftPlayer craftPlayer) {
|
||||
player = craftPlayer.getHandle();
|
||||
}
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
public static void handleMinecraftRegister(String channelId, IdentifierSelector selector) {
|
||||
ResourceLocation location = ResourceLocation.tryParse(channelId);
|
||||
if (location == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var wildHolder : WILD_MINECRAFT_REGISTER) {
|
||||
wildHolder.invoke(player, location);
|
||||
wildHolder.invoke(selector, location);
|
||||
}
|
||||
|
||||
MinecraftRegisterInvokerHolder holder;
|
||||
if ((holder = STRICT_MINECRAFT_REGISTER.get(location.toString())) != null) {
|
||||
holder.invoke(player, location);
|
||||
holder.invoke(selector, location);
|
||||
}
|
||||
if ((holder = NAMESPACED_MINECRAFT_REGISTER.get(location.getNamespace())) != null) {
|
||||
holder.invoke(player, location);
|
||||
holder.invoke(selector, location);
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendKnownId(ServerPlayer player) {
|
||||
Set<String> set = new HashSet<>();
|
||||
PAYLOAD_RECEIVERS.forEach((clazz, holder) -> set.add(IDS.get(clazz).toString()));
|
||||
STRICT_BYTEBUF_RECEIVERS.forEach((key, holder) -> set.add(key));
|
||||
if (set.isEmpty()) return;
|
||||
PAYLOAD_RECEIVERS.forEach((clazz, holder) -> {
|
||||
if (holder.owner().isActive()) {
|
||||
set.add(IDS.get(clazz).toString());
|
||||
}
|
||||
});
|
||||
STRICT_BYTEBUF_RECEIVERS.forEach((key, holder) -> {
|
||||
if (holder.owner().isActive()) {
|
||||
set.add(key);
|
||||
}
|
||||
});
|
||||
ProtocolUtils.sendBytebufPacket(player, ResourceLocation.fromNamespaceAndPath("minecraft", "register"), buf -> {
|
||||
for (String channel : set) {
|
||||
buf.writeBytes(channel.getBytes(StandardCharsets.US_ASCII));
|
||||
@@ -409,4 +392,4 @@ public class LeavesProtocolManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
package org.leavesmc.leaves.protocol.core;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
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 {
|
||||
@@ -15,6 +18,8 @@ public class ProtocolHandler {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface PayloadReceiver {
|
||||
Class<? extends LeavesCustomPayload> payload();
|
||||
|
||||
Stage stage() default Stage.GAME;
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@@ -23,6 +28,8 @@ public class ProtocolHandler {
|
||||
String key() default "";
|
||||
|
||||
boolean onlyNamespace() default false;
|
||||
|
||||
Stage stage() default Stage.GAME;
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@@ -52,10 +59,27 @@ public class ProtocolHandler {
|
||||
String key() default "";
|
||||
|
||||
boolean onlyNamespace() default false;
|
||||
|
||||
Stage stage() default Stage.CONFIGURATION;
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ReloadDataPack {
|
||||
}
|
||||
}
|
||||
|
||||
public enum Stage {
|
||||
CONFIGURATION(Context.class),
|
||||
GAME(ServerPlayer.class);
|
||||
|
||||
private final Class<?> identifier;
|
||||
|
||||
Stage(Class<?> identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public Class<?> identifier() {
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,33 +11,61 @@ import net.minecraft.network.protocol.common.custom.DiscardedPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerCommonPacketListenerImpl;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ProtocolUtils {
|
||||
|
||||
private static final Function<ByteBuf, RegistryFriendlyByteBuf> bufDecorator = buf -> buf instanceof RegistryFriendlyByteBuf registry ? registry : new RegistryFriendlyByteBuf(buf, MinecraftServer.getServer().registryAccess());
|
||||
private static final byte[] EMPTY = new byte[0];
|
||||
|
||||
public static String buildProtocolVersion(String protocol) {
|
||||
return protocol + "-leaves-" + ServerBuildInfo.buildInfo().asString(ServerBuildInfo.StringRepresentation.VERSION_SIMPLE);
|
||||
}
|
||||
|
||||
public static void sendEmptyPacket(ServerPlayer player, ResourceLocation id) {
|
||||
player.internalConnection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, null)));
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, EMPTY)));
|
||||
}
|
||||
|
||||
public static void sendBytebufPacket(@NotNull ServerPlayer player, ResourceLocation id, Consumer<? super RegistryFriendlyByteBuf> consumer) {
|
||||
RegistryFriendlyByteBuf buf = decorate(Unpooled.buffer());
|
||||
consumer.accept(buf);
|
||||
player.internalConnection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf))));
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf))));
|
||||
}
|
||||
|
||||
public static void sendPayloadPacket(ServerPlayer player, CustomPacketPayload payload) {
|
||||
player.internalConnection.send(new ClientboundCustomPayloadPacket(payload));
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(payload));
|
||||
}
|
||||
|
||||
public static void sendEmptyPacket(Context context, ResourceLocation id) {
|
||||
context.connection().send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, EMPTY)));
|
||||
}
|
||||
|
||||
public static void sendBytebufPacket(@NotNull Context context, ResourceLocation id, Consumer<? super RegistryFriendlyByteBuf> consumer) {
|
||||
RegistryFriendlyByteBuf buf = decorate(Unpooled.buffer());
|
||||
consumer.accept(buf);
|
||||
context.connection().send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf))));
|
||||
}
|
||||
|
||||
public static void sendPayloadPacket(Context context, CustomPacketPayload payload) {
|
||||
context.connection().send(new ClientboundCustomPayloadPacket(payload));
|
||||
}
|
||||
|
||||
public static RegistryFriendlyByteBuf decorate(ByteBuf buf) {
|
||||
return bufDecorator.apply(buf);
|
||||
}
|
||||
|
||||
public static IdentifierSelector createSelector(ServerCommonPacketListenerImpl common) {
|
||||
ServerPlayer player = common instanceof ServerGamePacketListenerImpl game ? game.getPlayer() : null;
|
||||
return new IdentifierSelector(new Context(common.profile, common.connection), player);
|
||||
}
|
||||
|
||||
public static ByteBuf wrapNullable(byte @Nullable [] data) {
|
||||
return data == null ? Unpooled.wrappedBuffer(EMPTY) : Unpooled.wrappedBuffer(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,18 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public abstract class AbstractInvokerHolder<T> {
|
||||
|
||||
protected final LeavesProtocol owner;
|
||||
protected final Method invoker;
|
||||
protected final T handler;
|
||||
protected final Class<?> returnType;
|
||||
protected final Class<?>[] parameterTypes;
|
||||
protected final boolean isStatic;
|
||||
|
||||
protected AbstractInvokerHolder(LeavesProtocol owner, Method invoker, T handler, @Nullable Class<?> returnType, @NotNull Class<?>... parameterTypes) {
|
||||
this.owner = owner;
|
||||
@@ -20,6 +23,7 @@ public abstract class AbstractInvokerHolder<T> {
|
||||
this.handler = handler;
|
||||
this.returnType = returnType;
|
||||
this.parameterTypes = parameterTypes;
|
||||
this.isStatic = Modifier.isStatic(invoker.getModifiers());
|
||||
|
||||
validateMethodSignature();
|
||||
}
|
||||
@@ -57,11 +61,13 @@ public abstract class AbstractInvokerHolder<T> {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
if (Modifier.isStatic(invoker.getModifiers())) {
|
||||
if (isStatic) {
|
||||
return invoker.invoke(null, args);
|
||||
} else {
|
||||
return invoker.invoke(owner, args);
|
||||
}
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e.getCause());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.leavesmc.leaves.protocol.core.invoker;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.leavesmc.leaves.protocol.core.IdentifierSelector;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
|
||||
@@ -9,10 +9,10 @@ import java.lang.reflect.Method;
|
||||
|
||||
public class BytebufReceiverInvokerHolder extends AbstractInvokerHolder<ProtocolHandler.BytebufReceiver> {
|
||||
public BytebufReceiverInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.BytebufReceiver handler) {
|
||||
super(owner, invoker, handler, null, ServerPlayer.class, FriendlyByteBuf.class);
|
||||
super(owner, invoker, handler, null, handler.stage().identifier(), FriendlyByteBuf.class);
|
||||
}
|
||||
|
||||
public boolean invoke(ServerPlayer player, FriendlyByteBuf buf) {
|
||||
return invoke0(false, player, buf) instanceof Boolean b && b;
|
||||
public boolean invoke(IdentifierSelector selector, FriendlyByteBuf buf) {
|
||||
return invoke0(false, selector.select(handler.stage()), buf) instanceof Boolean b && b;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.leavesmc.leaves.protocol.core.invoker;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.leavesmc.leaves.protocol.core.IdentifierSelector;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
|
||||
@@ -9,10 +9,10 @@ import java.lang.reflect.Method;
|
||||
|
||||
public class MinecraftRegisterInvokerHolder extends AbstractInvokerHolder<ProtocolHandler.MinecraftRegister> {
|
||||
public MinecraftRegisterInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.MinecraftRegister handler) {
|
||||
super(owner, invoker, handler, null, ServerPlayer.class, ResourceLocation.class);
|
||||
super(owner, invoker, handler, null, handler.stage().identifier(), ResourceLocation.class);
|
||||
}
|
||||
|
||||
public void invoke(ServerPlayer player, ResourceLocation id) {
|
||||
invoke0(false, player, id);
|
||||
public void invoke(IdentifierSelector selector, ResourceLocation id) {
|
||||
invoke0(false, selector.select(handler.stage()), id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.leavesmc.leaves.protocol.core.invoker;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.leavesmc.leaves.protocol.core.IdentifierSelector;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
@@ -9,10 +9,10 @@ import java.lang.reflect.Method;
|
||||
|
||||
public class PayloadReceiverInvokerHolder extends AbstractInvokerHolder<ProtocolHandler.PayloadReceiver> {
|
||||
public PayloadReceiverInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.PayloadReceiver handler) {
|
||||
super(owner, invoker, handler, null, ServerPlayer.class, handler.payload());
|
||||
super(owner, invoker, handler, null, handler.stage().identifier(), handler.payload());
|
||||
}
|
||||
|
||||
public void invoke(ServerPlayer player, LeavesCustomPayload payload) {
|
||||
invoke0(false, player, payload);
|
||||
public void invoke(IdentifierSelector selector, LeavesCustomPayload payload) {
|
||||
invoke0(false, selector.select(handler.stage()), payload);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,6 @@ import org.leavesmc.leaves.protocol.jade.util.PairHierarchyLookup;
|
||||
import org.leavesmc.leaves.protocol.jade.util.PriorityStore;
|
||||
import org.leavesmc.leaves.protocol.jade.util.WrappedHierarchyLookup;
|
||||
import org.leavesmc.leaves.util.NbtUtils;
|
||||
import org.purpurmc.purpur.util.MinecraftInternalPlugin;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -92,7 +91,7 @@ import java.util.Set;
|
||||
public class JadeProtocol implements LeavesProtocol {
|
||||
|
||||
public static final String PROTOCOL_ID = "jade";
|
||||
public static final String PROTOCOL_VERSION = "7";
|
||||
public static final String PROTOCOL_VERSION = "8";
|
||||
public static final HierarchyLookup<IServerDataProvider<EntityAccessor>> entityDataProviders = new HierarchyLookup<>(Entity.class);
|
||||
public static final PairHierarchyLookup<IServerDataProvider<BlockAccessor>> blockDataProviders = new PairHierarchyLookup<>(new HierarchyLookup<>(Block.class), new HierarchyLookup<>(BlockEntity.class));
|
||||
public static final WrappedHierarchyLookup<IServerExtensionProvider<ItemStack>> itemStorageProviders = WrappedHierarchyLookup.forAccessor();
|
||||
|
||||
@@ -3,13 +3,13 @@ package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamEncoder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface Accessor<T extends HitResult> {
|
||||
Level getLevel();
|
||||
ServerLevel getLevel();
|
||||
|
||||
Player getPlayer();
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import net.minecraft.nbt.ByteArrayTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamEncoder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@@ -14,20 +14,20 @@ import java.util.function.Supplier;
|
||||
|
||||
public abstract class AccessorImpl<T extends HitResult> implements Accessor<T> {
|
||||
|
||||
private final Level level;
|
||||
private final ServerLevel level;
|
||||
private final Player player;
|
||||
private final Supplier<T> hit;
|
||||
protected boolean verify;
|
||||
private RegistryFriendlyByteBuf buffer;
|
||||
|
||||
public AccessorImpl(Level level, Player player, Supplier<T> hit) {
|
||||
public AccessorImpl(ServerLevel level, Player player, Supplier<T> hit) {
|
||||
this.level = level;
|
||||
this.player = player;
|
||||
this.hit = hit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Level getLevel() {
|
||||
public ServerLevel getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -23,7 +23,7 @@ public interface BlockAccessor extends Accessor<BlockHitResult> {
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
interface Builder {
|
||||
Builder level(Level level);
|
||||
Builder level(ServerLevel level);
|
||||
|
||||
Builder player(Player player);
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
@@ -61,14 +61,14 @@ public class BlockAccessorImpl extends AccessorImpl<BlockHitResult> implements B
|
||||
}
|
||||
|
||||
public static class Builder implements BlockAccessor.Builder {
|
||||
private Level level;
|
||||
private ServerLevel level;
|
||||
private Player player;
|
||||
private BlockHitResult hit;
|
||||
private BlockState blockState = Blocks.AIR.defaultBlockState();
|
||||
private Supplier<BlockEntity> blockEntity;
|
||||
|
||||
@Override
|
||||
public Builder level(Level level) {
|
||||
public Builder level(ServerLevel level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@@ -19,7 +19,7 @@ public interface EntityAccessor extends Accessor<EntityHitResult> {
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
interface Builder {
|
||||
Builder level(Level level);
|
||||
Builder level(ServerLevel level);
|
||||
|
||||
Builder player(Player player);
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ import com.google.common.base.Suppliers;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
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.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -41,13 +41,13 @@ public class EntityAccessorImpl extends AccessorImpl<EntityHitResult> implements
|
||||
}
|
||||
|
||||
public static class Builder implements EntityAccessor.Builder {
|
||||
private Level level;
|
||||
private ServerLevel level;
|
||||
private Player player;
|
||||
private Supplier<EntityHitResult> hit;
|
||||
private Supplier<Entity> entity;
|
||||
|
||||
@Override
|
||||
public Builder level(Level level) {
|
||||
public Builder level(ServerLevel level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,12 @@ import java.util.Map;
|
||||
|
||||
import static org.leavesmc.leaves.protocol.jade.util.JadeCodec.PRIMITIVE_STREAM_CODEC;
|
||||
|
||||
public record ServerHandshakePayload(Map<ResourceLocation, Object> serverConfig, List<Block> shearableBlocks, List<ResourceLocation> blockProviderIds, List<ResourceLocation> entityProviderIds) implements LeavesCustomPayload {
|
||||
public record ServerHandshakePayload(
|
||||
Map<ResourceLocation, Object> serverConfig,
|
||||
List<Block> shearableBlocks,
|
||||
List<ResourceLocation> blockProviderIds,
|
||||
List<ResourceLocation> entityProviderIds
|
||||
) implements LeavesCustomPayload {
|
||||
|
||||
@ID
|
||||
private static final ResourceLocation PACKET_SERVER_HANDSHAKE = JadeProtocol.id("server_handshake");
|
||||
|
||||
@@ -13,7 +13,6 @@ import net.minecraft.world.entity.vehicle.ContainerEntity;
|
||||
import net.minecraft.world.inventory.PlayerEnderChestContainer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.ChestBlock;
|
||||
import net.minecraft.world.level.block.EnderChestBlock;
|
||||
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.EnderChestBlockEntity;
|
||||
@@ -58,7 +57,11 @@ public enum ItemStorageExtensionProvider implements IServerExtensionProvider<Ite
|
||||
if (blockEntity.getBlockState().getBlock() instanceof ChestBlock chestBlock) {
|
||||
Container compound = null;
|
||||
if (blockEntity.getLevel() != null) {
|
||||
compound = ChestBlock.getContainer(chestBlock, blockEntity.getBlockState(), blockEntity.getLevel(), blockEntity.getBlockPos(), false);
|
||||
compound = ChestBlock.getContainer(
|
||||
chestBlock, blockEntity.getBlockState(),
|
||||
blockEntity.getLevel(), blockEntity.getBlockPos(),
|
||||
true // Bypass lock check
|
||||
);
|
||||
}
|
||||
if (compound != null) {
|
||||
return compound;
|
||||
|
||||
@@ -22,7 +22,7 @@ public enum MobSpawnerCooldownProvider implements StreamServerDataProvider<Block
|
||||
public @Nullable Integer streamData(@NotNull BlockAccessor accessor) {
|
||||
TrialSpawnerBlockEntity spawner = (TrialSpawnerBlockEntity) accessor.getBlockEntity();
|
||||
TrialSpawnerStateData spawnerData = spawner.getTrialSpawner().getStateData();
|
||||
ServerLevel level = ((ServerLevel) accessor.getLevel());
|
||||
ServerLevel level = accessor.getLevel();
|
||||
if (spawner.getTrialSpawner().canSpawnInLevel(level) && level.getGameTime() < spawnerData.cooldownEndsAt) {
|
||||
return (int) (spawnerData.cooldownEndsAt - level.getGameTime());
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ItemCollector<T> {
|
||||
return null;
|
||||
}
|
||||
long currentVersion = iterator.getVersion(container);
|
||||
long gameTime = request.getLevel().getGameTime();
|
||||
long gameTime = request.getLevel().getServer().getTickCount();
|
||||
if (mergedResult != null && iterator.isFinished()) {
|
||||
if (version == currentVersion) {
|
||||
return mergedResult; // content not changed
|
||||
@@ -73,7 +73,7 @@ public class ItemCollector<T> {
|
||||
items.addTo(def, stack.getCount());
|
||||
}
|
||||
});
|
||||
iterator.afterPopulate(count.get());
|
||||
iterator.afterPopulate(container, count.get());
|
||||
if (mergedResult != null && !iterator.isFinished()) {
|
||||
updateCollectingProgress(mergedResult.getFirst());
|
||||
return mergedResult;
|
||||
|
||||
@@ -15,6 +15,7 @@ public abstract class ItemIterator<T> {
|
||||
protected final int fromIndex;
|
||||
protected boolean finished;
|
||||
protected int currentIndex;
|
||||
protected float progress;
|
||||
|
||||
protected ItemIterator(Function<Object, @Nullable T> containerFinder, int fromIndex) {
|
||||
this.containerFinder = containerFinder;
|
||||
@@ -35,16 +36,19 @@ public abstract class ItemIterator<T> {
|
||||
|
||||
public abstract Stream<ItemStack> populate(T container);
|
||||
|
||||
protected abstract int getSlotCount(T container);
|
||||
|
||||
public void reset() {
|
||||
currentIndex = fromIndex;
|
||||
finished = false;
|
||||
}
|
||||
|
||||
public void afterPopulate(int count) {
|
||||
public void afterPopulate(T container, int count) {
|
||||
currentIndex += count;
|
||||
if (count == 0 || currentIndex >= 10000) {
|
||||
finished = true;
|
||||
}
|
||||
progress = (float) (currentIndex - fromIndex) / (getSlotCount(container) - fromIndex);
|
||||
}
|
||||
|
||||
public float getCollectingProgress() {
|
||||
@@ -52,14 +56,11 @@ public abstract class ItemIterator<T> {
|
||||
}
|
||||
|
||||
public static abstract class SlottedItemIterator<T> extends ItemIterator<T> {
|
||||
protected float progress;
|
||||
|
||||
public SlottedItemIterator(Function<Object, @Nullable T> containerFinder, int fromIndex) {
|
||||
super(containerFinder, fromIndex);
|
||||
}
|
||||
|
||||
protected abstract int getSlotCount(T container);
|
||||
|
||||
protected abstract ItemStack getItemInSlot(T container, int slot);
|
||||
|
||||
@Override
|
||||
@@ -70,7 +71,6 @@ public abstract class ItemIterator<T> {
|
||||
toIndex = slotCount;
|
||||
finished = true;
|
||||
}
|
||||
progress = (float) (currentIndex - fromIndex) / (slotCount - fromIndex);
|
||||
return IntStream.range(currentIndex, toIndex).mapToObj(slot -> getItemInSlot(container, slot));
|
||||
}
|
||||
|
||||
|
||||
@@ -28,12 +28,20 @@ public class ServerPlacement {
|
||||
|
||||
public ServerPlacement(final UUID id, final String fileName, final UUID hashValue, final PlayerIdentifier owner) {
|
||||
this.id = id;
|
||||
this.fileName = fileName;
|
||||
this.fileName = removeExtension(fileName);
|
||||
this.hashValue = hashValue;
|
||||
this.owner = owner;
|
||||
lastModifiedBy = owner;
|
||||
}
|
||||
|
||||
private static String removeExtension(final String fileName) {
|
||||
final int pos = fileName.lastIndexOf(".");
|
||||
if (pos < 0) {
|
||||
return fileName;
|
||||
}
|
||||
return fileName.substring(0, pos);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ServerPlacement fromJson(final @NotNull JsonObject obj) {
|
||||
if (obj.has("id")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.leavesmc.leaves.protocol.syncmatica;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.bxteam.divinemc.config.DivineConfig;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -14,6 +15,7 @@ import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SyncmaticaProtocol {
|
||||
|
||||
public static final String PROTOCOL_ID = "syncmatica";
|
||||
public static final String PROTOCOL_VERSION = "leaves-syncmatica-1.1.0";
|
||||
private static final File litematicFolder = new File("." + File.separator + "syncmatics");
|
||||
@@ -80,11 +82,16 @@ public class SyncmaticaProtocol {
|
||||
|
||||
@NotNull
|
||||
public static String sanitizeFileName(final @NotNull String badFileName) {
|
||||
String input = badFileName;
|
||||
try {
|
||||
input = FilenameUtils.getName(input);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
final StringBuilder sanitized = new StringBuilder();
|
||||
final int len = badFileName.codePointCount(0, badFileName.length());
|
||||
final int len = input.codePointCount(0, input.length());
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
final int c = badFileName.codePointAt(i);
|
||||
final int c = input.codePointAt(i);
|
||||
if (Arrays.binarySearch(ILLEGAL_CHARS, c) < 0) {
|
||||
sanitized.appendCodePoint(c);
|
||||
if (sanitized.length() == 255) {
|
||||
|
||||
Reference in New Issue
Block a user