diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index a50cacd8..a68ab4d8 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -8,12 +8,9 @@ name: Java CI with Gradle on: - push: - branches: [ "v1.x.x", "v2.x.x" ] - pull_request: - branches: [ "v1.x.x", "v2.x.x" ] release: types: [published] + branches: [ "v1.x.x" ] concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} @@ -26,46 +23,37 @@ jobs: contents: write env: - MODRINTH_VERSIONS: '["1.18.x", "1.19.x", "1.20.x", "1.21.x", "26.1.x", "26.2.x"]' + MODRINTH_VERSIONS: '["1.18.x", "1.19.x", "1.20.x"]' MODRINTH_PLATFORMS: '["spigot", "paper", "purpur", "folia"]' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up JDKs - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: java-version: | 21 distribution: 'temurin' - cache: gradle - - - name: Cache Gradle root and wrapper - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: gradle-root-${{ runner.os }}-${{ hashFiles('build.gradle*') }} - restore-keys: gradle-root-${{ runner.os }}- - - # Setup paperweight cache - - name: Cache paperweight - uses: actions/cache@v3 - with: - path: | - ./nms/*/.gradle/caches/paperweight - key: paperweight-submodules-${{ runner.os }}-${{ hashFiles('nms/*/build.gradle*') }} - restore-keys: | - paperweight-submodules-${{ runner.os }}- # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@v6 - name: Make gradlew executable run: chmod +x ./gradlew + # Setup paperweight cache + - name: Cache paperweight + uses: actions/cache@v6 + with: + path: | + ./nms/*/.gradle/caches/paperweight + ./.gradle/caches/paperweight + key: paperweight-submodules-${{ runner.os }}-${{ hashFiles('nms/*/build.gradle*') }} + restore-keys: | + paperweight-submodules-${{ runner.os }}- + - name: Get small commit hash if: ${{ github.event_name != 'release' && success() }} run: echo "SMALL_COMMIT_HASH=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_ENV @@ -75,7 +63,7 @@ jobs: # only submit dependency on push - name: Generate and submit dependency graph - uses: gradle/actions/dependency-submission@v4 + uses: gradle/actions/dependency-submission@v6 if: ${{ github.event_name == 'push' && success() }} continue-on-error: true @@ -91,16 +79,16 @@ jobs: # upload the named jars as artifact - name: Upload online JAR artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: - name: CustomAnvil.jar path: build/libs/${{ env.ONLINE_JAR_NAME }} + archive: false - name: Upload offline JAR file - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: - name: CustomAnvil-offline.jar path: build/libs/${{ env.OFFLINE_JAR_NAME }} + archive: false - name: Summarize tests results uses: jeantessier/test-summary-action@v1 @@ -109,33 +97,12 @@ jobs: # upload the jar to release - name: Upload jar to release if: ${{ github.event_name == 'release' && success() }} - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@v3 with: files: | build/libs/${{ env.ONLINE_JAR_NAME }} build/libs/${{ env.OFFLINE_JAR_NAME }} - - name: Hangar release - if: ${{ (github.event_name != 'release' || github.event_name != 'push') && github.repository_owner == 'alexcrea' && success() }} - env: - HANGAR_API_TOKEN: ${{ secrets.HANGAR_API_TOKEN }} - RELEASE_CHANGELOG: ${{ github.event.release.body }} - run: ./gradlew publishAllPublicationsToHangar --stacktrace - - - name: Modrinth publish alpha - if: ${{ github.event_name == 'push' && github.repository_owner == 'alexcrea' && success() }} - uses: cloudnode-pro/modrinth-publish@v2 - with: - token: ${{ secrets.MODRINTH_TOKEN }} - project: S75Ueiq9 - name: dev-${{ env.SMALL_COMMIT_HASH }} - version: dev-${{ env.SMALL_COMMIT_HASH }} - loaders: ${{ env.MODRINTH_PLATFORMS }} - game-versions: ${{ env.MODRINTH_VERSIONS }} - channel: alpha - files: build/libs/${{ env.ONLINE_JAR_NAME }} - changelog: ${{ github.event.head_commit.message }} - - name: Modrinth publish release if: ${{ github.event_name == 'release' && github.repository_owner == 'alexcrea' && success() }} uses: cloudnode-pro/modrinth-publish@v2 @@ -156,8 +123,7 @@ jobs: with: webhook-url: ${{ secrets.RELEASE_WEBHOOK_URL }} content: | - ${{ github.event.release.prerelease == false && '<@&1338546156325568642>' || '<@&1352296092989001768>' }} - # New ${{ github.event.release.prerelease && 'beta ' || '' }}version of custom anvil ! <:CustomAnvil:1262550667986342001>([Modrinth](https://modrinth.com/plugin/customanvil), [Hangar](https://hangar.papermc.io/alexcrea/CustomAnvil) and [GitHub](${{ github.event.release.html_url }}) links) - -# note: automated release. spigot is not uploaded yet. + <@&1525259349423947867> + # New bugfix for CustomAnvil v1 ! <:CustomAnvil:1262550667986342001> [Modrinth](https://modrinth.com/plugin/customanvil) and [GitHub](${{ github.event.release.html_url }}) links ${{ github.event.release.body }} diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index 9d37521c..6de29076 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -17,7 +17,7 @@ These plugins have compatibility handled by custom anvil. seek help on custom an Also use ExcellentEnchant max enchant limit - [EcoEnchant](https://www.spigotmc.org/resources/ecoenchants-%E2%AD%95-250-enchantments-%E2%9C%85-create-custom-enchants-%E2%9C%A8-essentials-cmi-support.79573/) by Auxilor: - Need to use /anvilconfigreload or a server restart to add newly added enchantment. + Need to use /ca reload or a server restart to add newly added enchantment. Use EcoEnchant restriction system but new restriction can be added in custom anvil - [Enchantment²](https://www.spigotmc.org/resources/enchants-squared-the-enchantsplus-rewrite-custom-enchantments-that-act-like-vanilla-ones.86747/) by Athlaeos: @@ -40,6 +40,8 @@ Custom Items support is considered unstable. If you find issue please report it - [Disenchantment](https://www.spigotmc.org/resources/disenchantment-1-21-1-1-20-6-new-book-splitting-mechanics.110741/) by H7KZ Partially use Custom Anvil maximum XP settings (>= 6.1.5) +- [EnchantedBook](https://modrinth.com/plugin/enchantedbook) by Minacle + - [HavenBags](https://www.spigotmc.org/resources/havenbags-shulker-like-player-bound-bags-1-17-1-21-4.110420/) by hyperdefined For bag upgrade and skin via anvil. (version >= 1.31.0) diff --git a/README.md b/README.md index 9d9e678e..27d08fac 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,8 @@ ca.bypass.level: Allow player to bypass every level limit (no custom limit) # Command permissions ca.command.reload: Allow administrator to reload the plugin's configs -ca.command.diagnostic: Allow adminastator to diagnistic some simple problem with the plugin +ca.command.diagnostic: Get debug information about the plugin and server +ca.command.enchantment: Allows to set enchantment to holden item ca.config.edit: Allow administrator to edit the plugin's config in game # ----------------------------------------------------------------------------- diff --git a/build.gradle.kts b/build.gradle.kts index 4436e29e..fcde08c8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,24 +5,23 @@ import groovy.util.NodeList import io.papermc.hangarpublishplugin.model.HangarPublication import io.papermc.hangarpublishplugin.model.Platforms import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import java.io.ByteArrayOutputStream plugins { - kotlin("jvm") version "2.3.0" + kotlin("jvm") version "2.4.0" java - id("org.jetbrains.dokka").version("1.9.20") - id("com.gradleup.shadow").version("9.3.0") + id("org.jetbrains.dokka").version("2.2.0") + id("com.gradleup.shadow").version("9.6.1") // Maven publish `maven-publish` signing - id("cn.lalaki.central").version("1.2.8") + id("cn.lalaki.central").version("2.0.8") // Paper - id("io.papermc.paperweight.userdev") version "2.0.0-beta.17" apply false - id("io.papermc.hangar-publish-plugin") version "0.1.2" + id("io.papermc.paperweight.userdev") version "2.0.0-beta.21" apply false + id("io.papermc.hangar-publish-plugin") version "0.1.4" } group = "xyz.alexcrea" -version = "1.17.6" +version = "1.20.1" val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true" @@ -34,9 +33,6 @@ repositories { // EcoEnchants maven(url = "https://repo.auxilor.io/repository/maven-public/") - // ExcellentEnchants - maven(url = "https://repo.nightexpressdev.com/releases") - // ItemsAdder maven(url = "https://maven.devs.beer/") @@ -58,7 +54,7 @@ dependencies { compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT") // fast stats - implementation("dev.faststats.metrics:bukkit:0.27.0") + implementation("dev.faststats.metrics:bukkit:0.29.0") // minimessage implementation("net.kyori:adventure-text-minimessage:4.25.0") @@ -72,21 +68,22 @@ dependencies { compileOnly(files("libs/EnchantsSquared.jar")) // EcoEnchants & item - compileOnly("com.willfp:libreforge:4.79.0:all") - compileOnly("com.willfp:eco:6.74.5") + compileOnly("com.willfp:libreforge:2026.32:all") + compileOnly("com.willfp:eco:2026.32") - compileOnly("com.willfp:EcoEnchants:12.11.1") + compileOnly("com.willfp:EcoEnchants:2026.32:all") compileOnly(project(":impl:LegacyEcoEnchant")) compileOnly("com.willfp:EcoItems:5.66.0") // ExcellentEnchants implementation(project(":impl:ExcellentEnchant5_4")) - compileOnly("su.nightexpress.excellentenchants:Core:5.1.0") { - exclude("org.spigotmc") - } - compileOnly(files("libs/ExcellentEnchants-4.3.3-striped.jar")) // For pre v5 excellent enchants - compileOnly(files("libs/ExcellentEnchants-4.1.0-striped.jar")) // For legacy excellent enchants + compileOnly(files("libs/ExcellentEnchants/ExcellentEnchants-4.3.3-striped.jar")) // For pre v5 excellent enchants + compileOnly(files("libs/ExcellentEnchants/ExcellentEnchants-4.1.0-striped.jar")) // For legacy excellent enchants + // early v5 excellent enchants + compileOnly(files("libs/ExcellentEnchants/Core-5.1.0.jar")) + compileOnly(files("libs/ExcellentEnchants/API-5.1.0.jar")) + compileOnly(files("libs/ExcellentEnchants/main-2.7.9.jar")) // Disenchantment compileOnly(files("libs/Disenchantment-6.1.5.jar")) @@ -168,7 +165,7 @@ allprojects { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_16) } } @@ -180,7 +177,10 @@ tasks { fun ShadowJar.configureBaseShadow(suffix: String, libraries: Array) { val processedSuffix = if(suffix.isEmpty()) "" else "-$suffix" - val name = "${rootProject.name}-${effectiveVersion}${processedSuffix}.jar" + val version = effectiveVersion + val name = "${rootProject.name}-${version}${processedSuffix}.jar" + val librariesExpendTo = libraries.joinToString(transform = { "\"$it\"" }) + archiveFileName.set(name) // Shadow necessary dependency @@ -189,8 +189,8 @@ tasks { filesMatching("plugin.yml") { expand( - "version" to effectiveVersion + processedSuffix, - "libraries" to libraries.joinToString(transform = { "\"$it\"" }), + "version" to version + processedSuffix, + "libraries" to librariesExpendTo, ) } @@ -202,7 +202,7 @@ tasks { shadowJar { configureBaseShadow("", arrayOf( - "org.jetbrains.kotlin:kotlin-stdlib:2.3.0", + "org.jetbrains.kotlin:kotlin-stdlib:2.4.0", "net.kyori:adventure-text-minimessage:4.25.0", "net.kyori:adventure-text-serializer-plain:4.25.0", "net.kyori:adventure-text-serializer-legacy:4.25.0", @@ -214,7 +214,7 @@ tasks { exclude("net/kyori/**") } - val offlineJar by registering(ShadowJar::class) { + val offlineJar = register("offlineJar") { configureBaseShadow("offline", emptyArray()) from(sourceSets.main.get().output) @@ -228,12 +228,12 @@ tasks { } -val sourcesJar by tasks.registering(Jar::class) { +val sourcesJar = tasks.register("sourcesJar") { archiveClassifier.set("sources") from(kotlin.sourceSets.main.get().kotlin) } -val javadocJar by tasks.registering(Jar::class, fun Jar.() { +val javadocJar = tasks.register("javadocJar", fun Jar.() { group = JavaBasePlugin.DOCUMENTATION_GROUP description = "Assembles Javadoc JAR" archiveClassifier.set("javadoc") @@ -357,36 +357,25 @@ publishing { } // hangar publish - -fun executeGitCommand(vararg command: String): String { - val byteOut = ByteArrayOutputStream() - exec { - commandLine = listOf("git", *command) - standardOutput = byteOut - } - return byteOut.toString(Charsets.UTF_8.name()).trim() +fun latestCommitMessage(): Provider { + return providers.exec { + commandLine("git", "log", "-1", "--pretty=%B") + }.standardOutput.asText.map(String::trim) } - -fun latestCommitMessage(): String { - return executeGitCommand("log", "-1", "--pretty=%B") -} - -fun changelog(isOnline: Boolean): String { - var changelog = if(isDevBuild) latestCommitMessage() - else System.getenv("RELEASE_CHANGELOG") - - if(!isOnline) { - changelog = "This is an offline version of the plugin. \\\n" + - "This mean that this plugin libraries are shaded into this plugin \\\n" + - "You likely want to use the normal version of this plugin\n\n" + changelog - } - - if(changelog == null || changelog.isEmpty()) { - changelog = "empty changelog" - } +fun changelog(isOnline: Boolean): Provider { + val changelog = if(isDevBuild) latestCommitMessage() + else providers.environmentVariable("RELEASE_CHANGELOG") return changelog + .filter{!it.isEmpty()} + .map { + if(!isOnline) + return@map "This is an offline version of the plugin. \\\n" + + "This mean that this plugin libraries are shaded into this plugin \\\n" + + "You likely want to use the normal version of this plugin\n\n" + it + else return@map it + }.orElse("empty changelog") } hangarPublish { @@ -400,6 +389,7 @@ hangarPublish { channel.set(if (isDevBuild || isPreRelease) devChannel else releaseChannel) changelog.set(changelog(isOnline)) + id.set("CustomAnvil") apiKey.set(System.getenv("HANGAR_API_TOKEN")) diff --git a/defaultconfigs/1.18/config.yml b/defaultconfigs/1.18/config.yml index 4e08ca20..7574edd8 100644 --- a/defaultconfigs/1.18/config.yml +++ b/defaultconfigs/1.18/config.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # What service of metric should custom anvil use diff --git a/defaultconfigs/1.18/enchant_conflict.yml b/defaultconfigs/1.18/enchant_conflict.yml index 45d62c34..047b1b26 100644 --- a/defaultconfigs/1.18/enchant_conflict.yml +++ b/defaultconfigs/1.18/enchant_conflict.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # material conflicts @@ -160,13 +160,6 @@ 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 ] diff --git a/defaultconfigs/1.18/item_groups.yml b/defaultconfigs/1.18/item_groups.yml index 3c1eb5d0..7956fb61 100644 --- a/defaultconfigs/1.18/item_groups.yml +++ b/defaultconfigs/1.18/item_groups.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # Please note this config use spigot material names. diff --git a/defaultconfigs/1.18/unit_repair_item.yml b/defaultconfigs/1.18/unit_repair_item.yml index 2902cce4..a8bbcbe3 100644 --- a/defaultconfigs/1.18/unit_repair_item.yml +++ b/defaultconfigs/1.18/unit_repair_item.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # Unit repair configuration diff --git a/defaultconfigs/1.21.11/config.yml b/defaultconfigs/1.21.11/config.yml index 98f9a94d..22de446f 100644 --- a/defaultconfigs/1.21.11/config.yml +++ b/defaultconfigs/1.21.11/config.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # What service of metric should custom anvil use @@ -154,7 +154,6 @@ enchant_limits: minecraft:knockback: 2 minecraft:fire_aspect: 2 minecraft:looting: 3 - minecraft:sweeping: 3 minecraft:sweeping_edge: 3 minecraft:efficiency: 5 minecraft:unbreaking: 3 @@ -293,9 +292,6 @@ enchant_values: minecraft:swift_sneak: item: 8 book: 4 - minecraft:sweeping: - item: 4 - book: 2 minecraft:sweeping_edge: item: 4 book: 2 @@ -480,6 +476,32 @@ monetary_cost: work_penalty: 1.0 # for work penalty (aka use penalty) recipe: 1.0 # for custom anvil recipe cost +# Chance that an anvil get degraded +# set it to zero if you wish to disable it +anvil_degradation: 0.12 + +# see https://www.digminecraft.com/lists/sound_list_pc.php +# for a list of most of the sounds +anvil_sound: + enabled: true + # The sound are weighted so if there is multiples of them one is selected randomly + # so if you want to add a "rare sound" as an easter egg you can ! + # If invalid, it will be removed from the list. and if empty it will use the default + use: + default: + sound: block.anvil.use + category: blocks + volume: 1.0 + pitch: 1.0 + weight: 1.0 + destroy: + default: + sound: block.anvil.destroy + category: blocks + volume: 1.0 + pitch: 1.0 + weight: 1.0 + # Whether to show debug logging debug_log: false @@ -489,5 +511,5 @@ debug_log_verbose: false # Whether to show inside the console or require to run /ca debug get display_debug_in_console: false -configVersion: 1.15.5 +configVersion: 1.17.7 lowMinecraftVersion: 1.21.11 diff --git a/defaultconfigs/1.21.11/enchant_conflict.yml b/defaultconfigs/1.21.11/enchant_conflict.yml index 3d62daeb..bbbeac71 100644 --- a/defaultconfigs/1.21.11/enchant_conflict.yml +++ b/defaultconfigs/1.21.11/enchant_conflict.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # material conflicts @@ -270,16 +270,12 @@ restriction_soul_speed: 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: diff --git a/defaultconfigs/1.21.11/item_groups.yml b/defaultconfigs/1.21.11/item_groups.yml index 9f2a877e..e2ebdb3e 100644 --- a/defaultconfigs/1.21.11/item_groups.yml +++ b/defaultconfigs/1.21.11/item_groups.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # Please note this config use spigot material names. diff --git a/defaultconfigs/1.21.11/unit_repair_item.yml b/defaultconfigs/1.21.11/unit_repair_item.yml index ed981b18..24f8460b 100644 --- a/defaultconfigs/1.21.11/unit_repair_item.yml +++ b/defaultconfigs/1.21.11/unit_repair_item.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # Unit repair configuration @@ -104,7 +104,7 @@ leather: phantom_membrane: elytra: 0.25 -scute: +turtle_scute: turtle_helmet: 0.25 oak_planks: diff --git a/defaultconfigs/1.21.9/config.yml b/defaultconfigs/1.21.9/config.yml index 7b3afce1..4d1ae9d6 100644 --- a/defaultconfigs/1.21.9/config.yml +++ b/defaultconfigs/1.21.9/config.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # What service of metric should custom anvil use @@ -152,7 +152,6 @@ enchant_limits: minecraft:knockback: 2 minecraft:fire_aspect: 2 minecraft:looting: 3 - minecraft:sweeping: 3 minecraft:sweeping_edge: 3 minecraft:efficiency: 5 minecraft:unbreaking: 3 @@ -290,9 +289,6 @@ enchant_values: minecraft:swift_sneak: item: 8 book: 4 - minecraft:sweeping: - item: 4 - book: 2 minecraft:sweeping_edge: item: 4 book: 2 @@ -472,6 +468,33 @@ monetary_cost: work_penalty: 1.0 # for work penalty (aka use penalty) recipe: 1.0 # for custom anvil recipe cost +# Chance that an anvil get degraded +# set it to zero if you wish to disable it +anvil_degradation: 0.12 + +# see https://www.digminecraft.com/lists/sound_list_pc.php +# for a list of most of the sounds +anvil_sound: + enabled: true + # The sound are weighted so if there is multiples of them one is selected randomly + # so if you want to add a "rare sound" as an easter egg you can ! + # If invalid, it will be removed from the list. and if empty it will use the default + use: + default: + sound: block.anvil.use + category: blocks + volume: 1.0 + pitch: 1.0 + weight: 1.0 + destroy: + default: + sound: block.anvil.destroy + category: blocks + volume: 1.0 + pitch: 1.0 + weight: 1.0 + + # Whether to show debug logging debug_log: false diff --git a/defaultconfigs/1.21.9/enchant_conflict.yml b/defaultconfigs/1.21.9/enchant_conflict.yml index 9205061e..c161982e 100644 --- a/defaultconfigs/1.21.9/enchant_conflict.yml +++ b/defaultconfigs/1.21.9/enchant_conflict.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # material conflicts @@ -267,16 +267,12 @@ restriction_soul_speed: 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: diff --git a/defaultconfigs/1.21.9/item_groups.yml b/defaultconfigs/1.21.9/item_groups.yml index 2dbd5db6..a1af375e 100644 --- a/defaultconfigs/1.21.9/item_groups.yml +++ b/defaultconfigs/1.21.9/item_groups.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # Please note this config use spigot material names. diff --git a/defaultconfigs/1.21.9/unit_repair_item.yml b/defaultconfigs/1.21.9/unit_repair_item.yml index 0ce2bce5..1f256100 100644 --- a/defaultconfigs/1.21.9/unit_repair_item.yml +++ b/defaultconfigs/1.21.9/unit_repair_item.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # Unit repair configuration @@ -98,7 +98,7 @@ leather: phantom_membrane: elytra: 0.25 -scute: +turtle_scute: turtle_helmet: 0.25 oak_planks: diff --git a/defaultconfigs/1.21/config.yml b/defaultconfigs/1.21/config.yml index cb7e382b..50b94f1b 100644 --- a/defaultconfigs/1.21/config.yml +++ b/defaultconfigs/1.21/config.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # What service of metric should custom anvil use @@ -152,7 +152,6 @@ enchant_limits: minecraft:knockback: 2 minecraft:fire_aspect: 2 minecraft:looting: 3 - minecraft:sweeping: 3 minecraft:sweeping_edge: 3 minecraft:efficiency: 5 minecraft:unbreaking: 3 @@ -287,9 +286,6 @@ enchant_values: minecraft:swift_sneak: item: 8 book: 4 - minecraft:sweeping: - item: 4 - book: 2 minecraft:sweeping_edge: item: 4 book: 2 @@ -460,6 +456,33 @@ monetary_cost: work_penalty: 1.0 # for work penalty (aka use penalty) recipe: 1.0 # for custom anvil recipe cost +# Chance that an anvil get degraded +# set it to zero if you wish to disable it +anvil_degradation: 0.12 + +# see https://www.digminecraft.com/lists/sound_list_pc.php +# for a list of most of the sounds +anvil_sound: + enabled: true + # The sound are weighted so if there is multiples of them one is selected randomly + # so if you want to add a "rare sound" as an easter egg you can ! + # If invalid, it will be removed from the list. and if empty it will use the default + use: + default: + sound: block.anvil.use + category: blocks + volume: 1.0 + pitch: 1.0 + weight: 1.0 + destroy: + default: + sound: block.anvil.destroy + category: blocks + volume: 1.0 + pitch: 1.0 + weight: 1.0 + + # Whether to show debug logging debug_log: false diff --git a/defaultconfigs/1.21/enchant_conflict.yml b/defaultconfigs/1.21/enchant_conflict.yml index 45d62c34..1806abd4 100644 --- a/defaultconfigs/1.21/enchant_conflict.yml +++ b/defaultconfigs/1.21/enchant_conflict.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # material conflicts @@ -157,13 +157,10 @@ restriction_soul_speed: notAffectedGroups: [ enchanted_book, boots ] restriction_sweeping_edge: - enchantments: [ minecraft:sweeping, minecraft:sweeping_edge ] + enchantments: [ 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 ] diff --git a/defaultconfigs/1.21/item_groups.yml b/defaultconfigs/1.21/item_groups.yml index 3c1eb5d0..7956fb61 100644 --- a/defaultconfigs/1.21/item_groups.yml +++ b/defaultconfigs/1.21/item_groups.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # Please note this config use spigot material names. diff --git a/defaultconfigs/1.21/unit_repair_item.yml b/defaultconfigs/1.21/unit_repair_item.yml index 2902cce4..3fafd476 100644 --- a/defaultconfigs/1.21/unit_repair_item.yml +++ b/defaultconfigs/1.21/unit_repair_item.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # Unit repair configuration @@ -98,7 +98,7 @@ leather: phantom_membrane: elytra: 0.25 -scute: +turtle_scute: turtle_helmet: 0.25 oak_planks: diff --git a/gradle.properties b/gradle.properties index 4397d2e8..b9c47c92 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,5 @@ kotlin.code.style=official +org.gradle.configuration-cache=true # Signing signing.secretKeyRingFile=~/.gnupg/secring.gpg @@ -6,8 +7,8 @@ signing.secretKeyRingFile=~/.gnupg/secring.gpg 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 +subprojects.reobfnms=v1_17R1,v1_18R1,v1_18R2 # list of version for hangar release -paperVersion=1.18-26.2 +paperVersion=1.18-1.20.5 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0b55a3bd..8bf5ce26 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/impl/ExcellentEnchant5_4/build.gradle.kts b/impl/ExcellentEnchant5_4/build.gradle.kts index 9fe598b1..e624d159 100644 --- a/impl/ExcellentEnchant5_4/build.gradle.kts +++ b/impl/ExcellentEnchant5_4/build.gradle.kts @@ -2,7 +2,7 @@ group = rootProject.group version = rootProject.version plugins { - kotlin("jvm") version "2.3.0" + kotlin("jvm") version "2.4.0" } repositories { diff --git a/impl/LegacyEcoEnchant/build.gradle.kts b/impl/LegacyEcoEnchant/build.gradle.kts index 83057a73..00ecd1b8 100644 --- a/impl/LegacyEcoEnchant/build.gradle.kts +++ b/impl/LegacyEcoEnchant/build.gradle.kts @@ -2,7 +2,7 @@ group = rootProject.group version = rootProject.version plugins { - kotlin("jvm") version "2.3.0" + kotlin("jvm") version "2.4.0" } // Imitate needed class and method to support legacy version of EcoEnchant diff --git a/libs/ExcellentEnchants/API-5.1.0.jar b/libs/ExcellentEnchants/API-5.1.0.jar new file mode 100644 index 00000000..855724b5 Binary files /dev/null and b/libs/ExcellentEnchants/API-5.1.0.jar differ diff --git a/libs/ExcellentEnchants/Core-5.1.0.jar b/libs/ExcellentEnchants/Core-5.1.0.jar new file mode 100644 index 00000000..8899ac49 Binary files /dev/null and b/libs/ExcellentEnchants/Core-5.1.0.jar differ diff --git a/libs/ExcellentEnchants-4.1.0-striped.jar b/libs/ExcellentEnchants/ExcellentEnchants-4.1.0-striped.jar similarity index 100% rename from libs/ExcellentEnchants-4.1.0-striped.jar rename to libs/ExcellentEnchants/ExcellentEnchants-4.1.0-striped.jar diff --git a/libs/ExcellentEnchants-4.3.3-striped.jar b/libs/ExcellentEnchants/ExcellentEnchants-4.3.3-striped.jar similarity index 100% rename from libs/ExcellentEnchants-4.3.3-striped.jar rename to libs/ExcellentEnchants/ExcellentEnchants-4.3.3-striped.jar diff --git a/libs/ExcellentEnchants/main-2.7.9.jar b/libs/ExcellentEnchants/main-2.7.9.jar new file mode 100644 index 00000000..8ae699ed Binary files /dev/null and b/libs/ExcellentEnchants/main-2.7.9.jar differ diff --git a/nms/nms-common/build.gradle.kts b/nms/nms-common/build.gradle.kts index 950d8072..a75f9477 100644 --- a/nms/nms-common/build.gradle.kts +++ b/nms/nms-common/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_16) } } diff --git a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PaperSpigotUtil.kt b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PlatformUtil.kt similarity index 70% rename from nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PaperSpigotUtil.kt rename to nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PlatformUtil.kt index 3f709c7f..aaa218fa 100644 --- a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PaperSpigotUtil.kt +++ b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/util/PlatformUtil.kt @@ -37,7 +37,7 @@ object PlatformUtil { // Lore fun ItemMeta.componentLore(): MutableList { val lore: List? - if(isPaper){ + if (isPaper) { lore = this.lore() } else { val legacyLores = this.lore ?: return ArrayList() @@ -52,49 +52,41 @@ object PlatformUtil { } fun ItemMeta.setComponentLore(lore: List) { - if(isPaper){ + if (isPaper) { this.lore(lore) } else { val legacyLore = ArrayList(lore.size) for (component in lore) { - legacyLore.add(if(component == null) null - else legacy_mm.serialize(component)) + legacyLore.add( + if (component == null) null + else legacy_mm.serialize(component) + ) } this.lore = legacyLore } } - // Display name - private val useCustomName = hasMethod(ItemStack::class.java, "customName") - fun ItemMeta.componentDisplayName(): Component? { - if(useCustomName){ - if(!this.hasCustomName()) return null - return this.customName() - }else if(isPaper){ - if(!this.hasDisplayName()) return null - return this.displayName() - } else { - if(!this.hasDisplayName()) return null + if (!this.hasDisplayName()) return null - val legacy = this.displayName - return legacy_mm.deserialize(legacy) + return if (isPaper) { + this.displayName() + } else { + legacy_mm.deserialize(this.displayName) } } - fun ItemMeta.setComponentDisplayName(component: Component?) { - if(useCustomName){ - this.customName(component) - }else if(isPaper){ + fun ItemMeta.setComponentDisplayName(component: Component?, fallback: String? = null) { + if (isPaper) { this.displayName(component) } else { - if(component == null){ + if (component == null) { this.setDisplayName(null) return } - val legacy = legacy_mm.serialize(component) + val legacy = fallback ?: legacy_mm.serialize(component) this.setDisplayName(legacy) } } diff --git a/nms/nms-paper/build.gradle.kts b/nms/nms-paper/build.gradle.kts index d0e12a76..85a5537e 100644 --- a/nms/nms-paper/build.gradle.kts +++ b/nms/nms-paper/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_18) } } diff --git a/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt b/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt index 9003fdf4..4ec2349b 100644 --- a/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt +++ b/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackTester.kt @@ -1,3 +1,4 @@ +@file:Suppress("DEPRECATION", "removal") package xyz.alexcrea.cuanvil.dependency.datapack import io.papermc.paper.datapack.Datapack @@ -21,18 +22,21 @@ object DataPackTester { return Bukkit.getDatapackManager().enabledPacks .stream().map { obj: Datapack -> obj.name } .toList() - } catch (e: NoSuchMethodException) { + } catch (_: NoSuchMethodException) { try { DataPack::class.java.getDeclaredMethod("getKey") - } catch (e: NoSuchMethodException) { + } catch (_: NoSuchMethodException) { System.err.println("Could not find compatible datapack manager") System.err.println("If you are using a datapack that should be compatible with CustomAnvil. It will not get detected...") return emptyList() } return legacyNames - } catch (e: Exception){ + } catch (_: Exception){ // Assume cause UnimplementedOperationException on mock server return Collections.emptyList() + } catch(_: NoSuchMethodError) { + // Idk newer spigot may not have that ? + return Collections.emptyList() } } } diff --git a/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilTitleUtil.kt b/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilTitleUtil.kt index e40e7ede..cf9686c4 100644 --- a/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilTitleUtil.kt +++ b/nms/nms-paper/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilTitleUtil.kt @@ -12,6 +12,7 @@ object AnvilTitleUtil { private val runTaskMap = HashMap() + @Suppress("DEPRECATION") private fun actualRename(view: InventoryView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog) { runTaskMap.remove(player.uniqueId) if (view.title == name) return diff --git a/nms/v1_17R1/build.gradle.kts b/nms/v1_17R1/build.gradle.kts index c354b1ce..45599335 100644 --- a/nms/v1_17R1/build.gradle.kts +++ b/nms/v1_17R1/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_16) } } diff --git a/nms/v1_18R1/build.gradle.kts b/nms/v1_18R1/build.gradle.kts index 44873d5a..9c334f3c 100644 --- a/nms/v1_18R1/build.gradle.kts +++ b/nms/v1_18R1/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_17) } } diff --git a/nms/v1_18R2/build.gradle.kts b/nms/v1_18R2/build.gradle.kts index cf349ec6..3d31ad63 100644 --- a/nms/v1_18R2/build.gradle.kts +++ b/nms/v1_18R2/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_17) } } diff --git a/nms/v1_19R1/build.gradle.kts b/nms/v1_19R1/build.gradle.kts index 9791b9b9..fdd9d07a 100644 --- a/nms/v1_19R1/build.gradle.kts +++ b/nms/v1_19R1/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_17) } } diff --git a/nms/v1_19R2/build.gradle.kts b/nms/v1_19R2/build.gradle.kts index 88f1a8ad..bab486de 100644 --- a/nms/v1_19R2/build.gradle.kts +++ b/nms/v1_19R2/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_17) } } diff --git a/nms/v1_19R3/build.gradle.kts b/nms/v1_19R3/build.gradle.kts index 3d609af4..41d70647 100644 --- a/nms/v1_19R3/build.gradle.kts +++ b/nms/v1_19R3/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_17) } } diff --git a/nms/v1_20R1/build.gradle.kts b/nms/v1_20R1/build.gradle.kts index 67b46b5e..3bec3f81 100644 --- a/nms/v1_20R1/build.gradle.kts +++ b/nms/v1_20R1/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_18) } } diff --git a/nms/v1_20R2/build.gradle.kts b/nms/v1_20R2/build.gradle.kts index e8417cd8..0b28d317 100644 --- a/nms/v1_20R2/build.gradle.kts +++ b/nms/v1_20R2/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_18) } } diff --git a/nms/v1_20R3/build.gradle.kts b/nms/v1_20R3/build.gradle.kts index c49ff48d..2a6d822d 100644 --- a/nms/v1_20R3/build.gradle.kts +++ b/nms/v1_20R3/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_18) } } diff --git a/nms/v1_20R4/build.gradle.kts b/nms/v1_20R4/build.gradle.kts index 3b98361e..821c3cd3 100644 --- a/nms/v1_20R4/build.gradle.kts +++ b/nms/v1_20R4/build.gradle.kts @@ -29,7 +29,7 @@ tasks.withType().configureEach { kotlin { compilerOptions { - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) jvmTarget.set(JvmTarget.JVM_18) } } diff --git a/nms/v1_20R4/src/main/kotlin/xyz/alexcrea/cuanvil/util/MaxDamageCheckerUtil.kt b/nms/v1_20R4/src/main/kotlin/xyz/alexcrea/cuanvil/util/MaxDamageCheckerUtil.kt index b3ce0ff6..a05d9425 100644 --- a/nms/v1_20R4/src/main/kotlin/xyz/alexcrea/cuanvil/util/MaxDamageCheckerUtil.kt +++ b/nms/v1_20R4/src/main/kotlin/xyz/alexcrea/cuanvil/util/MaxDamageCheckerUtil.kt @@ -1,5 +1,6 @@ package xyz.alexcrea.cuanvil.util +import org.bukkit.Material import org.bukkit.inventory.meta.Damageable // I LOVE support of old versions and needing to do modules like that @@ -10,8 +11,8 @@ object MaxDamageCheckerUtil { /** * @return max damage or int max if not set */ - fun getMaxDamage(meta: Damageable): Int { - if(!meta.hasMaxDamage()) return Integer.MAX_VALUE + fun getMaxDamage(type: Material, meta: Damageable): Int { + if(!meta.hasMaxDamage()) return type.maxDurability.toInt() return meta.maxDamage } diff --git a/nms/v1_21R1/.gitignore b/nms/v1_21R1/.gitignore deleted file mode 100644 index 47374f17..00000000 --- a/nms/v1_21R1/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.lastDeploymentsId \ No newline at end of file diff --git a/nms/v1_21R1/build.gradle.kts b/nms/v1_21R1/build.gradle.kts deleted file mode 100644 index bf2152cc..00000000 --- a/nms/v1_21R1/build.gradle.kts +++ /dev/null @@ -1,35 +0,0 @@ -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.1-R0.1-SNAPSHOT") -} - -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_2) - jvmTarget.set(JvmTarget.JVM_21) - } -} diff --git a/nms/v1_21R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R1_PacketManager.kt b/nms/v1_21R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R1_PacketManager.kt deleted file mode 100644 index 4ea99508..00000000 --- a/nms/v1_21R1/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R1_PacketManager.kt +++ /dev/null @@ -1,33 +0,0 @@ -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_21R1_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) - } -} diff --git a/nms/v1_21R2/.gitignore b/nms/v1_21R2/.gitignore deleted file mode 100644 index 47374f17..00000000 --- a/nms/v1_21R2/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.lastDeploymentsId \ No newline at end of file diff --git a/nms/v1_21R2/build.gradle.kts b/nms/v1_21R2/build.gradle.kts deleted file mode 100644 index e65f6fd8..00000000 --- a/nms/v1_21R2/build.gradle.kts +++ /dev/null @@ -1,35 +0,0 @@ -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.3-R0.1-SNAPSHOT") -} - -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_2) - jvmTarget.set(JvmTarget.JVM_21) - } -} diff --git a/nms/v1_21R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R2_PacketManager.kt b/nms/v1_21R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R2_PacketManager.kt deleted file mode 100644 index 9d88c20b..00000000 --- a/nms/v1_21R2/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R2_PacketManager.kt +++ /dev/null @@ -1,33 +0,0 @@ -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_21R2_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) - } -} diff --git a/nms/v1_21R3/.gitignore b/nms/v1_21R3/.gitignore deleted file mode 100644 index 47374f17..00000000 --- a/nms/v1_21R3/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.lastDeploymentsId \ No newline at end of file diff --git a/nms/v1_21R3/build.gradle.kts b/nms/v1_21R3/build.gradle.kts deleted file mode 100644 index d06816cc..00000000 --- a/nms/v1_21R3/build.gradle.kts +++ /dev/null @@ -1,35 +0,0 @@ -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.4-R0.1-SNAPSHOT") -} - -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_2) - jvmTarget.set(JvmTarget.JVM_21) - } -} diff --git a/nms/v1_21R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R3_PacketManager.kt b/nms/v1_21R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R3_PacketManager.kt deleted file mode 100644 index 0f581d96..00000000 --- a/nms/v1_21R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R3_PacketManager.kt +++ /dev/null @@ -1,33 +0,0 @@ -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_21R3_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) - } -} diff --git a/nms/v1_21R4/.gitignore b/nms/v1_21R4/.gitignore deleted file mode 100644 index 47374f17..00000000 --- a/nms/v1_21R4/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.lastDeploymentsId \ No newline at end of file diff --git a/nms/v1_21R4/build.gradle.kts b/nms/v1_21R4/build.gradle.kts deleted file mode 100644 index 8bd22b9f..00000000 --- a/nms/v1_21R4/build.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ -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.5-R0.1-SNAPSHOT") -} - -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_2) - jvmTarget.set(JvmTarget.JVM_21) - } -} diff --git a/nms/v1_21R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R4_PacketManager.kt b/nms/v1_21R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R4_PacketManager.kt deleted file mode 100644 index b1236256..00000000 --- a/nms/v1_21R4/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R4_PacketManager.kt +++ /dev/null @@ -1,33 +0,0 @@ -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_21R4_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) - } -} diff --git a/nms/v1_21R5/.gitignore b/nms/v1_21R5/.gitignore deleted file mode 100644 index 47374f17..00000000 --- a/nms/v1_21R5/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.lastDeploymentsId \ No newline at end of file diff --git a/nms/v1_21R5/build.gradle.kts b/nms/v1_21R5/build.gradle.kts deleted file mode 100644 index e7f7c47c..00000000 --- a/nms/v1_21R5/build.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ -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.6-R0.1-SNAPSHOT") -} - -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_2) - jvmTarget.set(JvmTarget.JVM_21) - } -} diff --git a/nms/v1_21R5/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R5_PacketManager.kt b/nms/v1_21R5/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R5_PacketManager.kt deleted file mode 100644 index 561a6af4..00000000 --- a/nms/v1_21R5/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R5_PacketManager.kt +++ /dev/null @@ -1,33 +0,0 @@ -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_21R5_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) - } -} diff --git a/nms/v1_21R6/.gitignore b/nms/v1_21R6/.gitignore deleted file mode 100644 index 47374f17..00000000 --- a/nms/v1_21R6/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.lastDeploymentsId \ No newline at end of file diff --git a/nms/v1_21R6/build.gradle.kts b/nms/v1_21R6/build.gradle.kts deleted file mode 100644 index 3189b5cb..00000000 --- a/nms/v1_21R6/build.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ -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.10-R0.1-SNAPSHOT") -} - -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_2) - jvmTarget.set(JvmTarget.JVM_21) - } -} diff --git a/nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/PaperPacketManager.kt b/nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/PaperPacketManager.kt deleted file mode 100644 index ee006666..00000000 --- a/nms/v1_21R6/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/PaperPacketManager.kt +++ /dev/null @@ -1,33 +0,0 @@ -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_21R6_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/nms/v1_21R7/.gitignore b/nms/v1_21R7/.gitignore deleted file mode 100644 index 47374f17..00000000 --- a/nms/v1_21R7/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.lastDeploymentsId \ No newline at end of file diff --git a/nms/v1_21R7/build.gradle.kts b/nms/v1_21R7/build.gradle.kts deleted file mode 100644 index 91c3111a..00000000 --- a/nms/v1_21R7/build.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ -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-R0.1-SNAPSHOT") -} - -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_2) - jvmTarget.set(JvmTarget.JVM_21) - } -} 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 deleted file mode 100644 index 59ae9ceb..00000000 --- a/nms/v1_21R7/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/versions/V1_21R7_PacketManager.kt +++ /dev/null @@ -1,33 +0,0 @@ -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/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index 965d7495..3e8bb8af 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -128,7 +128,7 @@ public class EnchantmentApi { * @return The custom anvil enchantment of this key. null if not found. */ @Nullable - public static CAEnchantment getByKey(@NotNull NamespacedKey key) { + public static CAEnchantment getByKey(@Nullable NamespacedKey key) { return CAEnchantment.getByKey(key); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/UnitRepairApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/UnitRepairApi.java index bc50c162..f5df41bc 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/UnitRepairApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/UnitRepairApi.java @@ -3,18 +3,16 @@ package xyz.alexcrea.cuanvil.api; import io.delilaheve.CustomAnvil; import kotlin.Triple; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.dependency.DependencyManager; import xyz.alexcrea.cuanvil.gui.config.global.UnitRepairConfigGui; -import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.UnitRepairElementListGui; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; /** * Custom Anvil api for unit repair. @@ -22,7 +20,8 @@ import java.util.List; @SuppressWarnings("unused") public class UnitRepairApi { - private UnitRepairApi(){} + private UnitRepairApi() { + } private static Object saveChangeTask = null; @@ -35,7 +34,20 @@ public class UnitRepairApi { * @param repairable The item to be repaired. * @return true if successful. */ - public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable){ + public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable) { + return addUnitRepair(unit, repairable, 0.25, false); + } + + /** + * Write and add a custom anvil unit repair recipe. + * Will not write the recipe if it already exists or was deleted. + * Set the value to minecraft default value (0.25 = 25%) + * + * @param unit The unit material used to repair the bellow item. + * @param repairable The item to be repaired. + * @return true if successful. + */ + public static boolean addUnitRepair(@NotNull NamespacedKey unit, @NotNull NamespacedKey repairable) { return addUnitRepair(unit, repairable, 0.25, false); } @@ -48,7 +60,7 @@ public class UnitRepairApi { * @param value The amount to be repaired by every unit. (1% = 0.01) * @return true if successful. */ - public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value){ + public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value) { return addUnitRepair(unit, repairable, value, false); } @@ -62,12 +74,26 @@ public class UnitRepairApi { * @param overrideDeleted If we should write even if the recipe was previously deleted. * @return true if successful. */ - public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value, boolean overrideDeleted){ - FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); - String path = unit.name().toLowerCase() + "." + repairable.name().toLowerCase(); + public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value, boolean overrideDeleted) { + return addUnitRepair(unit.getKey(), repairable.getKey(), value, overrideDeleted); + } - if(!overrideDeleted && ConfigHolder.UNIT_REPAIR_HOLDER.isDeleted(path)) return false; - if(config.contains(path)) return false; + /** + * Write and add a custom anvil unit repair recipe. + * Will not write the recipe if it already exists. + * + * @param unit The unit material used to repair the bellow item. + * @param repairable The item to be repaired. + * @param value The amount to be repaired by every unit. (1% = 0.01) + * @param overrideDeleted If we should write even if the recipe was previously deleted. + * @return true if successful. + */ + public static boolean addUnitRepair(@NotNull NamespacedKey unit, @NotNull NamespacedKey repairable, double value, boolean overrideDeleted) { + FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); + String path = unit.toString().toLowerCase() + "." + repairable.toString().toLowerCase(); + + if (!overrideDeleted && ConfigHolder.UNIT_REPAIR_HOLDER.isDeleted(path)) return false; + if (config.contains(path)) return false; // Set unit repair return setUnitRepair(unit, repairable, value); @@ -82,11 +108,24 @@ public class UnitRepairApi { * @param value The amount to be repaired by every unit. (1% = 0.01) * @return true if successful. */ - public static boolean setUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value){ + public static boolean setUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value) { + return setUnitRepair(unit.getKey(), repairable.getKey(), value); + } + + /** + * Write and add a custom anvil unit repair recipe. + * Do not check if it previously existed or exist. + * + * @param unit The unit material used to repair the bellow item. + * @param repairable The item to be repaired. + * @param value The amount to be repaired by every unit. (1% = 0.01) + * @return true if successful. + */ + public static boolean setUnitRepair(@NotNull NamespacedKey unit, @NotNull NamespacedKey repairable, double value) { FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); - String repairableName = repairable.name().toLowerCase(); - String path = unit.name().toLowerCase() + "." + repairableName; + String repairableName = repairable.toString().toLowerCase(); + String path = unit.toString().toLowerCase() + "." + repairableName; // Add to config then prepare save config.set(path, value); @@ -94,10 +133,10 @@ public class UnitRepairApi { // Add to gui UnitRepairConfigGui repairConfigGui = UnitRepairConfigGui.getCurrentInstance(); - if(repairConfigGui != null) { + if (repairConfigGui != null) { UnitRepairElementListGui elementGui = repairConfigGui.getInstanceOrCreate(unit).getStored(); - if(elementGui != null) elementGui.updateValueForGeneric(repairableName, true); + if (elementGui != null) elementGui.updateValueForGeneric(repairable, true); repairConfigGui.updateValueForGeneric(unit, true); } @@ -111,48 +150,56 @@ public class UnitRepairApi { * @param repairable The item used to be repaired. * @return true if successful. */ - public static boolean removeUnitRepair(@NotNull Material unit, @NotNull Material repairable){ + public static boolean removeUnitRepair(@NotNull Material unit, @NotNull Material repairable) { + return removeUnitRepair(unit.getKey(), repairable.getKey()); + } + + /** + * Remove a custom anvil unit repair recipe. + * + * @param unit The unit material used to repair the bellow item. + * @param repairable The item used to be repaired. + * @return true if successful. + */ + public static boolean removeUnitRepair(@NotNull NamespacedKey unit, @NotNull NamespacedKey repairable) { // Delete every possible variation and save to file - String unitName = unit.name(); - String repairableName = repairable.name(); FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); - config.set(unitName.toLowerCase() + "." + repairableName.toUpperCase(), null); - config.set(unitName.toUpperCase() + "." + repairableName.toLowerCase(), null); - config.set(unitName.toUpperCase() + "." + repairableName.toUpperCase(), null); - config.set(unitName.toLowerCase() + "." + repairableName.toLowerCase(), null); + config.set(unit.getKey() + "." + repairable.getKey(), null); + config.set(unit.getKey() + "." + repairable, null); + config.set(unit + "." + repairable.getKey(), null); + config.set(unit + "." + repairable, null); // Test if it was the last value of this section boolean lastValue = false; - if(config.isConfigurationSection(unitName.toLowerCase())) { - ConfigurationSection section = config.getConfigurationSection(unitName.toLowerCase()); + if (config.isConfigurationSection(unit.toString())) { + ConfigurationSection section = config.getConfigurationSection(unit.toString()); - if(section != null && section.getKeys(false).isEmpty()) { + if (section != null && section.getKeys(false).isEmpty()) { lastValue = true; - config.set(unitName.toLowerCase(), null); + config.set(unit.toString(), null); } - } else if (config.isConfigurationSection(unitName.toUpperCase())) { - ConfigurationSection section = config.getConfigurationSection(unitName.toUpperCase()); - if(section != null && section.getKeys(false).isEmpty()) { + } else if (config.isConfigurationSection(unit.getKey())) { + ConfigurationSection section = config.getConfigurationSection(unit.getKey()); + if (section != null && section.getKeys(false).isEmpty()) { lastValue = true; - config.set(unitName.toUpperCase(), null); + config.set(unit.getKey(), null); } } else lastValue = true; - // We only need to "delete" as the lower case to be counted as deleted - ConfigHolder.UNIT_REPAIR_HOLDER.delete(unitName.toLowerCase() + "." + repairableName.toLowerCase()); + ConfigHolder.UNIT_REPAIR_HOLDER.delete(unit.toString().toLowerCase() + "." + repairable.toString().toLowerCase()); prepareSaveTask(); // Remove from gui UnitRepairConfigGui repairConfigGui = UnitRepairConfigGui.getCurrentInstance(); - if(repairConfigGui != null) { + if (repairConfigGui != null) { UnitRepairElementListGui elementGui = repairConfigGui.getInstanceOrCreate(unit).getStored(); - if(elementGui != null) elementGui.removeGeneric(repairableName); - if(lastValue){ + if (elementGui != null) elementGui.removeGeneric(repairable); + if (lastValue) { repairConfigGui.removeGeneric(unit); } } @@ -164,9 +211,9 @@ public class UnitRepairApi { * Prepare a task to save custom unit repair recipe configuration. */ private static void prepareSaveTask() { - if(saveChangeTask != null) return; + if (saveChangeTask != null) return; - saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, ()->{ + saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, () -> { ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(true); saveChangeTask = null; }); @@ -174,6 +221,7 @@ public class UnitRepairApi { /** * Get every unit repair recipes. + * * @return An immutable collection of unit repair recipes. *

