From 46cccfc39cafbca1681620d03947bc3ad558327f Mon Sep 17 00:00:00 2001 From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> Date: Fri, 25 Jul 2025 07:18:45 -0700 Subject: [PATCH] Fix #609 & #612, add maxNbt in litematics, improve protocol invoker (#611) * Fix #609, add maxNbt in litematics, improve protocol invoker * Add long validator * Go away inf check * Fix #612 --- .../org/leavesmc/leaves/LeavesConfig.java | 85 +++++++++++++------ .../leaves/config/AutoConfigValidator.java | 3 + .../leaves/config/ConfigValidatorImpl.java | 7 ++ .../core/invoker/AbstractInvokerHolder.java | 3 + .../litematics/ServuxLitematicsProtocol.java | 10 ++- .../leaves/util/ItemOverstackUtils.java | 45 +++++----- 6 files changed, 97 insertions(+), 56 deletions(-) diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/LeavesConfig.java b/leaves-server/src/main/java/org/leavesmc/leaves/LeavesConfig.java index 775d2205..fb96577a 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/LeavesConfig.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/LeavesConfig.java @@ -11,25 +11,38 @@ import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; import org.bukkit.plugin.PluginManager; import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.BotCommand; import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.Actions; import org.leavesmc.leaves.command.LeavesCommand; import org.leavesmc.leaves.config.ConfigValidatorImpl.BooleanConfigValidator; import org.leavesmc.leaves.config.ConfigValidatorImpl.DoubleConfigValidator; import org.leavesmc.leaves.config.ConfigValidatorImpl.EnumConfigValidator; import org.leavesmc.leaves.config.ConfigValidatorImpl.IntConfigValidator; import org.leavesmc.leaves.config.ConfigValidatorImpl.ListConfigValidator; +import org.leavesmc.leaves.config.ConfigValidatorImpl.LongConfigValidator; import org.leavesmc.leaves.config.ConfigValidatorImpl.StringConfigValidator; import org.leavesmc.leaves.config.GlobalConfigManager; import org.leavesmc.leaves.config.annotations.GlobalConfig; import org.leavesmc.leaves.config.annotations.GlobalConfigCategory; import org.leavesmc.leaves.config.annotations.RemovedConfig; +import org.leavesmc.leaves.profile.LeavesMinecraftSessionService; import org.leavesmc.leaves.protocol.CarpetServerProtocol.CarpetRule; import org.leavesmc.leaves.protocol.CarpetServerProtocol.CarpetRules; +import org.leavesmc.leaves.protocol.PcaSyncProtocol; import org.leavesmc.leaves.protocol.bladeren.BladerenProtocol.LeavesFeature; import org.leavesmc.leaves.protocol.bladeren.BladerenProtocol.LeavesFeatureSet; +import org.leavesmc.leaves.protocol.rei.REIServerProtocol; import org.leavesmc.leaves.protocol.servux.logger.DataLogger; +import org.leavesmc.leaves.protocol.syncmatica.SyncmaticaProtocol; +import org.leavesmc.leaves.region.IRegionFileFactory; import org.leavesmc.leaves.region.RegionFileFormat; +import org.leavesmc.leaves.region.linear.LinearVersion; +import org.leavesmc.leaves.util.LeavesUpdateHelper; import org.leavesmc.leaves.util.MathUtils; +import org.leavesmc.leaves.util.McTechnicalModeHelper; +import org.leavesmc.leaves.util.ServerI18nUtil; +import org.leavesmc.leaves.util.VillagerInfiniteDiscountHelper; import java.io.File; import java.io.IOException; @@ -134,8 +147,8 @@ public final class LeavesConfig { @Override public void verify(Boolean old, Boolean value) throws IllegalArgumentException { if (value) { - registerCommand("bot", new org.leavesmc.leaves.bot.BotCommand()); - org.leavesmc.leaves.bot.agent.Actions.registerAll(); + registerCommand("bot", new BotCommand()); + Actions.registerAll(); } else { unregisterCommand("bot"); } @@ -274,7 +287,7 @@ public final class LeavesConfig { private static class VillagerInfiniteDiscountsValidator extends BooleanConfigValidator { @Override public void verify(Boolean old, Boolean value) throws IllegalArgumentException { - org.leavesmc.leaves.util.VillagerInfiniteDiscountHelper.doVillagerInfiniteDiscount(value); + VillagerInfiniteDiscountHelper.doVillagerInfiniteDiscount(value); } } @@ -509,7 +522,7 @@ public final class LeavesConfig { @Override public void verify(Boolean old, Boolean value) throws IllegalArgumentException { if (value) { - org.leavesmc.leaves.util.McTechnicalModeHelper.doMcTechnicalMode(); + McTechnicalModeHelper.doMcTechnicalMode(); } } } @@ -829,7 +842,7 @@ public final class LeavesConfig { public static class SyncmaticaValidator extends BooleanConfigValidator { @Override public void verify(Boolean old, Boolean value) throws IllegalArgumentException { - org.leavesmc.leaves.protocol.syncmatica.SyncmaticaProtocol.init(value); + SyncmaticaProtocol.init(value); } } @@ -852,7 +865,7 @@ public final class LeavesConfig { @Override public void verify(Boolean old, Boolean value) throws IllegalArgumentException { if (old != null && old != value) { - org.leavesmc.leaves.protocol.PcaSyncProtocol.onConfigModify(value); + PcaSyncProtocol.onConfigModify(value); } } } @@ -904,19 +917,39 @@ public final class LeavesConfig { @GlobalConfig("hud-metadata-protocol-share-seed") public boolean hudMetadataShareSeed = true; - @GlobalConfig(value = "litematics-protocol", validator = LitematicsProtocolValidator.class) - public boolean litematicsProtocol = false; + public LitematicsConfig litematics = new LitematicsConfig(); - public static class LitematicsProtocolValidator extends BooleanConfigValidator { - @Override - public void verify(Boolean old, Boolean value) throws IllegalArgumentException { - PluginManager pluginManager = MinecraftServer.getServer().server.getPluginManager(); - if (value) { - if (pluginManager.getPermission("leaves.protocol.litematics") == null) { - pluginManager.addPermission(new Permission("leaves.protocol.litematics", PermissionDefault.OP)); + @GlobalConfigCategory("litematics") + public static class LitematicsConfig { + + @RemovedConfig(name = "litematics-protocol", category = {"protocol", "servux"}, transform = true) + @GlobalConfig(value = "enable", validator = LitematicsProtocolValidator.class) + public boolean enable = false; + + @GlobalConfig(value = "max-nbt-size", validator = MaxNbtSizeValidator.class) + public long maxNbtSize = 2097152; + + public static class MaxNbtSizeValidator extends LongConfigValidator { + + @Override + public void verify(Long old, Long value) throws IllegalArgumentException { + if (value <= 0) { + throw new IllegalArgumentException("Max nbt size can not be <= 0!"); + } + } + } + + public static class LitematicsProtocolValidator extends BooleanConfigValidator { + @Override + public void verify(Boolean old, Boolean value) throws IllegalArgumentException { + PluginManager pluginManager = MinecraftServer.getServer().server.getPluginManager(); + if (value) { + if (pluginManager.getPermission("leaves.protocol.litematics") == null) { + pluginManager.addPermission(new Permission("leaves.protocol.litematics", PermissionDefault.OP)); + } + } else { + pluginManager.removePermission("leaves.protocol.litematics"); } - } else { - pluginManager.removePermission("leaves.protocol.litematics"); } } } @@ -968,7 +1001,7 @@ public final class LeavesConfig { @Override public void verify(Boolean old, Boolean value) throws IllegalArgumentException { if (old != value && value != null) { - org.leavesmc.leaves.protocol.rei.REIServerProtocol.onConfigModify(value); + REIServerProtocol.onConfigModify(value); } } } @@ -999,7 +1032,7 @@ public final class LeavesConfig { @Override public void runAfterLoader(Boolean value, boolean reload) { if (!reload) { - org.leavesmc.leaves.util.LeavesUpdateHelper.init(); + LeavesUpdateHelper.init(); if (value) { LeavesLogger.LOGGER.warning("Auto-Update is not completely safe. Enabling it may cause data security problems!"); } @@ -1052,7 +1085,7 @@ public final class LeavesConfig { public static class ExtraYggdrasilUrlsValidator extends ListConfigValidator.STRING { @Override public void verify(List old, List value) throws IllegalArgumentException { - org.leavesmc.leaves.profile.LeavesMinecraftSessionService.initExtraYggdrasilList(value); + LeavesMinecraftSessionService.initExtraYggdrasilList(value); } } } @@ -1075,8 +1108,8 @@ public final class LeavesConfig { @Override public void verify(String old, String value) throws IllegalArgumentException { - if (!org.leavesmc.leaves.util.ServerI18nUtil.finishPreload || - !org.leavesmc.leaves.util.ServerI18nUtil.tryAppendLanguages(supportLang)) { + if (!ServerI18nUtil.finishPreload || + !ServerI18nUtil.tryAppendLanguages(supportLang)) { return; } if (!supportLang.contains(value)) { @@ -1109,12 +1142,12 @@ public final class LeavesConfig { public static class RegionConfig { @GlobalConfig(value = "format", lock = true, validator = RegionFormatValidator.class) - public org.leavesmc.leaves.region.RegionFileFormat format = org.leavesmc.leaves.region.RegionFileFormat.ANVIL; + public RegionFileFormat format = RegionFileFormat.ANVIL; - private static class RegionFormatValidator extends EnumConfigValidator { + private static class RegionFormatValidator extends EnumConfigValidator { @Override public void verify(RegionFileFormat old, RegionFileFormat value) throws IllegalArgumentException { - org.leavesmc.leaves.region.IRegionFileFactory.initFirstRegion(value); + IRegionFileFactory.initFirstRegion(value); } } @@ -1124,7 +1157,7 @@ public final class LeavesConfig { public static class LinearConfig { @GlobalConfig(value = "version", lock = true) - public org.leavesmc.leaves.region.linear.LinearVersion version = org.leavesmc.leaves.region.linear.LinearVersion.V2; + public LinearVersion version = LinearVersion.V2; @GlobalConfig(value = "flush-max-threads", lock = true) public int flushThreads = 6; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/config/AutoConfigValidator.java b/leaves-server/src/main/java/org/leavesmc/leaves/config/AutoConfigValidator.java index 1c4d4a7c..2f2ab3eb 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/config/AutoConfigValidator.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/config/AutoConfigValidator.java @@ -21,6 +21,9 @@ public final class AutoConfigValidator implements ConfigValidator { BASE_VALIDATOR.put(Integer.class, ConfigValidatorImpl.IntConfigValidator::new); BASE_VALIDATOR.put(int.class, ConfigValidatorImpl.IntConfigValidator::new); + BASE_VALIDATOR.put(Long.class, ConfigValidatorImpl.LongConfigValidator::new); + BASE_VALIDATOR.put(long.class, ConfigValidatorImpl.LongConfigValidator::new); + BASE_VALIDATOR.put(Double.class, ConfigValidatorImpl.DoubleConfigValidator::new); BASE_VALIDATOR.put(double.class, ConfigValidatorImpl.DoubleConfigValidator::new); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/config/ConfigValidatorImpl.java b/leaves-server/src/main/java/org/leavesmc/leaves/config/ConfigValidatorImpl.java index 16ed55ce..99860f29 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/config/ConfigValidatorImpl.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/config/ConfigValidatorImpl.java @@ -31,6 +31,13 @@ public abstract class ConfigValidatorImpl implements ConfigValidator { } } + public static class LongConfigValidator extends ConfigValidatorImpl { + @Override + public Long stringConvert(String value) throws IllegalArgumentException { + return Long.parseLong(value); + } + } + public static class StringConfigValidator extends ConfigValidatorImpl { @Override public String stringConvert(String value) throws IllegalArgumentException { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/AbstractInvokerHolder.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/AbstractInvokerHolder.java index 1e974b1b..906b7264 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/AbstractInvokerHolder.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/AbstractInvokerHolder.java @@ -4,6 +4,7 @@ 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; @@ -65,6 +66,8 @@ public abstract class AbstractInvokerHolder { } else { return invoker.invoke(owner, args); } + } catch (InvocationTargetException e) { + throw new RuntimeException(e.getCause()); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java index 5e82ea37..2e651864 100755 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java @@ -6,6 +6,8 @@ import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtAccounter; +import net.minecraft.nbt.Tag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; @@ -118,12 +120,12 @@ public class ServuxLitematicsProtocol implements LeavesProtocol { } playerSession.remove(uuid); fullPacket.readVarInt(); - CompoundTag compoundTag = fullPacket.readNbt(); - if (compoundTag == null) { + Tag tag = FriendlyByteBuf.readNbt(fullPacket, new NbtAccounter(LeavesConfig.protocol.servux.litematics.maxNbtSize, 512)); + if (!(tag instanceof CompoundTag)) { ServuxProtocol.LOGGER.error("cannot read nbt tag from packet"); return; } - handleClientPasteRequest(player, compoundTag); + handleClientPasteRequest(player, (CompoundTag) tag); } } } @@ -258,7 +260,7 @@ public class ServuxLitematicsProtocol implements LeavesProtocol { @Override public boolean isActive() { - return LeavesConfig.protocol.servux.litematicsProtocol; + return LeavesConfig.protocol.servux.litematics.enable; } public enum ServuxLitematicaPayloadType { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java index 5fa79445..ee52318f 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java @@ -1,17 +1,12 @@ package org.leavesmc.leaves.util; -import net.minecraft.core.MappedRegistry; import net.minecraft.core.component.DataComponents; -import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.MinecraftServer; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.component.ItemContainerContents; -import net.minecraft.world.item.enchantment.Enchantment; -import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.item.enchantment.ItemEnchantments; import net.minecraft.world.level.block.ShulkerBoxBlock; import org.jetbrains.annotations.NotNull; @@ -113,6 +108,17 @@ public class ItemOverstackUtils { } private static class ShulkerBox implements ItemUtil { + public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) { + if (LeavesConfig.modify.shulkerBox.sameNbtStackable) { + return Objects.equals(stack1.getComponents(), stack2.getComponents()); + } + return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents()); + } + + public static boolean shulkerBoxNoItem(@NotNull ItemStack stack) { + return stack.getComponents().getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).stream().findAny().isEmpty(); + } + @Override public boolean isEnabled() { return LeavesConfig.modify.shulkerBox.shulkerBoxStackSize > 1; @@ -159,21 +165,17 @@ public class ItemOverstackUtils { } return -1; } - - public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) { - if (LeavesConfig.modify.shulkerBox.sameNbtStackable) { - return Objects.equals(stack1.getComponents(), stack2.getComponents()); - } - return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents()); - } - - public static boolean shulkerBoxNoItem(@NotNull ItemStack stack) { - return stack.getComponents().getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).stream().findAny().isEmpty(); - } } public static class CurseEnchantedBook implements ItemUtil { - private static final MappedRegistry registry = (MappedRegistry) MinecraftServer.getServer().registryAccess().lookup(Registries.ENCHANTMENT).orElseThrow(); + public static boolean isCursedEnchantedBook(ItemStack stack) { + ItemEnchantments enchantments = stack.getOrDefault(DataComponents.STORED_ENCHANTMENTS, ItemEnchantments.EMPTY); + if (enchantments.size() != 1) { + return false; + } + return stack.getBukkitStack().getEnchantmentLevel(org.bukkit.enchantments.Enchantment.BINDING_CURSE) == 1 || + stack.getBukkitStack().getEnchantmentLevel(org.bukkit.enchantments.Enchantment.BINDING_CURSE) == 1; + } @Override public boolean isEnabled() { @@ -197,14 +199,5 @@ public class ItemOverstackUtils { } return -1; } - - public static boolean isCursedEnchantedBook(ItemStack stack) { - ItemEnchantments enchantments = stack.getOrDefault(DataComponents.STORED_ENCHANTMENTS, ItemEnchantments.EMPTY); - if (enchantments.size() != 1) { - return false; - } - return enchantments.getLevel(registry.getOrThrow(Enchantments.BINDING_CURSE)) == 1 || - enchantments.getLevel(registry.getOrThrow(Enchantments.VANISHING_CURSE)) == 1; - } } } \ No newline at end of file