From 0aad19166f61d59fc0562a0594762b58a6a228e8 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Mon, 1 Dec 2025 18:58:40 +0100 Subject: [PATCH 01/14] prepare 1.21.11 nms --- build.gradle.kts | 1 + nms/v1_21R7/.gitignore | 1 + nms/v1_21R7/build.gradle.kts | 34 +++++++++++++++++++ .../gui/version/v1_21R7_ExternGuiTester.kt | 34 +++++++++++++++++++ .../packet/versions/V1_21R7_PacketManager.kt | 33 ++++++++++++++++++ settings.gradle.kts | 2 ++ .../dependency/gui/GuiTesterSelector.kt | 1 + .../packet/PacketManagerSelector.kt | 1 + 8 files changed, 107 insertions(+) create mode 100644 nms/v1_21R7/.gitignore create mode 100644 nms/v1_21R7/build.gradle.kts create mode 100644 nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R7_ExternGuiTester.kt create mode 100644 nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R7_PacketManager.kt diff --git a/build.gradle.kts b/build.gradle.kts index 8ae931c..57b8b93 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -89,6 +89,7 @@ dependencies { implementation(project(":nms:v1_21R4", configuration = "reobf")) implementation(project(":nms:v1_21R5", configuration = "reobf")) implementation(project(":nms:v1_21R6", configuration = "reobf")) + implementation(project(":nms:v1_21R7"))// TODO reobf on release, configuration = "reobf")) // include kotlin for the offline jar implementation(kotlin("stdlib")) diff --git a/nms/v1_21R7/.gitignore b/nms/v1_21R7/.gitignore new file mode 100644 index 0000000..47374f1 --- /dev/null +++ b/nms/v1_21R7/.gitignore @@ -0,0 +1 @@ +.lastDeploymentsId \ No newline at end of file diff --git a/nms/v1_21R7/build.gradle.kts b/nms/v1_21R7/build.gradle.kts new file mode 100644 index 0000000..9c8a6f3 --- /dev/null +++ b/nms/v1_21R7/build.gradle.kts @@ -0,0 +1,34 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +group = rootProject.group +version = rootProject.version + +plugins { + id("io.papermc.paperweight.userdev") +} + +dependencies { + implementation(project(":nms:nms-common")) + + // Used for nms + paperweight.paperDevBundle("1.21.11-pre3-R0.1-SNAPSHOT") //TODO update to 1.21.11-R0.1-SNAPSHOT on release +} + +repositories { + maven("https://repo.papermc.io/repository/maven-public/") +} + +// Set target version +tasks.withType().configureEach { + sourceCompatibility = "21" + targetCompatibility = "21" + + options.encoding = "UTF-8" +} + +kotlin { + compilerOptions { + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) + jvmTarget.set(JvmTarget.JVM_21) + } +} diff --git a/nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R7_ExternGuiTester.kt b/nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R7_ExternGuiTester.kt new file mode 100644 index 0000000..c380211 --- /dev/null +++ b/nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R7_ExternGuiTester.kt @@ -0,0 +1,34 @@ +package xyz.alexcrea.cuanvil.dependency.gui.version + +import org.bukkit.craftbukkit.inventory.CraftInventoryView +import org.bukkit.inventory.InventoryView +import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester + +class v1_21R7_ExternGuiTester: ExternGuiTester { + override val wesjdAnvilGuiName = "Wrapper1_21_R7" + + var tested = false; + var possible = false; + + override fun getContainerClass(view: InventoryView): Class? { + // In case we are in a test environment + if(!tested) testClassExist() + if(!possible) return null + + if(view !is CraftInventoryView<*, *>) return null + val container = view.handle + + return container.javaClass + } + + fun testClassExist(){ + tested = true; + try { + Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView") + possible = true + } catch (e: ClassNotFoundException){ + possible = false + } + } + +} \ No newline at end of file diff --git a/nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R7_PacketManager.kt b/nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R7_PacketManager.kt new file mode 100644 index 0000000..59ae9ce --- /dev/null +++ b/nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R7_PacketManager.kt @@ -0,0 +1,33 @@ +package xyz.alexcrea.cuanvil.dependency.packet.versions + +import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket +import net.minecraft.world.entity.player.Abilities +import org.bukkit.craftbukkit.entity.CraftPlayer +import org.bukkit.entity.Player +import xyz.alexcrea.cuanvil.dependency.packet.PacketManager +import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase + +class V1_21R7_PacketManager : PacketManagerBase(), PacketManager { + override val canSetInstantBuild: Boolean + get() = true + + override fun setInstantBuild(player: Player, instantBuild: Boolean) { + val nmsPlayer = (player as CraftPlayer).handle + val playerAbilities = nmsPlayer.abilities + val sendedAbilities: Abilities + if (playerAbilities.instabuild == instantBuild) { + sendedAbilities = playerAbilities + } else { + sendedAbilities = Abilities() + sendedAbilities.invulnerable = playerAbilities.invulnerable + sendedAbilities.flying = playerAbilities.flying + sendedAbilities.mayfly = playerAbilities.mayfly + sendedAbilities.instabuild = instantBuild + sendedAbilities.mayBuild = playerAbilities.mayBuild + sendedAbilities.flyingSpeed = playerAbilities.flyingSpeed + sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed + } + val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities) + nmsPlayer.connection.send(packet) + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 1d401da..0790502 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -35,6 +35,8 @@ include("nms:v1_21R5") findProject(":nms:v1_21R5")?.name = "v1_21R5" include("nms:v1_21R6") findProject(":nms:v1_21R6")?.name = "v1_21R6" +include("nms:v1_21R7") +findProject(":nms:v1_21R7")?.name = "v1_21R7" include(":impl:LegacyEcoEnchant") findProject(":impl:LegacyEcoEnchant")?.name = "LegacyEcoEnchant" diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GuiTesterSelector.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GuiTesterSelector.kt index f3d2122..aa2ab95 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GuiTesterSelector.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GuiTesterSelector.kt @@ -46,6 +46,7 @@ object GuiTesterSelector { 5 -> v1_21R4_ExternGuiTester() 6, 7, 8 -> v1_21R5_ExternGuiTester() 9, 10 -> v1_21R6_ExternGuiTester() + 11 -> v1_21R7_ExternGuiTester() else -> null } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/PacketManagerSelector.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/PacketManagerSelector.kt index 985b3f5..ccb8620 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/PacketManagerSelector.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/PacketManagerSelector.kt @@ -60,6 +60,7 @@ object PacketManagerSelector { 5 -> V1_21R4_PacketManager() 6, 7, 8 -> V1_21R5_PacketManager() 9, 10 -> V1_21R6_PacketManager() + 11 -> V1_21R7_PacketManager() else -> null } From eb24fb4be8bf61b2156e498c822e2200dd7348b0 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Mon, 1 Dec 2025 19:16:14 +0100 Subject: [PATCH 02/14] fix copper unit repair not being present --- .../cuanvil/update/UpdateHandler.java | 3 ++- .../update/minecraft/Update_1_21_11.java | 5 ++++ .../update/minecraft/Update_1_21_9.java | 21 ++++++++++++++- .../cuanvil/update/plugin/PUpdate_1_15_6.java | 27 +++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_15_6.java diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java b/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java index 34f385c..a563b7f 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java @@ -31,7 +31,8 @@ public class UpdateHandler { new Version(1, 6, 7), PUpdate_1_6_7::handleUpdate, new Version(1, 8, 0), PUpdate_1_8_0::handleUpdate, new Version(1, 11, 0), PUpdate_1_11_0::handleUpdate, - new Version(1, 15, 5), PUpdate_1_15_5::handleUpdate + new Version(1, 15, 5), PUpdate_1_15_5::handleUpdate, + new Version(1, 15, 6), PUpdate_1_15_6::handleUpdate ); private static final List mcUpdateMap = List.of( diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_11.java b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_11.java index a060394..90c17bf 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_11.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_11.java @@ -17,6 +17,7 @@ public class Update_1_21_11 extends MCUpdate{ var baseConfig = ConfigHolder.DEFAULT_CONFIG.getConfig(); var groupConfig = ConfigHolder.ITEM_GROUP_HOLDER.getConfig(); var conflictConfig = ConfigHolder.CONFLICT_HOLDER.getConfig(); + var unitConfig = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); // Create spear group groupConfig.set("spears.type", "include"); @@ -36,6 +37,9 @@ public class Update_1_21_11 extends MCUpdate{ addAbsentToList(conflictConfig, "restriction_knockback.notAffectedGroups", "spears"); addAbsentToList(conflictConfig, "restriction_fire_aspect.notAffectedGroups", "spears"); + // Unit repair for spears + + // Create lunge enchant value and group baseConfig.set("enchant_limits.minecraft:lunge", 3); baseConfig.set("enchant_values.minecraft:lunge.item", 2); @@ -51,6 +55,7 @@ public class Update_1_21_11 extends MCUpdate{ ConfigHolder.DEFAULT_CONFIG.saveToDisk(true); ConfigHolder.ITEM_GROUP_HOLDER.saveToDisk(true); ConfigHolder.CONFLICT_HOLDER.saveToDisk(true); + ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(true); // imply reload of CONFLICT_HOLDER // We also do not need to reload base config as there is no object related to it. diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_9.java b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_9.java index a4e21a7..d289b9b 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_9.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_9.java @@ -1,6 +1,6 @@ package xyz.alexcrea.cuanvil.update.minecraft; -import io.delilaheve.CustomAnvil; +import org.bukkit.configuration.file.FileConfiguration; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.update.UpdateUtils; import xyz.alexcrea.cuanvil.update.Version; @@ -17,6 +17,7 @@ public class Update_1_21_9 extends MCUpdate{ protected void doUpdate() { var baseConfig = ConfigHolder.DEFAULT_CONFIG.getConfig(); var groupConfig = ConfigHolder.ITEM_GROUP_HOLDER.getConfig(); + var unitConfig = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); // Add cooper items to groups addAbsentToList(groupConfig, "helmets.items", "copper_helmet"); @@ -30,16 +31,34 @@ public class Update_1_21_9 extends MCUpdate{ addAbsentToList(groupConfig, "axes.items", "copper_axe"); addAbsentToList(groupConfig, "swords.items", "copper_sword"); + // Add unit repair + addCopperUnitRepair(unitConfig); + // Set version string as current baseConfig.set(UpdateUtils.MINECRAFT_VERSION_PATH, version.toString()); // Save ConfigHolder.DEFAULT_CONFIG.saveToDisk(true); ConfigHolder.ITEM_GROUP_HOLDER.saveToDisk(true); + ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(true); // imply reload of CONFLICT_HOLDER // We also do not need to reload base config as there is no object related to it. ConfigHolder.ITEM_GROUP_HOLDER.reload(); } + public static void addCopperUnitRepair(FileConfiguration unitConfig) { + // Add unit repair + unitConfig.set("copper_ingot.copper_helmet", 0.25); + unitConfig.set("copper_ingot.copper_chestplate", 0.25); + unitConfig.set("copper_ingot.copper_leggings", 0.25); + unitConfig.set("copper_ingot.copper_boots", 0.25); + + unitConfig.set("copper_ingot.copper_pickaxe", 0.25); + unitConfig.set("copper_ingot.copper_shovel", 0.25); + unitConfig.set("copper_ingot.copper_hoe", 0.25); + unitConfig.set("copper_ingot.copper_axe", 0.25); + unitConfig.set("copper_ingot.copper_sword", 0.25); + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_15_6.java b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_15_6.java new file mode 100644 index 0000000..fde7cfc --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_15_6.java @@ -0,0 +1,27 @@ +package xyz.alexcrea.cuanvil.update.plugin; + +import org.bukkit.configuration.file.FileConfiguration; +import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.update.UpdateUtils; +import xyz.alexcrea.cuanvil.update.Version; +import xyz.alexcrea.cuanvil.update.minecraft.Update_1_21_9; + +import javax.annotation.Nonnull; +import java.util.Set; + +public class PUpdate_1_15_6 { + + public static void handleUpdate(@Nonnull Set toSave) { + // fix only needed for 1.21.9 and above + Version current = UpdateUtils.currentMinecraftVersion(); + if (new Version(1, 21, 9).greaterThan(current)) return; + + FileConfiguration unitConfig = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); + + // Add unit repair + Update_1_21_9.addCopperUnitRepair(unitConfig); + + toSave.add(ConfigHolder.UNIT_REPAIR_HOLDER); + } + +} From 8582038c715c1db187b2728d4deff6877bd178cc Mon Sep 17 00:00:00 2001 From: alexcrea Date: Mon, 1 Dec 2025 19:19:50 +0100 Subject: [PATCH 03/14] add unit repair for spears --- .../update/minecraft/Update_1_21_11.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_11.java b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_11.java index 90c17bf..d639596 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_11.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21_11.java @@ -38,7 +38,26 @@ public class Update_1_21_11 extends MCUpdate{ addAbsentToList(conflictConfig, "restriction_fire_aspect.notAffectedGroups", "spears"); // Unit repair for spears + unitConfig.set("gold_ingot.golden_spear", 0.25); + unitConfig.set("copper_ingot.copper_spear", 0.25); + unitConfig.set("iron_ingot.iron_spear", 0.25); + unitConfig.set("diamond.diamond_spear", 0.25); + unitConfig.set("netherite_ingot.netherite_spear", 0.25); + unitConfig.set("cobblestone.stone_spear", 0.25); + unitConfig.set("cobbled_deepslate.stone_spear", 0.25); + + unitConfig.set("oak_planks.wooden_spear", 0.25); + unitConfig.set("spruce_planks.wooden_spear", 0.25); + unitConfig.set("birch_planks.wooden_spear", 0.25); + unitConfig.set("jungle_planks.wooden_spear", 0.25); + unitConfig.set("acacia_planks.wooden_spear", 0.25); + unitConfig.set("dark_oak_planks.wooden_spear", 0.25); + unitConfig.set("mangrove_planks.wooden_spear", 0.25); + unitConfig.set("cherry_planks.wooden_spear", 0.25); + unitConfig.set("bamboo_planks.wooden_spear", 0.25); + unitConfig.set("crimson_planks.wooden_spear", 0.25); + unitConfig.set("warped_planks.wooden_spear", 0.25); // Create lunge enchant value and group baseConfig.set("enchant_limits.minecraft:lunge", 3); From d096ee7f35854507cd2920f24a2458d62bce7f9d Mon Sep 17 00:00:00 2001 From: alexcrea Date: Mon, 1 Dec 2025 19:26:19 +0100 Subject: [PATCH 04/14] less vebose about minecraft config update --- .../java/xyz/alexcrea/cuanvil/update/UpdateHandler.java | 2 +- .../xyz/alexcrea/cuanvil/update/minecraft/MCUpdate.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java b/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java index a563b7f..82ee0f7 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java @@ -71,7 +71,7 @@ public class UpdateHandler { boolean hadUpdate = false; for (MCUpdate mcUpdate : mcUpdateMap) { - hadUpdate |= mcUpdate.handleUpdate(current); + hadUpdate |= mcUpdate.handleUpdate(current, hadUpdate); } if (hadUpdate) { diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/MCUpdate.java b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/MCUpdate.java index d9db0ea..40fc587 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/MCUpdate.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/MCUpdate.java @@ -13,7 +13,7 @@ public abstract class MCUpdate { this.version = version; } - public boolean handleUpdate(Version current){ + public boolean handleUpdate(Version current, boolean hadUpdate){ // Test if we are running in this update version or better if(version.greaterThan(current)) return false; @@ -25,7 +25,9 @@ public abstract class MCUpdate { if(this.version.lesserEqual(version)) return false; } - CustomAnvil.instance.getLogger().info("Updating config to support " + version +" ..."); + if(!hadUpdate){ + CustomAnvil.instance.getLogger().info("Updating config to support minecraft " + current +" ..."); + } doUpdate(); return true; } From 35fb136a40a8a6cf011d25f8295b57b2c05abaf9 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Mon, 1 Dec 2025 19:30:50 +0100 Subject: [PATCH 05/14] default config for 1.21.11 --- README.md | 4 +- defaultconfigs/1.21.11/README.md | 6 + defaultconfigs/1.21.11/config.yml | 427 ++++++++++++++++++++ defaultconfigs/1.21.11/custom_recipes.yml | 5 + defaultconfigs/1.21.11/enchant_conflict.yml | 398 ++++++++++++++++++ defaultconfigs/1.21.11/item_groups.yml | 247 +++++++++++ defaultconfigs/1.21.11/unit_repair_item.yml | 220 ++++++++++ defaultconfigs/README.md | 6 +- 8 files changed, 1308 insertions(+), 5 deletions(-) create mode 100644 defaultconfigs/1.21.11/README.md create mode 100644 defaultconfigs/1.21.11/config.yml create mode 100644 defaultconfigs/1.21.11/custom_recipes.yml create mode 100644 defaultconfigs/1.21.11/enchant_conflict.yml create mode 100644 defaultconfigs/1.21.11/item_groups.yml create mode 100644 defaultconfigs/1.21.11/unit_repair_item.yml diff --git a/README.md b/README.md index cc868c5..3f5a806 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,7 @@ For information about the API, please refer to [the Wiki](https://github.com/ale --- ### Default Plugin's Configurations -For 1.18 to 1.20.6 use the [1.18 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.18)\ -For 1.21 to 1.21.8 use the [1.21 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21)\ -From 1.21.9 use the [1.21.9 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21) +see [Here](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs) --- Custom anvil [use bstat](https://bstats.org/plugin/bukkit/Unsafe%20Enchants%20Plus/20923) for metric. You can [disable it](https://bstats.org/getting-started) if you like. diff --git a/defaultconfigs/1.21.11/README.md b/defaultconfigs/1.21.11/README.md new file mode 100644 index 0000000..a33a09b --- /dev/null +++ b/defaultconfigs/1.21.11/README.md @@ -0,0 +1,6 @@ +### Default Plugin's Configurations For 1.21.11 +- [config.yml](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11/config.yml) +- [enchant_conflict.yml](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11/enchant_conflict.yml) +- [item_groups.yml](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11/item_groups.yml) +- [unit_repair_item.yml](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11/unit_repair_item.yml) +- [custom_recipes.yml](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11/custom_recipes.yml) diff --git a/defaultconfigs/1.21.11/config.yml b/defaultconfigs/1.21.11/config.yml new file mode 100644 index 0000000..10fe8af --- /dev/null +++ b/defaultconfigs/1.21.11/config.yml @@ -0,0 +1,427 @@ +# +# It is recommended that you use /configanvil to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes ! +# + +# All anvil cost will be capped to limit_repair_value if enabled. +# +# In other words: +# For any anvil cost greater than limit_repair_value, Cost will be set to limit_repair_value. +limit_repair_cost: false + +# Max cost value the Anvil can get to. +# +# Valid values include 0 to 1000. +# Cost will be displayed as "Too Expensive": +# - If Cost is above 39 +# - And replace_too_expensive is disabled (false) +limit_repair_value: 39 + +# Whether the anvil's cost limit should be removed entirely. +# +# The anvil will still visually display "Too Expensive" if "replace_too_expensive" is disabled +# However, the action will be completable if xp requirement is meet. +remove_repair_limit: false + +# Whenever anvil cost is above 39 should display the true price and not "Too Expensive". +# +# However, when bypassing "Too Expensive", anvil price will be displayed as Green. +# If the action is not completable, the cost will still be displayed as "Too expensive". +# That mean you also need to change other settings like remove_repair_limit or limit_repair_cost. +# +# Require ProtocoLib. +replace_too_expensive: false + +# XP Level amount added to the anvil when the item is repaired by another item of the same type +# +# Valid values include 0 to 1000 +item_repair_cost: 2 + +# XP Level amount added to the anvil when the item is renamed +# +# Valid values include 0 to 1000 +item_rename_cost: 1 + +# XP Level amount added to the anvil when the item is repaired by an "unit" +# For example: a Diamond on a Diamond Sword +# What's considered unit for what can be edited on the unit repair configuration. +# +# Valid values include 0 to 1000 +unit_repair_cost: 1 + +# XP Level amount added to the anvil when a sacrifice enchantment +# conflict with one of the left item enchantment +# +# Valid values include 0 to 1000 +sacrifice_illegal_enchant_cost: 1 + +# Allow using color code and hexadecimal color. +# +# Color code are prefixed by "&" and hexadecimal color by "#". +# Color code will not be applied if it colors nothing. "&&" can be used to write "&". +# For minimessage search for minimessage formating https://docs.papermc.io/adventure/minimessage/format/ +# Note that only color and decoration tags are allowed for minimisage in the v1 version of this plugin +# but any global tag will be allowed later when v2 release +allow_color_code: false +allow_hexadecimal_color: false +allow_minimessage: false + +# Toggle if color should only be applicable if the player a certain permission. +# +# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color. +permission_needed_for_color: true + +# Xp cost if the player use color in the items name on rename. +# +# Valid values include 0 to 1000. +use_of_color_cost: 0 + +# Default limit to apply to any enchants missing from enchant_limits +# +# Valid values include 1 to 1000 +default_limit: 5 + +# Override limits for specific enchants +# +# Enchantments not listed here will use the value of default_limit +# +# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels +# +# Valid range of 1 - 255 for each enchantment +enchant_limits: + minecraft:aqua_affinity: 1 + minecraft:binding_curse: 1 + minecraft:channeling: 1 + minecraft:flame: 1 + minecraft:infinity: 1 + minecraft:mending: 1 + minecraft:multishot: 1 + minecraft:silk_touch: 1 + minecraft:vanishing_curse: 1 + minecraft:depth_strider: 3 # anything more than 3 is treated as 3 by the game + minecraft:protection: 4 + minecraft:fire_protection: 4 + minecraft:blast_protection: 4 + minecraft:projectile_protection: 4 + minecraft:feather_falling: 4 + minecraft:thorns: 3 + minecraft:respiration: 3 + minecraft:sharpness: 5 + minecraft:smite: 5 + minecraft:bane_of_arthropods: 5 + minecraft:knockback: 2 + minecraft:fire_aspect: 2 + minecraft:looting: 3 + minecraft:sweeping: 3 + minecraft:sweeping_edge: 3 + minecraft:efficiency: 5 + minecraft:unbreaking: 3 + minecraft:fortune: 3 + minecraft:power: 5 + minecraft:punch: 2 + minecraft:luck_of_the_sea: 3 + minecraft:lure: 3 + minecraft:frost_walker: 2 + minecraft:impaling: 5 + minecraft:riptide: 3 + minecraft:loyalty: 3 + minecraft:piercing: 4 + minecraft:quick_charge: 3 + minecraft:soul_speed: 3 + minecraft:swift_sneak: 3 + minecraft:density: 5 + minecraft:breach: 4 + minecraft:wind_burst: 3 + minecraft:lunge: 3 + +# Multipliers used to calculate the enchantment's value in repair/combining +# +# Values here are pulled from the fandom wiki: +# https://minecraft.fandom.com/wiki/Anvil_mechanics#Costs_for_combining_enchantments +# +# If an enchantment is missing values here, or is less than 0, it will default to 0 +# +# Calculated as: [Enchantment lvl] * [multiplier] +# +# With default values protection 4 would have a value of 4 when +# coming from either a book (4 * 1) or an item (4 * 1) +enchant_values: + minecraft:aqua_affinity: + item: 4 + book: 2 + minecraft:bane_of_arthropods: + item: 2 + book: 1 + minecraft:binding_curse: + item: 8 + book: 4 + minecraft:blast_protection: + item: 4 + book: 2 + minecraft:channeling: + item: 8 + book: 4 + minecraft:depth_strider: + item: 4 + book: 2 + minecraft:efficiency: + item: 1 + book: 1 + minecraft:flame: + item: 4 + book: 2 + minecraft:feather_falling: + item: 2 + book: 1 + minecraft:fire_aspect: + item: 4 + book: 2 + minecraft:fire_protection: + item: 2 + book: 1 + minecraft:fortune: + item: 4 + book: 2 + minecraft:frost_walker: + item: 4 + book: 2 + minecraft:impaling: + item: 4 + book: 2 + minecraft:infinity: + item: 8 + book: 4 + minecraft:knockback: + item: 2 + book: 1 + minecraft:looting: + item: 4 + book: 2 + minecraft:loyalty: + item: 1 + book: 1 + minecraft:luck_of_the_sea: + item: 4 + book: 2 + minecraft:lure: + item: 4 + book: 2 + minecraft:mending: + item: 4 + book: 2 + minecraft:multishot: + item: 4 + book: 2 + minecraft:piercing: + item: 1 + book: 1 + minecraft:power: + item: 1 + book: 1 + minecraft:projectile_protection: + item: 2 + book: 1 + minecraft:protection: + item: 1 + book: 1 + minecraft:punch: + item: 4 + book: 2 + minecraft:quick_charge: + item: 2 + book: 1 + minecraft:respiration: + item: 4 + book: 2 + minecraft:riptide: + item: 4 + book: 2 + minecraft:silk_touch: + item: 8 + book: 4 + minecraft:sharpness: + item: 1 + book: 1 + minecraft:smite: + item: 2 + book: 1 + minecraft:soul_speed: + item: 8 + book: 4 + minecraft:swift_sneak: + item: 8 + book: 4 + minecraft:sweeping: + item: 4 + book: 2 + minecraft:sweeping_edge: + item: 4 + book: 2 + minecraft:thorns: + item: 8 + book: 4 + minecraft:unbreaking: + item: 2 + book: 1 + minecraft:vanishing_curse: + item: 8 + book: 4 + minecraft:density: + item: 2 + book: 1 + minecraft:breach: + item: 4 + book: 2 + minecraft:wind_burst: + item: 4 + book: 2 + minecraft:lunge: + item: 2 + book: 1 + +# Disable enchantment merging for level above the set value +# Enchantment merging is when, for example, 2 unbreaking II book combine to give sharpness III +# But Enchantment above this value can still be applied. following the previous example, we could still apply a unbreaking III book to a sword +# Even if disable-merge-over of unbreaking is set to 2 +# -1 mean enchantment merge for this enchantment is not disabled. default to -1 if absent. +disable-merge-over: + # Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla) + minecraft:sharpness: -1 +# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied +# minecraft:unbreaking: 2 + +# The maximum number of enchantment an item can get. -1 for infinity +# Use eco enchant enchant_limit if present by default unless "default" is not equal to -1 +enchantment_count_limit: + default: -1 + # Limit for specific items. example bellow is an example with stick + # Per item enchantment limit override eco enchant enchant_limit and default limit + items: + stick: -1 + +# Settings for lore modification +lore_edit: + book_and_quil: + # Permission is ca.lore_edit.book + use_permission: true + append: + # If adding lore using book & quil is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Cost used for every lore line added + per_line_cost: 0 + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false + # If adding the lore consume the book & quil + do_consume: false + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + # For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/ + # + # Note that currently minimessage would disable hex code when adding color + allow_color_code: true + allow_hexadecimal_color: false + allow_minimessage: true + use_cost: 0 + + remove: + # If removing lore using book & quil is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Cost used for every lore line removed + per_line_cost: 0 + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false + # If removing the lore consume the book & quil + do_consume: false + # Cost of replacing colors + remove_color_cost: 0 + # Allowed some color and tags to be reverted to plain text + # Custom anvil will prioritise format that result is a smaller resulting text + # Note that not allowing certain format will lead to some lost of color or tags. + # If configuration are exact as append appending this book should result in the exact same color + # + # Color code will be prefixed by "&" and hexadecimal color by "#". + # If color code is allowed, "&" in the text will get converted to "&&" + # For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/ + allow_color_code: true + allow_hexadecimal_color: false + allow_minimessage: true + + paper: + # Permission is ca.lore_edit.paper + use_permission: true + # what order should the lines should get added/removed (start/end, if invalid or not present will be end) + order: end + + append_line: + # If adding lore line using paper is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false + # If adding the lore line consume the paper + do_consume: false + # Allow using color code and hexadecimal color when editing lore via book & quil + # + # Color code are prefixed by "&" and hexadecimal color by "#" + # Color code will not be applied if it colors nothing. "&&" can be used to write "&" + # For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/ + # + # Note that currently minimessage would disable hex code when adding color + allow_color_code: true + allow_hexadecimal_color: false + allow_minimessage: true + color_use_cost: 0 + use_cost: 0 + + remove_line: + # If removing lore line using paper is enabled + enabled: false + # Cost used every time + fixed_cost: 1 + # Use left item vanilla cost penalty if any + shared_increase: false + # Increase shared left item cost penalty + shared_additive: false + # If removing the lore line consume the paper + do_consume: false + # Cost of replacing colors + remove_color_cost: 0 + # Allowed some color and tags to be reverted to plain text + # Custom anvil will prioritise format that result is a smaller resulting text + # Note that not allowing certain format will lead to some lost of color or tags. + # If configuration are exact as append appending this paper should result in the exact same color + # + # Color code will be prefixed by "&" and hexadecimal color by "#". + # If color code is allowed, "&" in the text will get converted to "&&" + # For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/ + allow_color_code: true + allow_hexadecimal_color: false + allow_minimessage: true + +# Whether to show debug logging +debug_log: false + +# Whether to show verbose debug logging +debug_log_verbose: false + +# In case something when wrong with CustomAnvil packet manager. +# If you see "missing class exception" or similar you may test this. +# If enabled and Protocolib absent or disabled "Replace to expensive" will not work. +# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled. +force_protocolib: false + +configVersion: 1.15.5 +lowMinecraftVersion: 1.21.11 diff --git a/defaultconfigs/1.21.11/custom_recipes.yml b/defaultconfigs/1.21.11/custom_recipes.yml new file mode 100644 index 0000000..57c2220 --- /dev/null +++ b/defaultconfigs/1.21.11/custom_recipes.yml @@ -0,0 +1,5 @@ +# ---------------------------------------------------- +# This config file is to store custom craft +# It is recommended to use the in game config editor for this configuration. +# /customanvilconfig With ca.config.edit permission +# ---------------------------------------------------- diff --git a/defaultconfigs/1.21.11/enchant_conflict.yml b/defaultconfigs/1.21.11/enchant_conflict.yml new file mode 100644 index 0000000..3d62dae --- /dev/null +++ b/defaultconfigs/1.21.11/enchant_conflict.yml @@ -0,0 +1,398 @@ +# +# It is recommended that you use /configanvil to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes ! +# + +# material conflicts +# +# If you want to edit this file: +# - A conflict will apply to every item except if in one of the notAffectedGroups group +# - the conflict will count only if the user try to combine at least as +# many conflicting enchantment as "maxEnchantmentBeforeConflict" +# +# +# ---------------------------------------------------- +# These restriction are about not allowing enchantment +# on illegal items +# ---------------------------------------------------- + +restriction_aqua_affinity: + enchantments: + - minecraft:aqua_affinity + notAffectedGroups: + - enchanted_book + - helmets + +restriction_bane_of_arthropods: + enchantments: + - minecraft:bane_of_arthropods + notAffectedGroups: + - enchanted_book + - melee_weapons + - mace + +restriction_blast_protection: + enchantments: + - minecraft:blast_protection + notAffectedGroups: + - enchanted_book + - armors + +restriction_channeling: + enchantments: + - minecraft:channeling + notAffectedGroups: + - enchanted_book + - trident + +restriction_binding_curse: + enchantments: + - minecraft:binding_curse + notAffectedGroups: + - enchanted_book + - wearable + +restriction_vanishing_curse: + enchantments: + - minecraft:vanishing_curse + notAffectedGroups: + - enchanted_book + - can_vanish + +restriction_depth_strider: + enchantments: + - minecraft:depth_strider + notAffectedGroups: + - enchanted_book + - boots + +restriction_efficiency: + enchantments: + - minecraft:efficiency + notAffectedGroups: + - enchanted_book + - tools + - shears + +restriction_feather_falling: + enchantments: + - minecraft:feather_falling + notAffectedGroups: + - enchanted_book + - boots + +restriction_fire_aspect: + enchantments: + - minecraft:fire_aspect + notAffectedGroups: + - enchanted_book + - swords + - mace + - spears + +restriction_fire_protection: + enchantments: + - minecraft:fire_protection + notAffectedGroups: + - enchanted_book + - armors + +restriction_flame: + enchantments: + - minecraft:flame + notAffectedGroups: + - enchanted_book + - bow + +restriction_fortune: + enchantments: + - minecraft:fortune + notAffectedGroups: + - enchanted_book + - tools + +restriction_frost_walker: + enchantments: + - minecraft:frost_walker + notAffectedGroups: + - enchanted_book + - boots + +restriction_impaling: + enchantments: + - minecraft:impaling + notAffectedGroups: + - enchanted_book + - trident + +restriction_infinity: + enchantments: + - minecraft:infinity + notAffectedGroups: + - enchanted_book + - bow + +restriction_knockback: + enchantments: + - minecraft:knockback + notAffectedGroups: + - enchanted_book + - swords + - spears + +restriction_looting: + enchantments: + - minecraft:looting + notAffectedGroups: + - enchanted_book + - swords + - spears + +restriction_loyalty: + enchantments: + - minecraft:loyalty + notAffectedGroups: + - enchanted_book + - trident + +restriction_luck_of_the_sea: + enchantments: + - minecraft:luck_of_the_sea + notAffectedGroups: + - enchanted_book + - fishing_rod + +restriction_lure: + enchantments: + - minecraft:lure + notAffectedGroups: + - enchanted_book + - fishing_rod + +restriction_mending: + enchantments: + - minecraft:mending + notAffectedGroups: + - enchanted_book + - can_unbreak + +restriction_minecraft_multishot: + enchantments: + - minecraft:multishot + notAffectedGroups: + - enchanted_book + - crossbow + +restriction_piercing: + enchantments: + - minecraft:piercing + notAffectedGroups: + - enchanted_book + - crossbow + +restriction_power: + enchantments: + - minecraft:power + notAffectedGroups: + - enchanted_book + - bow + +restriction_projectile_protection: + enchantments: + - minecraft:projectile_protection + notAffectedGroups: + - enchanted_book + - armors + +restriction_protection: + enchantments: + - minecraft:protection + notAffectedGroups: + - enchanted_book + - armors + +restriction_punch: + enchantments: + - minecraft:punch + notAffectedGroups: + - enchanted_book + - bow + +restriction_quick_charge: + enchantments: + - minecraft:quick_charge + notAffectedGroups: + - enchanted_book + - crossbow + +restriction_respiration: + enchantments: + - minecraft:respiration + notAffectedGroups: + - enchanted_book + - helmets + +restriction_riptide: + enchantments: + - minecraft:riptide + notAffectedGroups: + - enchanted_book + - trident + +restriction_sharpness: + enchantments: + - minecraft:sharpness + notAffectedGroups: + - enchanted_book + - melee_weapons + +restriction__silk_touch: + enchantments: + - minecraft:silk_touch + notAffectedGroups: + - enchanted_book + - tools + +restriction_smite: + enchantments: + - minecraft:smite + notAffectedGroups: + - enchanted_book + - melee_weapons + - mace + +restriction_soul_speed: + enchantments: + - minecraft:soul_speed + notAffectedGroups: + - enchanted_book + - boots + +restriction_sweeping_edge: + enchantments: + - minecraft:sweeping + - minecraft:sweeping_edge + notAffectedGroups: + - enchanted_book + - swords + +# Do not exist in 1.18, that mean useInFuture will be set to true +# useInFuture set to true also mean it will not warn if there is an issue +restriction_swift_sneak: + useInFuture: true + enchantments: + - minecraft:swift_sneak + notAffectedGroups: + - enchanted_book + - leggings + +restriction_thorns: + enchantments: + - minecraft:thorns + notAffectedGroups: + - enchanted_book + - armors + +restriction__unbreaking: + enchantments: + - minecraft:unbreaking + notAffectedGroups: + - enchanted_book + - can_unbreak + +# ---------------------------------------------------- +# Now we have conflicts about enchantment Incompatibility +# We just filtered what item enchantments can be applied +# notAffectedGroups is empty as we don't want anything to not respect theses rules +# maxEnchantmentBeforeConflict is set to 1 to only have 1 on those enchantment available +# ---------------------------------------------------- + +sword_enchant_conflict: + enchantments: + - minecraft:bane_of_arthropods + - minecraft:smite + - minecraft:sharpness + - minecraft:density + - minecraft:breach + notAffectedGroups: [] + maxEnchantmentBeforeConflict: 1 + +protection_enchant_conflict: + enchantments: + - minecraft:blast_protection + - minecraft:fire_protection + - minecraft:projectile_protection + - minecraft:protection + notAffectedGroups: [] + maxEnchantmentBeforeConflict: 1 + +trident_conflict1: + enchantments: + - minecraft:channeling + - minecraft:riptide + notAffectedGroups: [] + maxEnchantmentBeforeConflict: 1 + +trident_conflict2: + enchantments: + - minecraft:loyalty + - minecraft:riptide + notAffectedGroups: [] + maxEnchantmentBeforeConflict: 1 + +boot_conflict: + enchantments: + - minecraft:depth_strider + - minecraft:frost_walker + notAffectedGroups: [] + maxEnchantmentBeforeConflict: 1 + +tool_conflict: + enchantments: + - minecraft:fortune + - minecraft:silk_touch + notAffectedGroups: [] + maxEnchantmentBeforeConflict: 1 + +bow_conflict: + enchantments: + - minecraft:mending + - minecraft:infinity + notAffectedGroups: [] + maxEnchantmentBeforeConflict: 1 + +crossbow_conflict: + enchantments: + - minecraft:multishot + - minecraft:piercing + notAffectedGroups: [] + maxEnchantmentBeforeConflict: 1 +restriction_density: + enchantments: + - minecraft:density + notAffectedGroups: + - mace + - enchanted_book +restriction_breach: + enchantments: + - minecraft:breach + notAffectedGroups: + - mace + - enchanted_book +restriction_wind_burst: + enchantments: + - minecraft:wind_burst + notAffectedGroups: + - mace + - enchanted_book +restriction_lunge: + enchantments: + - minecraft:lunge + notAffectedGroups: + - spears + - enchanted_book + +# ---------------------------------------------------- +# Bellow is for custom conflicts. +# This is also where conflict create from the gui will be placed. +# ---------------------------------------------------- diff --git a/defaultconfigs/1.21.11/item_groups.yml b/defaultconfigs/1.21.11/item_groups.yml new file mode 100644 index 0000000..9f2a877 --- /dev/null +++ b/defaultconfigs/1.21.11/item_groups.yml @@ -0,0 +1,247 @@ +# +# It is recommended that you use /configanvil to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes ! +# + +# Please note this config use spigot material names. +# It should match minecraft name in most case, maybe every case, but I can't be sure +# In case there an issue with material name, you can found them here: +# https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + +# An empty Exclude group exclude nothing, so it contain everything +everything: + type: exclude + +# An empty include group will include nothing +nothing: + type: include + +# This group is an example of a group including only stone and polished granite +example_include: + type: include + items: + - stone + - polished_granite + +# This group contain everything except polished granite and elements of example_include +example_exclude: + type: exclude + items: + - polished_granite + groups: + - example_include + +# Default configuration should be vanilla enchantment conflict group +# there may have error, if you find one you can fix it ! +# https://minecraft.fandom.com/wiki/Enchanting + +swords: + type: include + items: + - wooden_sword + - stone_sword + - iron_sword + - diamond_sword + - golden_sword + - netherite_sword + - copper_sword + +axes: + type: include + items: + - wooden_axe + - stone_axe + - iron_axe + - diamond_axe + - golden_axe + - netherite_axe + - copper_axe + +melee_weapons: + type: include + groups: + - swords + - axes + - spears + +helmets: + type: include + items: + - leather_helmet + - chainmail_helmet + - iron_helmet + - diamond_helmet + - golden_helmet + - netherite_helmet + - turtle_helmet + - copper_helmet + +chestplate: + type: include + items: + - leather_chestplate + - chainmail_chestplate + - iron_chestplate + - diamond_chestplate + - golden_chestplate + - netherite_chestplate + - copper_chestplate + +leggings: + type: include + items: + - leather_leggings + - chainmail_leggings + - iron_leggings + - diamond_leggings + - golden_leggings + - netherite_leggings + - copper_leggings + +boots: + type: include + items: + - leather_boots + - chainmail_boots + - iron_boots + - diamond_boots + - golden_boots + - netherite_boots + - copper_boots + +armors: + type: include + groups: + - helmets + - chestplate + - leggings + - boots + +wearable: + type: include + items: + - elytra + - carved_pumpkin + - skeleton_skull + - wither_skeleton_skull + - zombie_head + - player_head + - creeper_head + - dragon_head + - piglin_head + groups: + - armors + +pickaxes: + type: include + items: + - wooden_pickaxe + - stone_pickaxe + - iron_pickaxe + - diamond_pickaxe + - golden_pickaxe + - netherite_pickaxe + - copper_pickaxe + +shovels: + type: include + items: + - wooden_shovel + - stone_shovel + - iron_shovel + - diamond_shovel + - golden_shovel + - netherite_shovel + - copper_shovel + +hoes: + type: include + items: + - wooden_hoe + - stone_hoe + - iron_hoe + - diamond_hoe + - golden_hoe + - netherite_hoe + - copper_hoe + +tools: + type: include + groups: + - pickaxes + - shovels + - hoes + - axes + +enchanted_book: + type: include + items: + - enchanted_book + +trident: + type: include + items: + - trident + +bow: + type: include + items: + - bow + +crossbow: + type: include + items: + - crossbow + +fishing_rod: + type: include + items: + - fishing_rod + +shears: + type: include + items: + - shears + +can_unbreak: + type: include + items: + - elytra + - flint_and_steel + - shield + - carrot_on_a_stick + - warped_fungus_on_a_stick + - brush + groups: + - melee_weapons + - tools + - armors + - trident + - bow + - crossbow + - fishing_rod + - shears + - mace + +can_vanish: + type: include + items: + - compass + groups: + - wearable + - can_unbreak +mace: + type: include + items: + - mace +spears: + type: include + items: + - wooden_spear + - golden_spear + - stone_spear + - copper_spear + - iron_spear + - diamond_spear + - netherite_spear + diff --git a/defaultconfigs/1.21.11/unit_repair_item.yml b/defaultconfigs/1.21.11/unit_repair_item.yml new file mode 100644 index 0000000..ed981b1 --- /dev/null +++ b/defaultconfigs/1.21.11/unit_repair_item.yml @@ -0,0 +1,220 @@ +# +# It is recommended that you use /configanvil to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes ! +# + +# Unit repair configuration +# +# This configuration is to make custom unit repair +# A unit repair is, for example, a diamond to repair a diamond sword +# In vanilla, a unit repair 25% of object durability +# you can make a custom value here +# +# Item name should NOT combine caps and no caps (example: Stone) + +# Default value if the config is an invalid value (value <= 0 ) +# If value > 1 it will be treated as being = 1 +default_repair_amount: 0.25 + +# You can add custom unit repair +# The example bellow make a shield repaired by 10% by sticks + +# stick: +# shield: 0.10 + + +# Vanilla unit repair group is bellow +diamond: + diamond_helmet: 0.25 + diamond_chestplate: 0.25 + diamond_leggings: 0.25 + diamond_boots: 0.25 + diamond_sword: 0.25 + diamond_pickaxe: 0.25 + diamond_axe: 0.25 + diamond_shovel: 0.25 + diamond_hoe: 0.25 + diamond_spear: 0.25 + +netherite_ingot: + netherite_helmet: 0.25 + netherite_chestplate: 0.25 + netherite_leggings: 0.25 + netherite_boots: 0.25 + netherite_sword: 0.25 + netherite_pickaxe: 0.25 + netherite_axe: 0.25 + netherite_shovel: 0.25 + netherite_hoe: 0.25 + netherite_spear: 0.25 + +gold_ingot: + golden_helmet: 0.25 + golden_chestplate: 0.25 + golden_leggings: 0.25 + golden_boots: 0.25 + golden_sword: 0.25 + golden_pickaxe: 0.25 + golden_axe: 0.25 + golden_shovel: 0.25 + golden_hoe: 0.25 + golden_spear: 0.25 + +iron_ingot: + iron_helmet: 0.25 + iron_chestplate: 0.25 + iron_leggings: 0.25 + iron_boots: 0.25 + iron_sword: 0.25 + iron_pickaxe: 0.25 + iron_axe: 0.25 + iron_shovel: 0.25 + iron_hoe: 0.25 + iron_spear: 0.25 + +cobblestone: + stone_sword: 0.25 + stone_pickaxe: 0.25 + stone_axe: 0.25 + stone_shovel: 0.25 + stone_hoe: 0.25 + stone_spear: 0.25 + +cobbled_deepslate: + stone_sword: 0.25 + stone_pickaxe: 0.25 + stone_axe: 0.25 + stone_shovel: 0.25 + stone_hoe: 0.25 + stone_spear: 0.25 + +blackstone: + stone_sword: 0.25 + stone_pickaxe: 0.25 + stone_axe: 0.25 + stone_shovel: 0.25 + stone_hoe: 0.25 + +leather: + leather_helmet: 0.25 + leather_chestplate: 0.25 + leather_leggings: 0.25 + leather_boots: 0.25 + +phantom_membrane: + elytra: 0.25 + +scute: + turtle_helmet: 0.25 + +oak_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 + +spruce_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 + +birch_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 + +jungle_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 + +acacia_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 + +dark_oak_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 + +mangrove_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 + +cherry_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 + +bamboo_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 + +crimson_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 + +warped_planks: + wooden_sword: 0.25 + wooden_pickaxe: 0.25 + wooden_axe: 0.25 + wooden_shovel: 0.25 + wooden_hoe: 0.25 + shield: 0.25 + wooden_spear: 0.25 +breeze_rod: + mace: 0.25 +copper_ingot: + copper_helmet: 0.25 + copper_chestplate: 0.25 + copper_leggings: 0.25 + copper_boots: 0.25 + copper_pickaxe: 0.25 + copper_shovel: 0.25 + copper_hoe: 0.25 + copper_axe: 0.25 + copper_sword: 0.25 + copper_spear: 0.25 diff --git a/defaultconfigs/README.md b/defaultconfigs/README.md index 72c88ca..a413b66 100644 --- a/defaultconfigs/README.md +++ b/defaultconfigs/README.md @@ -1,3 +1,5 @@ ### Default Plugin's Configurations -For 1.18 to 1.20.6 use [1.18 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.18) \ -For 1.21 use [1.21 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21) \ No newline at end of file +From 1.18 to 1.20.6 use [1.18 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.18) \ +From 1.21 to 1.21.8 use [1.21 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21) +From 1.21.9 to 1.21.10 use [1.21.9 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.9) +From 1.21.11 use [1.21.11 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11) \ No newline at end of file From 9e7a1a963d946e88d8b0a1a69beb8d150e64e737 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Sat, 6 Dec 2025 04:11:41 +0100 Subject: [PATCH 06/14] fix default rename text issue --- build.gradle.kts | 2 +- .../xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 901b89a..8ae931c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,7 +18,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.15.5" +version = "1.15.6" val effectiveVersion = "$version" + (if (System.getenv("SMALL_COMMIT_HASH") != null) "-dev-${System.getenv("SMALL_COMMIT_HASH")!!}" else "") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 17d5d0d..c47d828 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -213,7 +213,8 @@ class PrepareAnvilListener : Listener { else if (useColor) it.displayName else ChatColor.stripColor(it.displayName) - if (!displayName.contentEquals(renameText)) { + + if (!displayName.contentEquals(renameText) && !(displayName == null && renameText == "")) { it.setDisplayName(renameText) resultItem.itemMeta = it From c166d2a78a6cef8b8ac8789ee8f3f65cd7364ec9 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sun, 7 Dec 2025 15:33:39 +0100 Subject: [PATCH 07/14] start of nms generalization --- .../cuanvil/dependency/gui/ExternGuiTester.kt | 50 ++-------------- .../gui/version/v1_17R1_ExternGuiTester.kt | 16 ----- .../gui/version/v1_18R1_ExternGuiTester.kt | 16 ----- .../gui/version/v1_18R2_ExternGuiTester.kt | 16 ----- .../gui/version/v1_19R1_ExternGuiTester.kt | 16 ----- .../gui/version/v1_19R2_ExternGuiTester.kt | 16 ----- .../gui/version/v1_19R3_ExternGuiTester.kt | 16 ----- .../gui/version/v1_20R1_ExternGuiTester.kt | 16 ----- .../gui/version/v1_20R2_ExternGuiTester.kt | 17 ------ .../gui/version/v1_20R3_ExternGuiTester.kt | 17 ------ .../gui/version/v1_20R4_ExternGuiTester.kt | 17 ------ .../gui/version/v1_21R1_ExternGuiTester.kt | 17 ------ .../gui/version/v1_21R2_ExternGuiTester.kt | 34 ----------- .../gui/version/v1_21R3_ExternGuiTester.kt | 17 ------ .../gui/version/v1_21R4_ExternGuiTester.kt | 34 ----------- .../gui/version/v1_21R5_ExternGuiTester.kt | 34 ----------- .../gui/version/v1_21R6_ExternGuiTester.kt | 34 ----------- .../dependency/gui/GenericExternGuiTester.kt | 58 +++++++++++++++++++ .../dependency/gui/GuiTesterSelector.kt | 43 +------------- 19 files changed, 63 insertions(+), 421 deletions(-) delete mode 100644 nms/v1_17R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_17R1_ExternGuiTester.kt delete mode 100644 nms/v1_18R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_18R1_ExternGuiTester.kt delete mode 100644 nms/v1_18R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_18R2_ExternGuiTester.kt delete mode 100644 nms/v1_19R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R1_ExternGuiTester.kt delete mode 100644 nms/v1_19R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R2_ExternGuiTester.kt delete mode 100644 nms/v1_19R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R3_ExternGuiTester.kt delete mode 100644 nms/v1_20R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R1_ExternGuiTester.kt delete mode 100644 nms/v1_20R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R2_ExternGuiTester.kt delete mode 100644 nms/v1_20R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R3_ExternGuiTester.kt delete mode 100644 nms/v1_20R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R4_ExternGuiTester.kt delete mode 100644 nms/v1_21R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R1_ExternGuiTester.kt delete mode 100644 nms/v1_21R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R2_ExternGuiTester.kt delete mode 100644 nms/v1_21R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R3_ExternGuiTester.kt delete mode 100644 nms/v1_21R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R4_ExternGuiTester.kt delete mode 100644 nms/v1_21R5/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R5_ExternGuiTester.kt delete mode 100644 nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R6_ExternGuiTester.kt create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GenericExternGuiTester.kt diff --git a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/ExternGuiTester.kt b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/ExternGuiTester.kt index 3079b8a..029e4a7 100644 --- a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/ExternGuiTester.kt +++ b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/ExternGuiTester.kt @@ -5,55 +5,13 @@ import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil interface ExternGuiTester { - object Const{ - val cannonicalPaperAnvilMenu = "net.minecraft.world.inventory.AnvilMenu" - } - - val wesjdAnvilGuiName: String? - - fun getContainerClass(inventory: InventoryView): Class? + fun getContainerClass(view: InventoryView): Class? fun testIfGui(inventory: InventoryView): Boolean { - // this mean we are on test - //TODO review why needed knowing previous mitigations should works - if(inventory.javaClass.name.endsWith("AnvilViewMock")) return false + // container class only allow default bukkit craft view class - val clazz = getContainerClass(inventory) ?: return false - - val clazzName = clazz.name - if(!PlatformUtil.isPaper){ - // Blacklist gui causing issue - if (expectWesjd(clazzName)) return true - if (expectXenondevUI(clazzName)) return true - if (expectVanePortal(clazzName)) return true - - return false - } - - // Only allow cannonical anvil menu class - return !Const.cannonicalPaperAnvilMenu.equals(clazzName, true) - } - - fun expectWesjd(name: String): Boolean { - val expectedWesjdGuiPath = "anvilgui.version.$wesjdAnvilGuiName" - - return name.contains(expectedWesjdGuiPath) - } - - private val XenondevUIPrefix: String - get() = "xyz.xenondevs.inventoryaccess." - private val XenondevUISufix: String - get() = ".AnvilInventoryImpl" - - fun expectXenondevUI(name: String): Boolean { - return name.startsWith(XenondevUIPrefix) - && name.endsWith(XenondevUISufix) - } - - fun expectVanePortal(name: String): Boolean { - val expected = "org.oddlama.vane.core.menu.AnvilMenu\$AnvilContainer" - - return name == expected + val clazz = getContainerClass(inventory) + return clazz != null } } \ No newline at end of file diff --git a/nms/v1_17R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_17R1_ExternGuiTester.kt b/nms/v1_17R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_17R1_ExternGuiTester.kt deleted file mode 100644 index 8e352e0..0000000 --- a/nms/v1_17R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_17R1_ExternGuiTester.kt +++ /dev/null @@ -1,16 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_17R1_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_17_R1" - - override fun getContainerClass(view: InventoryView): Class? { - if (view !is CraftInventoryView) return null - val container = view.handle - - return container.javaClass - } -} \ No newline at end of file diff --git a/nms/v1_18R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_18R1_ExternGuiTester.kt b/nms/v1_18R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_18R1_ExternGuiTester.kt deleted file mode 100644 index 659a0f6..0000000 --- a/nms/v1_18R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_18R1_ExternGuiTester.kt +++ /dev/null @@ -1,16 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_18R1_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_18_R1" - - override fun getContainerClass(view: InventoryView): Class? { - if (view !is CraftInventoryView) return null - val container = view.handle - - return container.javaClass - } -} \ No newline at end of file diff --git a/nms/v1_18R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_18R2_ExternGuiTester.kt b/nms/v1_18R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_18R2_ExternGuiTester.kt deleted file mode 100644 index 1447716..0000000 --- a/nms/v1_18R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_18R2_ExternGuiTester.kt +++ /dev/null @@ -1,16 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_18R2_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_18_R2" - - override fun getContainerClass(view: InventoryView): Class? { - if (view !is CraftInventoryView) return null - val container = view.handle - - return container.javaClass - } -} \ No newline at end of file diff --git a/nms/v1_19R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R1_ExternGuiTester.kt b/nms/v1_19R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R1_ExternGuiTester.kt deleted file mode 100644 index c151924..0000000 --- a/nms/v1_19R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R1_ExternGuiTester.kt +++ /dev/null @@ -1,16 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_19R1_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_19_R1" - - override fun getContainerClass(view: InventoryView): Class? { - if (view !is CraftInventoryView) return null - val container = view.handle - - return container.javaClass - } -} \ No newline at end of file diff --git a/nms/v1_19R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R2_ExternGuiTester.kt b/nms/v1_19R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R2_ExternGuiTester.kt deleted file mode 100644 index ac46674..0000000 --- a/nms/v1_19R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R2_ExternGuiTester.kt +++ /dev/null @@ -1,16 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_19R2_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_19_R2" - - override fun getContainerClass(view: InventoryView): Class? { - if (view !is CraftInventoryView) return null - val container = view.handle - - return container.javaClass - } -} \ No newline at end of file diff --git a/nms/v1_19R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R3_ExternGuiTester.kt b/nms/v1_19R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R3_ExternGuiTester.kt deleted file mode 100644 index 7ce5abd..0000000 --- a/nms/v1_19R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_19R3_ExternGuiTester.kt +++ /dev/null @@ -1,16 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_19R3_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_19_R3" - - override fun getContainerClass(view: InventoryView): Class? { - if (view !is CraftInventoryView) return null - val container = view.handle - - return container.javaClass - } -} \ No newline at end of file diff --git a/nms/v1_20R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R1_ExternGuiTester.kt b/nms/v1_20R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R1_ExternGuiTester.kt deleted file mode 100644 index dae3b98..0000000 --- a/nms/v1_20R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R1_ExternGuiTester.kt +++ /dev/null @@ -1,16 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_20R1_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_20_R1" - - override fun getContainerClass(view: InventoryView): Class? { - if (view !is CraftInventoryView) return null - val container = view.handle - - return container.javaClass - } -} diff --git a/nms/v1_20R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R2_ExternGuiTester.kt b/nms/v1_20R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R2_ExternGuiTester.kt deleted file mode 100644 index 6a8358a..0000000 --- a/nms/v1_20R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R2_ExternGuiTester.kt +++ /dev/null @@ -1,17 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester -import kotlin.jvm.javaClass - -class v1_20R2_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_20_R2" - - override fun getContainerClass(view: InventoryView): Class? { - if (view !is CraftInventoryView) return null - val container = view.handle - - return container.javaClass - } -} diff --git a/nms/v1_20R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R3_ExternGuiTester.kt b/nms/v1_20R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R3_ExternGuiTester.kt deleted file mode 100644 index 80362e2..0000000 --- a/nms/v1_20R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R3_ExternGuiTester.kt +++ /dev/null @@ -1,17 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester -import kotlin.jvm.javaClass - -class v1_20R3_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_20_R3" - - override fun getContainerClass(view: InventoryView): Class? { - if (view !is CraftInventoryView) return null - val container = view.handle - - return container.javaClass - } -} diff --git a/nms/v1_20R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R4_ExternGuiTester.kt b/nms/v1_20R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R4_ExternGuiTester.kt deleted file mode 100644 index 16e867c..0000000 --- a/nms/v1_20R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_20R4_ExternGuiTester.kt +++ /dev/null @@ -1,17 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester -import kotlin.jvm.javaClass - -class v1_20R4_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_20_R4" - - override fun getContainerClass(view: InventoryView): Class? { - if (view !is CraftInventoryView) return null - val container = view.handle - - return container.javaClass - } -} diff --git a/nms/v1_21R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R1_ExternGuiTester.kt b/nms/v1_21R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R1_ExternGuiTester.kt deleted file mode 100644 index 3111735..0000000 --- a/nms/v1_21R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R1_ExternGuiTester.kt +++ /dev/null @@ -1,17 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_21R1_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_21_R1" - - override fun getContainerClass(view: InventoryView): Class? { - if(view !is CraftInventoryView<*, *>) return null - val container = view.handle - - return container.javaClass - } - -} diff --git a/nms/v1_21R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R2_ExternGuiTester.kt b/nms/v1_21R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R2_ExternGuiTester.kt deleted file mode 100644 index 2604a16..0000000 --- a/nms/v1_21R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R2_ExternGuiTester.kt +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_21R2_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_21_R2" - - var tested = false; - var possible = false; - - override fun getContainerClass(view: InventoryView): Class? { - // In case we are in a test environment - if(!tested) testClassExist() - if(!possible) return null - - if(view !is CraftInventoryView<*, *>) return null - val container = view.handle - - return container.javaClass - } - - fun testClassExist(){ - tested = true; - try { - Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView") - possible = true - } catch (e: ClassNotFoundException){ - possible = false - } - } - -} diff --git a/nms/v1_21R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R3_ExternGuiTester.kt b/nms/v1_21R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R3_ExternGuiTester.kt deleted file mode 100644 index 70c5df9..0000000 --- a/nms/v1_21R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R3_ExternGuiTester.kt +++ /dev/null @@ -1,17 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_21R3_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_21_R3" - - override fun getContainerClass(view: InventoryView): Class? { - if(view !is CraftInventoryView<*, *>) return null - val container = view.handle - - return container.javaClass - } - -} diff --git a/nms/v1_21R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R4_ExternGuiTester.kt b/nms/v1_21R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R4_ExternGuiTester.kt deleted file mode 100644 index 6b76451..0000000 --- a/nms/v1_21R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R4_ExternGuiTester.kt +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_21R4_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_21_R4" - - var tested = false; - var possible = false; - - override fun getContainerClass(view: InventoryView): Class? { - // In case we are in a test environment - if(!tested) testClassExist() - if(!possible) return null - - if(view !is CraftInventoryView<*, *>) return null - val container = view.handle - - return container.javaClass - } - - fun testClassExist(){ - tested = true; - try { - Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView") - possible = true - } catch (e: ClassNotFoundException){ - possible = false - } - } - -} diff --git a/nms/v1_21R5/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R5_ExternGuiTester.kt b/nms/v1_21R5/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R5_ExternGuiTester.kt deleted file mode 100644 index 59eadbc..0000000 --- a/nms/v1_21R5/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R5_ExternGuiTester.kt +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_21R5_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_21_R5" - - var tested = false; - var possible = false; - - override fun getContainerClass(view: InventoryView): Class? { - // In case we are in a test environment - if(!tested) testClassExist() - if(!possible) return null - - if(view !is CraftInventoryView<*, *>) return null - val container = view.handle - - return container.javaClass - } - - fun testClassExist(){ - tested = true; - try { - Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView") - possible = true - } catch (e: ClassNotFoundException){ - possible = false - } - } - -} diff --git a/nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R6_ExternGuiTester.kt b/nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R6_ExternGuiTester.kt deleted file mode 100644 index 4e4c32b..0000000 --- a/nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R6_ExternGuiTester.kt +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_21R6_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_21_R6" - - var tested = false; - var possible = false; - - override fun getContainerClass(view: InventoryView): Class? { - // In case we are in a test environment - if(!tested) testClassExist() - if(!possible) return null - - if(view !is CraftInventoryView<*, *>) return null - val container = view.handle - - return container.javaClass - } - - fun testClassExist(){ - tested = true; - try { - Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView") - possible = true - } catch (e: ClassNotFoundException){ - possible = false - } - } - -} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GenericExternGuiTester.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GenericExternGuiTester.kt new file mode 100644 index 0000000..85e32d5 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GenericExternGuiTester.kt @@ -0,0 +1,58 @@ +package xyz.alexcrea.cuanvil.dependency.gui + +import org.bukkit.inventory.InventoryView +import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil +import java.lang.reflect.Method + +class GenericExternGuiTester: ExternGuiTester { + + companion object { + private const val ANVIL_CLASS_NAME = "org.bukkit.craftbukkit.inventory.view.CraftAnvilView" + private const val INV_CLASS_NAME = "org.bukkit.craftbukkit.inventory.CraftInventoryView" + private const val HANDLE_METHOD_NAME = "getHandle" + } + + var tested = false + + var testedClass: String? = null + lateinit var getHandleMethod: Method + + override fun getContainerClass(view: InventoryView): Class? { + // In case we are in a test environment + if(!tested) testClassExist() + + if(!testedClass.contentEquals(view.javaClass.name)) + return null + + val container = getHandleMethod.invoke(view) + return container.javaClass + } + + fun tryFromClass(className: String) { + val clazz = Class.forName(className) + testedClass = className + + getHandleMethod = clazz.getMethod(HANDLE_METHOD_NAME) + } + + fun testClassExist() { + tested = true + + // We first try to get craft anvil interface, + // but is absent on old version so we try craft inventory view before + try { + tryFromClass(ANVIL_CLASS_NAME) + return + } + catch (_: ClassNotFoundException) {} + catch (_: NoSuchMethodException) {} + + try { + tryFromClass(INV_CLASS_NAME) + return + } + catch (_: ClassNotFoundException) {} + catch (_: NoSuchMethodException) {} + } + +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GuiTesterSelector.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GuiTesterSelector.kt index f3d2122..f64a7f1 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GuiTesterSelector.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GuiTesterSelector.kt @@ -1,6 +1,5 @@ package xyz.alexcrea.cuanvil.dependency.gui -import xyz.alexcrea.cuanvil.dependency.gui.version.*; import xyz.alexcrea.cuanvil.update.UpdateUtils object GuiTesterSelector { @@ -10,47 +9,7 @@ object GuiTesterSelector { val versionParts = UpdateUtils.currentMinecraftVersionArray() if (versionParts[0] != 1) return null - return when (versionParts[1]) { - // Can't support 1.16.5 bc 1.16.5 paper userdev do not exist - - 17 -> when (versionParts[2]) { - 0, 1 -> v1_17R1_ExternGuiTester() - else -> null - } - - 18 -> when (versionParts[2]) { - 0, 1 -> v1_18R1_ExternGuiTester() - 2 -> v1_18R2_ExternGuiTester() - else -> null - } - - 19 -> when (versionParts[2]) { - 0, 1, 2 -> v1_19R1_ExternGuiTester() - 3 -> v1_19R2_ExternGuiTester() - 4 -> v1_19R3_ExternGuiTester() - else -> null - } - - 20 -> when (versionParts[2]) { - 0, 1 -> v1_20R1_ExternGuiTester() - 2 -> v1_20R2_ExternGuiTester() - 3, 4 -> v1_20R3_ExternGuiTester() - 5, 6 -> v1_20R4_ExternGuiTester() - else -> null - } - - 21 -> when (versionParts[2]) { - 0, 1 -> v1_21R1_ExternGuiTester() - 2, 3 -> v1_21R2_ExternGuiTester() - 4 -> v1_21R3_ExternGuiTester() - 5 -> v1_21R4_ExternGuiTester() - 6, 7, 8 -> v1_21R5_ExternGuiTester() - 9, 10 -> v1_21R6_ExternGuiTester() - else -> null - } - - else -> null - } + return GenericExternGuiTester() } } \ No newline at end of file From ee4936ecf51d91ea02df4702eee32a6d7133677a Mon Sep 17 00:00:00 2001 From: alexcrea Date: Thu, 25 Dec 2025 21:55:48 +0100 Subject: [PATCH 08/14] reobf for spigot --- build.gradle.kts | 4 ++-- nms/v1_21R7/build.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 57b8b93..b209202 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,7 +18,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.15.6" +version = "1.15.7" val effectiveVersion = "$version" + (if (System.getenv("SMALL_COMMIT_HASH") != null) "-dev-${System.getenv("SMALL_COMMIT_HASH")!!}" else "") @@ -89,7 +89,7 @@ dependencies { implementation(project(":nms:v1_21R4", configuration = "reobf")) implementation(project(":nms:v1_21R5", configuration = "reobf")) implementation(project(":nms:v1_21R6", configuration = "reobf")) - implementation(project(":nms:v1_21R7"))// TODO reobf on release, configuration = "reobf")) + implementation(project(":nms:v1_21R7", configuration = "reobf")) // include kotlin for the offline jar implementation(kotlin("stdlib")) diff --git a/nms/v1_21R7/build.gradle.kts b/nms/v1_21R7/build.gradle.kts index 9c8a6f3..6b5a242 100644 --- a/nms/v1_21R7/build.gradle.kts +++ b/nms/v1_21R7/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { implementation(project(":nms:nms-common")) // Used for nms - paperweight.paperDevBundle("1.21.11-pre3-R0.1-SNAPSHOT") //TODO update to 1.21.11-R0.1-SNAPSHOT on release + paperweight.paperDevBundle("1.21.11-R0.1-SNAPSHOT") } repositories { From fc94dbe16980f08f690128f5ee97ddcaf0465bb1 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Thu, 25 Dec 2025 22:33:37 +0100 Subject: [PATCH 09/14] Generic gui tester and generic paper nms --- build.gradle.kts | 1 + nms/nms-paper/.gitignore | 1 + nms/nms-paper/build.gradle.kts | 35 +++++++++++ .../dependency/datapack/DataPackTester.kt | 0 .../packet/versions/PaperPacketManager.kt | 33 +++++++++++ .../dependency/scheduler/FoliaScheduler.kt | 0 ...PacketManager.kt => PaperPacketManager.kt} | 0 .../gui/version/v1_21R7_ExternGuiTester.kt | 34 ----------- settings.gradle.kts | 2 + .../dependency/MinecraftVersionUtil.kt | 54 +++++++++++++++++ .../packet/PacketManagerSelector.kt | 58 +++++-------------- .../dependency/scheduler/BukkitScheduler.kt | 4 +- 12 files changed, 144 insertions(+), 78 deletions(-) create mode 100644 nms/nms-paper/.gitignore create mode 100644 nms/nms-paper/build.gradle.kts rename nms/{v1_20R1 => nms-paper}/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt (100%) create mode 100644 nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/PaperPacketManager.kt rename nms/{v1_20R3 => nms-paper}/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/FoliaScheduler.kt (100%) rename nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/{V1_21R6_PacketManager.kt => PaperPacketManager.kt} (100%) delete mode 100644 nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R7_ExternGuiTester.kt create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/dependency/MinecraftVersionUtil.kt diff --git a/build.gradle.kts b/build.gradle.kts index b209202..944175b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -73,6 +73,7 @@ dependencies { // Include nms implementation(project(":nms:nms-common")) + implementation(project(":nms:nms-paper")) implementation(project(":nms:v1_17R1", configuration = "reobf")) implementation(project(":nms:v1_18R1", configuration = "reobf")) implementation(project(":nms:v1_18R2", configuration = "reobf")) diff --git a/nms/nms-paper/.gitignore b/nms/nms-paper/.gitignore new file mode 100644 index 0000000..47374f1 --- /dev/null +++ b/nms/nms-paper/.gitignore @@ -0,0 +1 @@ +.lastDeploymentsId \ No newline at end of file diff --git a/nms/nms-paper/build.gradle.kts b/nms/nms-paper/build.gradle.kts new file mode 100644 index 0000000..3b98361 --- /dev/null +++ b/nms/nms-paper/build.gradle.kts @@ -0,0 +1,35 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +group = rootProject.group +version = rootProject.version + +plugins { + id("io.papermc.paperweight.userdev") +} + +dependencies { + implementation(project(":nms:nms-common")) + + // Used for nms + paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT") +} + +repositories { + maven("https://repo.papermc.io/repository/maven-public/") + +} + +// Set target version +tasks.withType().configureEach { + sourceCompatibility = "18" + targetCompatibility = "18" + + options.encoding = "UTF-8" +} + +kotlin { + compilerOptions { + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) + jvmTarget.set(JvmTarget.JVM_18) + } +} diff --git a/nms/v1_20R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt b/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt similarity index 100% rename from nms/v1_20R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt rename to nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt diff --git a/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/PaperPacketManager.kt b/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/PaperPacketManager.kt new file mode 100644 index 0000000..7e248e1 --- /dev/null +++ b/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/PaperPacketManager.kt @@ -0,0 +1,33 @@ +package xyz.alexcrea.cuanvil.dependency.packet.versions + +import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket +import net.minecraft.world.entity.player.Abilities +import org.bukkit.craftbukkit.entity.CraftPlayer +import org.bukkit.entity.Player +import xyz.alexcrea.cuanvil.dependency.packet.PacketManager +import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase + +class PaperPacketManager : PacketManagerBase(), PacketManager { + override val canSetInstantBuild: Boolean + get() = true + + override fun setInstantBuild(player: Player, instantBuild: Boolean) { + val nmsPlayer = (player as CraftPlayer).handle + val playerAbilities = nmsPlayer.abilities + val sendedAbilities: Abilities + if (playerAbilities.instabuild == instantBuild) { + sendedAbilities = playerAbilities + } else { + sendedAbilities = Abilities() + sendedAbilities.invulnerable = playerAbilities.invulnerable + sendedAbilities.flying = playerAbilities.flying + sendedAbilities.mayfly = playerAbilities.mayfly + sendedAbilities.instabuild = instantBuild + sendedAbilities.mayBuild = playerAbilities.mayBuild + sendedAbilities.flyingSpeed = playerAbilities.flyingSpeed + sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed + } + val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities) + nmsPlayer.connection.send(packet) + } +} diff --git a/nms/v1_20R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/FoliaScheduler.kt b/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/FoliaScheduler.kt similarity index 100% rename from nms/v1_20R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/FoliaScheduler.kt rename to nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/FoliaScheduler.kt diff --git a/nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R6_PacketManager.kt b/nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/PaperPacketManager.kt similarity index 100% rename from nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R6_PacketManager.kt rename to nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/PaperPacketManager.kt diff --git a/nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R7_ExternGuiTester.kt b/nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R7_ExternGuiTester.kt deleted file mode 100644 index c380211..0000000 --- a/nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/version/v1_21R7_ExternGuiTester.kt +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.alexcrea.cuanvil.dependency.gui.version - -import org.bukkit.craftbukkit.inventory.CraftInventoryView -import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester - -class v1_21R7_ExternGuiTester: ExternGuiTester { - override val wesjdAnvilGuiName = "Wrapper1_21_R7" - - var tested = false; - var possible = false; - - override fun getContainerClass(view: InventoryView): Class? { - // In case we are in a test environment - if(!tested) testClassExist() - if(!possible) return null - - if(view !is CraftInventoryView<*, *>) return null - val container = view.handle - - return container.javaClass - } - - fun testClassExist(){ - tested = true; - try { - Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView") - possible = true - } catch (e: ClassNotFoundException){ - possible = false - } - } - -} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 0790502..85566be 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,6 +3,8 @@ rootProject.name = "CustomAnvil" // NMS subproject include("nms:nms-common") findProject(":nms:nms-common")?.name = "nms-common" +include("nms:nms-paper") +findProject(":nms:nms-paper")?.name = "nms-paper" include("nms:v1_17R1") findProject(":nms:v1_17R1")?.name = "v1_17R1" include("nms:v1_18R1") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/MinecraftVersionUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/MinecraftVersionUtil.kt new file mode 100644 index 0000000..69ec546 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/MinecraftVersionUtil.kt @@ -0,0 +1,54 @@ +package xyz.alexcrea.cuanvil.dependency + +import xyz.alexcrea.cuanvil.update.UpdateUtils + +object MinecraftVersionUtil { + + val craftbukkitVersion: String? + get() { + val versionParts = UpdateUtils.currentMinecraftVersionArray() + if (versionParts[0] != 1) return null + + return when (versionParts[1]) { + 17 -> when (versionParts[2]) { + 0, 1 -> "1_17R1" + else -> null + } + + 18 -> when (versionParts[2]) { + 0, 1 -> "1_18R1" + 2 -> "1_18R2" + else -> null + } + + 19 -> when (versionParts[2]) { + 0, 1, 2 -> "1_19R1" + 3 -> "1_19R2" + 4 -> "1_19R3" + else -> null + } + + 20 -> when (versionParts[2]) { + 0, 1 -> "1_20R1" + 2 -> "1_20R2" + 3, 4 -> "1_20R3" + 5, 6 -> "1_20R4" + else -> null + } + + 21 -> when (versionParts[2]) { + 0, 1 -> "1_21R1" + 2, 3 -> "1_21R2" + 4 -> "1_21R3" + 5 -> "1_21R4" + 6, 7, 8 -> "1_21R5" + 9, 10 -> "1_21R6" + 11 -> "1_21R7" + else -> null + } + + else -> null + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/PacketManagerSelector.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/PacketManagerSelector.kt index ccb8620..f38b9e4 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/PacketManagerSelector.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/PacketManagerSelector.kt @@ -1,7 +1,10 @@ package xyz.alexcrea.cuanvil.dependency.packet import org.bukkit.Bukkit +import su.nightexpress.nightcore.bridge.paper.PaperBridge +import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil import xyz.alexcrea.cuanvil.dependency.packet.versions.* +import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil import xyz.alexcrea.cuanvil.update.UpdateUtils object PacketManagerSelector { @@ -10,7 +13,9 @@ object PacketManagerSelector { return if (forceProtocolib) protocolibIfPresent else - versionSpecificManager ?: protocolibIfPresent + reobfPacketManager ?: + if(PlatformUtil.isPaper) PaperPacketManager() + else protocolibIfPresent } private val protocolibIfPresent: PacketManager @@ -19,52 +24,21 @@ object PacketManagerSelector { ProtocoLibWrapper() else NoPacketManager() - private val versionSpecificManager: PacketManagerBase? + + // Reobfuscated packet manager for spigot or paper as it remap + private val reobfPacketManager: PacketManagerBase? get() { val versionParts = UpdateUtils.currentMinecraftVersionArray() if (versionParts[0] != 1) return null - return when (versionParts[1]) { - // Can't support 1.16.5 bc 1.16.5 paper userdev do not exist + try { + val clazz = Class.forName("xyz.alexcrea.cuanvil.dependency.packet.versions." + + "V${MinecraftVersionUtil.craftbukkitVersion}_PacketManager") - 17 -> when (versionParts[2]) { - 0, 1 -> V1_17R1_PacketManager() - else -> null - } - - 18 -> when (versionParts[2]) { - 0, 1 -> V1_18R1_PacketManager() - 2 -> V1_18R2_PacketManager() - else -> null - } - - 19 -> when (versionParts[2]) { - 0, 1, 2 -> V1_19R1_PacketManager() - 3 -> V1_19R2_PacketManager() - 4 -> V1_19R3_PacketManager() - else -> null - } - - 20 -> when (versionParts[2]) { - 0, 1 -> V1_20R1_PacketManager() - 2 -> V1_20R2_PacketManager() - 3, 4 -> V1_20R3_PacketManager() - 5, 6 -> V1_20R4_PacketManager() - else -> null - } - - 21 -> when (versionParts[2]) { - 0, 1 -> V1_21R1_PacketManager() - 2, 3 -> V1_21R2_PacketManager() - 4 -> V1_21R3_PacketManager() - 5 -> V1_21R4_PacketManager() - 6, 7, 8 -> V1_21R5_PacketManager() - 9, 10 -> V1_21R6_PacketManager() - 11 -> V1_21R7_PacketManager() - else -> null - } - - else -> null + val manager = clazz.getConstructor().newInstance() + return manager as PacketManagerBase + } catch (e: ClassNotFoundException) { + return null } } } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/BukkitScheduler.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/BukkitScheduler.kt index b26dd42..8c04162 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/BukkitScheduler.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/BukkitScheduler.kt @@ -6,12 +6,12 @@ import org.bukkit.plugin.Plugin class BukkitScheduler : TaskScheduler { - override fun scheduleGlobally(plugin: Plugin, task: Runnable, time: Long): Any? { + override fun scheduleGlobally(plugin: Plugin, task: Runnable, time: Long): Any { return Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, task, time) } - override fun scheduleOnEntity(plugin: Plugin, entity: Entity, task: Runnable, time: Long): Any? { + override fun scheduleOnEntity(plugin: Plugin, entity: Entity, task: Runnable, time: Long): Any { return Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, task, time) } } From 87c99716266255cd155f78f5baa6edfe0ab9c4cb Mon Sep 17 00:00:00 2001 From: alexcrea Date: Thu, 25 Dec 2025 23:49:40 +0100 Subject: [PATCH 10/14] fix spigot and refactor some gradlew things --- build.gradle.kts | 38 ++++++++++++-------------------------- gradle.properties | 5 ++++- settings.gradle.kts | 44 ++++++++++---------------------------------- 3 files changed, 26 insertions(+), 61 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index b209202..b6ad03f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -31,6 +31,9 @@ repositories { maven(url = "https://repo.nightexpressdev.com/releases") } +val reobfNMS = providers.gradleProperty("subprojects.reobfnms") + .get().split(",") + dependencies { // Spigot api compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT") @@ -73,23 +76,9 @@ dependencies { // Include nms implementation(project(":nms:nms-common")) - implementation(project(":nms:v1_17R1", configuration = "reobf")) - implementation(project(":nms:v1_18R1", configuration = "reobf")) - implementation(project(":nms:v1_18R2", configuration = "reobf")) - implementation(project(":nms:v1_19R1", configuration = "reobf")) - implementation(project(":nms:v1_19R2", configuration = "reobf")) - implementation(project(":nms:v1_19R3", configuration = "reobf")) - implementation(project(":nms:v1_20R1", configuration = "reobf")) - implementation(project(":nms:v1_20R2", configuration = "reobf")) - implementation(project(":nms:v1_20R3", configuration = "reobf")) - implementation(project(":nms:v1_20R4", configuration = "reobf")) - implementation(project(":nms:v1_21R1", configuration = "reobf")) - implementation(project(":nms:v1_21R2", configuration = "reobf")) - implementation(project(":nms:v1_21R3", configuration = "reobf")) - implementation(project(":nms:v1_21R4", configuration = "reobf")) - implementation(project(":nms:v1_21R5", configuration = "reobf")) - implementation(project(":nms:v1_21R6", configuration = "reobf")) - implementation(project(":nms:v1_21R7", configuration = "reobf")) + for (nmsPart in reobfNMS) { + implementation(project(":nms:$nmsPart", configuration = "reobf")) + } // include kotlin for the offline jar implementation(kotlin("stdlib")) @@ -169,7 +158,8 @@ tasks { filesMatching("plugin.yml") { expand( "version" to effectiveVersion, - "libraries" to " \"org.jetbrains.kotlin:kotlin-stdlib:2.1.0\" " + "libraries" to " \"org.jetbrains.kotlin:kotlin-stdlib:2.1.0\" " + + ", \"net.kyori:adventure-platform-bukkit:4.4.1\"" ) } @@ -259,13 +249,9 @@ object Meta { const val snapshot = "https://s01.oss.sonatype.org/content/repositories/snapshots/" } -val disalowedDependency = setOf( - "nms-common", "kotlin-stdlib", - "v1_17R1", - "v1_18R1", "v1_18R2", "v1_19R1", "v1_19R2", "v1_19R3", - "v1_20R1", "v1_20R2", "v1_20R3", "v1_20R4", - "v1_21R1", "v1_21R2", "v1_21R3", "v1_21R4", "v1_21R5" -) +val disallowedDependency = HashSet() +disallowedDependency.addAll(reobfNMS) +disallowedDependency.addAll(listOf("nms-common", "nms-paper", "kotlin-stdlib")) publishing { repositories { @@ -333,7 +319,7 @@ publishing { val artifactNode = ((child as Node).get("artifactId") as NodeList)[0] as Node val artifactID = artifactNode.value() as String - if(disalowedDependency.contains(artifactID)) { + if(disallowedDependency.contains(artifactID)) { toRemove.add(child) } } diff --git a/gradle.properties b/gradle.properties index a1f0681..95311bf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,7 @@ kotlin.code.style=official # Signing signing.secretKeyRingFile=~/.gnupg/secring.gpg -kotlin.daemon.jvmargs=-Xmx8G \ No newline at end of file +kotlin.daemon.jvmargs=-Xmx8G + +# list of nms +subprojects.reobfnms=v1_17R1,v1_18R1,v1_18R2,v1_19R1,v1_19R2,v1_19R3,v1_20R1,v1_20R2,v1_20R3,v1_20R4,v1_21R1,v1_21R2,v1_21R3,v1_21R4,v1_21R5,v1_21R6,v1_21R7 \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 0790502..bf069c3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,41 +3,17 @@ rootProject.name = "CustomAnvil" // NMS subproject include("nms:nms-common") findProject(":nms:nms-common")?.name = "nms-common" -include("nms:v1_17R1") -findProject(":nms:v1_17R1")?.name = "v1_17R1" -include("nms:v1_18R1") -findProject(":nms:v1_18R1")?.name = "v1_18R1" -include("nms:v1_18R2") -findProject(":nms:v1_18R2")?.name = "v1_18R2" -include("nms:v1_19R1") -findProject(":nms:v1_19R1")?.name = "v1_19R1" -include("nms:v1_19R2") -findProject(":nms:v1_19R2")?.name = "v1_19R2" -include("nms:v1_19R3") -findProject(":nms:v1_19R3")?.name = "v1_19R3" -include("nms:v1_20R1") -findProject(":nms:v1_20R1")?.name = "v1_20R1" -include("nms:v1_20R2") -findProject(":nms:v1_20R2")?.name = "v1_20R2" -include("nms:v1_20R3") -findProject(":nms:v1_20R3")?.name = "v1_20R3" -include("nms:v1_20R4") -findProject(":nms:v1_20R4")?.name = "v1_20R4" -include("nms:v1_21R1") -findProject(":nms:v1_21R1")?.name = "v1_21R1" -include("nms:v1_21R2") -findProject(":nms:v1_21R2")?.name = "v1_21R2" -include("nms:v1_21R3") -findProject(":nms:v1_21R3")?.name = "v1_21R3" -include("nms:v1_21R4") -findProject(":nms:v1_21R4")?.name = "v1_21R4" -include("nms:v1_21R5") -findProject(":nms:v1_21R5")?.name = "v1_21R5" -include("nms:v1_21R6") -findProject(":nms:v1_21R6")?.name = "v1_21R6" -include("nms:v1_21R7") -findProject(":nms:v1_21R7")?.name = "v1_21R7" + +val reobfNMS = providers.gradleProperty("subprojects.reobfnms") + .get().split(",") + +for (nmsPart in reobfNMS) { + include("nms:$nmsPart") + findProject(":nms:$nmsPart")?.name = nmsPart +} + +// compatibility subprojects include(":impl:LegacyEcoEnchant") findProject(":impl:LegacyEcoEnchant")?.name = "LegacyEcoEnchant" include("impl:ExcellentEnchant5_3") From 1544cd315b7f15759f40460221a06f744d494020 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Fri, 26 Dec 2025 00:51:14 +0100 Subject: [PATCH 11/14] fix older version issue --- nms/nms-common/build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nms/nms-common/build.gradle.kts b/nms/nms-common/build.gradle.kts index 6088e77..67936b9 100644 --- a/nms/nms-common/build.gradle.kts +++ b/nms/nms-common/build.gradle.kts @@ -21,8 +21,8 @@ repositories { // Set target version tasks.withType().configureEach { - sourceCompatibility = "21" - targetCompatibility = "21" + sourceCompatibility = "16" + targetCompatibility = "16" options.encoding = "UTF-8" } @@ -30,6 +30,6 @@ tasks.withType().configureEach { kotlin { compilerOptions { apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) - jvmTarget.set(JvmTarget.JVM_21) + jvmTarget.set(JvmTarget.JVM_16) } } From 59d3c9a85cd1b9ab5ba5cf364b0aaab24d6190f3 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Fri, 26 Dec 2025 01:04:41 +0100 Subject: [PATCH 12/14] update doc --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f5a806..dbe2f00 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,10 @@ as low priority as I work for the plugin on my free time for free. One of the configurations allow displaying price about 40 and removing Too Expensive. \ By how the minecraft client work: price above 40 can only be displayed green, even if the player does not own enough experience level. -Minecraft version 1.17 to 1.21.7 do not need any dependency. Other version need ProtocoLib enabled on your server for this feature. \ +Minecraft version 1.17 to latest marked as supported do not need any dependency. \ +Any recent paper version also are supported for this feature. +But you should wait for update for new version containing new enchantable item or new enchantments. +Other version need ProtocoLib enabled on your server for this feature. \ You can also wait for an update of the plugin to support a newer version. Please note that 1.16.5 to 1.17.1 are not officially supported. Run at your own risk. From 89eec84a6693e7a848fe88f4293f167cdde38b46 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Fri, 26 Dec 2025 01:34:47 +0100 Subject: [PATCH 13/14] update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dbe2f00..bf119e9 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ as low priority as I work for the plugin on my free time for free. One of the configurations allow displaying price about 40 and removing Too Expensive. \ By how the minecraft client work: price above 40 can only be displayed green, even if the player does not own enough experience level. -Minecraft version 1.17 to latest marked as supported do not need any dependency. \ +Minecraft version 1.18 to latest marked as supported do not need any ProtocoLib dependency. \ Any recent paper version also are supported for this feature. But you should wait for update for new version containing new enchantable item or new enchantments. Other version need ProtocoLib enabled on your server for this feature. \ From be7f4d0bcb488db7c1e0dfc79109e5f4fbe78eb0 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Mon, 29 Dec 2025 15:20:28 +0100 Subject: [PATCH 14/14] fix big issue extern gui wrongly tested --- build.gradle.kts | 4 ++-- .../cuanvil/dependency/gui/ExternGuiTester.kt | 5 ++--- .../cuanvil/dependency/gui/GenericExternGuiTester.kt | 11 +++++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index bec4d26..3affa9e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { kotlin("jvm") version "2.1.0" java id("org.jetbrains.dokka").version("1.9.20") - id("com.gradleup.shadow").version("9.0.0-beta16") + id("com.gradleup.shadow").version("9.3.0") // Maven publish `maven-publish` signing @@ -18,7 +18,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.15.7" +version = "1.15.8" val effectiveVersion = "$version" + (if (System.getenv("SMALL_COMMIT_HASH") != null) "-dev-${System.getenv("SMALL_COMMIT_HASH")!!}" else "") diff --git a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/ExternGuiTester.kt b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/ExternGuiTester.kt index 029e4a7..8b06b10 100644 --- a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/ExternGuiTester.kt +++ b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/ExternGuiTester.kt @@ -1,17 +1,16 @@ package xyz.alexcrea.cuanvil.dependency.gui import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil interface ExternGuiTester { fun getContainerClass(view: InventoryView): Class? fun testIfGui(inventory: InventoryView): Boolean { - // container class only allow default bukkit craft view class + // container class only allow default bukkit craft view or test class val clazz = getContainerClass(inventory) - return clazz != null + return clazz == null } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GenericExternGuiTester.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GenericExternGuiTester.kt index 85e32d5..4ff3354 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GenericExternGuiTester.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/gui/GenericExternGuiTester.kt @@ -1,7 +1,6 @@ package xyz.alexcrea.cuanvil.dependency.gui import org.bukkit.inventory.InventoryView -import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil import java.lang.reflect.Method class GenericExternGuiTester: ExternGuiTester { @@ -12,14 +11,16 @@ class GenericExternGuiTester: ExternGuiTester { private const val HANDLE_METHOD_NAME = "getHandle" } - var tested = false + var testExist = false + var inTesting = false var testedClass: String? = null lateinit var getHandleMethod: Method override fun getContainerClass(view: InventoryView): Class? { // In case we are in a test environment - if(!tested) testClassExist() + if(!testExist) testClassExist() + if(inTesting) return view.javaClass //TEMPORARY if(!testedClass.contentEquals(view.javaClass.name)) return null @@ -36,7 +37,7 @@ class GenericExternGuiTester: ExternGuiTester { } fun testClassExist() { - tested = true + testExist = true // We first try to get craft anvil interface, // but is absent on old version so we try craft inventory view before @@ -53,6 +54,8 @@ class GenericExternGuiTester: ExternGuiTester { } catch (_: ClassNotFoundException) {} catch (_: NoSuchMethodException) {} + + inTesting = true } } \ No newline at end of file