* Each element of the provided triple represent a part of the recipe @@ -182,29 +230,32 @@ public class UnitRepairApi { *

  • Second object is the item to be repaired. *
  • Last object is the amount to be repaired by every unit. (1% = 0.01) * + * @deprecated some may be missing. use {@link #getModernUnitRepairs()} + * */ + @Deprecated @NotNull - public static List> getUnitRepairs(){ + public static List> getUnitRepairs() { List> mutableList = new ArrayList<>(); FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); for (String unitKey : config.getKeys(false)) { // Test if config section exist - if(!config.isConfigurationSection(unitKey)) continue; + if (!config.isConfigurationSection(unitKey)) continue; // Test if unit is a material Material unit = Material.getMaterial(unitKey.toUpperCase()); - if(unit == null) continue; + if (unit == null) continue; // Iterate over reparable items ConfigurationSection section = config.getConfigurationSection(unitKey); for (String repairableKey : section.getKeys(false)) { // Test if value section exist - if(!section.isDouble(repairableKey)) continue; + if (!section.isDouble(repairableKey)) continue; // Test if repairable is valid a material Material repairable = Material.getMaterial(repairableKey.toUpperCase()); - if(repairable == null) continue; + if (repairable == null) continue; // Add the values mutableList.add(new Triple<>(unit, repairable, section.getDouble(repairableKey))); @@ -215,4 +266,53 @@ public class UnitRepairApi { return Collections.unmodifiableList(mutableList); } + /** + * Get every unit repair recipes. + * + * @return An immutable collection of unit repair recipes. + *

    + *

  • First map contain a key the unit material used to repair the bellow item and value the second map + *
  • Second map contain as key the item to be repaired and as value the amount to be repaired by every unit. (1% = 0.01) + * + */ + @NotNull + public static Map> getModernUnitRepairs() { + Map> mutableList = new HashMap<>(); + + FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); + for (String unitKey : config.getKeys(false)) { + // Test if config section exist + if (!config.isConfigurationSection(unitKey)) continue; + + // Test if unit is a material + NamespacedKey unit = NamespacedKey.fromString(unitKey.toLowerCase()); + if (unit == null) continue; + + Map map; + if (!mutableList.containsKey(unit)) { + map = new HashMap<>(); + mutableList.put(unit, map); + } else { + map = mutableList.get(unit); + } + + // Iterate over reparable items + ConfigurationSection section = config.getConfigurationSection(unitKey); + for (String repairableKey : section.getKeys(false)) { + // Test if value section exist + if (!section.isDouble(repairableKey)) continue; + + // Test if repairable is valid a material + NamespacedKey repairable = NamespacedKey.fromString(repairableKey.toLowerCase()); + if (repairable == null) continue; + + // Add the values + map.put(repairable, section.getDouble(repairableKey)); + + } + } + + return mutableList; + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java index ea657ace..95f3001b 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantment.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.enchant.bulk.BulkCleanEnchantOperation; import xyz.alexcrea.cuanvil.enchant.bulk.BulkGetEnchantOperation; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; +import xyz.alexcrea.cuanvil.util.CasedStringUtil; import java.util.Collection; import java.util.HashMap; @@ -45,6 +46,14 @@ public interface CAEnchantment { @NotNull String getName(); + /** + * Get the enchantment name prettified (upper spaced case) + * @return Prettier enchantment name + */ + default String getPrettyName() { + return CasedStringUtil.snakeToUpperSpacedCase(getName()); + } + /** * Get the default maximum level of this enchantment. * @return The default maximum level of this enchantment. @@ -221,7 +230,7 @@ public interface CAEnchantment { * @param key The enchantment key * @return Array of enchantment. */ - static @Nullable CAEnchantment getByKey(@NotNull NamespacedKey key){ + static @Nullable CAEnchantment getByKey(@Nullable NamespacedKey key){ return CAEnchantmentRegistry.getInstance().getByKey(key); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java index 854ed55c..b1f9a7b8 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/CAEnchantmentRegistry.java @@ -99,8 +99,7 @@ public class CAEnchantmentRegistry { if ((!hasWarnedRegistering) && byNameMap.containsKey(enchantment.getName())) { hasWarnedRegistering = true; - CustomAnvil.instance.getLogger().log(Level.WARNING, - "Duplicate registered enchantment name. Please check that configuration is using namespace."); + CustomAnvil.Companion.log("Duplicate registered enchantment name. Please check that configuration is using namespace."); } byKeyMap.put(enchantment.getKey(), enchantment); @@ -151,7 +150,7 @@ public class CAEnchantmentRegistry { * @return Registered enchantment. null if absent. */ @Nullable - public CAEnchantment getByKey(@NotNull NamespacedKey key) { + public CAEnchantment getByKey(@Nullable NamespacedKey key) { return byKeyMap.get(key); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java index cc4fddc5..57cc35bc 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java @@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.gui.config; import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import io.delilaheve.CustomAnvil; @@ -39,116 +40,142 @@ public class MainConfigGui extends ChestGui { GuiGlobalItems.addBackgroundItem(pane); // Basic config item - ItemStack basicConfigItemstack = new ItemStack(Material.COMMAND_BLOCK); - ItemMeta basicConfigMeta = basicConfigItemstack.getItemMeta(); - assert basicConfigMeta != null; - - basicConfigMeta.setDisplayName("§aBasic Config Menu"); - basicConfigMeta.setLore(Collections.singletonList("§7Click here to open basic config menu")); - basicConfigItemstack.setItemMeta(basicConfigMeta); - - GuiItem basicConfigItem = GuiGlobalItems.goToGuiItem(basicConfigItemstack, new BasicConfigGui(packetManager)); + var basicConfigItem = basicConfigItem(new BasicConfigGui(packetManager)); pane.bindItem('1', basicConfigItem); // enchant level limit item - ItemStack enchantLimitItemstack = new ItemStack(Material.ENCHANTED_BOOK); - ItemMeta enchantLimitMeta = enchantLimitItemstack.getItemMeta(); - assert enchantLimitMeta != null; - - enchantLimitMeta.setDisplayName("§aEnchantment Level Limit"); - enchantLimitMeta.setLore(Collections.singletonList("§7Click here to open enchantment level limit menu")); - enchantLimitItemstack.setItemMeta(enchantLimitMeta); - - GuiItem enchantLimitItem = GuiGlobalItems.goToGuiItem(enchantLimitItemstack, new EnchantLimitConfigGui()); + var enchantLimitItem = enchantLimitItem(new EnchantLimitConfigGui()); pane.bindItem('2', enchantLimitItem); // enchant level limit item - ItemStack enchantMergeLimitItemstack = new ItemStack(Material.ENCHANTED_BOOK); - ItemMeta enchantMergeLimitMeta = enchantMergeLimitItemstack.getItemMeta(); - assert enchantMergeLimitMeta != null; - - enchantMergeLimitMeta.setDisplayName("§aEnchantment Merge Limit"); - enchantMergeLimitMeta.setLore(Collections.singletonList("§7Click here to open enchantment merge limit menu")); - enchantMergeLimitItemstack.setItemMeta(enchantMergeLimitMeta); - - GuiItem enchantMergeLimitItem = GuiGlobalItems.goToGuiItem(enchantMergeLimitItemstack, new EnchantMergeLimitConfigGui()); + var enchantMergeLimitItem = enchantMergeLimitItem(new EnchantMergeLimitConfigGui()); pane.bindItem('3', enchantMergeLimitItem); // enchant cost item - ItemStack enchantCostItemstack = new ItemStack(Material.EXPERIENCE_BOTTLE); - ItemMeta enchantCostMeta = enchantCostItemstack.getItemMeta(); - assert enchantCostMeta != null; - - enchantCostMeta.setDisplayName("§aEnchantment Cost"); - enchantCostMeta.setLore(Collections.singletonList("§7Click here to open enchantment costs menu")); - enchantCostItemstack.setItemMeta(enchantCostMeta); - - GuiItem enchantCostItem = GuiGlobalItems.goToGuiItem(enchantCostItemstack, new EnchantCostConfigGui()); + var enchantCostItem = enchantCostItem(new EnchantCostConfigGui()); pane.bindItem('4', enchantCostItem); // Enchantment Conflicts item - ItemStack enchantConflictItemstack = new ItemStack(Material.OAK_FENCE); - ItemMeta enchantConflictMeta = enchantConflictItemstack.getItemMeta(); - assert enchantConflictMeta != null; - - enchantConflictMeta.setDisplayName("§aEnchantment Conflict"); - enchantConflictMeta.setLore(Collections.singletonList("§7Click here to open enchantment conflict menu")); - enchantConflictItemstack.setItemMeta(enchantConflictMeta); - - GuiItem enchantConflictItem = GuiGlobalItems.goToGuiItem(enchantConflictItemstack, EnchantConflictGui.getInstance()); + var enchantConflictItem = enchantConflictItem(EnchantConflictGui.getInstance()); pane.bindItem('5', enchantConflictItem); // Group config items - ItemStack groupItemstack = new ItemStack(Material.CHEST); - ItemMeta groupMeta = groupItemstack.getItemMeta(); - assert groupMeta != null; - - groupMeta.setDisplayName("§aItem Groups"); - groupMeta.setLore(Collections.singletonList("§7Click here to open item group menu")); - groupItemstack.setItemMeta(groupMeta); - - GuiItem groupConfigItem = GuiGlobalItems.goToGuiItem(groupItemstack, GroupConfigGui.getInstance()); - + var groupConfigItem = groupConfigItem(GroupConfigGui.getInstance()); pane.bindItem('6', groupConfigItem); // Unit repair item - ItemStack unirRepairItemstack = new ItemStack(Material.DIAMOND); - ItemMeta unitRepairMeta = unirRepairItemstack.getItemMeta(); - assert unitRepairMeta != null; - - unitRepairMeta.setDisplayName("§aUnit Repair"); - unitRepairMeta.setLore(Collections.singletonList("§7Click here to open anvil unit repair menu")); - unirRepairItemstack.setItemMeta(unitRepairMeta); - - GuiItem unitRepairItem = GuiGlobalItems.goToGuiItem(unirRepairItemstack, UnitRepairConfigGui.getInstance()); + var unitRepairItem = unitRepairItem(UnitRepairConfigGui.getInstance()); pane.bindItem('7', unitRepairItem); // Custom recipe item - ItemStack customRecipeItemstack = new ItemStack(Material.CRAFTING_TABLE); - ItemMeta customRecipeMeta = customRecipeItemstack.getItemMeta(); - assert customRecipeMeta != null; - - customRecipeMeta.setDisplayName("§aCustom recipes"); - customRecipeMeta.setLore(Collections.singletonList("§7Click here to open anvil custom recipe menu")); - customRecipeItemstack.setItemMeta(customRecipeMeta); - - GuiItem customRecipeItem = GuiGlobalItems.goToGuiItem(customRecipeItemstack, CustomRecipeConfigGui.getInstance()); + var customRecipeItem = customRecipeItem(CustomRecipeConfigGui.getInstance()); pane.bindItem('8', customRecipeItem); // quit item - ItemStack quitItemstack = new ItemStack(Material.BARRIER); - ItemMeta quitMeta = quitItemstack.getItemMeta(); - assert quitMeta != null; + pane.bindItem('Q', quitItem()); + } - quitMeta.setDisplayName("§cQuit"); - quitItemstack.setItemMeta(quitMeta); + public static GuiItem basicConfigItem(Gui target) { + var item = new ItemStack(Material.COMMAND_BLOCK); + var meta = item.getItemMeta(); + assert meta != null; - GuiItem quitItem = new GuiItem(quitItemstack, event -> { + meta.setDisplayName("§aBasic Config Menu"); + meta.setLore(Collections.singletonList("§7Click here to open basic config menu")); + item.setItemMeta(meta); + return GuiGlobalItems.goToGuiItem(item, target); + } + + public static GuiItem enchantLimitItem(Gui target) { + var item = new ItemStack(Material.ENCHANTED_BOOK); + var meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("§aEnchantment Level Limit"); + meta.setLore(Collections.singletonList("§7Click here to open enchantment level limit menu")); + item.setItemMeta(meta); + return GuiGlobalItems.goToGuiItem(item, target); + } + + public static GuiItem enchantMergeLimitItem(Gui target) { + ItemStack item = new ItemStack(Material.ENCHANTED_BOOK); + ItemMeta meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("§aEnchantment Merge Limit"); + meta.setLore(Collections.singletonList("§7Click here to open enchantment merge limit menu")); + item.setItemMeta(meta); + return GuiGlobalItems.goToGuiItem(item, target); + } + + public static GuiItem enchantCostItem(Gui target) { + ItemStack item = new ItemStack(Material.EXPERIENCE_BOTTLE); + ItemMeta meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("§aEnchantment Cost"); + meta.setLore(Collections.singletonList("§7Click here to open enchantment costs menu")); + item.setItemMeta(meta); + return GuiGlobalItems.goToGuiItem(item, target); + } + + public static GuiItem enchantConflictItem(Gui target) { + var item = new ItemStack(Material.OAK_FENCE); + var meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("§aEnchantment Conflict"); + meta.setLore(Collections.singletonList("§7Click here to open enchantment conflict menu")); + item.setItemMeta(meta); + return GuiGlobalItems.goToGuiItem(item, target); + } + + public static GuiItem groupConfigItem(Gui target) { + var item = new ItemStack(Material.CHEST); + var meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("§aItem Groups"); + meta.setLore(Collections.singletonList("§7Click here to open item group menu")); + item.setItemMeta(meta); + return GuiGlobalItems.goToGuiItem(item, target); + } + + public static GuiItem unitRepairItem(Gui target) { + var item = new ItemStack(Material.DIAMOND); + var meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("§aUnit Repair"); + meta.setLore(Collections.singletonList("§7Click here to open anvil unit repair menu")); + item.setItemMeta(meta); + + return GuiGlobalItems.goToGuiItem(item, target); + } + + public static GuiItem customRecipeItem(Gui target) { + var item = new ItemStack(Material.CRAFTING_TABLE); + var meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("§aCustom recipes"); + meta.setLore(Collections.singletonList("§7Click here to open anvil custom recipe menu")); + item.setItemMeta(meta); + return GuiGlobalItems.goToGuiItem(item, target); + } + + public static GuiItem quitItem() { + var item = new ItemStack(Material.BARRIER); + var meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("§cQuit"); + item.setItemMeta(meta); + + return new GuiItem(item, event -> { event.setCancelled(true); event.getWhoClicked().closeInventory(); }, CustomAnvil.instance); - pane.bindItem('Q', quitItem); - } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java index 6bd7ea34..5583b382 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java @@ -1,11 +1,11 @@ package xyz.alexcrea.cuanvil.gui.config.global; import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import org.bukkit.event.inventory.InventoryClickEvent; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; -import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; @@ -31,13 +31,17 @@ public abstract class AbstractEnchantConfigGui getEveryDisplayableInstanceOfGeneric() { + protected Collection getEveryInstanceOfGeneric() { return CAEnchantmentRegistry.getInstance().getNameSortedEnchantments(); } @@ -73,7 +77,7 @@ public abstract class AbstractEnchantConfigGui getEveryDisplayableInstanceOfGeneric() { + protected Collection getEveryInstanceOfGeneric() { return ConfigHolder.CUSTOM_RECIPE_HOLDER.getRecipeManager().getRecipeList(); } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConfigGui.java new file mode 100644 index 00000000..817aa7ac --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConfigGui.java @@ -0,0 +1,196 @@ +package xyz.alexcrea.cuanvil.gui.config.global; + +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.pane.PatternPane; +import com.github.stefvanschie.inventoryframework.pane.util.Pattern; +import io.delilaheve.CustomAnvil; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.api.EnchantmentApi; +import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.enchant.CAEnchantment; +import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; +import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; +import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; +import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; +import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; + +import java.util.HashMap; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class EnchantConfigGui extends ChestGui implements ValueUpdatableGui { + + private final Set enchantments; + private final PatternPane pane; + + private EnchantLimitConfigGui enchantLimitConfigGui; + private EnchantMergeLimitConfigGui enchantMergeLimitConfigGui; + private EnchantCostConfigGui enchantCostConfigGui; + + private EnchantConflictGui enchantConflictGui; + private GroupConfigGui groupConfigGui; + + public EnchantConfigGui(@NotNull Set enchantments) { + super(3, + "Configuring Enchantments", + CustomAnvil.instance); + this.enchantments = enchantments; + + Pattern pattern = new Pattern( + "0000D0000", + "023405600", + "Q00000000" + ); + pane = new PatternPane(0, 0, 9, 3, pattern); + addPane(pane); + + GuiGlobalItems.addBackgroundItem(pane); + + ItemStack displayItemstack = new ItemStack(Material.ENCHANTED_BOOK); + ItemMeta displayMeta = displayItemstack.getItemMeta(); + assert displayMeta != null; + + displayMeta.setDisplayName("§aConfiguring Enchantments:"); + displayItemstack.setItemMeta(displayMeta); + + // Set enchantments + HashMap enchantmentMap = new HashMap<>(); + for (CAEnchantment enchantment : enchantments) { + enchantmentMap.put(enchantment, 1); + } + EnchantmentApi.setEnchantments(displayItemstack, enchantmentMap); + + pane.bindItem('D', new GuiItem(displayItemstack, GuiGlobalActions.stayInPlace, CustomAnvil.instance)); + + updateGuiValues(); + + // Enchantment Conflicts item + var enchantConflictItem = MainConfigGui.enchantConflictItem(getEnchantConflictGui()); + pane.bindItem('5', enchantConflictItem); + + // Group config items + var groupConfigItem = MainConfigGui.groupConfigItem(getGroupConfigGui()); + pane.bindItem('6', groupConfigItem); + + // quit item + pane.bindItem('Q', MainConfigGui.quitItem()); + } + + private GuiItem enchantLimitConfigGui() { + if (enchantLimitConfigGui == null) { + enchantLimitConfigGui = new EnchantLimitConfigGui(this); + enchantLimitConfigGui.setFilter(enchantments::contains); + enchantLimitConfigGui.init(); + } + + // Bypass + if(enchantments.size() == 1) { + var enchant = enchantments.iterator().next(); + var factory = EnchantLimitConfigGui.createFactory(enchant, this); + + return enchantLimitConfigGui.itemFromFactory(enchant, factory); + } + + return MainConfigGui.enchantLimitItem(enchantLimitConfigGui); + } + + private GuiItem enchantMergeLimitConfigGui() { + if (enchantMergeLimitConfigGui == null) { + enchantMergeLimitConfigGui = new EnchantMergeLimitConfigGui(this); + enchantMergeLimitConfigGui.setFilter(enchantments::contains); + enchantMergeLimitConfigGui.init(); + } + + // Bypass + if(enchantments.size() == 1) { + var enchant = enchantments.iterator().next(); + var factory = EnchantMergeLimitConfigGui.createFactory(enchant, this); + + return enchantMergeLimitConfigGui.itemFromFactory(enchant, factory); + } + + return MainConfigGui.enchantMergeLimitItem(enchantMergeLimitConfigGui); + } + + private GuiItem enchantCostConfigGui() { + if (enchantCostConfigGui == null) { + enchantCostConfigGui = new EnchantCostConfigGui(this); + enchantCostConfigGui.setFilter(enchantments::contains); + enchantCostConfigGui.init(); + } + + // Bypass + if(enchantments.size() == 1) { + var enchant = enchantments.iterator().next(); + var factory = EnchantCostConfigGui.createFactory(enchant, this); + + return enchantCostConfigGui.itemFromFactory(enchant, factory); + } + + return MainConfigGui.enchantCostItem(enchantCostConfigGui); + } + + @NotNull + @Contract(pure = true) + private Predicate getGroupFilter() { + return group -> group.getEnchants() + .stream() + .anyMatch(enchantments::contains); + } + + private EnchantConflictGui getEnchantConflictGui() { + if (enchantConflictGui == null) { + enchantConflictGui = new EnchantConflictGui(this); + enchantConflictGui.setFilter(getGroupFilter()); + enchantConflictGui.init(); + } + + return enchantConflictGui; + } + + private GroupConfigGui getGroupConfigGui() { + if (groupConfigGui == null) { + groupConfigGui = new GroupConfigGui(this); + + // Get all the conflict related to this enchantment + var groups = ConfigHolder.CONFLICT_HOLDER + .getConflictManager() + .getConflictList() + .stream() + .filter(getGroupFilter()) + .map(EnchantConflictGroup::getCantConflictGroup) + .collect(Collectors.toSet()); + + groupConfigGui.setFilter(group -> + groups.stream().anyMatch(other -> other.isReferencing(group)) + ); + groupConfigGui.init(); + } + + return groupConfigGui; + } + + @Override + public void updateGuiValues() { + // enchant level limit item + pane.bindItem('2', enchantLimitConfigGui()); + + // enchant level limit item + pane.bindItem('3', enchantMergeLimitConfigGui()); + + // enchant cost item + pane.bindItem('4', enchantCostConfigGui()); + } + + @Override + public Gui getConnectedGui() { + return this; + } +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java index 912e6cb3..3c28e7c5 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java @@ -1,6 +1,7 @@ package xyz.alexcrea.cuanvil.gui.config.global; import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; @@ -24,26 +25,30 @@ public class EnchantConflictGui extends MappedGuiListConfigGui getEveryDisplayableInstanceOfGeneric() { + protected Collection getEveryInstanceOfGeneric() { return ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList(); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java index a6145368..677ca54d 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantCostConfigGui.java @@ -1,14 +1,14 @@ package xyz.alexcrea.cuanvil.gui.config.global; import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; -import xyz.alexcrea.cuanvil.enchant.EnchantmentProperties; -import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; +import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.config.settings.EnchantCostSettingsGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.util.CasedStringUtil; @@ -18,13 +18,13 @@ import java.util.Arrays; import java.util.List; import java.util.Locale; +import static io.delilaheve.util.ConfigOptions.ENCHANT_VALUES_ROOT; + /** * Global Config gui for enchantment cost settings. */ public class EnchantCostConfigGui extends AbstractEnchantConfigGui { - private static final String SECTION_NAME = "enchant_values"; - private static EnchantCostConfigGui INSTANCE = null; @Nullable @@ -37,18 +37,29 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui displayLore = factory.getDisplayLore(); - if(!displayLore.isEmpty()){ + if (!displayLore.isEmpty()) { lore.add(""); lore.addAll(displayLore); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java index e9edbebf..1d5c9ec5 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java @@ -1,11 +1,13 @@ package xyz.alexcrea.cuanvil.gui.config.global; import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import io.delilaheve.util.ConfigOptions; import org.bukkit.Material; import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; +import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui; import xyz.alexcrea.cuanvil.util.CasedStringUtil; @@ -36,14 +38,22 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui getEveryDisplayableInstanceOfGeneric() { + protected Collection getEveryInstanceOfGeneric() { ArrayList includeGroups = new ArrayList<>(); for (AbstractMaterialGroup group : ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values()) { diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/ItemConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/ItemConfigGui.java new file mode 100644 index 00000000..35ad5bf1 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/ItemConfigGui.java @@ -0,0 +1,132 @@ +package xyz.alexcrea.cuanvil.gui.config.global; + +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; +import com.github.stefvanschie.inventoryframework.pane.PatternPane; +import com.github.stefvanschie.inventoryframework.pane.util.Pattern; +import io.delilaheve.CustomAnvil; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; +import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; +import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; +import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import xyz.alexcrea.cuanvil.util.MaterialUtil; +import xyz.alexcrea.cuanvil.util.UnitRepairUtil; + +public class ItemConfigGui extends ChestGui { + + private EnchantConflictGui enchantConflictGui; + private GroupConfigGui groupConfigGui; + private UnitRepairConfigGui unitRepairConfigGui; + private CustomRecipeConfigGui customRecipeConfigGui; + + public ItemConfigGui(@NotNull Material display, @NotNull NamespacedKey material) { + super(3, + CasedStringUtil.snakeToUpperSpacedCase( + material.getKey().toLowerCase() + ) + " Config", + CustomAnvil.instance); + + Pattern pattern = new Pattern( + "0000D0000", + "056000780", + "Q00000000" + ); + PatternPane pane = new PatternPane(0, 0, 9, 3, pattern); + addPane(pane); + + GuiGlobalItems.addBackgroundItem(pane); + + ItemStack displayItemstack = new ItemStack(display); + ItemMeta displayMeta = displayItemstack.getItemMeta(); + assert displayMeta != null; + + displayMeta.setDisplayName("§aConfiguring " + material); + displayItemstack.setItemMeta(displayMeta); + pane.bindItem('D', new GuiItem(displayItemstack, GuiGlobalActions.stayInPlace, CustomAnvil.instance)); + + // Enchantment Conflicts item + GuiItem enchantConflictItem = MainConfigGui.enchantConflictItem(getEnchantConflictGui(material)); + pane.bindItem('5', enchantConflictItem); + + // Group config items + GuiItem groupConfigItem = MainConfigGui.groupConfigItem(getGroupConfigGui(material)); + pane.bindItem('6', groupConfigItem); + + // Unit repair item + GuiItem unitRepairItem = MainConfigGui.unitRepairItem(getUnitRepairConfigGui(material)); + pane.bindItem('7', unitRepairItem); + + // Custom recipe item + GuiItem customRecipeItem = MainConfigGui.customRecipeItem(getCustomRecipeConfigGui(material)); + pane.bindItem('8', customRecipeItem); + + // quit item + pane.bindItem('Q', MainConfigGui.quitItem()); + } + + private EnchantConflictGui getEnchantConflictGui(@NotNull NamespacedKey material) { + if (enchantConflictGui == null) { + enchantConflictGui = new EnchantConflictGui(this); + enchantConflictGui.setFilter(group -> + group.getCantConflictGroup().contain(material) + ); + enchantConflictGui.init(); + } + + return enchantConflictGui; + } + + private GroupConfigGui getGroupConfigGui(@NotNull NamespacedKey material) { + if (groupConfigGui == null) { + groupConfigGui = new GroupConfigGui(this); + groupConfigGui.setFilter(group -> + group.contain(material) + ); + groupConfigGui.init(); + } + + return groupConfigGui; + } + + private UnitRepairConfigGui getUnitRepairConfigGui(@NotNull NamespacedKey material) { + if (unitRepairConfigGui == null) { + unitRepairConfigGui = new UnitRepairConfigGui(this); + unitRepairConfigGui.setFilter(otherMat -> + otherMat.equals(material) || UnitRepairUtil.INSTANCE.findRawRepairValue( + material, otherMat, ConfigHolder.UNIT_REPAIR_HOLDER.getConfig()) != null + ); + unitRepairConfigGui.init(); + } + + return unitRepairConfigGui; + } + + private CustomRecipeConfigGui getCustomRecipeConfigGui(@NotNull NamespacedKey material) { + if (customRecipeConfigGui == null) { + customRecipeConfigGui = new CustomRecipeConfigGui(this); + customRecipeConfigGui.setFilter(recipe -> { + if (isMaterial(recipe.getLeftItem(), material)) return true; + if (isMaterial(recipe.getRightItem(), material)) return true; + return isMaterial(recipe.getResultItem(), material); + } + ); + customRecipeConfigGui.init(); + } + + return customRecipeConfigGui; + } + + private boolean isMaterial(@Nullable ItemStack item, @NotNull NamespacedKey material) { + if (item == null) return false; + + return material.equals(MaterialUtil.INSTANCE.getCustomType(item)); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/UnitRepairConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/UnitRepairConfigGui.java index 0e366ae6..54c4ce13 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/UnitRepairConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/UnitRepairConfigGui.java @@ -1,9 +1,10 @@ package xyz.alexcrea.cuanvil.gui.config.global; import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import io.delilaheve.CustomAnvil; import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.NamespacedKey; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; @@ -13,24 +14,25 @@ import xyz.alexcrea.cuanvil.gui.config.ask.SelectItemTypeGui; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.UnitRepairElementListGui; import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import xyz.alexcrea.cuanvil.util.MaterialUtil; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashSet; public class UnitRepairConfigGui extends - MappedGuiListConfigGui> { + MappedGuiListConfigGui> { private static UnitRepairConfigGui INSTANCE; @Nullable - public static UnitRepairConfigGui getCurrentInstance(){ + public static UnitRepairConfigGui getCurrentInstance() { return INSTANCE; } @NotNull - public static UnitRepairConfigGui getInstance(){ - if(INSTANCE == null) INSTANCE = new UnitRepairConfigGui(); + public static UnitRepairConfigGui getInstance() { + if (INSTANCE == null) INSTANCE = new UnitRepairConfigGui(); return INSTANCE; } @@ -41,8 +43,12 @@ public class UnitRepairConfigGui extends init(); } + public UnitRepairConfigGui(Gui parent) { + super("Unit Repair Config", parent); + } + @Override - protected LazyElement newInstanceOfGui(Material material, GuiItem item) { + protected LazyElement newInstanceOfGui(NamespacedKey material, GuiItem item) { return new LazyElement<>(item, () -> { UnitRepairElementListGui element = new UnitRepairElementListGui(material, this); element.init(); @@ -51,23 +57,34 @@ public class UnitRepairConfigGui extends } @Override - protected ItemStack createItemForGeneric(Material material) { - ConfigurationSection materialSection = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getConfigurationSection(material.name().toLowerCase()); - String materialName = CasedStringUtil.snakeToUpperSpacedCase(material.name().toLowerCase()); + protected ItemStack createItemForGeneric(@NotNull NamespacedKey material) { + var unitConfig = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); + var section = unitConfig.getConfigurationSection(material.toString().toLowerCase()); + var legacySection = unitConfig.getConfigurationSection(material.getKey().toLowerCase()); - if(material.isAir()){ - material = Material.BARRIER; + String materialName = CasedStringUtil.snakeToUpperSpacedCase(material.getKey().toLowerCase()); + + var display = MaterialUtil.INSTANCE.getMatFromKey(material); + + if (display == null || display.isAir()) { + display = Material.BARRIER; } - int reparableItemCount = materialSection == null ? 0 : materialSection.getKeys(false).size(); // Probably an expensive call but... why not + var reparable = new HashSet(); + if (section != null) + reparable.addAll(section.getKeys(false)); + if (legacySection != null) + reparable.addAll(legacySection.getKeys(false)); - ItemStack item = new ItemStack(material); + var reparableItemCount = reparable.size(); + + ItemStack item = new ItemStack(display); ItemMeta meta = item.getItemMeta(); assert meta != null; - meta.setDisplayName("§eRepaired by " +materialName); + meta.setDisplayName("§eRepaired by " + materialName); meta.setLore(Arrays.asList( - "§7There is currently §e" +reparableItemCount+ " §7reparable item with "+materialName, + "§7There is currently §e" + reparableItemCount + " §7reparable item with " + materialName, "§7Click here to open the menu to edit reparable item by " + materialName )); @@ -77,13 +94,16 @@ public class UnitRepairConfigGui extends } @Override - protected Collection getEveryDisplayableInstanceOfGeneric() { - ArrayList materials = new ArrayList<>(); + protected Collection getEveryInstanceOfGeneric() { + var materials = new HashSet(); + var config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); - for (String matName : ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getKeys(false)) { - Material mat = Material.getMaterial(matName.toUpperCase()); - if(mat != null){ - materials.add(mat); + for (String matName : config.getKeys(false)) { + if(!config.isConfigurationSection(matName)) continue; + + NamespacedKey material = NamespacedKey.fromString(matName.toLowerCase()); + if (material != null) { + materials.add(material); } } return materials; @@ -113,7 +133,7 @@ public class UnitRepairConfigGui extends "§7You like to be an unit repair item", this, (itemStack, player) -> { - Material type = itemStack.getType(); + NamespacedKey type = MaterialUtil.INSTANCE.getCustomType(itemStack); // Add new material updateValueForGeneric(type, true); @@ -126,9 +146,9 @@ public class UnitRepairConfigGui extends } @NotNull - public LazyElement getInstanceOrCreate(Material mat){ + public LazyElement getInstanceOrCreate(NamespacedKey mat) { LazyElement element = this.elementGuiMap.get(mat); - if(element == null){ + if (element == null) { updateValueForGeneric(mat, false); element = this.elementGuiMap.get(mat); @@ -141,8 +161,10 @@ public class UnitRepairConfigGui extends protected String genericDisplayedName() { return "this function Should not be used."; } + @Override // Not used in this implementation. - protected Material createAndSaveNewEmptyGeneric(String name) { + protected NamespacedKey createAndSaveNewEmptyGeneric(String name) { return null; } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/ElementListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/ElementListConfigGui.java index f3cc0b46..19d31d9f 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/ElementListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/ElementListConfigGui.java @@ -23,18 +23,22 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.UUID; +import java.util.function.Predicate; -public abstract class ElementListConfigGui< T > extends ChestGui implements ValueUpdatableGui { - - private final String namePrefix; - - protected PatternPane backgroundPane; +public abstract class ElementListConfigGui extends ChestGui implements ValueUpdatableGui { public static final int LIST_FILLER_START_X = 1; public static final int LIST_FILLER_START_Y = 1; public static final int LIST_FILLER_LENGTH = 7; public static final int LIST_FILLER_HEIGHT = 4; + private final String namePrefix; + + protected PatternPane backgroundPane; + + private Predicate filter = (t) -> true; + private boolean hasDefaultFilter = true; + protected ElementListConfigGui(@NotNull String title, Gui parent) { super(6, title, CustomAnvil.instance); this.namePrefix = title; @@ -46,7 +50,12 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu } - protected Pattern getBackgroundPattern(){ + public void setFilter(Predicate filter) { + this.filter = filter; + this.hasDefaultFilter = false; + } + + protected Pattern getBackgroundPattern() { return new Pattern( GuiSharedConstant.UPPER_FILLER_FULL_PLANE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE, @@ -61,7 +70,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu protected ArrayList pages; protected HashMap pageMap; - public void init() { // Why I'm using an init function ? //TODO determine why is it using a init function and not used on constructor. + public void init() { GuiGlobalItems.addBackgroundItem(this.backgroundPane); this.backgroundPane.bindItem('1', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM); addPane(this.backgroundPane); @@ -81,7 +90,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu protected GuiItem goLeftItem; protected GuiItem goRightItem; - protected void prepareStaticValues(){ + protected void prepareStaticValues() { // Left item creation for consumer & bind this.goLeftItem = new GuiItem(new ItemStack(Material.RED_STAINED_GLASS_PANE), event -> { HumanEntity viewer = event.getWhoClicked(); @@ -112,17 +121,23 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu viewer.setItemOnCursor(cursor); }, CustomAnvil.instance); - GuiItem createNew = prepareCreateNewItem(); - if(createNew != null){ + GuiItem createNew; + if(hasDefaultFilter) + createNew = prepareCreateNewItem(); + else + createNew = GuiSharedConstant.SECONDARY_BACKGROUND_ITEM; + + if (createNew != null) { this.backgroundPane.bindItem('C', createNew); } } - protected void reloadValues(){ + + protected void reloadValues() { this.firstPage.clear(); this.pages.clear(); this.pages.add(this.firstPage); - for (T generic : getEveryDisplayableInstanceOfGeneric()) { + for (T generic : getDisplayableInstanceOfGeneric()) { updateValueForGeneric(generic, false); } @@ -247,7 +262,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu // set title StringBuilder title = new StringBuilder(this.namePrefix); int pagesSize = this.pages.size(); - if(pagesSize > 1){ + if (pagesSize > 1) { title.append(" (").append(pageID + 1).append('/').append(pagesSize).append(')'); } setTitle(title.toString()); @@ -288,7 +303,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu public void removeGeneric(T generic) { GuiItem item = findGuiItemForRemoval(generic); - if(item == null) return; + if (item == null) return; removeFromPage(item); update(); @@ -300,7 +315,11 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu protected abstract void updateGeneric(T generic, ItemStack usedItem); - protected abstract Collection getEveryDisplayableInstanceOfGeneric(); + protected abstract Collection getEveryInstanceOfGeneric(); + + protected Collection getDisplayableInstanceOfGeneric() { + return getEveryInstanceOfGeneric().stream().filter(filter).toList(); + } @Override public void updateGuiValues() { diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java index 31ab7184..9b6c6100 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java @@ -1,6 +1,7 @@ package xyz.alexcrea.cuanvil.gui.config.list; import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import io.delilaheve.CustomAnvil; import org.bukkit.Material; import org.bukkit.entity.HumanEntity; @@ -14,27 +15,32 @@ import java.util.Arrays; import java.util.HashMap; import java.util.function.Consumer; -public abstract class MappedElementListConfigGui< T, S > extends ElementListConfigGui< T > { +public abstract class MappedElementListConfigGui extends ElementListConfigGui { protected final HashMap elementGuiMap; - protected MappedElementListConfigGui(@NotNull String title) { - super(title, MainConfigGui.getInstance()); + + protected MappedElementListConfigGui(@NotNull String title, @NotNull Gui parent) { + super(title, parent); this.elementGuiMap = new HashMap<>(); } + protected MappedElementListConfigGui(@NotNull String title) { + this(title, MainConfigGui.getInstance()); + } + @Override - protected GuiItem prepareCreateNewItem(){ + protected GuiItem prepareCreateNewItem() { // Create new conflict item ItemStack createItem = new ItemStack(Material.PAPER); ItemMeta createMeta = createItem.getItemMeta(); assert createMeta != null; - createMeta.setDisplayName("§aCreate new "+genericDisplayedName()); + createMeta.setDisplayName("§aCreate new " + genericDisplayedName()); createMeta.setLore(Arrays.asList( - "§7Create a new "+genericDisplayedName()+".", - "§7You will be asked to name the "+genericDisplayedName()+" in chat.", - "§7Then, you should edit the "+genericDisplayedName()+" config as you need" + "§7Create a new " + genericDisplayedName() + ".", + "§7You will be asked to name the " + genericDisplayedName() + " in chat.", + "§7Then, you should edit the " + genericDisplayedName() + " config as you need" )); createItem.setItemMeta(createMeta); @@ -51,8 +57,8 @@ public abstract class MappedElementListConfigGui< T, S > extends ElementListConf } player.closeInventory(); - player.sendMessage("§eWrite the "+genericDisplayedName()+" name you want to create in the chat.\n" + - "§eOr write §ccancel §eto go back to "+genericDisplayedName()+" config menu"); + player.sendMessage("§eWrite the " + genericDisplayedName() + " name you want to create in the chat.\n" + + "§eOr write §ccancel §eto go back to " + genericDisplayedName() + " config menu"); CustomAnvil.Companion.getChatListener().setListenedCallback(player, prepareCreateItemConsumer(player)); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java index 3aa18e0b..8180694e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java @@ -1,6 +1,7 @@ package xyz.alexcrea.cuanvil.gui.config.list; import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import io.delilaheve.CustomAnvil; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryClickEvent; @@ -14,19 +15,22 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.Supplier; -public abstract class MappedGuiListConfigGui< T, S extends MappedGuiListConfigGui.LazyElement> - extends MappedElementListConfigGui< T, S > { +public abstract class MappedGuiListConfigGui> + extends MappedElementListConfigGui { protected MappedGuiListConfigGui(@NotNull String title) { super(title); + } + protected MappedGuiListConfigGui(@NotNull String title, @NotNull Gui parent) { + super(title, parent); } @Override public void reloadValues() { this.elementGuiMap.forEach((conflict, element) -> { ElementMappedToListGui gui = element.getStored(); - if(gui != null) gui.cleanAndBeUnusable(); + if (gui != null) gui.cleanAndBeUnusable(); }); this.elementGuiMap.clear(); @@ -49,7 +53,7 @@ public abstract class MappedGuiListConfigGui< T, S extends MappedGuiListConfigGu @Override protected void updateElement(T generic, S element) { ElementMappedToListGui gui = element.getStored(); - if(gui != null) gui.updateLocal(); + if (gui != null) gui.updateLocal(); } @Override @@ -58,7 +62,7 @@ public abstract class MappedGuiListConfigGui< T, S extends MappedGuiListConfigGu } @Override - protected Consumer prepareCreateItemConsumer(HumanEntity player){ + protected Consumer prepareCreateItemConsumer(HumanEntity player) { AtomicReference> selfRef = new AtomicReference<>(); Consumer selfCallback = (message) -> { if (message == null) return; @@ -71,7 +75,7 @@ public abstract class MappedGuiListConfigGui< T, S extends MappedGuiListConfigGu message = message.toLowerCase(Locale.ROOT); if ("cancel".equalsIgnoreCase(message)) { - player.sendMessage(genericDisplayedName()+" creation cancelled..."); + player.sendMessage(genericDisplayedName() + " creation cancelled..."); show(player); return; } @@ -80,9 +84,9 @@ public abstract class MappedGuiListConfigGui< T, S extends MappedGuiListConfigGu // Try to find if it already exists in a for loop // Not the most efficient on large number of conflict, but it should not run often. - for (T generic : getEveryDisplayableInstanceOfGeneric()) { + for (T generic : getDisplayableInstanceOfGeneric()) { if (generic.toString().equalsIgnoreCase(message)) { - player.sendMessage("§cPlease enter a "+genericDisplayedName()+" name that do not already exist..."); + player.sendMessage("§cPlease enter a " + genericDisplayedName() + " name that do not already exist..."); // wait next message. CustomAnvil.Companion.getChatListener().setListenedCallback(player, selfRef.get()); return; @@ -90,7 +94,7 @@ public abstract class MappedGuiListConfigGui< T, S extends MappedGuiListConfigGu } T generic = createAndSaveNewEmptyGeneric(message); - if(generic == null) {// we don't know what to do. so we back up by opening this gui. + if (generic == null) {// we don't know what to do. so we back up by opening this gui. this.show(player); return; } @@ -117,6 +121,7 @@ public abstract class MappedGuiListConfigGui< T, S extends MappedGuiListConfigGu private final GuiItem parentItem; private final LazyValue> lazyOpenConsumer; + public LazyElement(GuiItem parentItem, Supplier valueSupplier) { super(valueSupplier); this.parentItem = parentItem; @@ -131,7 +136,7 @@ public abstract class MappedGuiListConfigGui< T, S extends MappedGuiListConfigGu } @NotNull - public Consumer openAction(){ + public Consumer openAction() { return event -> lazyOpenConsumer.get().accept(event); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java index f0e7cb0e..cb55ed08 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java @@ -15,10 +15,11 @@ import java.util.HashMap; import java.util.List; import java.util.function.Consumer; -public abstract class SettingGuiListConfigGui< T, S extends SettingGui.SettingGuiFactory> extends ElementListConfigGui< T >{ +public abstract class SettingGuiListConfigGui extends ElementListConfigGui { protected HashMap guiItemMap; protected HashMap factoryMap; + protected SettingGuiListConfigGui(@NotNull String title, Gui parent) { super(title, parent); this.guiItemMap = new HashMap<>(); @@ -44,7 +45,7 @@ public abstract class SettingGuiListConfigGui< T, S extends SettingGui.SettingGu @Override public void updateValueForGeneric(T generic, boolean shouldUpdate) { - if(!this.factoryMap.containsKey(generic)){ + if (!this.factoryMap.containsKey(generic)) { // Create new item & factory S factory = createFactory(generic); GuiItem newItem = itemFromFactory(generic, factory); @@ -52,7 +53,7 @@ public abstract class SettingGuiListConfigGui< T, S extends SettingGui.SettingGu addToPage(newItem); this.guiItemMap.put(generic, newItem); this.factoryMap.put(generic, factory); - }else{ + } else { S factory = this.factoryMap.get(generic); // Update old item GuiItem oldItem = this.guiItemMap.get(generic); @@ -61,7 +62,7 @@ public abstract class SettingGuiListConfigGui< T, S extends SettingGui.SettingGu updateGuiItem(oldItem, newItem); } - if(shouldUpdate){ + if (shouldUpdate) { update(); } } @@ -74,7 +75,7 @@ public abstract class SettingGuiListConfigGui< T, S extends SettingGui.SettingGu super.reloadValues(); } - private void updateGuiItem(GuiItem oldITem, GuiItem newItem){ + private void updateGuiItem(GuiItem oldITem, GuiItem newItem) { oldITem.setItem(newItem.getItem()); oldITem.setProperties(newItem.getProperties()); oldITem.setVisible(newItem.isVisible()); @@ -86,17 +87,22 @@ public abstract class SettingGuiListConfigGui< T, S extends SettingGui.SettingGu } @Override // Not used - protected void updateGeneric(T generic, ItemStack usedItem) {} + protected void updateGeneric(T generic, ItemStack usedItem) { + } + @Override // Not used protected ItemStack createItemForGeneric(T generic) { return null; } protected abstract List getCreateItemLore(); + protected abstract Consumer getCreateClickConsumer(); + protected abstract String createItemName(); protected abstract S createFactory(T generic); + protected abstract GuiItem itemFromFactory(T generic, S factory); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java index 35f8ebb9..9b879fdc 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java @@ -3,12 +3,14 @@ package xyz.alexcrea.cuanvil.gui.config.list; import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.config.ask.SelectItemTypeGui; import xyz.alexcrea.cuanvil.gui.config.global.UnitRepairConfigGui; @@ -17,26 +19,25 @@ import xyz.alexcrea.cuanvil.gui.config.settings.DoubleSettingGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import xyz.alexcrea.cuanvil.util.MaterialUtil; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; +import java.util.*; import java.util.function.Consumer; -public class UnitRepairElementListGui extends SettingGuiListConfigGui implements ElementMappedToListGui { +public class UnitRepairElementListGui extends SettingGuiListConfigGui implements ElementMappedToListGui { - private final Material parentMaterial; + private final NamespacedKey parentMaterial; private final UnitRepairConfigGui parentGui; private final String materialName; private boolean shouldWork = true; - public UnitRepairElementListGui(@NotNull Material parentMaterial, + + public UnitRepairElementListGui(@NotNull NamespacedKey parentMaterial, @NotNull UnitRepairConfigGui parentGui) { - super("§e" + CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.name().toLowerCase()) + " §rUnit repair"); + super("§e" + CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.getKey().toLowerCase()) + " §rUnit repair"); this.parentMaterial = parentMaterial; this.parentGui = parentGui; - this.materialName = CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.name().toLowerCase()); + this.materialName = CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.getKey().toLowerCase()); GuiGlobalItems.addBackItem(this.backgroundPane, parentGui); } @@ -54,7 +55,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui getCreateClickConsumer() { return event -> { event.setCancelled(true); - if(!this.shouldWork){ + if (!this.shouldWork) { return; } event.setCancelled(true); @@ -66,28 +67,28 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui { ItemMeta meta = itemStack.getItemMeta(); - Material type = itemStack.getType(); + NamespacedKey type = MaterialUtil.INSTANCE.getCustomType(itemStack); - if(!(meta instanceof Damageable) || (type.getMaxDurability() <= 0)) { + if (!(meta instanceof Damageable)) { player.sendMessage("§cThis item can't be damaged, so it can't be repaired."); return; } - if(type == this.parentMaterial){ + if (type.equals(this.parentMaterial)) { player.sendMessage("§cItem can't repair something of the same type."); return; } - String materialName = type.name().toLowerCase(); + String materialName = type.toString(); // Add new material - ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().set(parentMaterial.name().toLowerCase() + "." + materialName,0.25); + ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().set(parentMaterial.toString().toLowerCase() + "." + materialName, 0.25); if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); } // Update gui - updateValueForGeneric(materialName, true); + updateValueForGeneric(type, true); this.parentGui.updateValueForGeneric(this.parentMaterial, true); @@ -106,17 +107,17 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui getEveryDisplayableInstanceOfGeneric() { - ArrayList keys = new ArrayList<>(); - if(!this.shouldWork){ + protected Collection getEveryInstanceOfGeneric() { + Set keys = new HashSet<>(); + if (!this.shouldWork) { return keys; } - ConfigurationSection materialSection = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getConfigurationSection(parentMaterial.name().toLowerCase()); - if(materialSection == null){ - return keys; - } - keys.addAll(materialSection.getKeys(false)); + ConfigurationSection legacySection = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getConfigurationSection(parentMaterial.getKey().toLowerCase()); + ConfigurationSection materialSection = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getConfigurationSection(parentMaterial.toString().toLowerCase()); + + addAllKeys(legacySection, keys); + addAllKeys(materialSection, keys); + return keys; } - private Material materialFromName(String materialName){ - Material mat = Material.getMaterial(materialName.toUpperCase()); - if(mat == null || mat.isAir()) return Material.BARRIER; + private void addAllKeys(@Nullable ConfigurationSection section, @NotNull Set keys) { + if (section == null) return; + for (var key : section.getKeys(false)) { + var material = NamespacedKey.fromString(key); + if (material == null) continue; + + keys.add(material); + } + } + + private Material materialFromName(NamespacedKey material) { + Material mat = MaterialUtil.INSTANCE.getMatFromKey(material); + if (mat == null || mat.isAir()) return Material.BARRIER; return mat; } @@ -163,7 +175,8 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui getEveryDisplayableInstanceOfGeneric() { + protected Collection getEveryInstanceOfGeneric() { Stream toDisplayStream; if(this.displayUnselected){ toDisplayStream = CAEnchantmentRegistry.getInstance().getNameSortedEnchantments().stream(); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java index 73121a64..c32d22ca 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java @@ -318,9 +318,9 @@ public class IntSettingsGui extends AbstractSettingGui { this.defaultVal = defaultVal; this.steps = steps; - if(displayLore == null){ + if (displayLore == null) { this.displayLore = Collections.emptyList(); - }else { + } else { this.displayLore = displayLore; } } @@ -392,7 +392,7 @@ public class IntSettingsGui extends AbstractSettingGui { protected String deltaDisplay(ValueDisplayType type, int now, int planned) { var delta = planned - now; - if(delta < 0) return "§c" + delta; + if (delta < 0) return "§c" + delta; else return "§a+" + delta; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java index fc519ff1..1869ad34 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java @@ -217,7 +217,7 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui getEveryDisplayableInstanceOfGeneric() { + protected Collection getEveryInstanceOfGeneric() { return this.defaultMaterials; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java b/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java index 660accb0..92418a3a 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/UpdateHandler.java @@ -2,10 +2,7 @@ package xyz.alexcrea.cuanvil.update; import io.delilaheve.CustomAnvil; import xyz.alexcrea.cuanvil.config.ConfigHolder; -import xyz.alexcrea.cuanvil.update.minecraft.MCUpdate; -import xyz.alexcrea.cuanvil.update.minecraft.Update_1_21; -import xyz.alexcrea.cuanvil.update.minecraft.Update_1_21_11; -import xyz.alexcrea.cuanvil.update.minecraft.Update_1_21_9; +import xyz.alexcrea.cuanvil.update.minecraft.*; import xyz.alexcrea.cuanvil.update.plugin.*; import javax.annotation.Nonnull; @@ -32,10 +29,13 @@ public class UpdateHandler { 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, 6), PUpdate_1_15_6::handleUpdate + new Version(1, 15, 6), PUpdate_1_15_6::handleUpdate, + new Version(1, 18, 0), PUpdate_1_18::handleUpdate ); private static final List mcUpdateMap = List.of( + new Update_1_19(), + new Update_1_20_5(), new Update_1_21(), new Update_1_21_9(), new Update_1_21_11() diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/UpdateUtils.java b/src/main/java/xyz/alexcrea/cuanvil/update/UpdateUtils.java index 2907fefb..4577b7a5 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/UpdateUtils.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/UpdateUtils.java @@ -1,6 +1,7 @@ package xyz.alexcrea.cuanvil.update; import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import java.util.ArrayList; @@ -33,4 +34,20 @@ public class UpdateUtils { } + public static boolean removeFromList(FileConfiguration config, String path, String toRemove) { + List groups = new ArrayList<>(config.getStringList(path)); + if (!groups.remove(toRemove)) return false; + + config.set(path, groups); + return true; + } + + public static void mergeSections(ConfigurationSection source, ConfigurationSection target) { + for (String key : source.getKeys(false)) { + if(target.contains(key)) continue; + target.set(key, source.get(key)); + } + } + + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_19.java b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_19.java new file mode 100644 index 00000000..fc598658 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_19.java @@ -0,0 +1,40 @@ +package xyz.alexcrea.cuanvil.update.minecraft; + +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.update.Version; + +import java.util.HashSet; +import java.util.Set; + +import static xyz.alexcrea.cuanvil.update.UpdateUtils.addAbsentToList; + +public class Update_1_19 extends MCUpdate { + + public Update_1_19() { + super(new Version(1, 19)); + } + + @Override + protected void doUpdate() { + var tosave = new HashSet(); + updateName(tosave); + + for (ConfigHolder holder : tosave) { + holder.saveToDisk(true); + } + } + + public static void updateName(@NotNull Set tosave) { + var conflict = ConfigHolder.CONFLICT_HOLDER.getConfig(); + + addAbsentToList(conflict, "restriction_swift_sneak.enchantments", "minecraft:swift_sneak"); + addAbsentToList(conflict, "restriction_swift_sneak.notAffectedGroups", "leggings", "enchanted_book"); + + ConfigHolder.ITEM_GROUP_HOLDER.reload(); + + tosave.add(ConfigHolder.DEFAULT_CONFIG); + tosave.add(ConfigHolder.CONFLICT_HOLDER); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_20_5.java b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_20_5.java new file mode 100644 index 00000000..53b996a6 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_20_5.java @@ -0,0 +1,98 @@ +package xyz.alexcrea.cuanvil.update.minecraft; + +import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.update.Version; + +import java.util.HashSet; +import java.util.Set; + +import static xyz.alexcrea.cuanvil.update.UpdateUtils.*; + +public class Update_1_20_5 extends MCUpdate { + + public Update_1_20_5() { + super(new Version(1, 20, 5)); + } + + @Override + protected void doUpdate() { + var tosave = new HashSet(); + updateName(tosave); + + for (ConfigHolder holder : tosave) { + holder.saveToDisk(true); + } + } + + private static String SWEEPING_ENCHANTS = "restriction_sweeping_edge.enchantments"; + + public static void updateName(@NotNull Set tosave) { + var config = ConfigHolder.DEFAULT_CONFIG.getConfig(); + var unitConfig = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig(); + var conflict = ConfigHolder.CONFLICT_HOLDER.getConfig(); + + // Rename sweeping to sweeping_edge + migrateEnchantLimit(config, "minecraft:sweeping"); + migrateEnchantLimit(config, "sweeping"); + + migrateEnchantValues(config, "minecraft:sweeping"); + migrateEnchantValues(config, "sweeping"); + + if (removeFromList(conflict, SWEEPING_ENCHANTS, "minecraft:sweeping")) + addAbsentToList(conflict, SWEEPING_ENCHANTS, "minecraft:sweeping_edge"); + if (removeFromList(conflict, SWEEPING_ENCHANTS, "sweeping")) + addAbsentToList(conflict, SWEEPING_ENCHANTS, "minecraft:sweeping_edge"); + + // Rename scute to turtle_scute + migrateUnitRepair(unitConfig, "minecraft:scute"); + migrateUnitRepair(unitConfig, "scute"); + + ConfigHolder.ITEM_GROUP_HOLDER.reload(); + + tosave.add(ConfigHolder.DEFAULT_CONFIG); + tosave.add(ConfigHolder.UNIT_REPAIR_HOLDER); + tosave.add(ConfigHolder.CONFLICT_HOLDER); + } + + private static void migrateEnchantLimit(FileConfiguration config, String path) { + var finalPath = "enchant_limits." + path; + if (!config.isInt(finalPath)) return; + var value = config.getInt(finalPath); + + config.set(finalPath, null); + if (!config.contains("enchant_limits.minecraft:sweeping_edge")) return; + if (!config.contains("enchant_limits.sweeping_edge")) return; + + config.set("enchant_limits.minecraft:sweeping_edge", value); + } + + private static void migrateEnchantValues(FileConfiguration config, String path) { + migrateEnchantValues(config, path, "item"); + migrateEnchantValues(config, path, "book"); + } + + private static void migrateEnchantValues(FileConfiguration config, String path, String child) { + var finalPath = "enchant_values." + path + "." + child; + if (config.isInt(finalPath)) return; + var value = config.getInt(finalPath); + + config.set(finalPath, null); + if (!config.contains("enchant_values.minecraft:sweeping_edge." + child)) return; + if (!config.contains("enchant_values.sweeping_edge." + child)) return; + + config.set("enchant_values.minecraft:sweeping_edge." + child, value); + } + + private static void migrateUnitRepair(FileConfiguration config, String path) { + var section = config.getConfigurationSection(path); + if (section == null) return; + + config.set(path, null); + var turtle_scute = config.getConfigurationSection("minecraft:turtle_scute"); + if (turtle_scute == null) config.set("minecraft:turtle_scute", section); + else mergeSections(section, turtle_scute); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21.java b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21.java index 3aa60730..bbe35589 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/minecraft/Update_1_21.java @@ -1,6 +1,5 @@ package xyz.alexcrea.cuanvil.update.minecraft; -import io.delilaheve.CustomAnvil; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.update.UpdateUtils; import xyz.alexcrea.cuanvil.update.Version; 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 d6395966..6dd8b5ba 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,26 +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("minecraft:gold_ingot.minecraft:golden_spear", 0.25); + unitConfig.set("minecraft:copper_ingot.minecraft:copper_spear", 0.25); + unitConfig.set("minecraft:iron_ingot.minecraft:iron_spear", 0.25); + unitConfig.set("minecraft:diamond.minecraft:diamond_spear", 0.25); + unitConfig.set("minecraft:netherite_ingot.minecraft:netherite_spear", 0.25); - unitConfig.set("cobblestone.stone_spear", 0.25); - unitConfig.set("cobbled_deepslate.stone_spear", 0.25); + unitConfig.set("minecraft:cobblestone.stone_spear", 0.25); + unitConfig.set("minecraft: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); + unitConfig.set("minecraft:oak_planks.minecraft:wooden_spear", 0.25); + unitConfig.set("minecraft:spruce_planks.minecraft:wooden_spear", 0.25); + unitConfig.set("minecraft:birch_planks.minecraft:wooden_spear", 0.25); + unitConfig.set("minecraft:jungle_planks.minecraft:wooden_spear", 0.25); + unitConfig.set("minecraft:acacia_planks.minecraft:wooden_spear", 0.25); + unitConfig.set("minecraft:dark_oak_planks.minecraft:wooden_spear", 0.25); + unitConfig.set("minecraft:mangrove_planks.minecraft:wooden_spear", 0.25); + unitConfig.set("minecraft:cherry_planks.minecraft:wooden_spear", 0.25); + unitConfig.set("minecraft:bamboo_planks.minecraft:wooden_spear", 0.25); + unitConfig.set("minecraft:crimson_planks.minecraft:wooden_spear", 0.25); + unitConfig.set("minecraft:warped_planks.minecraft:wooden_spear", 0.25); // Create lunge enchant value and group baseConfig.set("enchant_limits.minecraft:lunge", 3); 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 d289b9bf..ec464ba1 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 @@ -49,16 +49,16 @@ public class Update_1_21_9 extends MCUpdate{ 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("minecraft:copper_ingot.minecraft:copper_helmet", 0.25); + unitConfig.set("minecraft:copper_ingot.minecraft:copper_chestplate", 0.25); + unitConfig.set("minecraft:copper_ingot.minecraft:copper_leggings", 0.25); + unitConfig.set("minecraft:copper_ingot.minecraft: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); + unitConfig.set("minecraft:copper_ingot.minecraft:copper_pickaxe", 0.25); + unitConfig.set("minecraft:copper_ingot.minecraft:copper_shovel", 0.25); + unitConfig.set("minecraft:copper_ingot.minecraft:copper_hoe", 0.25); + unitConfig.set("minecraft:copper_ingot.minecraft:copper_axe", 0.25); + unitConfig.set("minecraft:copper_ingot.minecraft:copper_sword", 0.25); } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_18.java b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_18.java new file mode 100644 index 00000000..b52ec7ac --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/plugin/PUpdate_1_18.java @@ -0,0 +1,22 @@ +package xyz.alexcrea.cuanvil.update.plugin; + +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_19; +import xyz.alexcrea.cuanvil.update.minecraft.Update_1_20_5; + +import javax.annotation.Nonnull; +import java.util.Set; + +public class PUpdate_1_18 { + + public static void handleUpdate(@Nonnull Set toSave) { + Version current = UpdateUtils.currentMinecraftVersion(); + if (new Version(1, 19, 0).greaterThan(current)) return; + Update_1_19.updateName(toSave); + + if (new Version(1, 20, 5).greaterThan(current)) return; + Update_1_20_5.updateName(toSave); + } +} diff --git a/src/main/kotlin/io/delilaheve/CustomAnvil.kt b/src/main/kotlin/io/delilaheve/CustomAnvil.kt index 321165e5..762c8b63 100644 --- a/src/main/kotlin/io/delilaheve/CustomAnvil.kt +++ b/src/main/kotlin/io/delilaheve/CustomAnvil.kt @@ -11,7 +11,6 @@ import xyz.alexcrea.cuanvil.command.EditConfigExecutor import xyz.alexcrea.cuanvil.command.ReloadExecutor import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.dependency.DependencyManager -import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry @@ -24,6 +23,8 @@ import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener import xyz.alexcrea.cuanvil.update.ModrinthUpdateChecker import xyz.alexcrea.cuanvil.update.PluginSetDefault import xyz.alexcrea.cuanvil.update.UpdateHandler +import xyz.alexcrea.cuanvil.update.UpdateUtils +import xyz.alexcrea.cuanvil.update.Version import xyz.alexcrea.cuanvil.util.MetricsUtil import java.io.File import java.io.FileReader @@ -56,6 +57,8 @@ open class CustomAnvil : JavaPlugin() { // Permission string required to edit the plugin's config const val editConfigPermission = "ca.config.edit" + // Permission string required to edit the plugin's config + const val giveEnchantmentPermission = "ca.command.enchantment" // Command Name to reload the config const val commandReloadName = "anvilconfigreload" @@ -133,7 +136,7 @@ open class CustomAnvil : JavaPlugin() { override fun onEnable() { instance = this try { - legacyCheck() + if(legacyCheck()) return } catch (e: Exception) { logger.log(Level.SEVERE, "error trying to check for legacy system", e) MetricsUtil.trackError(e) @@ -199,7 +202,16 @@ open class CustomAnvil : JavaPlugin() { } } - private fun legacyCheck() { + private fun legacyCheck(): Boolean { + val currentVersion = UpdateUtils.currentMinecraftVersion() + if (currentVersion.greaterEqual(Version(1, 21, 0)) + && !DependencyManager.inTesting + && !"true".equals(System.getenv("CUSTOM_ANVIL_BYPASS_LEGACY_CHECK"), true)) { + logger.warning("You are running a Minecraft version above or equal to 1.21.0") + logger.warning("Please use CustomAnvil v2 instead if you wish to use the plugin with this version.") + Bukkit.getPluginManager().disablePlugin(this) + return true + } // Disable old plugin name if exist val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus") if (potentialPlugin != null) { @@ -212,10 +224,6 @@ open class CustomAnvil : JavaPlugin() { if(!isPaper) { logger.warning("It seems you are using spigot") logger.warning("Please take notice that spigot is less supported than paper and derivatives") - if(MinecraftVersionUtil.isTooNewForSpigot) { - logger.warning("If replace too expensive is not working this is likely because of spigot") - logger.warning("As native nms is not supported for spigot starting 26.1") - } } val loader = if(isPaper) "paper" else "spigot" @@ -223,7 +231,8 @@ open class CustomAnvil : JavaPlugin() { val version = description.version val featured = if(version.contains("dev")) null else true - ModrinthUpdateChecker(modrinthPluginID, loader, null) + ModrinthUpdateChecker(modrinthPluginID, loader, + UpdateUtils.currentMinecraftVersion().toString()) .setFeatured(featured) .setOnError { logger.log(Level.WARNING, "error trying to fetch latest update", it) @@ -234,6 +243,7 @@ open class CustomAnvil : JavaPlugin() { logger.warning("An update may be available: $latestVer") } + return false } private fun registerListeners() { diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index fc8a53a9..9b0c4cd0 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -86,6 +86,7 @@ object ConfigOptions { // Keys for specific enchantment values private const val KEY_BOOK = "book" + private const val KEY_BOOK_ON_BOOK = "book_on_book" private const val KEY_ITEM = "item" // Debug flag @@ -578,14 +579,15 @@ object ConfigOptions { */ fun enchantmentValue( enchantment: CAEnchantment, - isFromBook: Boolean + isToBook: Boolean, + isFromBook: Boolean, ): Int { // Test namespace - var limit = enchantmentValue(enchantment.key.toString(), isFromBook) + var limit = enchantmentValue(enchantment.key.toString(), isToBook, isFromBook) if (limit != null) return limit // Test legacy (name only) - limit = enchantmentValue(enchantment.enchantmentName, isFromBook) + limit = enchantmentValue(enchantment.enchantmentName, isToBook, isFromBook) if (limit != null) return limit // get default (and test old legacy if present) @@ -599,13 +601,22 @@ object ConfigOptions { */ private fun enchantmentValue( enchantmentName: String, - isFromBook: Boolean + isToBook: Boolean, + isFromBook: Boolean, ): Int? { val typeKey = if (isFromBook) KEY_BOOK else KEY_ITEM val path = "${ENCHANT_VALUES_ROOT}.${enchantmentName}.$typeKey" - return CustomAnvil.instance - .config - .getInt(path, DEFAULT_ENCHANT_VALUE - 1) + + val config = ConfigHolder.DEFAULT_CONFIG.config + if(isFromBook && isToBook) { + val specialPath = "${ENCHANT_VALUES_ROOT}.${enchantmentName}.$KEY_BOOK_ON_BOOK" + + if(config.isInt(specialPath)) + return config.getInt(specialPath) + .takeIf { it >= DEFAULT_ENCHANT_VALUE } + } + + return config.getInt(path, DEFAULT_ENCHANT_VALUE - 1) .takeIf { it >= DEFAULT_ENCHANT_VALUE } } @@ -613,20 +624,9 @@ object ConfigOptions { * Get default value if enchantment do not exist on config */ private fun getDefaultValue( - enchantment: CAEnchantment, // compatibility with 1.20.5. TODO better update system + enchantment: CAEnchantment, isFromBook: Boolean ): Int { - - val enchantmentName = enchantment.key.toString() - if (enchantmentName == "minecraft:sweeping_edge") { - var limit = enchantmentValue("minecraft:sweeping", isFromBook) - if (limit != null) return limit - - // legacy name - limit = enchantmentValue("sweeping", isFromBook) - if (limit != null) return limit - } - val rarity = enchantment.defaultRarity() return if (isFromBook) rarity.bookValue @@ -648,15 +648,6 @@ object ConfigOptions { value = maxBeforeMergeDisabled(legacy) if (value >= 0) return value - if (key == "minecraft:sweeping_edge") { - value = maxBeforeMergeDisabled("minecraft:sweeping") - if (value >= 0) return value - - // legacy name of legacy enchantment name - value = maxBeforeMergeDisabled("sweeping") - if (value >= 0) return value - } - return DEFAULT_MAX_BEFORE_MERGE_DISABLED } diff --git a/src/main/kotlin/io/delilaheve/util/ItemUtil.kt b/src/main/kotlin/io/delilaheve/util/ItemUtil.kt index bf075231..dba79b28 100644 --- a/src/main/kotlin/io/delilaheve/util/ItemUtil.kt +++ b/src/main/kotlin/io/delilaheve/util/ItemUtil.kt @@ -1,12 +1,11 @@ package io.delilaheve.util +import org.bukkit.Material import org.bukkit.Material.ENCHANTED_BOOK import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.Damageable -import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.update.UpdateUtils import xyz.alexcrea.cuanvil.util.MaterialUtil.customType -import xyz.alexcrea.cuanvil.util.MaxDamageCheckerUtil import kotlin.math.ceil import kotlin.math.max import kotlin.math.min @@ -21,13 +20,6 @@ object ItemUtil { */ fun ItemStack.isEnchantedBook() = type == ENCHANTED_BOOK - private fun maxDamage(damageable: Damageable): Int { - val ver = UpdateUtils.currentMinecraftVersion() - if(ver.major <= 1 && ver.minor <= 20 && ver.patch < 5) return Integer.MAX_VALUE - - return MaxDamageCheckerUtil.getMaxDamage(damageable) - } - /** * Set this [ItemStack]s durability from a combination of the * [first] and [second] item's durability values @@ -37,23 +29,22 @@ object ItemUtil { first: ItemStack, second: ItemStack ): Boolean { - (itemMeta as? Damageable)?.let { - val durability = type.maxDurability.toInt() - val firstDamage = (first.itemMeta as? Damageable)?.damage ?: 0 - if (firstDamage == 0) return false + val meta = itemMeta + if(meta !is Damageable) return false - val firstDurability = durability - firstDamage - val secondDamage = (second.itemMeta as? Damageable)?.damage ?: 0 - val secondDurability = durability - secondDamage - val combinedDurability = firstDurability + secondDurability - val newDurability = min(combinedDurability, durability) + val maxDamage = type.maxDurability.toInt() + val damage = (first.itemMeta as? Damageable)?.damage ?: 0 + if (damage == 0) return false - val maxDamage = maxDamage(it) - it.damage = min(durability - newDurability, maxDamage) - itemMeta = it - return true - } - return false + val firstDurability = maxDamage - damage + val secondDamage = (second.itemMeta as? Damageable)?.damage ?: 0 + val secondDurability = maxDamage - secondDamage + val combinedDurability = firstDurability + secondDurability + val newDurability = min(combinedDurability, maxDamage) + + meta.damage = min(maxDamage - newDurability, maxDamage) + this.itemMeta = meta + return true } fun ItemStack.unitRepair( @@ -84,6 +75,6 @@ object ItemUtil { * The two items should either be the same type, or, the [other] is a book */ fun ItemStack.canMergeWith( - other: ItemStack? - ) = (other != null) && (customType == other.customType || (other.isEnchantedBook())) + other: ItemStack + ) = customType == other.customType || (other.isEnchantedBook()) } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt index fd7055ed..f398fd97 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt @@ -6,6 +6,7 @@ import io.delilaheve.util.EnchantmentUtil.combineWith import io.delilaheve.util.ItemUtil.isEnchantedBook import io.delilaheve.util.ItemUtil.repairFrom import io.delilaheve.util.ItemUtil.unitRepair +import net.kyori.adventure.text.Component import org.bukkit.ChatColor import org.bukkit.Material import org.bukkit.entity.HumanEntity @@ -17,6 +18,7 @@ import org.bukkit.inventory.meta.ItemMeta import org.bukkit.persistence.PersistentDataType import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.dependency.DependencyManager +import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe @@ -139,11 +141,12 @@ object AnvilMergeLogic { private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int { // Can be null var renameText = ChatColor.stripColor(inventory.renameText) + var component: Component? = null var sumCost = 0 var useColor = false if (ConfigOptions.renameColorPossible && renameText != null) { - val component = AnvilColorUtil.handleColor( + component = AnvilColorUtil.handleColor( renameText, AnvilColorUtil.renamePermission(player) ) @@ -170,7 +173,11 @@ object AnvilMergeLogic { renameText == CasedStringUtil.snakeToUpperSpacedCase(resultItem.type.name.lowercase()) ) ) { - it.setDisplayName(renameText) + if (component == null) + component = if (renameText == null || renameText.isEmpty()) null + else Component.text(renameText) + it.setComponentDisplayName(component, renameText) + processDialogPCD(it, player) resultItem.itemMeta = it diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt index 4c71c68b..60dcdbee 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/CASubCommand.kt @@ -4,6 +4,7 @@ import org.bukkit.ChatColor import org.bukkit.command.Command import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender +import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry abstract class CASubCommand: CommandExecutor { @@ -43,4 +44,14 @@ abstract class CASubCommand: CommandExecutor { return "no description" } + protected fun allEnchantmentsByName(): Collection { + val names = mutableSetOf() + for (enchantment in CAEnchantmentRegistry.getInstance().values()) { + names.add(enchantment.name) + names.add(enchantment.key.toString()) + } + + return names + } + } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/CustomAnvilCommand.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/CustomAnvilCommand.kt index 8bd1d827..9b9402c9 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/CustomAnvilCommand.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/CustomAnvilCommand.kt @@ -7,7 +7,6 @@ import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import org.bukkit.command.TabCompleter import xyz.alexcrea.cuanvil.util.MetricsUtil -import java.util.ArrayList class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter { @@ -18,12 +17,14 @@ class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter { private val editConfigCommand = EditConfigExecutor() private val helpCommand = HelpExecutor() - private val commands = ImmutableMap.of( + private val commands: ImmutableMap = ImmutableMap.of( "gui", editConfigCommand, + "config", editConfigCommand, "reload", ReloadExecutor(), "diagnostic", DiagnosticExecutor(), "debug", DebugToggleExecutor(), "help", helpCommand, + "enchant", EnchantExecutor(), ) init { @@ -42,12 +43,16 @@ class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter { ): Boolean { // Find sub command to execute based on the provided command name val subcmd: CASubCommand? + val subcmdStr: String + val newargs: Array if(args.isEmpty()) { + subcmdStr = "config" subcmd = editConfigCommand newargs = args }else { - subcmd = commands[args[0].lowercase()] + subcmdStr = args[0].lowercase() + subcmd = commands[subcmdStr] newargs = args.copyOfRange(1, args.size) } @@ -57,7 +62,7 @@ class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter { } try { - return subcmd.executeCommand(sender, cmd, cmdstr, newargs) + return subcmd.executeCommand(sender, cmd, subcmdStr, newargs) } catch (e: Throwable) { MetricsUtil.trackError(e) sender.sendMessage("§cError running this command") @@ -75,6 +80,7 @@ class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter { if(args.size < 2) { for ((key, cmd) in commands) { if(!cmd.allowed(sender)) continue + if("gui".contentEquals(key)) continue result.add(key) } } else { @@ -89,9 +95,11 @@ class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter { } //assumed all provided tab completed string are lowercase + val prefix = args[args.size - 1] return result.stream() - .filter { it.startsWith(args[args.size - 1]) } + .filter { it.startsWith(prefix) } .sorted() .toList() } + } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt index b095e14c..75459728 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/DiagnosticExecutor.kt @@ -130,9 +130,9 @@ class DiagnosticExecutor: CASubCommand() { message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString()) message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, Text("§7Click to copy")) - sender.spigot().sendMessage(message); + sender.spigot().sendMessage(message) } else { - sender.sendMessage(stb.toString()); + sender.sendMessage(stb.toString()) } return true @@ -267,8 +267,8 @@ class DiagnosticExecutor: CASubCommand() { try { val fakeInv = Bukkit.createInventory(player, InventoryType.ANVIL) invView = player.openInventory(fakeInv)!! - event = PrepareAnvilEvent(invView, result) - } catch (e: Throwable) { + event = DependencyManager.createFakeEvent(invView, result) + } catch (_: Throwable) { // Help val menuTypeClazz = Class.forName("org.bukkit.inventory.MenuType") val anvilTypeField = menuTypeClazz.getField("ANVIL") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt index fba89b71..c6bc191b 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt @@ -4,35 +4,17 @@ import io.delilaheve.CustomAnvil import org.bukkit.command.Command import org.bukkit.command.CommandSender import org.bukkit.entity.HumanEntity +import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil +import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.gui.config.MainConfigGui +import xyz.alexcrea.cuanvil.gui.config.global.EnchantConfigGui +import xyz.alexcrea.cuanvil.gui.config.global.ItemConfigGui import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions +import xyz.alexcrea.cuanvil.util.MaterialUtil.customType +import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir -class EditConfigExecutor: CASubCommand() { - - override fun executeCommand(sender: CommandSender, - cmd: Command, - cmdstr: String, - args: Array): Boolean { - if (sender !is HumanEntity) return false - - if (!allowed(sender)) { - sender.sendMessage(GuiGlobalActions.NO_EDIT_PERM) - return false - } - if(PlatformUtil.isFolia){ - sender.sendMessage("§cIt look like you are using Folia. Sadly Custom Anvil do not support Config gui for Folia.") - sender.sendMessage("§eIt is may come in a future version.") - sender.sendMessage("") - sender.sendMessage("§eCurrently you need to edit manually the config or copy from another server (spigot or better)") - sender.sendMessage("§eThen /anvilconfigreload after config file is edited") - return false - } - - MainConfigGui.getInstance().show(sender) - - return true - } +class EditConfigExecutor : CASubCommand() { override fun allowed(sender: CommandSender): Boolean { return sender.hasPermission(CustomAnvil.editConfigPermission) @@ -42,4 +24,98 @@ class EditConfigExecutor: CASubCommand() { return "Gui to edit the plugin's config" } + override fun executeCommand( + sender: CommandSender, + cmd: Command, + cmdstr: String, + args: Array + ): Boolean { + if (sender !is HumanEntity) return false + + if (!allowed(sender)) { + sender.sendMessage(GuiGlobalActions.NO_EDIT_PERM) + return false + } + if (PlatformUtil.isFolia) { + sender.sendMessage("§cIt look like you are using Folia. Sadly Custom Anvil do not support Config gui for Folia.") + sender.sendMessage("§eIt is may come in a future version.") + sender.sendMessage("") + sender.sendMessage("§eCurrently you need to edit manually the config or copy from another server (spigot or better)") + sender.sendMessage("§eThen /ca reload after config file is edited") + return false + } + + if ("gui".equals(cmdstr, ignoreCase = true)) { + sender.sendMessage("§c/ca gui has been moved to /ca config") + } + + if (args.isEmpty()) + processOpen(sender) + else when (args[0].lowercase()) { + "open" -> processOpen(sender) + "enchant" -> processEnchant(sender, args) + "item" -> processItem(sender) + else -> sender.sendMessage("Unknown subcommand \"${args[0]}\"") + } + + return true + } + + private fun processEnchant(sender: HumanEntity, args: Array) { + val enchantToFilter: Set + if (args.size <= 1) { + val item = sender.inventory.itemInMainHand + + enchantToFilter = EnchantmentApi.getEnchantments(item).keys + if (enchantToFilter.isEmpty()) { + sender.sendMessage("No enchantment found in the item you are holding") + return + } + } else { + enchantToFilter = HashSet(EnchantmentApi.getListByName(args[1].lowercase())) + + if (enchantToFilter.isEmpty()) { + sender.sendMessage("No enchantment found with the name \"${args[1]}\"") + return + } + } + + EnchantConfigGui(enchantToFilter).show(sender) + + } + + private fun processItem(sender: HumanEntity) { + val item = sender.inventory.itemInMainHand + if (item.isAir) { + sender.sendMessage("Cannot configure the item in hand") + return + } + + ItemConfigGui(item.type, item.customType).show(sender) + } + + private fun processOpen(sender: HumanEntity) { + MainConfigGui.getInstance().show(sender) + } + + // --------------- + // Tab completer + // --------------- + + override fun tabCompleter(sender: CommandSender, args: Array, list: MutableList) { + list.addAll( + when (args.size) { + 1 -> listOf("item", "enchant", "open") + 2 -> { + when (args[0].lowercase()) { + "enchant" -> allEnchantmentsByName() + else -> listOf() + } + } + + else -> listOf() + } + ) + } + } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt new file mode 100644 index 00000000..1bdf56a1 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EnchantExecutor.kt @@ -0,0 +1,126 @@ +package xyz.alexcrea.cuanvil.command + +import io.delilaheve.CustomAnvil +import io.delilaheve.util.ConfigOptions +import io.delilaheve.util.ItemUtil.isEnchantedBook +import org.bukkit.Material +import org.bukkit.NamespacedKey +import org.bukkit.command.Command +import org.bukkit.command.CommandSender +import org.bukkit.entity.HumanEntity +import xyz.alexcrea.cuanvil.api.EnchantmentApi +import xyz.alexcrea.cuanvil.enchant.CAEnchantment +import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir + +class EnchantExecutor : CASubCommand() { + + + override fun allowed(sender: CommandSender): Boolean { + return sender.hasPermission(CustomAnvil.giveEnchantmentPermission) + } + + override fun description(): String { + return "Allows to set enchantment to holden item" + } + + override fun executeCommand( + sender: CommandSender, + cmd: Command, + cmdstr: String, + args: Array + ): Boolean { + if (sender !is HumanEntity) return true + + if (!allowed(sender)) { + sender.sendMessage("No permission to execute this command") + return true + } + + when (args.size) { + 0 -> { + sender.sendMessage("Missing enchantment parameter") + return true + } + } + + val enchant = firstEnchantment(args[0]) + if (enchant == null) { + sender.sendMessage("Enchantment not found: ${args[0]}") + return true + } + + val level = if (args.size > 1) + args[1].toIntOrNull()?.coerceIn(0, ConfigOptions.ENCHANT_LIMIT) + else 1 + + if (level == null) { + sender.sendMessage("Invalid number: ${args[1]}") + return true + } + + val inHand = sender.inventory.itemInMainHand + if (inHand.isAir) { + sender.sendMessage("Cannot enchant this item") + return true + } + + if (level == 0) { + enchant.removeFrom(inHand) + + if (inHand.isEnchantedBook() && EnchantmentApi.getEnchantments(inHand).isEmpty()) + inHand.type = Material.BOOK + + sender.sendMessage("${enchant.prettyName} removed") + } else { + if (Material.BOOK == inHand.type) + inHand.type = Material.ENCHANTED_BOOK + + enchant.addEnchantmentUnsafe(inHand, level) + sender.sendMessage("${enchant.prettyName} set to level $level") + } + + return true + } + + override fun tabCompleter(sender: CommandSender, args: Array, list: MutableList) { + if (sender !is HumanEntity) return + + list.addAll( + when (args.size) { + 1 -> allEnchantmentsByName() + 2 -> findEnchantmentLevels(sender, args[0]) + + else -> listOf() + } + ) + } + + private fun findEnchantmentLevels( + sender: HumanEntity, + name: String + ): Collection { + val enchant = firstEnchantment(name) ?: return listOf() + + val limit = ConfigOptions.enchantLimit(enchant) + val result = mutableListOf() + + for (i in 1 until limit + 1) { + result.add(i.toString()) + } + + val inHand = sender.inventory.itemInMainHand + if (enchant.isEnchantmentPresent(inHand)) + result.add("0") + + return result + } + + private fun firstEnchantment(name: String): CAEnchantment? { + val enchants = EnchantmentApi.getListByName(name.lowercase()) + if (!enchants.isEmpty()) + return enchants.iterator().next() + + return EnchantmentApi.getByKey(NamespacedKey.fromString(name)) + } + +} diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt index ef23e7d6..cb0d24a9 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt @@ -3,7 +3,6 @@ package xyz.alexcrea.cuanvil.command import io.delilaheve.CustomAnvil import org.bukkit.Bukkit import org.bukkit.command.Command -import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import xyz.alexcrea.cuanvil.api.event.CAConfigReadyEvent import xyz.alexcrea.cuanvil.config.ConfigHolder diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/config/AnvilFinishOptions.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/config/AnvilFinishOptions.kt new file mode 100644 index 00000000..4cda8d83 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/config/AnvilFinishOptions.kt @@ -0,0 +1,146 @@ +package xyz.alexcrea.cuanvil.config + +import io.delilaheve.CustomAnvil +import org.bukkit.NamespacedKey +import org.bukkit.Registry +import org.bukkit.Sound +import org.bukkit.SoundCategory +import org.bukkit.configuration.ConfigurationSection +import java.util.Random +import java.util.logging.Level + +object AnvilFinishOptions { + + data class ConfiguredSound( + val sound: Sound, + val category: SoundCategory, + val volume: Float, + val pitch: Float, + val weight: Double, + ) + + // Paths + private const val SOUND_ENABLED = "anvil_sound.enabled" + + private const val USE_SOUNDS_ROOT = "anvil_sound.use" + private const val DESTROY_SOUNDS_ROOT = "anvil_sound.destroy" + + private const val ANVIL_DEGRADATION_PATH = "anvil_degradation" + + // Defaults + private const val DEFAULT_SOUND_ENABLED = true + private val DEFAULT_USE_SOUND = ConfiguredSound( + Sound.BLOCK_ANVIL_USE, + SoundCategory.BLOCKS, + 1.0f, + 1.0f, + 1.0, + ) + + private val DEFAULT_DESTROY_SOUND = ConfiguredSound( + Sound.BLOCK_ANVIL_DESTROY, + SoundCategory.BLOCKS, + 1.0f, + 1.0f, + 1.0, + ) + private const val DEFAULT_ANVIL_DEGRADATION_PATH = 0.12 + + // Others + private val RANDOM = Random() + + // Fetch + val sound_enabled: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(SOUND_ENABLED, DEFAULT_SOUND_ENABLED) + } + + fun getAnvilSound(wasDestroyed: Boolean): ConfiguredSound { + return if(wasDestroyed) + getRandomDestroySound() + else getRandomUseSound() + } + + val degradation_chance: Double + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getDouble(ANVIL_DEGRADATION_PATH, DEFAULT_ANVIL_DEGRADATION_PATH) + } + + // Utils + private fun getRandomUseSound(): ConfiguredSound { + return fromListing(USE_SOUNDS_ROOT, DEFAULT_USE_SOUND) + } + + private fun getRandomDestroySound(): ConfiguredSound { + return fromListing(DESTROY_SOUNDS_ROOT, DEFAULT_DESTROY_SOUND) + } + + private fun fromListing(path: String, default: ConfiguredSound): ConfiguredSound { + val section = ConfigHolder.DEFAULT_CONFIG + .config.getConfigurationSection(path) ?: return default + + val list = readSounds(section) + return weightedRandom(list, default) + } + + private fun readSounds(section: ConfigurationSection): List { + val sounds = ArrayList() + + for (key in section.getKeys(false)) { + if(!section.isConfigurationSection(key)) continue + + val result = readSound(section.getConfigurationSection(key)!!) + if(result == null) { + CustomAnvil.instance.logger.warning("Couldn't read sounds for key $key") + continue + } + + sounds.add(result) + } + return sounds + } + + private fun readSound(section: ConfigurationSection): ConfiguredSound? { + val name = section.getString("sound", null)?: return null + val key = NamespacedKey.fromString(name)?: return null + val sound = Registry.SOUNDS.get(key)?: return null + + val categoryName = section.getString("category", null)?: return null + val category = try { + SoundCategory.valueOf(categoryName.uppercase()) + } catch (_: IllegalArgumentException) { + return null + } + + val volume = section.getDouble("volume", 1.0).toFloat() + val pitch = section.getDouble("pitch", 1.0).toFloat() + val weight = section.getDouble("weight", 1.0) + if(weight <= 0) return null + + return ConfiguredSound(sound, category, volume, pitch, weight) + } + + private fun weightedRandom(sounds: List, default: ConfiguredSound): ConfiguredSound { + if(sounds.isEmpty()) return default + + val weightSum = sounds.sumOf { it.weight } + if(weightSum == .0) return sounds.first() + + val selectedWeight = RANDOM.nextDouble(weightSum) + + var currentSum = .0 + sounds.forEach { + currentSum += it.weight + if(currentSum > selectedWeight) return it + } + + // What ? how + CustomAnvil.instance.logger.log(Level.SEVERE, "Something very... very wrong happen on sound handling. please report this to the developer") + return default + } + +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index b730a0ee..e736a8fa 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -33,6 +33,7 @@ import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError +import java.lang.IllegalStateException import java.util.logging.Level object DependencyManager { @@ -41,8 +42,11 @@ object DependencyManager { lateinit var packetManager: PacketManager var externGuiTester: GenericExternGuiTester = GenericExternGuiTester() + val inTesting = externGuiTester.isInTest() + var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null var ecoEnchantCompatibility: EcoEnchantDependency? = null + var hasEcoItem: Boolean = false var excellentEnchantsCompatibility: ExcellentEnchantsDependency? = null var disenchantmentCompatibility: DisenchantmentDependency? = null @@ -79,6 +83,10 @@ object DependencyManager { ecoEnchantCompatibility = EcoEnchantDependency(pluginManager.getPlugin("EcoEnchants")!!) ecoEnchantCompatibility!!.disableAnvilListener() } + // EcoItem check + if (pluginManager.isPluginEnabled("EcoItems")) { + hasEcoItem = true + } // Excellent Enchants dependency if (pluginManager.isPluginEnabled("ExcellentEnchants")) { @@ -103,7 +111,7 @@ object DependencyManager { axPlayerWarpsCompatibility = AxPlayerWarpsDependency() } - if (pluginManager.isPluginEnabled("ItemsAdder")){ + if (pluginManager.isPluginEnabled("ItemsAdder")) { val dependency = ItemsAdderDependency(pluginManager.getPlugin("ItemsAdder")!!) itemsAdderCompatibility = dependency genericDependencies.add(dependency) @@ -116,12 +124,16 @@ object DependencyManager { if (pluginManager.isPluginEnabled("ItemsAdder")) genericDependencies.add(GenericPluginDependency(pluginManager.getPlugin("ItemsAdder")!!)) - if (pluginManager.isPluginEnabled("SuperEnchants")){ + if (pluginManager.isPluginEnabled("SuperEnchants")) { val compatibility = SuperEnchantDependency(pluginManager.getPlugin("SuperEnchants")!! as SuperEnchants) - if(compatibility.registerEnchantments()) + if (compatibility.registerEnchantments()) genericDependencies.add(compatibility) } + if (pluginManager.isPluginEnabled("EnchantedBook")) { + genericDependencies.add(EnchantedBookDependency(pluginManager.getPlugin("EnchantedBook")!!)) + } + for (dependency in genericDependencies) dependency.redirectListeners() @@ -307,7 +319,7 @@ object DependencyManager { private fun unsafeCloneItem(item: ItemStack): ItemStack { val cloned = itemsAdderCompatibility?.tryClone(item) - if(cloned != null) return cloned + if (cloned != null) return cloned return item.clone() } @@ -328,4 +340,16 @@ object DependencyManager { enchantmentSquaredCompatibility?.updateLore(item) } + + private val prepareAnvilConstructor = + PrepareAnvilEvent::class.java.constructors.first() + + fun createFakeEvent(view: InventoryView, result: ItemStack?): PrepareAnvilEvent { + val result = prepareAnvilConstructor.newInstance(view, result) + if(result !is PrepareAnvilEvent) + throw IllegalStateException("Could not create a PrepareAnvilEvent ?") + + return result + } + } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/MinecraftVersionUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/MinecraftVersionUtil.kt index cbd22095..5d333e29 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/MinecraftVersionUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/MinecraftVersionUtil.kt @@ -51,8 +51,4 @@ object MinecraftVersionUtil { } } - val isTooNewForSpigot: Boolean get() { - return UpdateUtils.currentMinecraftVersion().major != 1 - } - } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt index 6d544565..af3ce203 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/datapack/DataPackDependency.kt @@ -223,7 +223,11 @@ object DataPackDependency { private fun setEnchantAsAll(ench: String) { // We assume current is not null and of type CABukkitEnchantment - val current = EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!) as CABukkitEnchantment + val current = EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!) as? CABukkitEnchantment + if(current == null) { + CustomAnvil.instance.logger.warning("Could not find enchant $ench") + return + } // We need to replace current wrapped enchantment with the all conflict wrapper EnchantmentApi.unregisterEnchantment(current) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/economy/VaultEconomyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/economy/VaultEconomyManager.kt index 058485e2..23d22b52 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/economy/VaultEconomyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/economy/VaultEconomyManager.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package xyz.alexcrea.cuanvil.dependency.economy import net.milkbowl.vault.economy.Economy 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 d74ef089..69ca28cc 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/PacketManagerSelector.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/packet/PacketManagerSelector.kt @@ -12,7 +12,7 @@ object PacketManagerSelector { fun selectPacketManager(forceProtocolib: Boolean): PacketManager { // Try to find version - if(DependencyManager.externGuiTester.isInTest()) + if(DependencyManager.inTesting) return NoPacketManager() return if (forceProtocolib) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/EcoEnchantDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/EcoEnchantDependency.kt index 079d5707..78bc9d13 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/EcoEnchantDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/EcoEnchantDependency.kt @@ -3,7 +3,7 @@ package xyz.alexcrea.cuanvil.dependency.plugins import com.willfp.eco.core.EcoPlugin import com.willfp.ecoenchants.enchant.EcoEnchant import com.willfp.ecoenchants.enchant.EcoEnchants -import com.willfp.ecoenchants.mechanics.infiniteIfNegative +import com.willfp.ecoenchants.enchant.UtilKt import io.delilaheve.CustomAnvil import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.plugin.Plugin @@ -35,7 +35,7 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { } public fun getEcoLevelLimit(): Int { - return (ecoEnchantPlugin as EcoPlugin).configYml.getInt("anvil.enchant-limit").infiniteIfNegative() + return UtilKt.infiniteIfNegative((ecoEnchantPlugin as EcoPlugin).configYml.getInt("anvil.enchant-limit")) } fun disableAnvilListener() { @@ -51,7 +51,7 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { return } - val enchantments = EcoEnchants.values() + val enchantments = EcoEnchants.INSTANCE.values() for (ecoEnchant in enchantments) { EnchantmentApi.unregisterEnchantment(ecoEnchant.enchantment) // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant. EnchantmentApi.registerEnchantment(CAEcoEnchant(ecoEnchant)) @@ -71,7 +71,7 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) { // Should not happen in known case. if (this.ecoEnchantOldEnchantments == null) return - val newEnchantments = EcoEnchants.values() + val newEnchantments = EcoEnchants.INSTANCE.values() // Add new enchantments for (ecoEnchant in newEnchantments) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/EnchantedBookDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/EnchantedBookDependency.kt new file mode 100644 index 00000000..54de4e12 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/EnchantedBookDependency.kt @@ -0,0 +1,32 @@ +package xyz.alexcrea.cuanvil.dependency.plugins + +import org.bukkit.event.Event +import org.bukkit.event.inventory.InventoryClickEvent +import org.bukkit.plugin.Plugin +import xyz.alexcrea.cuanvil.dependency.DependencyManager +import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT +import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT + +class EnchantedBookDependency(plugin: Plugin) : GenericPluginDependency(plugin) { + + override fun testAnvilResult(event: InventoryClickEvent): Boolean { + val view = event.view + val inv = event.inventory + + //TODO use view here (v2) + val current = inv.getItem(ANVIL_OUTPUT_SLOT) + inv.setItem(ANVIL_OUTPUT_SLOT, null) + val fakeEvent = DependencyManager.createFakeEvent(view, null) + + if (testPrepareAnvil(fakeEvent)) { + event.result = Event.Result.DEFAULT + + inv.setItem(ANVIL_INPUT_LEFT, fakeEvent.result) + return true + } + + inv.setItem(ANVIL_INPUT_LEFT, current) + return false + } + +} diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt index 816a4dfe..8ac479f1 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt @@ -9,11 +9,11 @@ import org.bukkit.inventory.ItemStack import org.bukkit.plugin.RegisteredListener import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResult2Event +import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5_4Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEEEnchantment -import java.lang.reflect.Constructor import java.lang.reflect.Method import su.nightexpress.excellentenchants.api.EnchantRegistry as V5EnchantRegistry import su.nightexpress.excellentenchants.enchantment.impl.universal.CurseOfFragilityEnchant as LegacyCurseOfFragilityEnchant @@ -47,7 +47,7 @@ class ExcellentEnchantsDependency { listenerVersion = value break - } catch (ignored: ClassNotFoundException) { + } catch (_: ClassNotFoundException) { } } @@ -60,7 +60,7 @@ class ExcellentEnchantsDependency { var isModernCurseOfFragility = true try { Class.forName("su.nightexpress.excellentenchants.enchantment.universal.CurseOfFragilityEnchant") - } catch (ignored: ClassNotFoundException) { + } catch (_: ClassNotFoundException) { isModernCurseOfFragility = false } @@ -118,8 +118,6 @@ class ExcellentEnchantsDependency { private lateinit var handleRechargeMethod: Method private lateinit var handleCombineMethod: Method - private val prepareAnvilConstructor = PrepareAnvilEvent::class.java.constructors.first() as Constructor - fun redirectListeners() { val toUnregister = ArrayList() // get required PrepareAnvilEvent listener @@ -226,7 +224,7 @@ class ExcellentEnchantsDependency { val first: ItemStack = treatInput(event.leftItem) val second: ItemStack = treatInput(event.rightItem) - val fakeEvent = prepareAnvilConstructor.newInstance(event.view, result) + val fakeEvent = DependencyManager.createFakeEvent(event.view, result) handleCombineMethod.invoke(this.usedAnvilListener, fakeEvent, first, second, result) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ItemsAdderDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ItemsAdderDependency.kt index 7f977e18..548080fb 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ItemsAdderDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ItemsAdderDependency.kt @@ -6,6 +6,7 @@ import org.bukkit.NamespacedKey import org.bukkit.inventory.ItemStack import org.bukkit.plugin.Plugin +@Suppress("DEPRECATION") class ItemsAdderDependency(plugin: Plugin) : GenericPluginDependency(plugin) { var isLoaded: Boolean = false get() { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/LegacyEcoEnchantDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/LegacyEcoEnchantDependency.kt index 60f00b85..7f4196cf 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/LegacyEcoEnchantDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/LegacyEcoEnchantDependency.kt @@ -10,13 +10,20 @@ class LegacyEcoEnchantDependency { private var ecoEnchantOldEnchantments: MutableSet? = null + private fun unregisterEnchantment(enchant: Any) { + EnchantmentApi.unregisterEnchantment((enchant as Enchantment).key) + } + + private fun registerEnchantment(ecoEnchant: EcoEnchant, enchant: Any) { + EnchantmentApi.registerEnchantment(CALegacyEcoEnchant(ecoEnchant, enchant as Enchantment)) + } + fun registerEnchantments() { val enchantments = EcoEnchants.values() for (ecoEnchant in enchantments) { - ecoEnchant as Enchantment - - EnchantmentApi.unregisterEnchantment(ecoEnchant) // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant. - EnchantmentApi.registerEnchantment(CALegacyEcoEnchant(ecoEnchant, ecoEnchant)) + // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant. + unregisterEnchantment(ecoEnchant) + registerEnchantment(ecoEnchant, ecoEnchant) } ecoEnchantOldEnchantments = HashSet(enchantments) @@ -31,13 +38,13 @@ class LegacyEcoEnchantDependency { // Add new enchantments for (ecoEnchant in newEnchantments) if (!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant)) - EnchantmentApi.registerEnchantment(CALegacyEcoEnchant(ecoEnchant, ecoEnchant as Enchantment)) + registerEnchantment(ecoEnchant, ecoEnchant) // Remove old enchantments that not now currently used this.ecoEnchantOldEnchantments!!.removeAll(newEnchantments) for (oldEnchantment in this.ecoEnchantOldEnchantments!!) { - EnchantmentApi.unregisterEnchantment(oldEnchantment as Enchantment) + unregisterEnchantment(oldEnchantment) } this.ecoEnchantOldEnchantments = HashSet(newEnchantments) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ToolStatsDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ToolStatsDependency.kt index 255f7373..8456ec87 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ToolStatsDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ToolStatsDependency.kt @@ -5,7 +5,6 @@ import lol.hyper.toolstats.tools.ItemChecker import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.inventory.ItemStack import org.bukkit.plugin.Plugin -import org.bukkit.plugin.RegisteredListener import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener import java.lang.reflect.Method @@ -19,9 +18,13 @@ class ToolStatsDependency(plugin: Plugin) : GenericPluginDependency(plugin) { getTokenMethod.trySetAccessible() } - private fun ItemChecker.getTokenSafe(item: ItemStack?): Array { - if (item == null) return arrayOf() - return getTokenMethod.invoke(this, item) as Array + private fun ItemChecker.getTokenSafe(item: ItemStack?): Array<*> { + if (item == null) return arrayOf() + val result = getTokenMethod.invoke(this, item) + if(result !is Array<*>) + throw IllegalStateException("Could not get token from ToolStats") + + return result } override fun testAnvilResult(event: InventoryClickEvent): Boolean { diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index 5b256dd8..ee9c718b 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -3,7 +3,6 @@ package xyz.alexcrea.cuanvil.group import io.delilaheve.CustomAnvil import org.bukkit.NamespacedKey import org.bukkit.configuration.ConfigurationSection -import org.bukkit.enchantments.Enchantment import org.bukkit.inventory.ItemStack import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment @@ -33,19 +32,8 @@ class EnchantConflictManager { // Path for the maximum number of enchantment before validating the conflict const val ENCH_MAX_PATH = "maxEnchantmentBeforeConflict" - // Path for a flag: if the enchantment will be used in the last supported version - // TODO maybe replace this system by a list of "future" enchantment. - private const val FUTURE_USE_PATH = "useInFuture" - // Default name for a joining group const val DEFAULT_GROUP_NAME = "joinedGroup" - - // 1.20.5 compatibility TODO better update system - private val SWEEPING_EDGE_ENCHANT = Collections.singletonList( - CAEnchantment.getByKey(NamespacedKey.minecraft("sweeping_edge")) - ?: CAEnchantment.getByKey(Enchantment.SWEEPING_EDGE.key) - ) - } lateinit var conflictList: ArrayList @@ -108,8 +96,6 @@ class EnchantConflictManager { itemManager: ItemGroupManager, conflictName: String ): EnchantConflictGroup { - // Is it planed for the future - val futureUse = section.getBoolean(FUTURE_USE_PATH, false) // Create conflict val conflict = createConflictObject(section, itemManager, conflictName) // Read and add enchantment to conflict @@ -117,17 +103,13 @@ class EnchantConflictManager { for (enchantName in enchantList) { val enchants = getEnchantByIdentifier(enchantName) if (enchants.isEmpty()) { - if (!futureUse) { //TODO future use will be deprecated once the new update system is finished - CustomAnvil.instance.logger.warning("Enchantment $enchantName do not exist but was asked for conflict $conflictName") - } + CustomAnvil.instance.logger.warning("Enchantment $enchantName do not exist but was asked for conflict $conflictName") continue } conflict.addEnchantments(enchants) } if (conflict.getEnchants().isEmpty()) { - if (!futureUse) { //TODO future use will be deprecated once the new update system is finished - CustomAnvil.instance.logger.warning("Conflict $conflictName do not have valid enchantment, it will not do anything") - } + CustomAnvil.instance.logger.warning("Conflict $conflictName do not have valid enchantment, it will not do anything") } val conflictsAfterLevel = section.getConfigurationSection(CONFLICT_AFTER_LEVEL_LIST_PATH) @@ -172,14 +154,6 @@ class EnchantConflictManager { } - // Temporary solution for 1.20.5 - when (enchantName) { - "minecraft:sweeping", "sweeping", - "minecraft:sweeping_edge", "sweeping_edge" -> { - return SWEEPING_EDGE_ENCHANT - } - } - return CAEnchantment.getListByName(enchantName) } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt index e9290ac9..11dc1936 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt @@ -4,7 +4,9 @@ import io.delilaheve.CustomAnvil import io.delilaheve.util.ConfigOptions import io.delilaheve.util.ItemUtil.canMergeWith import org.bukkit.GameMode +import org.bukkit.Location import org.bukkit.Material +import org.bukkit.entity.HumanEntity import org.bukkit.entity.Player import org.bukkit.event.Event import org.bukkit.event.EventHandler @@ -21,6 +23,7 @@ import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.AnvilResult import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.CustomCraftResult import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.LoreEditResult import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.UnitRepairResult +import xyz.alexcrea.cuanvil.config.AnvilFinishOptions import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName @@ -28,6 +31,7 @@ import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_ import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT import xyz.alexcrea.cuanvil.util.CustomRecipeUtil +import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MiniMessageUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil @@ -89,7 +93,7 @@ class AnvilResultListener : Listener { } // Rename - if (rightItem == null) { + if (rightItem.isAir) { val result = AnvilMergeLogic.doRenaming(view, inventory, player, leftItem) if (result.isEmpty()) return @@ -103,7 +107,7 @@ class AnvilResultListener : Listener { } // Merge - val canMerge = leftItem.canMergeWith(rightItem) + val canMerge = leftItem.canMergeWith(rightItem!!) if (canMerge) { val result = AnvilMergeLogic.doMerge(view, inventory, player, leftItem, rightItem) @@ -193,6 +197,9 @@ class AnvilResultListener : Listener { result ) ) return + else if(player.gameMode != GameMode.CREATIVE) { + return + } // Finally, we add the item to the player if (slotDestination.type == SlotType.CURSOR) { @@ -212,10 +219,10 @@ class AnvilResultListener : Listener { val recipe = result.recipe!! // We remove what should be removed - if (rightItem != null) { - if (recipe.rightItem == null) return false// in case it changed + if (!rightItem.isAir) { + if (recipe.rightItem.isAir) return false// in case it changed - rightItem.amount -= amount * recipe.rightItem!!.amount + rightItem!!.amount -= amount * recipe.rightItem!!.amount inventory.setItem(ANVIL_INPUT_RIGHT, rightItem) } @@ -243,6 +250,8 @@ class AnvilResultListener : Listener { player.updateInventory() } + + handleAnvilMechanic(player, inventory) return true } @@ -345,6 +354,8 @@ class AnvilResultListener : Listener { inventory.setItem(ANVIL_OUTPUT_SLOT, null) + } else if(player.gameMode != GameMode.CREATIVE) { + return false } // Finally, we add the item to the player @@ -354,7 +365,9 @@ class AnvilResultListener : Listener { player.inventory.setItem(slotDestination.slot, result.item) } - // TODO probably anvil damage & sound here ?? + if (event.click != ClickType.MIDDLE) + handleAnvilMechanic(player, inventory) + return true } @@ -382,6 +395,61 @@ class AnvilResultListener : Listener { } } + // Process both sound & degradation + private fun handleAnvilMechanic(player: HumanEntity, inventory: AnvilInventory) { + return handleAnvilMechanic(player, inventory, player.gameMode != GameMode.CREATIVE) + } + + // Process both sound & degradation + private fun handleAnvilMechanic(player: HumanEntity, inventory: AnvilInventory, canDegrade: Boolean) { + // ok so we do not provide a getLocation on view ? + val location = inventory.location + + val wasDestroyed = canDegrade && tryDegradeAnvil(player, location) + tryPlaySound(location, wasDestroyed) + } + + private fun tryDegradeAnvil(player: HumanEntity, location: Location?): Boolean { + val world = location?.world ?: return false + if (Math.random() > AnvilFinishOptions.degradation_chance) return false + + val block = world.getBlockAt(location) + + val next = when (block.type) { + Material.ANVIL -> Material.CHIPPED_ANVIL + Material.CHIPPED_ANVIL -> Material.DAMAGED_ANVIL + Material.DAMAGED_ANVIL -> Material.AIR + else -> return false + } + + block.type = next + + if (next == Material.AIR) { + player.closeInventory() + return true + } + + return false + } + + private fun tryPlaySound( + location: Location?, + wasDestroyed: Boolean, + ) { + val world = location?.world + + if (!AnvilFinishOptions.sound_enabled) return + + val sound = AnvilFinishOptions.getAnvilSound(wasDestroyed) + world?.playSound( + location, + sound.sound, + sound.category, + sound.volume, + sound.pitch, + ) + } + private fun onUnitRepairExtract( rightItem: ItemStack, event: InventoryClickEvent, diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt index fd079c3a..1cd2b616 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt @@ -176,8 +176,8 @@ class AnvilCustomRecipe( CustomAnvil.verboseLog("Left item passed !") // we don't know if right item can be - if (rightItem == null) { // null test - if (item2 != null) return false + if (rightItem.isAir) { // null test + if (!item2.isAir) return false } else { val rightSimilar = rightItem!!.isSimilar(item2) CustomAnvil.verboseLog("Right similar: $rightSimilar") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/CustomRecipeUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/CustomRecipeUtil.kt index 058b25ad..b8a1907a 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/CustomRecipeUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/CustomRecipeUtil.kt @@ -4,6 +4,7 @@ import io.delilaheve.CustomAnvil import org.bukkit.inventory.ItemStack import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe +import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import kotlin.math.min object CustomRecipeUtil { @@ -32,7 +33,7 @@ object CustomRecipeUtil { return if(recipe.exactCount) { if(leftItem.amount != recipe.leftItem!!.amount){ 0 - }else if(rightItem != null && rightItem.amount != recipe.rightItem!!.amount){ + }else if(!rightItem.isAir && rightItem!!.amount != recipe.rightItem!!.amount){ 0 }else{ 1 @@ -43,7 +44,7 @@ object CustomRecipeUtil { val resultItem = recipe.resultItem!! // we know exist as the recipe was returned to us val maxResultAmount = resultItem.maxStackSize/resultItem.amount val maxLeftAmount = leftItem.amount/recipe.leftItem!!.amount - val maxRightAmount = if(rightItem == null){ maxLeftAmount } else{ rightItem.amount/recipe.rightItem!!.amount } + val maxRightAmount = if(rightItem.isAir){ maxLeftAmount } else{ rightItem!!.amount/recipe.rightItem!!.amount } CustomAnvil.verboseLog("resultItem: $resultItem, maxResultAmount: $maxResultAmount, maxLeftAmount: $maxLeftAmount, maxRightAmount: $maxRightAmount") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/MaterialUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/MaterialUtil.kt index 6b55662f..f9a6acc3 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/MaterialUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/MaterialUtil.kt @@ -1,11 +1,11 @@ package xyz.alexcrea.cuanvil.util -import org.bukkit.Bukkit import org.bukkit.Material import org.bukkit.NamespacedKey import org.bukkit.inventory.ItemStack import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.plugins.EcoItemDependencyUtil +import javax.annotation.Nullable object MaterialUtil { @@ -21,7 +21,7 @@ object MaterialUtil { val ItemStack.customType: NamespacedKey get() { - if(DependencyManager.ecoEnchantCompatibility != null) { + if(DependencyManager.hasEcoItem) { val result = EcoItemDependencyUtil.ecoItemNamespace(this) if(result != null) return result } @@ -35,13 +35,15 @@ object MaterialUtil { return this.type.key } + @Nullable private fun bukkitMaterialFromKey(key: NamespacedKey): Material? { //TODO on paper only transition Registry.MATERIAL.get(key) return Material.matchMaterial(key.toString()) } + @Nullable fun getMatFromKey(key: NamespacedKey): Material? { - if(DependencyManager.ecoEnchantCompatibility != null) { + if(DependencyManager.hasEcoItem) { val result = EcoItemDependencyUtil.ecoItemMaterialFromKey(key) if(result != null) return result } @@ -56,7 +58,7 @@ object MaterialUtil { } fun itemFromKey(key: NamespacedKey): ItemStack { - if(DependencyManager.ecoEnchantCompatibility != null) { + if(DependencyManager.hasEcoItem) { val result = EcoItemDependencyUtil.newEcoItemstack(key) if(result != null) return result } @@ -76,7 +78,7 @@ object MaterialUtil { fun getMaterialCount(): Int { var count = Material.entries.size - if(DependencyManager.ecoEnchantCompatibility != null) { + if(DependencyManager.hasEcoItem) { count += EcoItemDependencyUtil.getItems().size } @@ -90,7 +92,7 @@ object MaterialUtil { fun getMaterials(): MutableList { val all = ArrayList(Material.entries.map { it.key }) - if(DependencyManager.ecoEnchantCompatibility != null) { + if(DependencyManager.hasEcoItem) { all.addAll(EcoItemDependencyUtil.getItems()) } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/MetricsUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/MetricsUtil.kt index 1763db56..9459ad9e 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/MetricsUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/MetricsUtil.kt @@ -18,7 +18,7 @@ object MetricsUtil { private var FAST_STATS_METRICS: BukkitContext? = null fun loadMetrics(plugin: CustomAnvil) { - if(DependencyManager.externGuiTester.isInTest()) return + if(DependencyManager.inTesting) return val config = ConfigHolder.DEFAULT_CONFIG.config val metricString = config.getString(ConfigOptions.METRIC_TYPE, MetricType.AUTO.value)!! diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/UnitRepairUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/UnitRepairUtil.kt index 8463e27e..5d059870 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/UnitRepairUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/UnitRepairUtil.kt @@ -1,6 +1,8 @@ package xyz.alexcrea.cuanvil.util +import org.bukkit.NamespacedKey import org.bukkit.configuration.ConfigurationSection +import org.bukkit.configuration.file.FileConfiguration import org.bukkit.inventory.ItemStack import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.util.MaterialUtil.customType @@ -11,7 +13,7 @@ object UnitRepairUtil { private const val DEFAULT_DEFAULT_UNIT_REPAIR = 0.25 // Path to user default unit repair value - private const val UNIT_REPAIR_DEFAULT_PATH = "default_repair_amount" + public const val UNIT_REPAIR_DEFAULT_PATH = "default_repair_amount" /** * Get the % of repair by unit [other] will do to this [ItemStack]. @@ -22,40 +24,56 @@ object UnitRepairUtil { ): Double? { if (other == null) return null val config = ConfigHolder.UNIT_REPAIR_HOLDER.config - // Get configuration section if exist - val otherName = other.customType.key.lowercase() - var section = config.getConfigurationSection(otherName) - if (section == null) { - section = config.getConfigurationSection(otherName.uppercase()) - if (section == null) return null - } - // Get repair amount - var userDefault = config.getDouble(UNIT_REPAIR_DEFAULT_PATH, DEFAULT_DEFAULT_UNIT_REPAIR) - if (userDefault <= 0) { - userDefault = DEFAULT_DEFAULT_UNIT_REPAIR - } + val result = findRawRepairValue(this, other, config) ?: return null - return getRepairAmount(this, section, userDefault) + if(result > 0) return result + + // Get default + val userDefault = config.getDouble(UNIT_REPAIR_DEFAULT_PATH, DEFAULT_DEFAULT_UNIT_REPAIR) + if (userDefault <= 0) + return DEFAULT_DEFAULT_UNIT_REPAIR + return userDefault } - /** - * Get the item % repaired by this configuration section of a unit repair. - * null if not found. - * If value is set to less than or equal to 0 then it will be set to default - */ - private fun getRepairAmount(item: ItemStack, section: ConfigurationSection, default: Double): Double? { - val itemName = item.customType.key.lowercase() - val repairValue = if (section.isDouble(itemName)) { - section.getDouble(itemName) - } else if (section.isDouble(itemName.uppercase())) { - section.getDouble(itemName.uppercase()) - } else { - return null - } - if (repairValue <= 0) - return default - return repairValue + private fun findRawRepairValue( + self: ItemStack, + other: ItemStack, + config: FileConfiguration + ): Double? { + val material = other.customType + val selfType = self.customType + + val result = checkSection(config, material.toString(), selfType) + if (result != null) return result + + return checkSection(config, material.key, selfType) + } + + fun findRawRepairValue( + self: NamespacedKey, + other: NamespacedKey, + config: FileConfiguration + ): Double? { + val result = checkSection(config, other.toString(), self) + if (result != null) return result + + return checkSection(config, other.key, self) + } + + fun checkSection( + config: FileConfiguration, + path: String, + material: NamespacedKey + ): Double? { + val section = config.getConfigurationSection(path) ?: return null + + if (section.isDouble(material.toString())) + return section.getDouble(material.toString()) + if (section.isDouble(material.key)) + return section.getDouble(material.key) + + return null } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilUseTypeUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilUseTypeUtil.kt index a9c7f396..52630454 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilUseTypeUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilUseTypeUtil.kt @@ -5,16 +5,11 @@ import io.delilaheve.util.ConfigOptions object AnvilUseTypeUtil { /* - By stupidity of kotlin not allowing static function outside of companion object I need to do another util class only for 1 function: + By kotlin not having static function outside of companion object I need to do another util class only for 1 function: Companion object on enum class seems to get initialized AFTER the enum itself - that mean. if you want to call a static function on the enum class itself YOU CAN'T. you need to do this stupid thing - or you can make a stupid top level function OR object that even worse because of global scope pollution - (btw was gpt ""solution"". fortunately I do not "vibe code" so I do what I know instead of stupid AI solution & code) - I mean, this is still global scope pollution bc of a USELESS class that SHOULD not exist but as a class is better than a random *ss function - - sorry for the rent but this made me frustrated - - Note: I still like a lot of part of kotlin compared to java but this part is one that I hate + that mean. if you want to call a static function on enum construction YOU CAN'T. you need to do this stupid thing, + or you can make a stupid top level function or object that at least as bad as this + I mean, this is still an unnecessary class that should not exist but as a class is better than a random function in my opinion */ /** * Get config path for normal anvil use diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt index 9d2f5420..379694f2 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt @@ -23,6 +23,7 @@ import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager import xyz.alexcrea.cuanvil.group.ConflictType import xyz.alexcrea.cuanvil.util.AnvilTitleUtil import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil +import kotlin.math.sqrt object AnvilXpUtil { @@ -35,8 +36,9 @@ object AnvilXpUtil { inventory: AnvilInventory, view: InventoryView, player: Player, - result: AnvilResult) { - if(result.item == null) { + result: AnvilResult + ) { + if (result.item == null) { onNoResult(player, view) return } @@ -246,7 +248,8 @@ object AnvilXpUtil { fun getRightValues(left: ItemStack, right: ItemStack, result: ItemStack, cost: AnvilCost) { // Calculate right value and illegal enchant penalty - val rightIsFormBook = right.isEnchantedBook() + val isToBook = left.isEnchantedBook() + val isFromBook = right.isEnchantedBook() val rightEnchs = EnchantmentApi.getEnchantments(right) val resultEnchs = EnchantmentApi.getEnchantments(result) val resultEnchsKeys = HashMap(resultEnchs) @@ -274,22 +277,21 @@ object AnvilXpUtil { // We know "enchantment.key in resultEnchs" true val resultLevel = resultEnchs[enchantment.key]!! - val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, rightIsFormBook) + val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, isToBook, isFromBook) val value = resultLevel * enchantmentMultiplier CustomAnvil.log("Value for sacrifice item ${enchantment.key.enchantmentName} level ${enchantment.value} is $value ($resultLevel * $enchantmentMultiplier)") rightValue += value } - if(ConfigOptions.includeLeftEnchantmentForCost) { - val leftIsFormBook = left.isEnchantedBook() + if (ConfigOptions.includeLeftEnchantmentForCost) { val leftEnchs = EnchantmentApi.getEnchantments(left) for (enchantment in leftEnchs) { // Do not process enchantment that are present on the sacrifice - if(rightEnchs.contains(enchantment.key)) continue + if (rightEnchs.contains(enchantment.key)) continue val resultLevel = resultEnchs.getOrDefault(enchantment.key, 0) - val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, leftIsFormBook) + val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, isToBook, isFromBook) val value = resultLevel * enchantmentMultiplier CustomAnvil.log("Value for left item ${enchantment.key.enchantmentName} level ${enchantment.value} is $value ($resultLevel * $enchantmentMultiplier)") leftValue += value @@ -312,15 +314,15 @@ object AnvilXpUtil { */ fun calculateLevelForXp(xp: Int): Int { return when { - xp <= 352 -> (Math.sqrt((xp + 9).toDouble()) - 3).toInt() + xp <= 352 -> (sqrt((xp + 9).toDouble()) - 3).toInt() xp <= 1507 -> { val inner = (2.0 / 5.0) * (xp - 7839.0 / 40.0) - (81.0 / 10.0 + Math.sqrt(inner)).toInt() + (81.0 / 10.0 + sqrt(inner)).toInt() } else -> { val inner = (2.0 / 9.0) * (xp - 54215.0 / 72.0) - (325.0 / 18.0 + Math.sqrt(inner)).toInt() + (325.0 / 18.0 + sqrt(inner)).toInt() } } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c8fefb53..218c3a1f 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,6 +1,6 @@ # -# It is recommended that you use /configanvil to edit most of these config. -# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes ! +# It is recommended that you use /ca config to edit most of these config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # What service of metric should custom anvil use @@ -463,6 +463,32 @@ monetary_cost: work_penalty: 1.0 # for work penalty (aka use penalty) recipe: 1.0 # for custom anvil recipe cost +# Chance that an anvil get degraded +# set it to zero if you wish to disable it +anvil_degradation: 0.12 + +# see https://www.digminecraft.com/lists/sound_list_pc.php +# for a list of most of the sounds +anvil_sound: + enabled: true + # The sound are weighted so if there is multiples of them one is selected randomly + # so if you want to add a "rare sound" as an easter egg you can ! + # If invalid, it will be removed from the list. and if empty it will use the default + use: + default: + sound: block.anvil.use + category: blocks + volume: 1.0 + pitch: 1.0 + weight: 1.0 + destroy: + default: + sound: block.anvil.destroy + category: blocks + volume: 1.0 + pitch: 1.0 + weight: 1.0 + # Whether to show debug logging debug_log: false diff --git a/src/main/resources/enchant_conflict.yml b/src/main/resources/enchant_conflict.yml index 45d62c34..047b1b26 100644 --- a/src/main/resources/enchant_conflict.yml +++ b/src/main/resources/enchant_conflict.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # material conflicts @@ -160,13 +160,6 @@ 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 ] diff --git a/src/main/resources/item_groups.yml b/src/main/resources/item_groups.yml index 8a62f3dc..dff1b41c 100644 --- a/src/main/resources/item_groups.yml +++ b/src/main/resources/item_groups.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # Please note this config use spigot material names. diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index dab9997b..a8d98c8c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -43,6 +43,9 @@ permissions: ca.command.diagnostic: default: op description: Get debug information about the plugin and server + ca.command.enchantment: + default: op + description: Allows to set enchantment to holden item ca.config.edit: default: op description: Allow administrator to edit the plugin's config in game @@ -77,7 +80,9 @@ softdepend: - Disenchantment - EnchantsSquared - EcoEnchants + - EcoItems - eco - ExcellentEnchants - HavenBags - SuperEnchants + - EnchantedBook diff --git a/src/main/resources/unit_repair_item.yml b/src/main/resources/unit_repair_item.yml index 2902cce4..a8bbcbe3 100644 --- a/src/main/resources/unit_repair_item.yml +++ b/src/main/resources/unit_repair_item.yml @@ -1,6 +1,6 @@ # -# 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 ! +# It is recommended that you use /ca config to edit theses config. +# You can still manually edit here if you like to. but if you do, don't forget to /ca reload after you changes ! # # Unit repair configuration diff --git a/src/test/java/xyz/alexcrea/cuanvil/config/DefaultConfigTests.java b/src/test/java/xyz/alexcrea/cuanvil/config/DefaultConfigTests.java index ac3f73ea..a92b1d71 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/config/DefaultConfigTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/config/DefaultConfigTests.java @@ -49,8 +49,8 @@ public class DefaultConfigTests extends SharedCustomAnvilTest { CAEnchantment enchantment = CAEnchantmentRegistry.getInstance().getByKey(key); Assertions.assertNotNull(enchantment, "Enchantment was somehow not found"); - int itemValue = ConfigOptions.INSTANCE.enchantmentValue(enchantment, false); - int bookValue = ConfigOptions.INSTANCE.enchantmentValue(enchantment, true); + int itemValue = ConfigOptions.INSTANCE.enchantmentValue(enchantment, false, false); + int bookValue = ConfigOptions.INSTANCE.enchantmentValue(enchantment, false, true); EnchantmentRarity rarity = enchantment.defaultRarity();