From bb95be9955c2512c9ce51d0c5c9edeb7e8d759c1 Mon Sep 17 00:00:00 2001 From: Encode42 Date: Sat, 11 Jan 2025 18:07:22 -0800 Subject: [PATCH] Config to allow unsafe enchants --- ...0145-Config-to-allow-unsafe-enchants.patch | 137 ------------------ .../server/commands/EnchantCommand.java.patch | 20 +++ .../world/inventory/AnvilMenu.java.patch | 44 +++++- .../minecraft/world/item/ItemStack.java.patch | 13 ++ .../org/purpurmc/purpur/PurpurConfig.java | 30 ++++ 5 files changed, 102 insertions(+), 142 deletions(-) delete mode 100644 patches/server/0145-Config-to-allow-unsafe-enchants.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/server/commands/EnchantCommand.java.patch diff --git a/patches/server/0145-Config-to-allow-unsafe-enchants.patch b/patches/server/0145-Config-to-allow-unsafe-enchants.patch deleted file mode 100644 index 881c0b7e6..000000000 --- a/patches/server/0145-Config-to-allow-unsafe-enchants.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Encode42 -Date: Wed, 24 Mar 2021 17:59:54 -0400 -Subject: [PATCH] Config to allow unsafe enchants - - -diff --git a/net/minecraft/server/commands/EnchantCommand.java b/net/minecraft/server/commands/EnchantCommand.java -index cf0a5943f457c532958f40b4989fa18f967abae6..2ab8ff8ca51eb841932ccca4a348acc0141264a8 100644 ---- a/net/minecraft/server/commands/EnchantCommand.java -+++ b/net/minecraft/server/commands/EnchantCommand.java -@@ -70,7 +70,7 @@ public class EnchantCommand { - - private static int enchant(CommandSourceStack source, Collection targets, Holder enchantment, int level) throws CommandSyntaxException { - Enchantment enchantment2 = enchantment.value(); -- if (level > enchantment2.getMaxLevel()) { -+ if (!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && level > enchantment2.getMaxLevel()) { // Purpur - Config to allow unsafe enchants - throw ERROR_LEVEL_TOO_HIGH.create(level, enchantment2.getMaxLevel()); - } else { - int i = 0; -@@ -81,7 +81,7 @@ public class EnchantCommand { - ItemStack itemStack = livingEntity.getMainHandItem(); - if (!itemStack.isEmpty()) { - if (enchantment2.canEnchant(itemStack) -- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment)) { -+ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !itemStack.hasEnchantment(enchantment))) { // Purpur - Config to allow unsafe enchants - itemStack.enchant(enchantment, level); - i++; - } else if (targets.size() == 1) { -diff --git a/net/minecraft/world/inventory/AnvilMenu.java b/net/minecraft/world/inventory/AnvilMenu.java -index a7c3338ed6edcd26fce869ec66fdcaa4c32c0e4f..346681cf9c3c9ff5274f63236b0cc7c4eec76492 100644 ---- a/net/minecraft/world/inventory/AnvilMenu.java -+++ b/net/minecraft/world/inventory/AnvilMenu.java -@@ -234,7 +234,10 @@ public class AnvilMenu extends ItemCombinerMenu { - - i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1); - Enchantment enchantment = (Enchantment) holder.value(); -- boolean flag3 = enchantment.canEnchant(itemstack); -+ // Purpur start - Config to allow unsafe enchants -+ boolean flag3 = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || enchantment.canEnchant(itemstack); // whether the enchantment can be applied on specific item type -+ boolean flag4 = true; // whether two incompatible enchantments can be applied on a single item -+ // Purpur end - Config to allow unsafe enchants - - if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) { - flag3 = true; -@@ -246,16 +249,22 @@ public class AnvilMenu extends ItemCombinerMenu { - Holder holder1 = (Holder) iterator1.next(); - - if (!holder1.equals(holder) && !Enchantment.areCompatible(holder, holder1)) { -- flag3 = this.canDoUnsafeEnchants; // Purpur - Anvil API -+ flag4 = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants; // Purpur - Anvil API // Purpur - flag3 -> flag4 - Config to allow unsafe enchants -+ // Purpur start - Config to allow unsafe enchants -+ if (!flag4 && org.purpurmc.purpur.PurpurConfig.replaceIncompatibleEnchants) { -+ iterator1.remove(); // replace current enchant with the incompatible one trying to be applied -+ flag4 = true; -+ } -+ // Purpur end - Config to allow unsafe enchants - ++i; - } - } - -- if (!flag3) { -+ if (!flag3 || !flag4) { // Purpur - Config to allow unsafe enchants - flag2 = true; - } else { - flag1 = true; -- if (i2 > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions -+ if (!org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels && i2 > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions // Purpur - Config to allow unsafe enchants - i2 = enchantment.getMaxLevel(); - } - -@@ -384,7 +393,7 @@ public class AnvilMenu extends ItemCombinerMenu { - this.broadcastChanges(); - - // Purpur start - Anvil API -- if (this.canDoUnsafeEnchants && itemstack1 != ItemStack.EMPTY) { -+ if ((this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants) && itemstack1 != ItemStack.EMPTY) { // Purpur - Config to allow unsafe enchants - ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetSlotPacket(this.containerId, this.incrementStateId(), 2, itemstack1)); - ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetDataPacket(this.containerId, 0, this.cost.get())); - } -diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java -index c616ebbf0f709b8c3a500a23a2190f7023f7757d..aac771d7d8aefc6d5fcb497763ab9bac1ce2dc31 100644 ---- a/net/minecraft/world/item/ItemStack.java -+++ b/net/minecraft/world/item/ItemStack.java -@@ -1369,6 +1369,12 @@ public final class ItemStack implements DataComponentHolder { - return !((ItemEnchantments) this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY)).isEmpty(); - } - -+ // Purpur start - Config to allow unsafe enchants -+ public boolean hasEnchantment(Holder enchantment) { -+ return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).getLevel(enchantment) > 0; -+ } -+ // Purpur end - Config to allow unsafe enchants -+ - public ItemEnchantments getEnchantments() { - return (ItemEnchantments) this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); - } -diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -index 693b9f04a35f055ea21a1b6be5ac27a04f1d80ad..eb9e18e2b71559ed945c40d489618ac3bf976e35 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -286,6 +286,36 @@ public class PurpurConfig { - cryingObsidianValidForPortalFrame = getBoolean("settings.blocks.crying_obsidian.valid-for-portal-frame", cryingObsidianValidForPortalFrame); - } - -+ public static boolean allowInapplicableEnchants = false; -+ public static boolean allowIncompatibleEnchants = false; -+ public static boolean allowHigherEnchantsLevels = false; -+ public static boolean allowUnsafeEnchantCommand = false; -+ public static boolean replaceIncompatibleEnchants = false; -+ private static void enchantmentSettings() { -+ if (version < 30) { -+ boolean oldValue = getBoolean("settings.enchantment.allow-unsafe-enchants", false); -+ set("settings.enchantment.anvil.allow-unsafe-enchants", oldValue); -+ set("settings.enchantment.anvil.allow-inapplicable-enchants", true); -+ set("settings.enchantment.anvil.allow-incompatible-enchants", true); -+ set("settings.enchantment.anvil.allow-higher-enchants-levels", true); -+ set("settings.enchantment.allow-unsafe-enchants", null); -+ } -+ if (version < 37) { -+ boolean allowUnsafeEnchants = getBoolean("settings.enchantment.anvil.allow-unsafe-enchants", false); -+ if (!allowUnsafeEnchants) { -+ set("settings.enchantment.anvil.allow-inapplicable-enchants", false); -+ set("settings.enchantment.anvil.allow-incompatible-enchants", false); -+ set("settings.enchantment.anvil.allow-higher-enchants-levels", false); -+ } -+ set("settings.enchantment.anvil.allow-unsafe-enchants", null); -+ } -+ allowInapplicableEnchants = getBoolean("settings.enchantment.anvil.allow-inapplicable-enchants", allowInapplicableEnchants); -+ allowIncompatibleEnchants = getBoolean("settings.enchantment.anvil.allow-incompatible-enchants", allowIncompatibleEnchants); -+ allowHigherEnchantsLevels = getBoolean("settings.enchantment.anvil.allow-higher-enchants-levels", allowHigherEnchantsLevels); -+ allowUnsafeEnchantCommand = getBoolean("settings.enchantment.allow-unsafe-enchant-command", allowUnsafeEnchantCommand); -+ replaceIncompatibleEnchants = getBoolean("settings.enchantment.anvil.replace-incompatible-enchants", replaceIncompatibleEnchants); -+ } -+ - public static boolean endermanShortHeight = false; - private static void entitySettings() { - endermanShortHeight = getBoolean("settings.entity.enderman.short-height", endermanShortHeight); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/EnchantCommand.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/EnchantCommand.java.patch new file mode 100644 index 000000000..74bd1f710 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/EnchantCommand.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/server/commands/EnchantCommand.java ++++ b/net/minecraft/server/commands/EnchantCommand.java +@@ -70,7 +_,7 @@ + + private static int enchant(CommandSourceStack source, Collection targets, Holder enchantment, int level) throws CommandSyntaxException { + Enchantment enchantment1 = enchantment.value(); +- if (level > enchantment1.getMaxLevel()) { ++ if (!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && level > enchantment1.getMaxLevel()) { // Purpur - Config to allow unsafe enchants + throw ERROR_LEVEL_TOO_HIGH.create(level, enchantment1.getMaxLevel()); + } else { + int i = 0; +@@ -81,7 +_,7 @@ + ItemStack mainHandItem = livingEntity.getMainHandItem(); + if (!mainHandItem.isEmpty()) { + if (enchantment1.canEnchant(mainHandItem) +- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(mainHandItem).keySet(), enchantment)) { ++ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(mainHandItem).keySet(), enchantment) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !mainHandItem.hasEnchantment(enchantment))) { // Purpur - Config to allow unsafe enchants + mainHandItem.enchant(enchantment, level); + i++; + } else if (targets.size() == 1) { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch index d3c84fc61..fd44c47d0 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch @@ -64,15 +64,49 @@ ItemStack itemStack = item.copy(); ItemStack item1 = this.inputSlots.getItem(1); ItemEnchantments.Mutable mutable = new ItemEnchantments.Mutable(EnchantmentHelper.getEnchantmentsForCrafting(itemStack)); -@@ -198,7 +_,7 @@ +@@ -191,23 +_,36 @@ + int intValue = entry.getIntValue(); + intValue = level == intValue ? intValue + 1 : Math.max(intValue, level); + Enchantment enchantment = holder.value(); +- boolean canEnchant = enchantment.canEnchant(item); ++ // Purpur start - Config to allow unsafe enchants ++ boolean canEnchant = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || enchantment.canEnchant(item); // whether the enchantment can be applied on specific item type ++ boolean canEnchant1 = true; // whether two incompatible enchantments can be applied on a single item ++ // Purpur end - Config to allow unsafe enchants + if (this.player.getAbilities().instabuild || item.is(Items.ENCHANTED_BOOK)) { + canEnchant = true; + } - for (Holder holder1 : mutable.keySet()) { +- for (Holder holder1 : mutable.keySet()) { ++ // Purpur start - Config to allow unsafe enchants ++ java.util.Iterator> mutableIterator = mutable.keySet().iterator(); ++ while (mutableIterator.hasNext()) { ++ Holder holder1 = mutableIterator.next(); ++ // Purpur end - Config to allow unsafe enchants if (!holder1.equals(holder) && !Enchantment.areCompatible(holder, holder1)) { - canEnchant = false; -+ canEnchant = this.canDoUnsafeEnchants; // Purpur - Anvil API - i++; +- i++; ++ canEnchant1 = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants; // Purpur - Anvil API // Purpur - flag3 -> canEnchant1 - Config to allow unsafe enchants ++ // Purpur start - Config to allow unsafe enchants ++ if (!canEnchant1 && org.purpurmc.purpur.PurpurConfig.replaceIncompatibleEnchants) { ++ mutableIterator.remove(); // replace current enchant with the incompatible one trying to be applied // TODO: is this needed? ++ canEnchant1 = true; ++ } ++ // Purpur end - Config to allow unsafe enchants ++ ++i; } } + +- if (!canEnchant) { ++ if (!canEnchant || !canEnchant1) { // Purpur - Config to allow unsafe enchants + flag1 = true; + } else { + flag = true; +- if (intValue > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions ++ if (!org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels && intValue > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions // Purpur - Config to allow unsafe enchants + intValue = enchantment.getMaxLevel(); + } + @@ -236,6 +_,54 @@ if (!this.itemName.equals(item.getHoverName().getString())) { i1 = 1; @@ -147,7 +181,7 @@ this.broadcastChanges(); + + // Purpur start - Anvil API -+ if (this.canDoUnsafeEnchants && itemStack != ItemStack.EMPTY) { ++ if ((this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants) && itemStack != ItemStack.EMPTY) { // Purpur - Config to allow unsafe enchants + ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetSlotPacket(this.containerId, this.incrementStateId(), 2, itemStack)); + ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetDataPacket(this.containerId, 0, this.cost.get())); + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/item/ItemStack.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/item/ItemStack.java.patch index 65294be60..00a2e4a0a 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/item/ItemStack.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/item/ItemStack.java.patch @@ -27,3 +27,16 @@ public int getDamageValue() { return Mth.clamp(this.getOrDefault(DataComponents.DAMAGE, Integer.valueOf(0)), 0, this.getMaxDamage()); } +@@ -1232,6 +_,12 @@ + public boolean isEnchanted() { + return !this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty(); + } ++ ++ // Purpur start - Config to allow unsafe enchants ++ public boolean hasEnchantment(Holder enchantment) { ++ return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).getLevel(enchantment) > 0; ++ } ++ // Purpur end - Config to allow unsafe enchants + + public ItemEnchantments getEnchantments() { + return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java index 3b0875ed8..8733172b5 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -271,6 +271,36 @@ public class PurpurConfig { cryingObsidianValidForPortalFrame = getBoolean("settings.blocks.crying_obsidian.valid-for-portal-frame", cryingObsidianValidForPortalFrame); } + public static boolean allowInapplicableEnchants = false; + public static boolean allowIncompatibleEnchants = false; + public static boolean allowHigherEnchantsLevels = false; + public static boolean allowUnsafeEnchantCommand = false; + public static boolean replaceIncompatibleEnchants = false; + private static void enchantmentSettings() { + if (version < 30) { + boolean oldValue = getBoolean("settings.enchantment.allow-unsafe-enchants", false); + set("settings.enchantment.anvil.allow-unsafe-enchants", oldValue); + set("settings.enchantment.anvil.allow-inapplicable-enchants", true); + set("settings.enchantment.anvil.allow-incompatible-enchants", true); + set("settings.enchantment.anvil.allow-higher-enchants-levels", true); + set("settings.enchantment.allow-unsafe-enchants", null); + } + if (version < 37) { + boolean allowUnsafeEnchants = getBoolean("settings.enchantment.anvil.allow-unsafe-enchants", false); + if (!allowUnsafeEnchants) { + set("settings.enchantment.anvil.allow-inapplicable-enchants", false); + set("settings.enchantment.anvil.allow-incompatible-enchants", false); + set("settings.enchantment.anvil.allow-higher-enchants-levels", false); + } + set("settings.enchantment.anvil.allow-unsafe-enchants", null); + } + allowInapplicableEnchants = getBoolean("settings.enchantment.anvil.allow-inapplicable-enchants", allowInapplicableEnchants); + allowIncompatibleEnchants = getBoolean("settings.enchantment.anvil.allow-incompatible-enchants", allowIncompatibleEnchants); + allowHigherEnchantsLevels = getBoolean("settings.enchantment.anvil.allow-higher-enchants-levels", allowHigherEnchantsLevels); + allowUnsafeEnchantCommand = getBoolean("settings.enchantment.allow-unsafe-enchant-command", allowUnsafeEnchantCommand); + replaceIncompatibleEnchants = getBoolean("settings.enchantment.anvil.replace-incompatible-enchants", replaceIncompatibleEnchants); + } + public static boolean endermanShortHeight = false; private static void entitySettings() { endermanShortHeight = getBoolean("settings.entity.enderman.short-height", endermanShortHeight);