Compare commits

..

38 commits

Author SHA1 Message Date
643a5e9a8c
fix eco enchant again
Some checks failed
Java CI with Gradle / build (push) Has been cancelled
2026-08-14 00:40:52 +02:00
75b32bcf52
[skip ci] update branch in .md 2026-08-12 19:13:17 +02:00
16375af3bd
Duplicate registered enchantment name warning as debug log 2026-08-12 19:02:26 +02:00
ab47a9df93
proper eco item check
Some checks failed
Java CI with Gradle / build (push) Has been cancelled
2026-08-12 07:32:36 +02:00
d18ee56ff1
fix eco enchant issue 2026-08-12 07:32:36 +02:00
58c9fa129a
warn and cancel on datapack setEnchantAsAll enchantment not found 2026-08-12 07:32:35 +02:00
dff35bcc00
fix hangar release condition
Some checks failed
Java CI with Gradle / build (push) Has been cancelled
2026-08-03 14:42:02 +02:00
6f077a576b
fix anvil degradation not working for 2026-08-03 14:29:30 +02:00
d846ce51d8
update faststats 2026-08-03 14:18:09 +02:00
eb50bfcc01
fix some custom recipe not working 2026-08-03 14:10:23 +02:00
3bb817aeca
one last change
Some checks failed
Java CI with Gradle / build (push) Has been cancelled
2026-07-17 02:24:22 +02:00
c820092bb5
do not use java setup to cache gradlew 2026-07-17 02:14:05 +02:00
8485e8f668
fix paperweight cache 2026-07-17 01:23:56 +02:00
3ea16a5b44
do not depend on nightexpress repo 2026-07-17 01:02:50 +02:00
d806b7a6a5
upgrade actions 2026-07-16 20:27:31 +02:00
78e27c736a
trying better cache 2026-07-16 20:11:24 +02:00
ff995b3c02
yet another try 2026-07-16 19:56:18 +02:00
0a9477b3bc
oops 2026-07-16 19:51:05 +02:00
5405c6699a
remove offline alpha build 2026-07-16 19:39:54 +02:00
f2f39dc326
check isAir instead of null
Some checks are pending
Java CI with Gradle / build (push) Waiting to run
2026-07-16 19:16:57 +02:00
3bf083b762
correct logic for customName 2026-07-16 18:52:50 +02:00
7082da7beb
fix rename text not acting as vanilla 2026-07-16 18:45:18 +02:00
deaf428fcb
back to java 21 (oops !)
Some checks failed
Java CI with Gradle / build (push) Has been cancelled
2026-07-11 23:16:26 +02:00
ee3c086a4b
Anvil sound and degradation (#122) 2026-07-11 22:53:51 +02:00
8faa01e4fd
sound & anvil damage done 2026-07-11 22:38:48 +02:00
b4d7320002
add sound & degradation in config 2026-07-11 22:38:48 +02:00
5df9becb19
anvil sound & degrade basic feature 2026-07-11 22:38:37 +02:00
11e10b5850
set workflow for v2 only [ci skip] 2026-07-11 01:20:37 +02:00
036f480113
update from v1.18.0 2026-07-10 15:50:50 +02:00
13892f73b8
update from v1.x.x 2026-07-10 15:42:18 +02:00
5a6962b1c4
remove legacy command 2026-07-10 15:41:32 +02:00
0e65575c2b
rebase on news update 2026-07-10 15:41:31 +02:00
04ed7ea0b5
prepare for v2 2026-07-10 15:41:30 +02:00
63a9b5b1c6
rebase on new update 2026-07-10 15:41:09 +02:00
e2bbd66abf
1.21 cleanup and fix
also random cleanup
2026-07-10 15:40:55 +02:00
109ef0c5df
fix from rebase 2026-07-10 15:40:41 +02:00
38cf25ef1a
progress on 1.21 transition 2026-07-10 15:38:21 +02:00
5ba1bb98cc
initial 1.21 transition 2026-07-10 15:37:45 +02:00
112 changed files with 819 additions and 2486 deletions

View file

@ -8,9 +8,13 @@
name: Java CI with Gradle name: Java CI with Gradle
on: on:
push:
branches: [ "v2.x.x" ]
pull_request:
branches: [ "v2.x.x" ]
release: release:
types: [published] types: [published]
branches: [ "v1.x.x" ] branches: [ "v2.x.x" ]
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
@ -23,7 +27,7 @@ jobs:
contents: write contents: write
env: env:
MODRINTH_VERSIONS: '["1.18.x", "1.19.x", "1.20.x"]' MODRINTH_VERSIONS: '["1.21.x", "26.1.x", "26.2.x"]'
MODRINTH_PLATFORMS: '["spigot", "paper", "purpur", "folia"]' MODRINTH_PLATFORMS: '["spigot", "paper", "purpur", "folia"]'
steps: steps:
@ -103,6 +107,27 @@ jobs:
build/libs/${{ env.ONLINE_JAR_NAME }} build/libs/${{ env.ONLINE_JAR_NAME }}
build/libs/${{ env.OFFLINE_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 - name: Modrinth publish release
if: ${{ github.event_name == 'release' && github.repository_owner == 'alexcrea' && success() }} if: ${{ github.event_name == 'release' && github.repository_owner == 'alexcrea' && success() }}
uses: cloudnode-pro/modrinth-publish@v2 uses: cloudnode-pro/modrinth-publish@v2
@ -123,7 +148,8 @@ jobs:
with: with:
webhook-url: ${{ secrets.RELEASE_WEBHOOK_URL }} webhook-url: ${{ secrets.RELEASE_WEBHOOK_URL }}
content: | content: |
<@&1525259349423947867> ${{ github.event.release.prerelease == false && '<@&1338546156325568642>' || '<@&1352296092989001768>' }}
# New bugfix for CustomAnvil v1 ! <:CustomAnvil:1262550667986342001> [Modrinth](https://modrinth.com/plugin/customanvil) and [GitHub](${{ github.event.release.html_url }}) links # 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.
${{ github.event.release.body }} ${{ github.event.release.body }}

View file

@ -18,7 +18,7 @@ These dependencies (or a modified version of) are used by custom anvil
### Compatibility ### Compatibility
Thanks to all the cool creator making the minecraft plugin's ecosystem works ! \ Thanks to all the cool creator making the minecraft plugin's ecosystem works ! \
See [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md) for details See [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v2.x.x/COMPATIBILITY.md) for details
but especially, Big Thanks for H7KZ maker of [Disenchantment](https://github.com/H7KZ/Disenchantment) but especially, Big Thanks for H7KZ maker of [Disenchantment](https://github.com/H7KZ/Disenchantment)

View file

@ -67,16 +67,15 @@ run `/customanvil help` to get information about available commands \
this only show subcommands you have permission for this only show subcommands you have permission for
### Supported Plugins ### Supported Plugins
See the [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md) See the [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v2.x.x/COMPATIBILITY.md)
### Overriding Too Expensive ### Overriding Too Expensive
One of the configurations allow displaying price about 40 and removing Too Expensive. \ One of the configurations allow displaying price about 40 and removing Too Expensive. \
By how the minecraft client work: price above 40 can only be displayed green, even if the player does not own enough experience level. By how the minecraft client work: price above 40 can only be displayed green, even if the player does not own enough experience level.
spigot version 1.18 to 1.21.11 do not need any ProtocoLib dependency. (26.1.0 or above requires it) \ You do not need Protocolib unless you are using spigot above in 26.1 or above \
Any recent paper version also are supported for this feature.
But you should wait for update for new version containing new enchantable item or new enchantments if any of this got added. But you should wait for update or announcement for new version containing new enchantable item or new enchantments.
Else it is, likely, fine to use the current version you are ussing on a new paper version
### For custom enchantment plugin developers ### For custom enchantment plugin developers
For information about the API, please refer to [the Wiki](https://github.com/alexcrea/CustomAnvil/wiki) \ For information about the API, please refer to [the Wiki](https://github.com/alexcrea/CustomAnvil/wiki) \
@ -98,7 +97,7 @@ You can also [disable bstat](https://bstats.org/getting-started) and [faststats]
faststats is in beta testing please report me or them any error you encounter faststats is in beta testing please report me or them any error you encounter
### Credits and Thanks ### Credits and Thanks
Credits and thanks can be seen [here](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/CREDITS.md) Credits and thanks can be seen [here](https://github.com/alexcrea/CustomAnvil/blob/v2.x.x/CREDITS.md)
### Planned: ### Planned:
- Better Folia support (make gui work. fix some dirty handled parts) - Better Folia support (make gui work. fix some dirty handled parts)

View file

@ -5,23 +5,24 @@ import groovy.util.NodeList
import io.papermc.hangarpublishplugin.model.HangarPublication import io.papermc.hangarpublishplugin.model.HangarPublication
import io.papermc.hangarpublishplugin.model.Platforms import io.papermc.hangarpublishplugin.model.Platforms
import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import java.io.ByteArrayOutputStream
plugins { plugins {
kotlin("jvm") version "2.4.0" kotlin("jvm") version "2.3.0"
java java
id("org.jetbrains.dokka").version("2.2.0") id("org.jetbrains.dokka").version("1.9.20")
id("com.gradleup.shadow").version("9.6.1") id("com.gradleup.shadow").version("9.3.0")
// Maven publish // Maven publish
`maven-publish` `maven-publish`
signing signing
id("cn.lalaki.central").version("2.0.8") id("cn.lalaki.central").version("1.2.8")
// Paper // Paper
id("io.papermc.paperweight.userdev") version "2.0.0-beta.21" apply false id("io.papermc.paperweight.userdev") version "2.0.0-beta.17" apply false
id("io.papermc.hangar-publish-plugin") version "0.1.4" id("io.papermc.hangar-publish-plugin") version "0.1.2"
} }
group = "xyz.alexcrea" group = "xyz.alexcrea"
version = "1.20.1" version = "2.0.1"
val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null
val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true" val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true"
@ -51,7 +52,7 @@ val reobfNMS = providers.gradleProperty("subprojects.reobfnms")
dependencies { dependencies {
// Spigot api // Spigot api
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT") compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT")
// fast stats // fast stats
implementation("dev.faststats.metrics:bukkit:0.29.0") implementation("dev.faststats.metrics:bukkit:0.29.0")
@ -165,7 +166,7 @@ allprojects {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_16) jvmTarget.set(JvmTarget.JVM_16)
} }
} }
@ -177,10 +178,7 @@ tasks {
fun ShadowJar.configureBaseShadow(suffix: String, libraries: Array<String>) { fun ShadowJar.configureBaseShadow(suffix: String, libraries: Array<String>) {
val processedSuffix = if(suffix.isEmpty()) "" else "-$suffix" val processedSuffix = if(suffix.isEmpty()) "" else "-$suffix"
val version = effectiveVersion val name = "${rootProject.name}-${effectiveVersion}${processedSuffix}.jar"
val name = "${rootProject.name}-${version}${processedSuffix}.jar"
val librariesExpendTo = libraries.joinToString(transform = { "\"$it\"" })
archiveFileName.set(name) archiveFileName.set(name)
// Shadow necessary dependency // Shadow necessary dependency
@ -189,8 +187,8 @@ tasks {
filesMatching("plugin.yml") { filesMatching("plugin.yml") {
expand( expand(
"version" to version + processedSuffix, "version" to effectiveVersion + processedSuffix,
"libraries" to librariesExpendTo, "libraries" to libraries.joinToString(transform = { "\"$it\"" }),
) )
} }
@ -202,7 +200,7 @@ tasks {
shadowJar { shadowJar {
configureBaseShadow("", configureBaseShadow("",
arrayOf( arrayOf(
"org.jetbrains.kotlin:kotlin-stdlib:2.4.0", "org.jetbrains.kotlin:kotlin-stdlib:2.3.0",
"net.kyori:adventure-text-minimessage:4.25.0", "net.kyori:adventure-text-minimessage:4.25.0",
"net.kyori:adventure-text-serializer-plain:4.25.0", "net.kyori:adventure-text-serializer-plain:4.25.0",
"net.kyori:adventure-text-serializer-legacy:4.25.0", "net.kyori:adventure-text-serializer-legacy:4.25.0",
@ -214,7 +212,7 @@ tasks {
exclude("net/kyori/**") exclude("net/kyori/**")
} }
val offlineJar = register<ShadowJar>("offlineJar") { val offlineJar by registering(ShadowJar::class) {
configureBaseShadow("offline", emptyArray()) configureBaseShadow("offline", emptyArray())
from(sourceSets.main.get().output) from(sourceSets.main.get().output)
@ -228,12 +226,12 @@ tasks {
} }
val sourcesJar = tasks.register<Jar>("sourcesJar") { val sourcesJar by tasks.registering(Jar::class) {
archiveClassifier.set("sources") archiveClassifier.set("sources")
from(kotlin.sourceSets.main.get().kotlin) from(kotlin.sourceSets.main.get().kotlin)
} }
val javadocJar = tasks.register<Jar>("javadocJar", fun Jar.() { val javadocJar by tasks.registering(Jar::class, fun Jar.() {
group = JavaBasePlugin.DOCUMENTATION_GROUP group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Assembles Javadoc JAR" description = "Assembles Javadoc JAR"
archiveClassifier.set("javadoc") archiveClassifier.set("javadoc")
@ -357,39 +355,51 @@ publishing {
} }
// hangar publish // hangar publish
fun latestCommitMessage(): Provider<String> {
return providers.exec { fun executeGitCommand(vararg command: String): String {
commandLine("git", "log", "-1", "--pretty=%B") val byteOut = ByteArrayOutputStream()
}.standardOutput.asText.map(String::trim) exec {
commandLine = listOf("git", *command)
standardOutput = byteOut
}
return byteOut.toString(Charsets.UTF_8.name()).trim()
} }
fun changelog(isOnline: Boolean): Provider<String> {
val changelog = if(isDevBuild) latestCommitMessage() fun latestCommitMessage(): String {
else providers.environmentVariable("RELEASE_CHANGELOG") 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"
}
return 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 { hangarPublish {
fun HangarPublication.configure(isOnline: Boolean, devChannel: String, releaseChannel: String) { fun HangarPublication.configure(isOnline: Boolean, devChannel: String?, releaseChannel: String) {
var versionName = effectiveVersion var versionName = effectiveVersion
if(isPreRelease) versionName+= "-pre" if(isPreRelease) versionName+= "-pre"
if(!isOnline) versionName+= "-offline" if(!isOnline) versionName+= "-offline"
version.set(versionName) version.set(versionName)
channel.set(if (isDevBuild || isPreRelease) devChannel else releaseChannel) var releaseChannel = if (isDevBuild || isPreRelease) devChannel else releaseChannel
if(releaseChannel == null) return
channel.set(releaseChannel)
changelog.set(changelog(isOnline)) changelog.set(changelog(isOnline))
id.set("CustomAnvil") id.set("CustomAnvil")
apiKey.set(System.getenv("HANGAR_API_TOKEN")) apiKey.set(System.getenv("HANGAR_API_TOKEN"))
@ -438,8 +448,10 @@ hangarPublish {
configure(true, "DevSnapshot", "Release") configure(true, "DevSnapshot", "Release")
} }
if(!isDevBuild) {
publications.register("offline") { publications.register("offline") {
configure(false, "OfflineSnapshot", "OfflineRelease") configure(false, null, "OfflineRelease")
}
} }
} }

View file

@ -1,6 +0,0 @@
### Default Plugin's Configurations For 1.18 to 1.20.6
- [config.yml](https://github.com/alexcrea/CustomAnvil/blob/master/defaultconfigs/1.18/config.yml)
- [enchant_conflict.yml](https://github.com/alexcrea/CustomAnvil/blob/master/defaultconfigs/1.18/enchant_conflict.yml)
- [item_groups.yml](https://github.com/alexcrea/CustomAnvil/blob/master/defaultconfigs/1.18/item_groups.yml)
- [unit_repair_item.yml](https://github.com/alexcrea/CustomAnvil/blob/master/defaultconfigs/1.18/unit_repair_item.yml)
- [custom_recipes.yml](https://github.com/alexcrea/CustomAnvil/blob/master/defaultconfigs/1.18/custom_recipes.yml)

View file

@ -1,472 +0,0 @@
#
# 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
# Custom anvil collect generic information like server minecraft version, type, etc...
# It can also collect error information if error is happening (currently faststats only)
# It can also be disabled
# Please refer to README for public metric link
# Possible options: auto, bstat, faststats, disabled (auto by default)
metric_type: auto
# Allow to report errors made caused by this plugin (only for faststats)
# This allows me to fix potentials issue that I'm not aware of
# Accept true or false (true by default)
metric_collect_errors: true
# All anvil cost will be capped to limit_repair_value if enabled.
#
# In other words:
# For any anvil cost greater than limit_repair_value, Cost will be set to limit_repair_value.
limit_repair_cost: false
# Max cost value the Anvil can get to.
#
# Valid values include 0 to 1000.
# Cost will be displayed as "Too Expensive":
# - If Cost is above 39
# - And replace_too_expensive is disabled (false)
limit_repair_value: 39
# Whether the anvil's cost limit should be removed entirely.
#
# The anvil will still visually display "Too Expensive" if "replace_too_expensive" is disabled
# However, the action will be completable if xp requirement is meet.
remove_repair_limit: false
# Whenever anvil cost is above 39 should display the true price and not "Too Expensive".
#
# However, when bypassing "Too Expensive", anvil price will be displayed as Green.
# If the action is not completable, the cost will still be displayed as "Too expensive".
# That mean you also need to change other settings like remove_repair_limit or limit_repair_cost.
#
# Require ProtocoLib.
replace_too_expensive: false
# XP Level amount added to the anvil when the item is repaired by another item of the same type
#
# Valid values include 0 to 1000
item_repair_cost: 2
# XP Level amount added to the anvil when the item is renamed
#
# Valid values include 0 to 1000
item_rename_cost: 1
# XP Level amount added to the anvil when the item is repaired by an "unit"
# For example: a Diamond on a Diamond Sword
# What's considered unit for what can be edited on the unit repair configuration.
#
# Valid values include 0 to 1000
unit_repair_cost: 1
# XP Level amount added to the anvil when a sacrifice enchantment
# conflict with one of the left item enchantment
#
# Valid values include 0 to 1000
sacrifice_illegal_enchant_cost: 1
# Allow using color code and hexadecimal color.
#
# Color code are prefixed by "&" and hexadecimal color by "#".
# Color code will not be applied if it colors nothing. "&&" can be used to write "&".
# For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/
allow_color_code: false
allow_hexadecimal_color: false
allow_minimessage: false
# This enables restricting color code for player having specific permission
# It requires allow_color_code enabled for... obvious reasons
#
# For example: if player want to use "&aHello" it will be required that the player has
# the permission "ca.color.code.a" as he used the color code "a"
# In general permission to give to the player is "ca.color.code.[code]"
# where [code] is the color code you wish to allow the player
#
# It is kinda of useless when minimessage is supported as players would be able to bypass
# that using the equivalent minimessage tag
per_color_code_permission: false
# Toggle if color should only be applicable if the player a certain permission.
#
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
permission_needed_for_color: true
# Xp cost if the player use color in the items name on rename.
#
# Valid values include 0 to 1000.
use_of_color_cost: 0
# Dialogue rename menu make use of dialog menu to allow bigger rename
# You can also change the maximum size and set it to -1 or less for maximum
#
# This feature only work on paper 1.21.7 or later
#
# At the moment only english is available for this menu... sorry !
#
# CustomAnvil use "ca.rename.dialog" when permission
enable_dialog_rename: false
dialog_rename_max_size: 256
permission_needed_for_dialog_rename: false
# This allows custom anvil to not "guess" the text used for rename but store it in the item
# It will make item stackable only and only if it had used the same rename text
#
# For practical reason. this only work when dialog rename is enabled
dialog_rename_keep_user_text: true
# Also count left item enchantments for the final price
include_left_enchantment_for_cost: false
# Override limits for specific enchants
#
# Enchantments not listed here will use the value of default_limit
#
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
#
# Valid range of 0 - 255 for each enchantment
# -1 mean keep default
enchant_limits:
minecraft:aqua_affinity: 1
minecraft:binding_curse: 1
minecraft:channeling: 1
minecraft:flame: 1
minecraft:infinity: 1
minecraft:mending: 1
minecraft:multishot: 1
minecraft:silk_touch: 1
minecraft:vanishing_curse: 1
minecraft:depth_strider: 3 # anything more than 3 is treated as 3 by the game
minecraft:protection: 4
minecraft:fire_protection: 4
minecraft:blast_protection: 4
minecraft:projectile_protection: 4
minecraft:feather_falling: 4
minecraft:thorns: 3
minecraft:respiration: 3
minecraft:sharpness: 5
minecraft:smite: 5
minecraft:bane_of_arthropods: 5
minecraft:knockback: 2
minecraft:fire_aspect: 2
minecraft:looting: 3
minecraft:sweeping: 3
minecraft:sweeping_edge: 3
minecraft:efficiency: 5
minecraft:unbreaking: 3
minecraft:fortune: 3
minecraft:power: 5
minecraft:punch: 2
minecraft:luck_of_the_sea: 3
minecraft:lure: 3
minecraft:frost_walker: 2
minecraft:impaling: 5
minecraft:riptide: 3
minecraft:loyalty: 3
minecraft:piercing: 4
minecraft:quick_charge: 3
minecraft:soul_speed: 3
minecraft:swift_sneak: 3
# Multipliers used to calculate the enchantment's value in repair/combining
#
# Values here are pulled from the minecraft wiki:
# https://minecraft.wiki/w/Anvil_mechanics#Costs_for_combining_enchantments
#
# If an enchantment is missing values here, or is less than 0, it will default to 0
#
# Calculated as: [Enchantment lvl] * [multiplier]
#
# With default values protection 4 would have a value of 4 when
# coming from either a book (4 * 1) or an item (4 * 1)
enchant_values:
minecraft:aqua_affinity:
item: 4
book: 2
minecraft:bane_of_arthropods:
item: 2
book: 1
minecraft:binding_curse:
item: 8
book: 4
minecraft:blast_protection:
item: 4
book: 2
minecraft:channeling:
item: 8
book: 4
minecraft:depth_strider:
item: 4
book: 2
minecraft:efficiency:
item: 1
book: 1
minecraft:flame:
item: 4
book: 2
minecraft:feather_falling:
item: 2
book: 1
minecraft:fire_aspect:
item: 4
book: 2
minecraft:fire_protection:
item: 2
book: 1
minecraft:fortune:
item: 4
book: 2
minecraft:frost_walker:
item: 4
book: 2
minecraft:impaling:
item: 4
book: 2
minecraft:infinity:
item: 8
book: 4
minecraft:knockback:
item: 2
book: 1
minecraft:looting:
item: 4
book: 2
minecraft:loyalty:
item: 1
book: 1
minecraft:luck_of_the_sea:
item: 4
book: 2
minecraft:lure:
item: 4
book: 2
minecraft:mending:
item: 4
book: 2
minecraft:multishot:
item: 4
book: 2
minecraft:piercing:
item: 1
book: 1
minecraft:power:
item: 1
book: 1
minecraft:projectile_protection:
item: 2
book: 1
minecraft:protection:
item: 1
book: 1
minecraft:punch:
item: 4
book: 2
minecraft:quick_charge:
item: 2
book: 1
minecraft:respiration:
item: 4
book: 2
minecraft:riptide:
item: 4
book: 2
minecraft:silk_touch:
item: 8
book: 4
minecraft:sharpness:
item: 1
book: 1
minecraft:smite:
item: 2
book: 1
minecraft:soul_speed:
item: 8
book: 4
minecraft:swift_sneak:
item: 8
book: 4
minecraft:sweeping:
item: 4
book: 2
minecraft:sweeping_edge:
item: 4
book: 2
minecraft:thorns:
item: 8
book: 4
minecraft:unbreaking:
item: 2
book: 1
minecraft:vanishing_curse:
item: 8
book: 4
# Disable enchantment merging for level above the set value
# Enchantment merging is when, for example, 2 unbreaking II book combine to give sharpness III
# But Enchantment above this value can still be applied. following the previous example, we could still apply a unbreaking III book to a sword
# Even if disable-merge-over of unbreaking is set to 2
# -1 mean enchantment merge for this enchantment is not disabled. default to -1 if absent.
disable-merge-over:
# Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla on default configuration)
minecraft:sharpness: -1
# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied
#minecraft:unbreaking: 2
# The maximum number of enchantment an item can get. -1 for infinity
# Use eco enchant enchant_limit if present by default unless "default" is not equal to -1
enchantment_count_limit:
default: -1
# Limit for specific items. example bellow is an example with stick
# Per item enchantment limit override eco enchant enchant_limit and default limit
items:
stick: -1
# Settings for lore modification
lore_edit:
book_and_quil:
# Permission is ca.lore_edit.book
use_permission: true
append:
# If adding lore using book & quil is enabled
enabled: false
# Cost used every time
fixed_cost: 1
# Cost used for every lore line added
per_line_cost: 0
# Use left item vanilla cost penalty if any
shared_increase: false
# Increase shared left item cost penalty
shared_additive: false
# If adding the lore consume the book & quil
do_consume: false
# Allow using color code and hexadecimal color when editing lore via book & quil
#
# Color code are prefixed by "&" and hexadecimal color by "#"
# Color code will not be applied if it colors nothing. "&&" can be used to write "&"
# For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/
#
# Note that currently minimessage would disable hex code when adding color
allow_color_code: true
allow_hexadecimal_color: false
allow_minimessage: true
remove:
# If removing lore using book & quil is enabled
enabled: false
# Cost used every time
fixed_cost: 1
# Cost used for every lore line removed
per_line_cost: 0
# Use left item vanilla cost penalty if any
shared_increase: false
# Increase shared left item cost penalty
shared_additive: false
# If removing the lore consume the book & quil
do_consume: false
# Cost of replacing colors
remove_color_cost: 0
# Allowed some color and tags to be reverted to plain text
# Custom anvil will prioritise format that result is a smaller resulting text
# Note that not allowing certain format will lead to some lost of color or tags.
# If configuration are exact as append appending this book should result in the exact same color
#
# Color code will be prefixed by "&" and hexadecimal color by "#".
# If color code is allowed, "&" in the text will get converted to "&&"
# For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/
allow_color_code: true
allow_hexadecimal_color: false
allow_minimessage: true
paper:
# Permission is ca.lore_edit.paper
use_permission: true
# what order should the lines should get added/removed (start/end, if invalid or not present will be end)
order: end
append_line:
# If adding lore line using paper is enabled
enabled: false
# Cost used every time
fixed_cost: 1
# Use left item vanilla cost penalty if any
shared_increase: false
# Increase shared left item cost penalty
shared_additive: false
# If adding the lore line consume the paper
do_consume: false
# Allow using color code and hexadecimal color when editing lore via book & quil
#
# Color code are prefixed by "&" and hexadecimal color by "#"
# Color code will not be applied if it colors nothing. "&&" can be used to write "&"
# For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/
#
# Note that currently minimessage would disable hex code when adding color
allow_color_code: true
allow_hexadecimal_color: false
allow_minimessage: true
color_use_cost: 0
remove_line:
# If removing lore line using paper is enabled
enabled: false
# Cost used every time
fixed_cost: 1
# Use left item vanilla cost penalty if any
shared_increase: false
# Increase shared left item cost penalty
shared_additive: false
# If removing the lore line consume the paper
do_consume: false
# Cost of replacing colors
remove_color_cost: 0
# Allowed some color and tags to be reverted to plain text
# Custom anvil will prioritise format that result is a smaller resulting text
# Note that not allowing certain format will lead to some lost of color or tags.
# If configuration are exact as append appending this paper should result in the exact same color
#
# Color code will be prefixed by "&" and hexadecimal color by "#".
# If color code is allowed, "&" in the text will get converted to "&&"
# For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/
allow_color_code: true
allow_hexadecimal_color: false
allow_minimessage: true
# Allow to replace the xp cost by a monetary cost
# If enabled it will not be bound to the experience level limits
#
# It also requires to enable dialog rename (set "enable_dialog_rename: false" a bit higher)
# If dialog rename permission is enabled and player do not have the permission merge will fall back to vanilla xp cost
#
# If you are using custom craft I recommend using Linear Xp Cost with Exact Linear Xp as normal Xp Cost will act "weird"
# But Linear Xp will act as 1$ time global multiplier. In other word: like you expect
#
# As this feature require dialog rename, it can only be enabled starting with paper 1.21.6 and later
monetary_cost:
enabled: false
# If using vault unlocked this allow to specify what currency should be used for anvil usage
# default being the default currency
currency: default
# multiply the anvil cost by a value to allow to have price a big bigger than like 40
multipliers:
# global multipliers. all usage type will be multiplied by this value
global: 1.0
# usage specific type. it will only apply for specific xp "reason"
enchantment: 1.0 # related to enchantments level
repair: 1.0 # for repairing via unit repair (per unit)
rename: 1.0 # for renaming the item
lore_edit: 1.0 # for changing the lore of the item (only if lore edit is enabled)
work_penalty: 1.0 # for work penalty (aka use penalty)
recipe: 1.0 # for custom anvil recipe cost
# Whether to show debug logging
debug_log: false
# Whether to show verbose debug logging
debug_log_verbose: false
# Whether to show inside the console or require to run /ca debug get
display_debug_in_console: false
configVersion: 1.11.0

View file

@ -1,5 +0,0 @@
# ----------------------------------------------------
# This config file is to store custom craft
# It is recommended to use the in game config editor for this configuration.
# /customanvilconfig With ca.config.edit permission
# ----------------------------------------------------

View file

@ -1,240 +0,0 @@
#
# 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
#
# If you want to edit this file:
# - A conflict will apply to every item except if in one of the notAffectedGroups group
# - the conflict will count only if the user try to combine at least as
# many conflicting enchantment as "maxEnchantmentBeforeConflict"
#
#
# ----------------------------------------------------
# These restriction are about not allowing enchantment
# on illegal items
# ----------------------------------------------------
restriction_aqua_affinity:
enchantments: [ minecraft:aqua_affinity ]
notAffectedGroups: [ enchanted_book, helmets ]
restriction_bane_of_arthropods:
enchantments: [ minecraft:bane_of_arthropods ]
notAffectedGroups: [ enchanted_book, melee_weapons ]
restriction_blast_protection:
enchantments: [ minecraft:blast_protection ]
notAffectedGroups: [ enchanted_book, armors ]
restriction_channeling:
enchantments: [ minecraft:channeling ]
notAffectedGroups: [ enchanted_book, trident ]
restriction_binding_curse:
enchantments: [ minecraft:binding_curse ]
notAffectedGroups: [ enchanted_book, wearable ]
restriction_vanishing_curse:
enchantments: [ minecraft:vanishing_curse ]
notAffectedGroups: [ enchanted_book, can_vanish ]
restriction_depth_strider:
enchantments: [ minecraft:depth_strider ]
notAffectedGroups: [ enchanted_book, boots ]
restriction_efficiency:
enchantments: [ minecraft:efficiency ]
notAffectedGroups: [ enchanted_book, tools, shears ]
restriction_feather_falling:
enchantments: [ minecraft:feather_falling ]
notAffectedGroups: [ enchanted_book, boots ]
restriction_fire_aspect:
enchantments: [ minecraft:fire_aspect ]
notAffectedGroups: [ enchanted_book, swords ]
restriction_fire_protection:
enchantments: [ minecraft:fire_protection ]
notAffectedGroups: [ enchanted_book, armors ]
restriction_flame:
enchantments: [ minecraft:flame ]
notAffectedGroups: [ enchanted_book, bow ]
restriction_fortune:
enchantments: [ minecraft:fortune ]
notAffectedGroups: [ enchanted_book, tools ]
restriction_frost_walker:
enchantments: [ minecraft:frost_walker ]
notAffectedGroups: [ enchanted_book, boots ]
restriction_impaling:
enchantments: [ minecraft:impaling ]
notAffectedGroups: [ enchanted_book, trident ]
restriction_infinity:
enchantments: [ minecraft:infinity ]
notAffectedGroups: [ enchanted_book, bow ]
restriction_knockback:
enchantments: [ minecraft:knockback ]
notAffectedGroups: [ enchanted_book, swords ]
restriction_looting:
enchantments: [ minecraft:looting ]
notAffectedGroups: [ enchanted_book, swords ]
restriction_loyalty:
enchantments: [ minecraft:loyalty ]
notAffectedGroups: [ enchanted_book, trident ]
restriction_luck_of_the_sea:
enchantments: [ minecraft:luck_of_the_sea ]
notAffectedGroups: [ enchanted_book, fishing_rod ]
restriction_lure:
enchantments: [ minecraft:lure ]
notAffectedGroups: [ enchanted_book, fishing_rod ]
restriction_mending:
enchantments: [ minecraft:mending ]
notAffectedGroups: [ enchanted_book, can_unbreak ]
restriction_minecraft_multishot:
enchantments: [ minecraft:multishot ]
notAffectedGroups: [ enchanted_book, crossbow ]
restriction_piercing:
enchantments: [ minecraft:piercing ]
notAffectedGroups: [ enchanted_book, crossbow ]
restriction_power:
enchantments: [ minecraft:power ]
notAffectedGroups: [ enchanted_book, bow ]
restriction_projectile_protection:
enchantments: [ minecraft:projectile_protection ]
notAffectedGroups: [ enchanted_book, armors ]
restriction_protection:
enchantments: [ minecraft:protection ]
notAffectedGroups: [ enchanted_book, armors ]
restriction_punch:
enchantments: [ minecraft:punch ]
notAffectedGroups: [ enchanted_book, bow ]
restriction_quick_charge:
enchantments: [ minecraft:quick_charge ]
notAffectedGroups: [ enchanted_book, crossbow ]
restriction_respiration:
enchantments: [ minecraft:respiration ]
notAffectedGroups: [ enchanted_book, helmets ]
restriction_riptide:
enchantments: [ minecraft:riptide ]
notAffectedGroups: [ enchanted_book, trident ]
restriction_sharpness:
enchantments: [ minecraft:sharpness ]
notAffectedGroups: [ enchanted_book, melee_weapons ]
restriction__silk_touch:
enchantments: [ minecraft:silk_touch ]
notAffectedGroups: [ enchanted_book, tools ]
restriction_smite:
enchantments: [ minecraft:smite ]
notAffectedGroups: [ enchanted_book, melee_weapons ]
restriction_soul_speed:
enchantments: [ minecraft:soul_speed ]
notAffectedGroups: [ enchanted_book, boots ]
restriction_sweeping_edge:
enchantments: [ minecraft:sweeping, minecraft:sweeping_edge ]
notAffectedGroups: [ enchanted_book, swords ]
restriction_thorns:
enchantments: [ minecraft:thorns ]
notAffectedGroups: [ enchanted_book, armors ]
restriction__unbreaking:
enchantments: [ minecraft:unbreaking ]
notAffectedGroups: [ enchanted_book, can_unbreak ]
# ----------------------------------------------------
# Now we have conflicts about enchantment Incompatibility
# We just filtered what item enchantments can be applied
# notAffectedGroups is empty as we don't want anything to not respect theses rules
# maxEnchantmentBeforeConflict is set to 1 to only have 1 on those enchantment available
# ----------------------------------------------------
sword_enchant_conflict:
enchantments:
- minecraft:bane_of_arthropods
- minecraft:smite
- minecraft:sharpness
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
protection_enchant_conflict:
enchantments:
- minecraft:blast_protection
- minecraft:fire_protection
- minecraft:projectile_protection
- minecraft:protection
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
trident_conflict1:
enchantments:
- minecraft:channeling
- minecraft:riptide
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
trident_conflict2:
enchantments:
- minecraft:loyalty
- minecraft:riptide
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
boot_conflict:
enchantments:
- minecraft:depth_strider
- minecraft:frost_walker
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
tool_conflict:
enchantments:
- minecraft:fortune
- minecraft:silk_touch
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
bow_conflict:
enchantments:
- minecraft:mending
- minecraft:infinity
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
crossbow_conflict:
enchantments:
- minecraft:multishot
- minecraft:piercing
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
# ----------------------------------------------------
# Bellow is for custom conflicts.
# This is also where conflict create from the gui will be placed.
# ----------------------------------------------------

View file

@ -1,210 +0,0 @@
#
# 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.
# It should match minecraft name in most case, maybe every case, but I can't be sure
# In case there an issue with material name, you can found them here:
# https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
# An empty Exclude group exclude nothing, so it contain everything
everything:
type: exclude
# An empty include group will include nothing
nothing:
type: include
# This group is an example of a group including only stone and polished granite
example_include:
type: include
items:
- stone
- polished_granite
# This group contain everything except polished granite and elements of example_include
example_exclude:
type: exclude
items:
- polished_granite
groups:
- example_include
# Default configuration should be vanilla enchantment conflict group
# there may have error, if you find one you can fix it !
# https://minecraft.fandom.com/wiki/Enchanting
swords:
type: include
items:
- wooden_sword
- stone_sword
- iron_sword
- diamond_sword
- golden_sword
- netherite_sword
axes:
type: include
items:
- wooden_axe
- stone_axe
- iron_axe
- diamond_axe
- golden_axe
- netherite_axe
melee_weapons:
type: include
groups:
- swords
- axes
helmets:
type: include
items:
- leather_helmet
- chainmail_helmet
- iron_helmet
- diamond_helmet
- golden_helmet
- netherite_helmet
- turtle_helmet
chestplate:
type: include
items:
- leather_chestplate
- chainmail_chestplate
- iron_chestplate
- diamond_chestplate
- golden_chestplate
- netherite_chestplate
leggings:
type: include
items:
- leather_leggings
- chainmail_leggings
- iron_leggings
- diamond_leggings
- golden_leggings
- netherite_leggings
boots:
type: include
items:
- leather_boots
- chainmail_boots
- iron_boots
- diamond_boots
- golden_boots
- netherite_boots
armors:
type: include
groups:
- helmets
- chestplate
- leggings
- boots
wearable:
type: include
items:
- elytra
- carved_pumpkin
- skeleton_skull
- wither_skeleton_skull
- zombie_head
- player_head
- creeper_head
- dragon_head
# do not exist in 1.18 but exist in future update
- piglin_head
groups:
- armors
tools:
type: include
items:
- wooden_pickaxe
- stone_pickaxe
- iron_pickaxe
- diamond_pickaxe
- golden_pickaxe
- netherite_pickaxe
- wooden_shovel
- stone_shovel
- iron_shovel
- diamond_shovel
- golden_shovel
- netherite_shovel
- wooden_hoe
- stone_hoe
- iron_hoe
- diamond_hoe
- golden_hoe
- netherite_hoe
groups:
- axes
enchanted_book:
type: include
items:
- enchanted_book
trident:
type: include
items:
- trident
bow:
type: include
items:
- bow
crossbow:
type: include
items:
- crossbow
fishing_rod:
type: include
items:
- fishing_rod
shears:
type: include
items:
- shears
can_unbreak:
type: include
items:
- elytra
- flint_and_steel
- shield
- carrot_on_a_stick
- warped_fungus_on_a_stick
# do not exist in 1.18 but exist in future update
- brush
groups:
- melee_weapons
- tools
- armors
- trident
- bow
- crossbow
- fishing_rod
- shears
can_vanish:
type: include
items:
- compass
groups:
- wearable
- can_unbreak

View file

@ -1,190 +0,0 @@
#
# 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
#
# This configuration is to make custom unit repair
# A unit repair is, for example, a diamond to repair a diamond sword
# In vanilla, a unit repair 25% of object durability
# you can make a custom value here
#
# Item name should NOT combine caps and no caps (example: Stone)
# Default value if the config is an invalid value (value <= 0 )
# If value > 1 it will be treated as being = 1
default_repair_amount: 0.25
# You can add custom unit repair
# The example bellow make a shield repaired by 10% by sticks
#stick:
# shield: 0.10
# Vanilla unit repair group is bellow
diamond:
diamond_helmet: 0.25
diamond_chestplate: 0.25
diamond_leggings: 0.25
diamond_boots: 0.25
diamond_sword: 0.25
diamond_pickaxe: 0.25
diamond_axe: 0.25
diamond_shovel: 0.25
diamond_hoe: 0.25
netherite_ingot:
netherite_helmet: 0.25
netherite_chestplate: 0.25
netherite_leggings: 0.25
netherite_boots: 0.25
netherite_sword: 0.25
netherite_pickaxe: 0.25
netherite_axe: 0.25
netherite_shovel: 0.25
netherite_hoe: 0.25
gold_ingot:
golden_helmet: 0.25
golden_chestplate: 0.25
golden_leggings: 0.25
golden_boots: 0.25
golden_sword: 0.25
golden_pickaxe: 0.25
golden_axe: 0.25
golden_shovel: 0.25
golden_hoe: 0.25
iron_ingot:
iron_helmet: 0.25
iron_chestplate: 0.25
iron_leggings: 0.25
iron_boots: 0.25
iron_sword: 0.25
iron_pickaxe: 0.25
iron_axe: 0.25
iron_shovel: 0.25
iron_hoe: 0.25
cobblestone:
stone_sword: 0.25
stone_pickaxe: 0.25
stone_axe: 0.25
stone_shovel: 0.25
stone_hoe: 0.25
cobbled_deepslate:
stone_sword: 0.25
stone_pickaxe: 0.25
stone_axe: 0.25
stone_shovel: 0.25
stone_hoe: 0.25
blackstone:
stone_sword: 0.25
stone_pickaxe: 0.25
stone_axe: 0.25
stone_shovel: 0.25
stone_hoe: 0.25
leather:
leather_helmet: 0.25
leather_chestplate: 0.25
leather_leggings: 0.25
leather_boots: 0.25
phantom_membrane:
elytra: 0.25
scute:
turtle_helmet: 0.25
oak_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
spruce_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
birch_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
jungle_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
acacia_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
dark_oak_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
mangrove_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
cherry_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
bamboo_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
crimson_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
warped_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25

View file

@ -1,5 +1,4 @@
### Default Plugin's Configurations ### Default Plugin's Configurations
From 1.18 to 1.20.6 use [1.18 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.18) \
From 1.21 to 1.21.8 use [1.21 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21) \ From 1.21 to 1.21.8 use [1.21 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21) \
From 1.21.9 to 1.21.10 use [1.21.9 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.9) \ From 1.21.9 to 1.21.10 use [1.21.9 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.9) \
From 1.21.11 use [1.21.11 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11) From 1.21.11 use [1.21.11 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11)

View file

@ -1,5 +1,4 @@
kotlin.code.style=official kotlin.code.style=official
org.gradle.configuration-cache=true
# Signing # Signing
signing.secretKeyRingFile=~/.gnupg/secring.gpg signing.secretKeyRingFile=~/.gnupg/secring.gpg
@ -7,8 +6,8 @@ signing.secretKeyRingFile=~/.gnupg/secring.gpg
kotlin.daemon.jvmargs=-Xmx8G kotlin.daemon.jvmargs=-Xmx8G
# list of nms # list of nms
subprojects.reobfnms=v1_17R1,v1_18R1,v1_18R2 subprojects.reobfnms=v1_21R1,v1_21R2,v1_21R3,v1_21R4,v1_21R5,v1_21R6,v1_21R7
# list of version for hangar release # list of version for hangar release
paperVersion=1.18-1.20.5 paperVersion=1.18-26.2

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.0-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View file

@ -2,7 +2,7 @@ group = rootProject.group
version = rootProject.version version = rootProject.version
plugins { plugins {
kotlin("jvm") version "2.4.0" kotlin("jvm") version "2.3.0"
} }
repositories { repositories {

View file

@ -2,12 +2,12 @@ group = rootProject.group
version = rootProject.version version = rootProject.version
plugins { plugins {
kotlin("jvm") version "2.4.0" kotlin("jvm") version "2.3.0"
} }
// Imitate needed class and method to support legacy version of EcoEnchant // Imitate needed class and method to support legacy version of EcoEnchant
dependencies { dependencies {
// Spigot api // Spigot api
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT") compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT")
} }

View file

@ -21,15 +21,15 @@ repositories {
// Set target version // Set target version
tasks.withType<JavaCompile>().configureEach { tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "16" sourceCompatibility = "21"
targetCompatibility = "16" targetCompatibility = "21"
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_16) jvmTarget.set(JvmTarget.JVM_21)
} }
} }

View file

@ -67,7 +67,14 @@ object PlatformUtil {
} }
} }
// Display name
private val useCustomName = hasMethod(ItemMeta::class.java, "customName")
fun ItemMeta.componentDisplayName(): Component? { fun ItemMeta.componentDisplayName(): Component? {
if (useCustomName) {
if (!this.hasCustomName()) return null
return this.customName()
}
if (!this.hasDisplayName()) return null if (!this.hasDisplayName()) return null
return if (isPaper) { return if (isPaper) {
@ -78,7 +85,9 @@ object PlatformUtil {
} }
fun ItemMeta.setComponentDisplayName(component: Component?, fallback: String? = null) { fun ItemMeta.setComponentDisplayName(component: Component?, fallback: String? = null) {
if (isPaper) { if (useCustomName) {
this.customName(component)
} else if (isPaper) {
this.displayName(component) this.displayName(component)
} else { } else {
if (component == null) { if (component == null) {

View file

@ -21,15 +21,15 @@ repositories {
// Set target version // Set target version
tasks.withType<JavaCompile>().configureEach { tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "18" sourceCompatibility = "21"
targetCompatibility = "18" targetCompatibility = "21"
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_18) jvmTarget.set(JvmTarget.JVM_21)
} }
} }

View file

@ -1,42 +1,20 @@
@file:Suppress("DEPRECATION", "removal")
package xyz.alexcrea.cuanvil.dependency.datapack package xyz.alexcrea.cuanvil.dependency.datapack
import io.papermc.paper.datapack.Datapack import io.papermc.paper.datapack.Datapack
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.packs.DataPack
import java.util.* import java.util.*
object DataPackTester { object DataPackTester {
val legacyNames: List<String>
get() = Bukkit.getDataPackManager().dataPacks
.stream().filter { obj -> obj.isEnabled }
.map { pack -> pack.key.key }
.toList()
val enabledPacks: List<String> val enabledPacks: List<String>
get() { get() {
try { return try {
// will throw error if do not exist Bukkit.getDatapackManager().enabledPacks
Bukkit::class.java.getDeclaredMethod("getDatapackManager")
return Bukkit.getDatapackManager().enabledPacks
.stream().map { obj: Datapack -> obj.name } .stream().map { obj: Datapack -> obj.name }
.toList() .toList()
} catch (_: NoSuchMethodException) {
try {
DataPack::class.java.getDeclaredMethod("getKey")
} 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 (_: Exception){ } catch (_: Exception){
// Assume cause UnimplementedOperationException on mock server // Assume cause UnimplementedOperationException on mock server
return Collections.emptyList() Collections.emptyList()
} catch(_: NoSuchMethodError) {
// Idk newer spigot may not have that ?
return Collections.emptyList()
} }
} }
} }

View file

@ -18,8 +18,8 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView
import org.bukkit.craftbukkit.inventory.view.CraftAnvilView import org.bukkit.craftbukkit.inventory.view.CraftAnvilView
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.view.AnvilView
import org.bukkit.persistence.PersistentDataType import org.bukkit.persistence.PersistentDataType
import org.bukkit.plugin.Plugin import org.bukkit.plugin.Plugin
import java.util.* import java.util.*
@ -121,7 +121,7 @@ class AnvilRenameDialogImpl(
} }
} }
private fun setResult(player: HumanEntity, view: InventoryView, result: String?) { private fun setResult(player: HumanEntity, view: AnvilView, result: String?) {
val defaultName = itemDefaultName(view.getItem(0)) val defaultName = itemDefaultName(view.getItem(0))
if (defaultName == result) { if (defaultName == result) {
setName(player, view, "", null) setName(player, view, "", null)
@ -129,7 +129,7 @@ class AnvilRenameDialogImpl(
} else setName(player, view, result, result) } else setName(player, view, result, result)
} }
private fun setName(player: HumanEntity, view: InventoryView, name: String?, rename: String?) { private fun setName(player: HumanEntity, view: AnvilView, name: String?, rename: String?) {
val menu = (containerField.get(view) as AnvilMenu) val menu = (containerField.get(view) as AnvilMenu)
val isSameName = menu.itemName == name val isSameName = menu.itemName == name
menu.itemName = rename menu.itemName = rename

View file

@ -2,18 +2,18 @@ package xyz.alexcrea.cuanvil.util
import io.papermc.paper.threadedregions.scheduler.ScheduledTask import io.papermc.paper.threadedregions.scheduler.ScheduledTask
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import org.bukkit.inventory.InventoryView import org.bukkit.inventory.view.AnvilView
import org.bukkit.plugin.Plugin import org.bukkit.plugin.Plugin
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
import java.util.HashMap import java.util.HashMap
import java.util.UUID import java.util.UUID
@Suppress("UnstableApiUsage")
object AnvilTitleUtil { object AnvilTitleUtil {
private val runTaskMap = HashMap<UUID, ScheduledTask>() private val runTaskMap = HashMap<UUID, ScheduledTask>()
@Suppress("DEPRECATION") private fun actualRename(view: AnvilView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog) {
private fun actualRename(view: InventoryView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog) {
runTaskMap.remove(player.uniqueId) runTaskMap.remove(player.uniqueId)
if (view.title == name) return if (view.title == name) return
@ -25,7 +25,7 @@ object AnvilTitleUtil {
// We don't want to rename instantly it is causing issue with rename text // We don't want to rename instantly it is causing issue with rename text
// especially as it can "override" current ui when it is rename ui time but rename ui also need some delay // especially as it can "override" current ui when it is rename ui time but rename ui also need some delay
fun rename(view: InventoryView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog, plugin: Plugin) { fun rename(view: AnvilView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog, plugin: Plugin) {
runTaskMap.remove(player.uniqueId)?.cancel() runTaskMap.remove(player.uniqueId)?.cancel()
val task = player.scheduler.runDelayed( val task = player.scheduler.runDelayed(

View file

@ -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.v1_19_R1.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_19R1_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)
}
}

View file

@ -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.19.3-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "17"
targetCompatibility = "17"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_17)
}
}

View file

@ -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.v1_19_R2.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_19R2_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)
}
}

View file

@ -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.19.4-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "17"
targetCompatibility = "17"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_17)
}
}

View file

@ -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.v1_19_R3.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_19R3_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)
}
}

View file

@ -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.20.1-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "18"
targetCompatibility = "18"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_18)
}
}

View file

@ -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.v1_20_R1.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_20R1_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)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -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.20.2-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "18"
targetCompatibility = "18"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_18)
}
}

View file

@ -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.v1_20_R2.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_20R2_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)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -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.20.4-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "18"
targetCompatibility = "18"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_18)
}
}

View file

@ -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.v1_20_R3.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_20R3_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)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -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.20.6-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "18"
targetCompatibility = "18"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_18)
}
}

View file

@ -1,19 +0,0 @@
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
// That truly is my favorite activity
// TODO clean this one of legacy removal branch
object MaxDamageCheckerUtil {
/**
* @return max damage or int max if not set
*/
fun getMaxDamage(type: Material, meta: Damageable): Int {
if(!meta.hasMaxDamage()) return type.maxDurability.toInt()
return meta.maxDamage
}
}

View file

@ -11,7 +11,7 @@ dependencies {
implementation(project(":nms:nms-common")) implementation(project(":nms:nms-common"))
// Used for nms // Used for nms
paperweight.paperDevBundle("1.17.1-R0.1-SNAPSHOT") paperweight.paperDevBundle("1.21.1-R0.1-SNAPSHOT")
} }
repositories { repositories {
@ -21,15 +21,15 @@ repositories {
// Set target version // Set target version
tasks.withType<JavaCompile>().configureEach { tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "16" sourceCompatibility = "21"
targetCompatibility = "16" targetCompatibility = "21"
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_16) jvmTarget.set(JvmTarget.JVM_21)
} }
} }

View file

@ -7,7 +7,7 @@ import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_20R4_PacketManager : PacketManagerBase(), PacketManager { class V1_21R1_PacketManager : PacketManagerBase(), PacketManager {
override val canSetInstantBuild: Boolean override val canSetInstantBuild: Boolean
get() = true get() = true

View file

@ -11,7 +11,7 @@ dependencies {
implementation(project(":nms:nms-common")) implementation(project(":nms:nms-common"))
// Used for nms // Used for nms
paperweight.paperDevBundle("1.18.1-R0.1-SNAPSHOT") paperweight.paperDevBundle("1.21.3-R0.1-SNAPSHOT")
} }
repositories { repositories {
@ -21,15 +21,15 @@ repositories {
// Set target version // Set target version
tasks.withType<JavaCompile>().configureEach { tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "17" sourceCompatibility = "21"
targetCompatibility = "17" targetCompatibility = "21"
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_17) jvmTarget.set(JvmTarget.JVM_21)
} }
} }

View file

@ -2,12 +2,12 @@ package xyz.alexcrea.cuanvil.dependency.packet.versions
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket
import net.minecraft.world.entity.player.Abilities import net.minecraft.world.entity.player.Abilities
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_17R1_PacketManager : PacketManagerBase(), PacketManager { class V1_21R2_PacketManager : PacketManagerBase(), PacketManager {
override val canSetInstantBuild: Boolean override val canSetInstantBuild: Boolean
get() = true get() = true

View file

@ -11,7 +11,7 @@ dependencies {
implementation(project(":nms:nms-common")) implementation(project(":nms:nms-common"))
// Used for nms // Used for nms
paperweight.paperDevBundle("1.18.2-R0.1-SNAPSHOT") paperweight.paperDevBundle("1.21.4-R0.1-SNAPSHOT")
} }
repositories { repositories {
@ -21,15 +21,15 @@ repositories {
// Set target version // Set target version
tasks.withType<JavaCompile>().configureEach { tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "17" sourceCompatibility = "21"
targetCompatibility = "17" targetCompatibility = "21"
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_17) jvmTarget.set(JvmTarget.JVM_21)
} }
} }

View file

@ -2,12 +2,12 @@ package xyz.alexcrea.cuanvil.dependency.packet.versions
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket
import net.minecraft.world.entity.player.Abilities import net.minecraft.world.entity.player.Abilities
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_18R1_PacketManager : PacketManagerBase(), PacketManager { class V1_21R3_PacketManager : PacketManagerBase(), PacketManager {
override val canSetInstantBuild: Boolean override val canSetInstantBuild: Boolean
get() = true get() = true

View file

@ -11,25 +11,24 @@ dependencies {
implementation(project(":nms:nms-common")) implementation(project(":nms:nms-common"))
// Used for nms // Used for nms
paperweight.paperDevBundle("1.19.2-R0.1-SNAPSHOT") paperweight.paperDevBundle("1.21.5-R0.1-SNAPSHOT")
} }
repositories { repositories {
maven("https://repo.papermc.io/repository/maven-public/") maven("https://repo.papermc.io/repository/maven-public/")
} }
// Set target version // Set target version
tasks.withType<JavaCompile>().configureEach { tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "17" sourceCompatibility = "21"
targetCompatibility = "17" targetCompatibility = "21"
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_17) jvmTarget.set(JvmTarget.JVM_21)
} }
} }

View file

@ -2,12 +2,12 @@ package xyz.alexcrea.cuanvil.dependency.packet.versions
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket
import net.minecraft.world.entity.player.Abilities import net.minecraft.world.entity.player.Abilities
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_18R2_PacketManager : PacketManagerBase(), PacketManager { class V1_21R4_PacketManager : PacketManagerBase(), PacketManager {
override val canSetInstantBuild: Boolean override val canSetInstantBuild: Boolean
get() = true get() = true

View file

@ -0,0 +1,34 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
group = rootProject.group
version = rootProject.version
plugins {
id("io.papermc.paperweight.userdev")
}
dependencies {
implementation(project(":nms:nms-common"))
// Used for nms
paperweight.paperDevBundle("1.21.6-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().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)
}
}

View file

@ -0,0 +1,33 @@
package xyz.alexcrea.cuanvil.dependency.packet.versions
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket
import net.minecraft.world.entity.player.Abilities
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_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)
}
}

View file

@ -0,0 +1,34 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
group = rootProject.group
version = rootProject.version
plugins {
id("io.papermc.paperweight.userdev")
}
dependencies {
implementation(project(":nms:nms-common"))
// Used for nms
paperweight.paperDevBundle("1.21.10-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().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)
}
}

View file

@ -0,0 +1,33 @@
package xyz.alexcrea.cuanvil.dependency.packet.versions
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket
import net.minecraft.world.entity.player.Abilities
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_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)
}
}

View file

@ -0,0 +1,34 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
group = rootProject.group
version = rootProject.version
plugins {
id("io.papermc.paperweight.userdev")
}
dependencies {
implementation(project(":nms:nms-common"))
// Used for nms
paperweight.paperDevBundle("1.21.11-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().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)
}
}

View file

@ -0,0 +1,33 @@
package xyz.alexcrea.cuanvil.dependency.packet.versions
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket
import net.minecraft.world.entity.player.Abilities
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_21R7_PacketManager : PacketManagerBase(), PacketManager {
override val canSetInstantBuild: Boolean
get() = true
override fun setInstantBuild(player: Player, instantBuild: Boolean) {
val nmsPlayer = (player as CraftPlayer).handle
val playerAbilities = nmsPlayer.abilities
val sendedAbilities: Abilities
if (playerAbilities.instabuild == instantBuild) {
sendedAbilities = playerAbilities
} else {
sendedAbilities = Abilities()
sendedAbilities.invulnerable = playerAbilities.invulnerable
sendedAbilities.flying = playerAbilities.flying
sendedAbilities.mayfly = playerAbilities.mayfly
sendedAbilities.instabuild = instantBuild
sendedAbilities.mayBuild = playerAbilities.mayBuild
sendedAbilities.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -90,29 +90,6 @@ public class AnvilRecipeBuilder {
return this; return this;
} }
/**
* Get the xp level cost per craft. (default 0)
*
* @return The xp level cost per craft
* @deprecated use {@link #getLevelCostPerCraft() getLevelCostPerCraft} instead
*/
@Deprecated(since = "1.13.0")
public int getXpCostPerCraft() {
return getLevelCostPerCraft();
}
/**
* Sets the xp level cost per craft.
*
* @param xpCostPerCraft The xp level cost per craft
* @return This recipe builder instance.
* @deprecated use {@link #setLevelCostPerCraft(int) setLevelCostPerCraft} instead
*/
@Deprecated(since = "1.13.0")
public AnvilRecipeBuilder setXpCostPerCraft(int xpCostPerCraft) {
return setLevelCostPerCraft(xpCostPerCraft);
}
/** /**
* Get the xp level cost per craft. (default 0) * Get the xp level cost per craft. (default 0)
* *

View file

@ -387,7 +387,7 @@ public class ConflictBuilder {
*/ */
protected void appendEnchantments(@NotNull EnchantConflictGroup conflict) { protected void appendEnchantments(@NotNull EnchantConflictGroup conflict) {
for (String enchantmentName : getEnchantmentNames()) { for (String enchantmentName : getEnchantmentNames()) {
if (appendEnchantments(conflict, EnchantmentApi.getListByName(enchantmentName)) == 0) { if (appendEnchantments(conflict, EnchantmentApi.getByName(enchantmentName)) == 0) {
CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentName + " for conflict " + getName()); CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentName + " for conflict " + getName());
ConflictAPI.logConflictOrigin(this); ConflictAPI.logConflictOrigin(this);
} }

View file

@ -132,27 +132,14 @@ public class EnchantmentApi {
return CAEnchantment.getByKey(key); return CAEnchantment.getByKey(key);
} }
/**
* Get by name an enchantment.
*
* @param name The name used to fetch
* @return The custom anvil enchantment of this name. null if not found.
* @deprecated use {@link #getListByName(String)}
*/
@Deprecated(since = "1.6.3")
@Nullable
public static CAEnchantment getByName(@NotNull String name) {
return CAEnchantment.getByName(name);
}
/** /**
* Get list of enchantment using the provided name. * Get list of enchantment using the provided name.
* *
* @param name The name used to fetch * @param name The name used to fetch
* @return List of custom anvil enchantments of this name. May be empty if not found. * @return List of custom anvil enchantments of this name. May be empty if not found.
*/ */
public static List<CAEnchantment> getListByName(@NotNull String name) { public static List<CAEnchantment> getByName(@NotNull String name) {
return CAEnchantment.getListByName(name); return CAEnchantment.getByName(name);
} }
/** /**

View file

@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull;
* Most of the time you would likely need {@link CAPreAnvilBypassEvent} or {@link CAEarlyPreAnvilBypassEvent} * Most of the time you would likely need {@link CAPreAnvilBypassEvent} or {@link CAEarlyPreAnvilBypassEvent}
* for this event to be useful. * for this event to be useful.
* <p> * <p>
* There is also {@link CATreatAnvilResult2Event} that may be better for some use case. * There is also {@link CATreatAnvilResultEvent} that may be better for some use case.
*/ */
public class CAClickResultBypassEvent extends Event implements Cancellable { public class CAClickResultBypassEvent extends Event implements Cancellable {

View file

@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull;
* <p> * <p>
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful. * You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
* <p> * <p>
* It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResult2Event} * It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
* as your use case may be more prone to use theses. * as your use case may be more prone to use theses.
*/ */
public class CAEarlyPreAnvilBypassEvent extends Event implements Cancellable { public class CAEarlyPreAnvilBypassEvent extends Event implements Cancellable {

View file

@ -18,7 +18,7 @@ import org.jetbrains.annotations.NotNull;
* <p> * <p>
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful. * You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
* <p> * <p>
* It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResult2Event} * It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
* as your use case may be more prone to use theses. * as your use case may be more prone to use theses.
*/ */
public class CAPreAnvilBypassEvent extends Event implements Cancellable { public class CAPreAnvilBypassEvent extends Event implements Cancellable {

View file

@ -1,196 +0,0 @@
package xyz.alexcrea.cuanvil.api.event.listener;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.anvil.AnvilCost;
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
/**
* Called after custom anvil processed the click on the result on the anvil inventory.
* This event should be used to modify the result of an anvil use.
* <p>
* You may also want to check {@link CAClickResultBypassEvent},
* {@link CAPreAnvilBypassEvent}
* and {@link CAEarlyPreAnvilBypassEvent} for your use case
* <p>
* A null result will cancel this event
*/
@SuppressWarnings("unused")
public class CATreatAnvilResult2Event extends Event {
private static final HandlerList HANDLERS = new HandlerList();
public static HandlerList getHandlerList() {
return HANDLERS;
}
@Override
public @NotNull HandlerList getHandlers() {
return HANDLERS;
}
@NotNull
private final InventoryView view;
private final AnvilUseType useType;
@Nullable
private final ItemStack left;
@Nullable
private final ItemStack right;
@Nullable
private ItemStack result;
private final AnvilCost cost;
@ApiStatus.Internal
public CATreatAnvilResult2Event(
@NotNull InventoryView view,
Inventory inv,
AnvilUseType useType,
@Nullable ItemStack result,
AnvilCost cost) {
this.view = view;
this.useType = useType;
this.left = inv.getItem(0); // TODO use view here
this.right = inv.getItem(1);
this.result = result;
this.cost = cost;
}
/**
* Get the bukkit inventory view.
* <p>
* Temporarily marked as internal as it will get changed to anvil view on legacy removal
* so signature will change
*
* @return The inventory view of this event.
*/
@ApiStatus.Internal
public @NotNull InventoryView getView() {
return view;
}
/**
* Get the type of use source of the result.
*
* @return The craft use type.
*/
public AnvilUseType getUseType() {
return useType;
}
/**
* Get the left item of the anvil use
*
* @return the left item
*/
public @Nullable ItemStack getLeftItem() {
return left;
}
/**
* Get the right item of the anvil use
*
* @return the right item
*/
public @Nullable ItemStack getRightItem() {
return right;
}
/**
* Get the current result
* <p>
* note that it will not be null unless another listener previously set it to null.
*
* @return The current result.
*/
public @Nullable ItemStack getResult() {
return result;
}
/**
* Set the current result
* <p>
* note that a null result will cancel this anvil use.
*
* @param result The new result
*/
public void setResult(@Nullable ItemStack result) {
this.result = result;
}
/**
* Get the level cost displayed on the anvil.
* <h3>Important note:</h3>
* the final price are re calculated on click for the following use case:
* <ul>
* <li>Custom craft</li>
* <li>Unit repair</li>
* <li>Lore edit</li>
* </ul>
* This value will be used as final price for:
* <li>Item merge</li>
* <li>Item rename</li>
* </ul>
*
* @return The current cost.
* @deprecated use #{@link #getCost()} instead
*/
@Deprecated(forRemoval = true, since = "1.17.0")
public int getLevelCost() {
return cost.asXpCost();
}
/**
* Set the level cost displayed on the anvil.
* <h3>Important note:</h3>
* the final price are re calculated on click for the following use case:
* <ul>
* <li>Custom craft</li>
* <li>Unit repair</li>
* <li>Lore edit</li>
* </ul>
* This value will be used as final price for:
* <li>Item merge</li>
* <li>Item rename</li>
* </ul>
*
* @param levelCost The new cost.
* @deprecated use #{@link #getCost()} and set value on this instead
*/
@Deprecated(forRemoval = true, since = "1.17.0")
public void setLevelCost(int levelCost) {
cost.setGeneric(levelCost - cost.getGeneric() - cost.asXpCost());
}
/**
* Allow access to the current cost of the event
* Note that modifying this object will change the event resulting cost
*
* <h3>Important note:</h3>
* the final price are re calculated on click for the following use case:
* <ul>
* <li>Custom craft</li>
* <li>Unit repair</li>
* <li>Lore edit</li>
* </ul>
* This value will be used as final price for:
* <li>Item merge</li>
* <li>Item rename</li>
*
* @return the current anvil cost
*/
public AnvilCost getCost() {
return cost;
}
}

View file

@ -2,8 +2,8 @@ package xyz.alexcrea.cuanvil.api.event.listener;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.view.AnvilView;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.anvil.AnvilCost; import xyz.alexcrea.cuanvil.anvil.AnvilCost;
@ -17,13 +17,9 @@ import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
* {@link CAPreAnvilBypassEvent} * {@link CAPreAnvilBypassEvent}
* and {@link CAEarlyPreAnvilBypassEvent} for your use case * and {@link CAEarlyPreAnvilBypassEvent} for your use case
* <p> * <p>
* A null result will cancel this pre anvil event * A null result will cancel this event
*
* @deprecated Prepare anvil Event cannot be provided as it can be called on result and therefore not have prepared anvil event
* use {@link CATreatAnvilResult2Event} instead
*/ */
@SuppressWarnings("unused") @SuppressWarnings({"unused", "UnstableApiUsage"})
@Deprecated(forRemoval = true, since = "1.17.0")
public class CATreatAnvilResultEvent extends Event { public class CATreatAnvilResultEvent extends Event {
private static final HandlerList HANDLERS = new HandlerList(); private static final HandlerList HANDLERS = new HandlerList();
@ -38,31 +34,44 @@ public class CATreatAnvilResultEvent extends Event {
} }
@NotNull @NotNull
private final PrepareAnvilEvent event; private final AnvilView view;
private final AnvilUseType useType; private final AnvilUseType useType;
@Nullable
private final ItemStack left;
@Nullable
private final ItemStack right;
@Nullable @Nullable
private ItemStack result; private ItemStack result;
private final AnvilCost cost; private final AnvilCost cost;
public CATreatAnvilResultEvent(@NotNull PrepareAnvilEvent event, AnvilUseType useType, @Nullable ItemStack result, AnvilCost cost) { public CATreatAnvilResultEvent(
this.event = event; @NotNull AnvilView view,
AnvilUseType useType,
@Nullable ItemStack result,
AnvilCost cost) {
this.view = view;
this.useType = useType; this.useType = useType;
this.left = view.getItem(0);
this.right = view.getItem(1);
this.result = result; this.result = result;
this.cost = cost; this.cost = cost;
} }
/** /**
* Get the bukkit inventory click event causing to this event. * Get the bukkit inventory view.
* *
* @return The click event causing to this event. * @return The inventory view of this event.
*/ */
public @NotNull PrepareAnvilEvent getEvent() { public @NotNull AnvilView getView() {
return event; return view;
} }
/** /**
* Get the type of use source of the result. * Get the type of use source of the result.
* *
@ -72,6 +81,24 @@ public class CATreatAnvilResultEvent extends Event {
return useType; return useType;
} }
/**
* Get the left item of the anvil use
*
* @return the left item
*/
public @Nullable ItemStack getLeftItem() {
return left;
}
/**
* Get the right item of the anvil use
*
* @return the right item
*/
public @Nullable ItemStack getRightItem() {
return right;
}
/** /**
* Get the current result * Get the current result
* <p> * <p>
@ -94,50 +121,6 @@ public class CATreatAnvilResultEvent extends Event {
this.result = result; this.result = result;
} }
/**
* Get the level cost displayed on the anvil.
* <h3>Important note:</h3>
* the final price are re calculated on click for the following use case:
* <ul>
* <li>Custom craft</li>
* <li>Unit repair</li>
* <li>Lore edit</li>
* </ul>
* This value will be used as final price for:
* <li>Item merge</li>
* <li>Item rename</li>
* </ul>
*
* @return The current cost.
* @deprecated use #{@link #getCost()} instead
*/
@Deprecated(forRemoval = true, since = "1.17.0")
public int getLevelCost() {
return cost.asXpCost();
}
/**
* Set the level cost displayed on the anvil.
* <h3>Important note:</h3>
* the final price are re calculated on click for the following use case:
* <ul>
* <li>Custom craft</li>
* <li>Unit repair</li>
* <li>Lore edit</li>
* </ul>
* This value will be used as final price for:
* <li>Item merge</li>
* <li>Item rename</li>
* </ul>
*
* @param levelCost The new cost.
* @deprecated use #{@link #getCost()} and set value on this instead
*/
@Deprecated(forRemoval = true, since = "1.17.0")
public void setLevelCost(int levelCost) {
cost.setGeneric(levelCost - cost.getGeneric() - cost.asXpCost());
}
/** /**
* Allow access to the current cost of the event * Allow access to the current cost of the event
* Note that modifying this object will change the event resulting cost * Note that modifying this object will change the event resulting cost
@ -158,5 +141,4 @@ public class CATreatAnvilResultEvent extends Event {
public AnvilCost getCost() { public AnvilCost getCost() {
return cost; return cost;
} }
} }

View file

@ -234,25 +234,14 @@ public interface CAEnchantment {
return CAEnchantmentRegistry.getInstance().getByKey(key); return CAEnchantmentRegistry.getInstance().getByKey(key);
} }
/**
* Gets the enchantment by the provided name.
* @param name Name to fetch.
* @return Registered enchantment. null if absent.
*
* @deprecated use {@link #getListByName(String)}
*/
@Deprecated(since = "1.6.3")
static @Nullable CAEnchantment getByName(@NotNull String name){
return CAEnchantmentRegistry.getInstance().getByName(name);
}
/** /**
* Gets list of enchantment using the provided name. * Gets list of enchantment using the provided name.
*
* @param name Name to fetch. * @param name Name to fetch.
* @return List of registered enchantment. * @return List of registered enchantment.
*/ */
static List<CAEnchantment> getListByName(@NotNull String name){ static List<CAEnchantment> getByName(@NotNull String name){
return CAEnchantmentRegistry.getInstance().getListByName(name); return CAEnchantmentRegistry.getInstance().getByName(name);
} }
} }

View file

@ -154,22 +154,6 @@ public class CAEnchantmentRegistry {
return byKeyMap.get(key); return byKeyMap.get(key);
} }
/**
* Gets the enchantment by the provided name.
*
* @param name Name to fetch.
* @return Registered enchantment. null if absent.
* @deprecated use {@link #getListByName(String)}
*/
@Deprecated(since = "1.6.3")
@Nullable
public CAEnchantment getByName(@NotNull String name) {
List<CAEnchantment> enchantments = getListByName(name);
if (enchantments.isEmpty()) return null;
return enchantments.get(0);
}
/** /**
* Gets list of enchantment using the provided name. * Gets list of enchantment using the provided name.
* *
@ -177,7 +161,7 @@ public class CAEnchantmentRegistry {
* @return List of registered enchantment. * @return List of registered enchantment.
*/ */
@NotNull @NotNull
public List<CAEnchantment> getListByName(@NotNull String name) { public List<CAEnchantment> getByName(@NotNull String name) {
return byNameMap.getOrDefault(name, Collections.emptyList()); return byNameMap.getOrDefault(name, Collections.emptyList());
} }

View file

@ -1,6 +1,6 @@
package xyz.alexcrea.cuanvil.enchant; package xyz.alexcrea.cuanvil.enchant;
// because spigot (1.18) do not look like to provide access to enchantment rarity I need to do it myself... // because spigot (1.21) do not look like to provide access to enchantment rarity I need to do it myself...
public class EnchantmentRarity { public class EnchantmentRarity {
public static final EnchantmentRarity NO_RARITY = new EnchantmentRarity(0, 0); public static final EnchantmentRarity NO_RARITY = new EnchantmentRarity(0, 0);

View file

@ -141,10 +141,10 @@ public class EnchantSelectSettingGui extends SettingGuiListConfigGui<CAEnchantme
meta.setDisplayName("§" + (isIn ? 'a' : 'c') + CasedStringUtil.snakeToUpperSpacedCase(name)); meta.setDisplayName("§" + (isIn ? 'a' : 'c') + CasedStringUtil.snakeToUpperSpacedCase(name));
if (isIn) { if (isIn) {
meta.addEnchant(Enchantment.DAMAGE_UNDEAD, 1, true); meta.addEnchant(Enchantment.SHARPNESS, 1, true);
meta.setLore(TRUE_LORE); meta.setLore(TRUE_LORE);
} else { } else {
meta.removeEnchant(Enchantment.DAMAGE_UNDEAD); meta.removeEnchant(Enchantment.SHARPNESS);
meta.setLore(FALSE_LORE); meta.setLore(FALSE_LORE);
} }
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ENCHANTS); meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ENCHANTS);

View file

@ -112,10 +112,10 @@ public class GroupSelectSettingGui extends AbstractSettingGui {
meta.setDisplayName("§" + (isIn ? 'a' : 'c') + CasedStringUtil.snakeToUpperSpacedCase(name)); meta.setDisplayName("§" + (isIn ? 'a' : 'c') + CasedStringUtil.snakeToUpperSpacedCase(name));
if (isIn) { if (isIn) {
meta.addEnchant(Enchantment.DAMAGE_UNDEAD, 1, true); meta.addEnchant(Enchantment.SHARPNESS, 1, true);
meta.setLore(TRUE_LORE); meta.setLore(TRUE_LORE);
} else { } else {
meta.removeEnchant(Enchantment.DAMAGE_UNDEAD); meta.removeEnchant(Enchantment.SHARPNESS);
meta.setLore(FALSE_LORE); meta.setLore(FALSE_LORE);
} }
meta.addItemFlags(ItemFlag.values()); meta.addItemFlags(ItemFlag.values());

View file

@ -11,6 +11,7 @@ import xyz.alexcrea.cuanvil.command.EditConfigExecutor
import xyz.alexcrea.cuanvil.command.ReloadExecutor import xyz.alexcrea.cuanvil.command.ReloadExecutor
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
@ -24,7 +25,6 @@ import xyz.alexcrea.cuanvil.update.ModrinthUpdateChecker
import xyz.alexcrea.cuanvil.update.PluginSetDefault import xyz.alexcrea.cuanvil.update.PluginSetDefault
import xyz.alexcrea.cuanvil.update.UpdateHandler import xyz.alexcrea.cuanvil.update.UpdateHandler
import xyz.alexcrea.cuanvil.update.UpdateUtils import xyz.alexcrea.cuanvil.update.UpdateUtils
import xyz.alexcrea.cuanvil.update.Version
import xyz.alexcrea.cuanvil.util.MetricsUtil import xyz.alexcrea.cuanvil.util.MetricsUtil
import java.io.File import java.io.File
import java.io.FileReader import java.io.FileReader
@ -136,7 +136,7 @@ open class CustomAnvil : JavaPlugin() {
override fun onEnable() { override fun onEnable() {
instance = this instance = this
try { try {
if(legacyCheck()) return legacyCheck()
} catch (e: Exception) { } catch (e: Exception) {
logger.log(Level.SEVERE, "error trying to check for legacy system", e) logger.log(Level.SEVERE, "error trying to check for legacy system", e)
MetricsUtil.trackError(e) MetricsUtil.trackError(e)
@ -145,7 +145,7 @@ open class CustomAnvil : JavaPlugin() {
// Add commands // Add commands
try { try {
prepareCommand() CustomAnvilCommand(this)
} catch (e: Exception) { } catch (e: Exception) {
logger.log(Level.SEVERE, "error trying to register commands", e) logger.log(Level.SEVERE, "error trying to register commands", e)
MetricsUtil.trackError(e) MetricsUtil.trackError(e)
@ -202,16 +202,7 @@ open class CustomAnvil : JavaPlugin() {
} }
} }
private fun legacyCheck(): Boolean { private fun legacyCheck() {
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 // Disable old plugin name if exist
val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus") val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus")
if (potentialPlugin != null) { if (potentialPlugin != null) {
@ -224,6 +215,10 @@ open class CustomAnvil : JavaPlugin() {
if(!isPaper) { if(!isPaper) {
logger.warning("It seems you are using spigot") logger.warning("It seems you are using spigot")
logger.warning("Please take notice that spigot is less supported than paper and derivatives") 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" val loader = if(isPaper) "paper" else "spigot"
@ -243,7 +238,6 @@ open class CustomAnvil : JavaPlugin() {
logger.warning("An update may be available: $latestVer") logger.warning("An update may be available: $latestVer")
} }
return false
} }
private fun registerListeners() { private fun registerListeners() {
@ -336,14 +330,4 @@ open class CustomAnvil : JavaPlugin() {
return yamlConfig return yamlConfig
} }
fun prepareCommand() {
var command = getCommand(commandReloadName)
command?.setExecutor(ReloadExecutor())
command = getCommand(commandConfigName)
command?.setExecutor(EditConfigExecutor())
CustomAnvilCommand(this)
}
} }

View file

@ -20,6 +20,13 @@ object ItemUtil {
*/ */
fun ItemStack.isEnchantedBook() = type == ENCHANTED_BOOK fun ItemStack.isEnchantedBook() = type == ENCHANTED_BOOK
private fun maxDamage(type: Material, damageable: Damageable): Int {
val ver = UpdateUtils.currentMinecraftVersion()
if(ver.major <= 1 && ver.minor <= 20 && ver.patch < 5) return type.maxDurability.toInt()
return if(damageable.hasMaxDamage()) damageable.maxDamage else type.maxDurability.toInt()
}
/** /**
* Set this [ItemStack]s durability from a combination of the * Set this [ItemStack]s durability from a combination of the
* [first] and [second] item's durability values * [first] and [second] item's durability values
@ -32,7 +39,7 @@ object ItemUtil {
val meta = itemMeta val meta = itemMeta
if(meta !is Damageable) return false if(meta !is Damageable) return false
val maxDamage = type.maxDurability.toInt() val maxDamage = maxDamage(type, meta)
val damage = (first.itemMeta as? Damageable)?.damage ?: 0 val damage = (first.itemMeta as? Damageable)?.damage ?: 0
if (damage == 0) return false if (damage == 0) return false

View file

@ -11,10 +11,9 @@ import org.bukkit.ChatColor
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.inventory.view.AnvilView
import org.bukkit.persistence.PersistentDataType import org.bukkit.persistence.PersistentDataType
import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.api.EnchantmentApi
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
@ -33,6 +32,7 @@ import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditType import xyz.alexcrea.cuanvil.util.config.LoreEditType
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
@Suppress("UnstableApiUsage")
object AnvilMergeLogic { object AnvilMergeLogic {
open class AnvilResult { open class AnvilResult {
@ -99,13 +99,12 @@ object AnvilMergeLogic {
} }
fun doRenaming( fun doRenaming(
view: InventoryView, //TODO use anvil view view: AnvilView,
inventory: AnvilInventory,
player: Player, first: ItemStack player: Player, first: ItemStack
): AnvilResult { ): AnvilResult {
val resultItem = DependencyManager.cloneItem(player, first) val resultItem = DependencyManager.cloneItem(player, first)
val cost = AnvilCost() val cost = AnvilCost()
cost.rename = handleRename(resultItem, inventory, player) cost.rename = handleRename(resultItem, view, player)
// Test/stop if nothing changed. // Test/stop if nothing changed.
if (first == resultItem) { if (first == resultItem) {
@ -115,7 +114,7 @@ object AnvilMergeLogic {
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY) cost.workPenalty = AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY)
val result = val result =
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.RENAME_ONLY, cost) DependencyManager.tryTreatAnvilResult(view, player, resultItem, AnvilUseType.RENAME_ONLY, cost)
return AnvilResult(result, cost) return AnvilResult(result, cost)
} }
@ -138,9 +137,9 @@ object AnvilMergeLogic {
} }
} }
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int { private fun handleRename(resultItem: ItemStack, view: AnvilView, player: HumanEntity): Int {
// Can be null // Can be null
var renameText = ChatColor.stripColor(inventory.renameText) var renameText = ChatColor.stripColor(view.renameText)
var component: Component? = null var component: Component? = null
var sumCost = 0 var sumCost = 0
@ -190,8 +189,7 @@ object AnvilMergeLogic {
} }
fun doMerge( fun doMerge(
view: InventoryView, //TODO use anvil view instead view: AnvilView,
inventory: AnvilInventory,
player: Player, player: Player,
first: ItemStack, second: ItemStack first: ItemStack, second: ItemStack
): AnvilResult { ): AnvilResult {
@ -226,10 +224,10 @@ object AnvilMergeLogic {
// As calculatePenalty edit result, we need to calculate penalty after checking equality // As calculatePenalty edit result, we need to calculate penalty after checking equality
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, second, resultItem, AnvilUseType.MERGE) cost.workPenalty = AnvilXpUtil.calculatePenalty(first, second, resultItem, AnvilUseType.MERGE)
// Calculate rename cost // Calculate rename cost
cost.rename = handleRename(resultItem, inventory, player) cost.rename = handleRename(resultItem, view, player)
val result = val result =
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.MERGE, cost) DependencyManager.tryTreatAnvilResult(view, player, resultItem, AnvilUseType.MERGE, cost)
return AnvilResult(result, cost) return AnvilResult(result, cost)
} }
@ -248,8 +246,7 @@ object AnvilMergeLogic {
// return true if a custom recipe exist with these ingredients // return true if a custom recipe exist with these ingredients
fun testCustomRecipe( fun testCustomRecipe(
view: InventoryView, //TODO use anvil view instead view: AnvilView,
inventory: AnvilInventory,
player: Player, player: Player,
first: ItemStack, second: ItemStack? first: ItemStack, second: ItemStack?
): CustomCraftResult { ): CustomCraftResult {
@ -271,31 +268,29 @@ object AnvilMergeLogic {
else AnvilXpUtil.calculateLevelForXp(xpCost) else AnvilXpUtil.calculateLevelForXp(xpCost)
val result = val result =
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.CUSTOM_CRAFT, cost) DependencyManager.tryTreatAnvilResult(view, player, resultItem, AnvilUseType.CUSTOM_CRAFT, cost)
return CustomCraftResult(result, cost, amount, recipe) return CustomCraftResult(result, cost, amount, recipe)
} }
fun testUnitRepair( fun testUnitRepair(
view: InventoryView, //TODO use anvil view view: AnvilView,
inventory: AnvilInventory,
player: Player, player: Player,
first: ItemStack, second: ItemStack first: ItemStack, second: ItemStack
): UnitRepairResult { ): UnitRepairResult {
val unitRepairAmount = first.getRepair(second) ?: return UnitRepairResult.EMPTY val unitRepairAmount = first.getRepair(second) ?: return UnitRepairResult.EMPTY
return testUnitRepair(view, inventory, player, first, second, unitRepairAmount) return testUnitRepair(view, player, first, second, unitRepairAmount)
} }
fun testUnitRepair( fun testUnitRepair(
view: InventoryView, //TODO use anvil view instead view: AnvilView,
inventory: AnvilInventory,
player: Player, player: Player,
first: ItemStack, second: ItemStack, first: ItemStack, second: ItemStack,
unitRepairAmount: Double unitRepairAmount: Double
): UnitRepairResult { ): UnitRepairResult {
val resultItem = DependencyManager.cloneItem(player, first) val resultItem = DependencyManager.cloneItem(player, first)
val cost = AnvilCost() val cost = AnvilCost()
cost.rename = handleRename(resultItem, inventory, player) cost.rename = handleRename(resultItem, view, player)
val repairAmount = resultItem.unitRepair(second.amount, unitRepairAmount) val repairAmount = resultItem.unitRepair(second.amount, unitRepairAmount)
if (repairAmount > 0) if (repairAmount > 0)
@ -311,7 +306,7 @@ object AnvilMergeLogic {
} }
val result = val result =
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.UNIT_REPAIR, cost) DependencyManager.tryTreatAnvilResult(view, player, resultItem, AnvilUseType.UNIT_REPAIR, cost)
return UnitRepairResult(result, cost, repairAmount) return UnitRepairResult(result, cost, repairAmount)
} }

View file

@ -1,50 +1,29 @@
package xyz.alexcrea.cuanvil.command package xyz.alexcrea.cuanvil.command
import org.bukkit.ChatColor
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
abstract class CASubCommand: CommandExecutor { interface CASubCommand {
private var alreadySaid = false; fun executeCommand(
override fun onCommand(
sender: CommandSender, sender: CommandSender,
cmd: Command, cmd: Command,
cmdstr: String, cmdstr: String,
args: Array<out String> args: Array<out String>
): Boolean { ): Boolean
if(!alreadySaid){
sender.sendMessage(ChatColor.RED.toString() +
"Please not that this command will be replaced as a subcommand of `/customanvil` or `/ca`")
alreadySaid = true
}
return executeCommand(sender, cmd, cmdstr, args) fun allowed(sender: CommandSender): Boolean
}
abstract fun executeCommand( fun tabCompleter(
sender: CommandSender,
cmd: Command,
cmdstr: String,
args: Array<out String>): Boolean
open fun allowed(sender: CommandSender): Boolean {
return true
}
open fun tabCompleter(
sender: CommandSender, sender: CommandSender,
args: Array<out String>, args: Array<out String>,
list: MutableList<String>) { list: MutableList<String>
} )
open fun description(): String { fun description(): String
return "no description"
}
protected fun allEnchantmentsByName(): Collection<String> { fun allEnchantmentsByName(): Collection<String> {
val names = mutableSetOf<String>() val names = mutableSetOf<String>()
for (enchantment in CAEnchantmentRegistry.getInstance().values()) { for (enchantment in CAEnchantmentRegistry.getInstance().values()) {
names.add(enchantment.name) names.add(enchantment.name)

View file

@ -46,17 +46,17 @@ class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter {
val subcmdStr: String val subcmdStr: String
val newargs: Array<out String> val newargs: Array<out String>
if(args.isEmpty()) { if (args.isEmpty()) {
subcmdStr = "config" subcmdStr = "config"
subcmd = editConfigCommand subcmd = editConfigCommand
newargs = args newargs = args
}else { } else {
subcmdStr = args[0].lowercase() subcmdStr = args[0].lowercase()
subcmd = commands[subcmdStr] subcmd = commands[subcmdStr]
newargs = args.copyOfRange(1, args.size) newargs = args.copyOfRange(1, args.size)
} }
if(subcmd == null || !subcmd.allowed(sender)) { if (subcmd == null || !subcmd.allowed(sender)) {
sender.sendMessage("Invalid subcommand. run `$cmdstr help` to see available commands") sender.sendMessage("Invalid subcommand. run `$cmdstr help` to see available commands")
return true return true
} }
@ -77,18 +77,18 @@ class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter {
args: Array<out String> args: Array<out String>
): MutableList<String> { ): MutableList<String> {
val result = ArrayList<String>() val result = ArrayList<String>()
if(args.size < 2) { if (args.size < 2) {
for ((key, cmd) in commands) { for ((key, cmd) in commands) {
if(!cmd.allowed(sender)) continue if (!cmd.allowed(sender)) continue
if("gui".contentEquals(key)) continue if("gui".contentEquals(key)) continue
result.add(key) result.add(key)
} }
} else { } else {
val subcmd = commands[args[0].lowercase()] val subcmd = commands[args[0].lowercase()]
if(subcmd != null) { if (subcmd != null) {
val newArgs = args.copyOfRange(1, args.size) val newArgs = args.copyOfRange(1, args.size)
if(!subcmd.allowed(sender)) return result if (!subcmd.allowed(sender)) return result
subcmd.tabCompleter(sender, newArgs, result) subcmd.tabCompleter(sender, newArgs, result)
} }

View file

@ -12,7 +12,7 @@ import org.bukkit.command.CommandSender
import org.bukkit.entity.Player import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.command.DiagnosticExecutor.Companion.NO_DIAG_PERM import xyz.alexcrea.cuanvil.command.DiagnosticExecutor.Companion.NO_DIAG_PERM
class DebugToggleExecutor : CASubCommand() { class DebugToggleExecutor : CASubCommand {
override fun description(): String { override fun description(): String {
return "Used to toggle debug logs and retrieve it" return "Used to toggle debug logs and retrieve it"

View file

@ -1,6 +1,5 @@
package xyz.alexcrea.cuanvil.command package xyz.alexcrea.cuanvil.command
import com.github.stefvanschie.inventoryframework.inventoryview.interface_.InventoryViewUtil
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import net.md_5.bungee.api.chat.ClickEvent import net.md_5.bungee.api.chat.ClickEvent
import net.md_5.bungee.api.chat.HoverEvent import net.md_5.bungee.api.chat.HoverEvent
@ -16,11 +15,10 @@ import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryType import org.bukkit.event.inventory.InventoryType
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Damageable import org.bukkit.inventory.meta.Damageable
import org.bukkit.inventory.meta.EnchantmentStorageMeta import org.bukkit.inventory.meta.EnchantmentStorageMeta
import org.bukkit.inventory.view.AnvilView
import org.bukkit.plugin.Plugin import org.bukkit.plugin.Plugin
import org.bukkit.plugin.RegisteredListener import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
@ -32,10 +30,9 @@ import xyz.alexcrea.cuanvil.util.MetricsUtil
import java.util.* import java.util.*
import java.util.stream.Collectors import java.util.stream.Collectors
class DiagnosticExecutor : CASubCommand {
class DiagnosticExecutor: CASubCommand() { companion object {
companion object{
const val NO_DIAG_PERM = "You do not have permission to diagnostic this server" const val NO_DIAG_PERM = "You do not have permission to diagnostic this server"
fun fetchNMSType(): String { fun fetchNMSType(): String {
@ -43,7 +40,7 @@ class DiagnosticExecutor: CASubCommand() {
val packetManagerClass = packetManager.javaClass val packetManagerClass = packetManager.javaClass
val className = packetManagerClass.name val className = packetManagerClass.name
val result = if(className.contains("PaperPacket")) { val result = if (className.contains("PaperPacket")) {
"Paper" "Paper"
} else { } else {
when (packetManagerClass) { when (packetManagerClass) {
@ -54,7 +51,7 @@ class DiagnosticExecutor: CASubCommand() {
} }
return "$result ${if(packetManager.canSetInstantBuild) '✅' else '❌'}" return "$result ${if (packetManager.canSetInstantBuild) '✅' else '❌'}"
} }
} }
@ -75,7 +72,7 @@ class DiagnosticExecutor: CASubCommand() {
} }
for (param in DiagParams.entries) { for (param in DiagParams.entries) {
if(argSet.contains(param.value)) if (argSet.contains(param.value))
result.add(param) result.add(param)
} }
@ -85,12 +82,13 @@ class DiagnosticExecutor: CASubCommand() {
override fun tabCompleter( override fun tabCompleter(
sender: CommandSender, sender: CommandSender,
args: Array<out String>, args: Array<out String>,
list: MutableList<String>) { list: MutableList<String>
if(!allowed(sender)) return ) {
if (!allowed(sender)) return
val map = fetchParameters(args) val map = fetchParameters(args)
for (param in DiagParams.entries) { for (param in DiagParams.entries) {
if(!map.contains(param)) if (!map.contains(param))
list.add(param.value) list.add(param.value)
} }
@ -112,7 +110,7 @@ class DiagnosticExecutor: CASubCommand() {
var hasError = false var hasError = false
try { try {
diagnostic(sender, stb, params) diagnostic(sender, stb, params)
} catch(e: Throwable){ } catch (e: Throwable) {
stb.append("\n\nError happened trying to get diagnostic data:\n") stb.append("\n\nError happened trying to get diagnostic data:\n")
.append(e.message).append("\n") .append(e.message).append("\n")
.append(e.stackTrace.joinToString("\n")) .append(e.stackTrace.joinToString("\n"))
@ -123,8 +121,9 @@ class DiagnosticExecutor: CASubCommand() {
stb.append("\n```") stb.append("\n```")
if (sender is HumanEntity) { if (sender is HumanEntity) {
if(hasError) if (hasError)
sender.spigot().sendMessage(TextComponent(ChatColor.RED.toString() + "There was an error running the diagnostic")) sender.spigot()
.sendMessage(TextComponent(ChatColor.RED.toString() + "There was an error running the diagnostic"))
val message = TextComponent(ChatColor.GREEN.toString() + "Click to copy diagnostic data") val message = TextComponent(ChatColor.GREEN.toString() + "Click to copy diagnostic data")
message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString()) message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString())
@ -142,41 +141,41 @@ class DiagnosticExecutor: CASubCommand() {
return sender.hasPermission(CustomAnvil.diagnosticPermission) return sender.hasPermission(CustomAnvil.diagnosticPermission)
} }
fun diagnostic(sender: CommandSender, stb: StringBuilder, params: Set<DiagParams>){ fun diagnostic(sender: CommandSender, stb: StringBuilder, params: Set<DiagParams>) {
stb.append("Server Info\n") stb.append("Server Info\n")
val version = CustomAnvil.instance.description.version val version = CustomAnvil.instance.description.version
stb.append("\nPlugin Version: ").append(version) stb.append("\nPlugin Version: ").append(version)
if(version.contains("dev")) stb.append(" (alpha)") if (version.contains("dev")) stb.append(" (alpha)")
stb.append("\nLatest Update: ").append(CustomAnvil.latestVer) stb.append("\nLatest Update: ").append(CustomAnvil.latestVer)
stb.append("\nServer Version: ").append(Bukkit.getVersion()).append(" (").append(Bukkit.getName()).append(')') stb.append("\nServer Version: ").append(Bukkit.getVersion()).append(" (").append(Bukkit.getName()).append(')')
stb.append("\nPlugin Enabled: ").append(if(CustomAnvil.instance.isEnabled) "Yes" else "No") stb.append("\nPlugin Enabled: ").append(if (CustomAnvil.instance.isEnabled) "Yes" else "No")
stb.append("\nNMS type: ").append(fetchNMSType()) stb.append("\nNMS type: ").append(fetchNMSType())
if(!params.contains(DiagParams.OS_PRIVACY)) { if (!params.contains(DiagParams.OS_PRIVACY)) {
stb.append("\nJava Version: ").append(System.getProperty("java.version")) stb.append("\nJava Version: ").append(System.getProperty("java.version"))
stb.append("\nOS: ").append(System.getProperty("os.name")).append(" ") stb.append("\nOS: ").append(System.getProperty("os.name")).append(" ")
.append(System.getProperty("os.version")) .append(System.getProperty("os.version"))
.append(System.getProperty("os.arch")) .append(System.getProperty("os.arch"))
} }
stb.append("\nHad detect error: ").append(if(MetricsUtil.lastError != null) "Yes" else "No") stb.append("\nHad detect error: ").append(if (MetricsUtil.lastError != null) "Yes" else "No")
if(!params.contains(DiagParams.PLUGIN_PRIVACY)) { if (!params.contains(DiagParams.PLUGIN_PRIVACY)) {
pluginListDiag(sender, stb) pluginListDiag(sender, stb)
} }
prepareAnvilListeners(stb) prepareAnvilListeners(stb)
if(!params.contains(DiagParams.NO_MERGE_TEST)){ if (!params.contains(DiagParams.NO_MERGE_TEST)) {
if(sender is Player) testMerge(sender, stb) if (sender is Player) testMerge(sender, stb)
} }
stb.append("\n\nEnchantments data:") stb.append("\n\nEnchantments data:")
partialEnchantmentData(stb) partialEnchantmentData(stb)
if(params.contains(DiagParams.FULL_ENCHANTMENT_DATA)){ if (params.contains(DiagParams.FULL_ENCHANTMENT_DATA)) {
fullEnchantmentData(stb) fullEnchantmentData(stb)
} }
if(params.contains(DiagParams.INCLUDE_LAST_ERROR)){ if (params.contains(DiagParams.INCLUDE_LAST_ERROR)) {
includeLastError(stb) includeLastError(stb)
} }
} }
@ -193,11 +192,11 @@ class DiagnosticExecutor: CASubCommand() {
damagedSword.itemMeta = meta damagedSword.itemMeta = meta
meta = enchantedSword.itemMeta meta = enchantedSword.itemMeta
meta!!.addEnchant(Enchantment.DAMAGE_ALL, 1, true) meta!!.addEnchant(Enchantment.SHARPNESS, 1, true)
enchantedSword.itemMeta = meta enchantedSword.itemMeta = meta
meta = enchantedBook.itemMeta meta = enchantedBook.itemMeta
(meta as EnchantmentStorageMeta).addStoredEnchant(Enchantment.DAMAGE_ALL, 1, true) (meta as EnchantmentStorageMeta).addStoredEnchant(Enchantment.SHARPNESS, 1, true)
enchantedBook.itemMeta = meta enchantedBook.itemMeta = meta
stb.append("\n\nItem to Item repair:") stb.append("\n\nItem to Item repair:")
@ -262,11 +261,11 @@ class DiagnosticExecutor: CASubCommand() {
} }
fun simulateAnvil(player: Player, stb: StringBuilder, left: ItemStack?, right: ItemStack?, result: ItemStack?) { fun simulateAnvil(player: Player, stb: StringBuilder, left: ItemStack?, right: ItemStack?, result: ItemStack?) {
var invView: InventoryView var invView: AnvilView
var event: PrepareAnvilEvent var event: PrepareAnvilEvent
try { try {
val fakeInv = Bukkit.createInventory(player, InventoryType.ANVIL) val fakeInv = Bukkit.createInventory(player, InventoryType.ANVIL)
invView = player.openInventory(fakeInv)!! invView = player.openInventory(fakeInv)!! as AnvilView
event = DependencyManager.createFakeEvent(invView, result) event = DependencyManager.createFakeEvent(invView, result)
} catch (_: Throwable) { } catch (_: Throwable) {
// Help // Help
@ -274,42 +273,40 @@ class DiagnosticExecutor: CASubCommand() {
val anvilTypeField = menuTypeClazz.getField("ANVIL") val anvilTypeField = menuTypeClazz.getField("ANVIL")
val anvilType = anvilTypeField.get(null) val anvilType = anvilTypeField.get(null)
val createMethod = anvilType.javaClass.getMethod("create", HumanEntity::class.java) val createMethod = anvilType.javaClass.getMethod("create", HumanEntity::class.java)
invView = createMethod.invoke(anvilType, player) as InventoryView invView = createMethod.invoke(anvilType, player) as AnvilView
player.openInventory(invView) player.openInventory(invView)
val anvilViewClass = Class.forName("org.bukkit.inventory.view.AnvilView") val constructor = PrepareAnvilEvent::class.java.getConstructor(AnvilView::class.java, ItemStack::class.java)
val constructor = PrepareAnvilEvent::class.java.getConstructor(anvilViewClass, ItemStack::class.java)
event = constructor.newInstance(invView, result) event = constructor.newInstance(invView, result)
} }
val fakeInv = InventoryViewUtil.getInstance().getTopInventory(invView) as AnvilInventory invView.setItem(0, left)
fakeInv.setItem(0, left) invView.setItem(1, right)
fakeInv.setItem(1, right)
val xp = fakeInv.repairCost val xp = invView.repairCost
val maxXp = fakeInv.maximumRepairCost val maxXp = invView.maximumRepairCost
val mergeResult = fakeInv.getItem(2) val mergeResult = invView.getItem(2)
stb.append("\n${if(result == mergeResult) "E" else "Une"}xpected Result") stb.append("\n${if (result == mergeResult) "E" else "Une"}xpected Result")
PrepareAnvilListener().anvilCombineCheck(event) PrepareAnvilListener().anvilCombineCheck(event)
// Now we check if item and xp same // Now we check if item and xp same
stb.append("\nXP/Max XP: ") stb.append("\nXP/Max XP: ")
.append(if(fakeInv.repairCost == xp) "Correct" else "Incorrect") .append(if (invView.repairCost == xp) "Correct" else "Incorrect")
.append("/") .append("/")
.append(if(fakeInv.maximumRepairCost == maxXp) "Correct" else "Incorrect") .append(if (invView.maximumRepairCost == maxXp) "Correct" else "Incorrect")
.append(" (${fakeInv.repairCost} $xp|${fakeInv.maximumRepairCost} $maxXp)") .append(" (${invView.repairCost} $xp|${invView.maximumRepairCost} $maxXp)")
.append("\nMerge result: ") .append("\nMerge result: ")
.append(if(fakeInv.getItem(2) == mergeResult) "Correct" else "Incorrect") .append(if (invView.getItem(2) == mergeResult) "Correct" else "Incorrect")
PrepareAnvilListener.IS_EMPTY_TEST = true PrepareAnvilListener.IS_EMPTY_TEST = true
Bukkit.getPluginManager().callEvent(event) Bukkit.getPluginManager().callEvent(event)
stb.append("\nNull result test: ") stb.append("\nNull result test: ")
.append(if(event.result == null) "Correct" else "Incorrect") .append(if (event.result == null) "Correct" else "Incorrect")
fakeInv.setItem(0, null) invView.setItem(0, null)
fakeInv.setItem(1, null) invView.setItem(1, null)
fakeInv.setItem(2, null) invView.setItem(2, null)
player.closeInventory() player.closeInventory()
} }
@ -327,11 +324,13 @@ class DiagnosticExecutor: CASubCommand() {
map[enchant.key.namespace] = map.getOrDefault(enchant.key.namespace, 0) + 1 map[enchant.key.namespace] = map.getOrDefault(enchant.key.namespace, 0) + 1
} }
stb.append("\nNamespaces: ${ stb.append(
"\nNamespaces: ${
map.entries.stream() map.entries.stream()
.map { (key, value) -> "$key ($value)" } .map { (key, value) -> "$key ($value)" }
.reduce { a, b -> "$a, $b" }.get() .reduce { a, b -> "$a, $b" }.get()
}") }"
)
} }
@ -341,7 +340,6 @@ class DiagnosticExecutor: CASubCommand() {
stb.append("\n\nLast stack trace: ${e.stackTraceToString()}") stb.append("\n\nLast stack trace: ${e.stackTraceToString()}")
} }
} }

View file

@ -14,7 +14,7 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions
import xyz.alexcrea.cuanvil.util.MaterialUtil.customType import xyz.alexcrea.cuanvil.util.MaterialUtil.customType
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
class EditConfigExecutor : CASubCommand() { class EditConfigExecutor : CASubCommand {
override fun allowed(sender: CommandSender): Boolean { override fun allowed(sender: CommandSender): Boolean {
return sender.hasPermission(CustomAnvil.editConfigPermission) return sender.hasPermission(CustomAnvil.editConfigPermission)
@ -72,7 +72,7 @@ class EditConfigExecutor : CASubCommand() {
return return
} }
} else { } else {
enchantToFilter = HashSet(EnchantmentApi.getListByName(args[1].lowercase())) enchantToFilter = HashSet(EnchantmentApi.getByName(args[1].lowercase()))
if (enchantToFilter.isEmpty()) { if (enchantToFilter.isEmpty()) {
sender.sendMessage("No enchantment found with the name \"${args[1]}\"") sender.sendMessage("No enchantment found with the name \"${args[1]}\"")

View file

@ -12,7 +12,7 @@ import xyz.alexcrea.cuanvil.api.EnchantmentApi
import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
class EnchantExecutor : CASubCommand() { class EnchantExecutor : CASubCommand {
override fun allowed(sender: CommandSender): Boolean { override fun allowed(sender: CommandSender): Boolean {
@ -116,7 +116,7 @@ class EnchantExecutor : CASubCommand() {
} }
private fun firstEnchantment(name: String): CAEnchantment? { private fun firstEnchantment(name: String): CAEnchantment? {
val enchants = EnchantmentApi.getListByName(name.lowercase()) val enchants = EnchantmentApi.getByName(name.lowercase())
if (!enchants.isEmpty()) if (!enchants.isEmpty())
return enchants.iterator().next() return enchants.iterator().next()

View file

@ -4,18 +4,20 @@ import com.google.common.collect.ImmutableMap
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
class HelpExecutor: CASubCommand() { class HelpExecutor : CASubCommand {
lateinit var commands: ImmutableMap<String, CASubCommand> lateinit var commands: ImmutableMap<String, CASubCommand>
override fun executeCommand(sender: CommandSender, override fun executeCommand(
sender: CommandSender,
cmd: Command, cmd: Command,
cmdstr: String, cmdstr: String,
args: Array<out String>): Boolean { args: Array<out String>
): Boolean {
val stb = StringBuilder("List of available commands:") val stb = StringBuilder("List of available commands:")
for ((key, cmd) in commands) { for ((key, cmd) in commands) {
if(!cmd.allowed(sender)) continue if (!cmd.allowed(sender)) continue
stb.append("\n- $key: ").append(cmd.description()) stb.append("\n- $key: ").append(cmd.description())
} }
@ -25,6 +27,17 @@ class HelpExecutor: CASubCommand() {
return true return true
} }
override fun allowed(sender: CommandSender): Boolean {
return true
}
override fun tabCompleter(
sender: CommandSender,
args: Array<out String>,
list: MutableList<String>
) {
}
override fun description(): String { override fun description(): String {
return "Help command" return "Help command"
} }

View file

@ -10,12 +10,14 @@ import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.gui.config.global.* import xyz.alexcrea.cuanvil.gui.config.global.*
import xyz.alexcrea.cuanvil.update.UpdateHandler import xyz.alexcrea.cuanvil.update.UpdateHandler
class ReloadExecutor : CASubCommand() { class ReloadExecutor : CASubCommand {
override fun executeCommand(sender: CommandSender, override fun executeCommand(
sender: CommandSender,
cmd: Command, cmd: Command,
cmdstr: String, cmdstr: String,
args: Array<out String>): Boolean { args: Array<out String>
): Boolean {
if (!allowed(sender)) { if (!allowed(sender)) {
sender.sendMessage("§cYou do not have permission to reload the config") sender.sendMessage("§cYou do not have permission to reload the config")
return false return false
@ -38,6 +40,13 @@ class ReloadExecutor : CASubCommand() {
return sender.hasPermission(CustomAnvil.commandReloadPermission) return sender.hasPermission(CustomAnvil.commandReloadPermission)
} }
override fun tabCompleter(
sender: CommandSender,
args: Array<out String>,
list: MutableList<String>
) {
}
override fun description(): String { override fun description(): String {
return "Reload the configuration of this plugin" return "Reload the configuration of this plugin"
} }

View file

@ -1,6 +1,5 @@
package xyz.alexcrea.cuanvil.dependency package xyz.alexcrea.cuanvil.dependency
import com.maddoxh.superEnchants.SuperEnchants
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import org.bukkit.Bukkit import org.bukkit.Bukkit
@ -10,16 +9,14 @@ import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.anvil.AnvilCost import xyz.alexcrea.cuanvil.anvil.AnvilCost
import xyz.alexcrea.cuanvil.anvil.AnvilUseType import xyz.alexcrea.cuanvil.anvil.AnvilUseType
import xyz.alexcrea.cuanvil.api.event.listener.CAClickResultBypassEvent import xyz.alexcrea.cuanvil.api.event.listener.CAClickResultBypassEvent
import xyz.alexcrea.cuanvil.api.event.listener.CAEarlyPreAnvilBypassEvent import xyz.alexcrea.cuanvil.api.event.listener.CAEarlyPreAnvilBypassEvent
import xyz.alexcrea.cuanvil.api.event.listener.CAPreAnvilBypassEvent import xyz.alexcrea.cuanvil.api.event.listener.CAPreAnvilBypassEvent
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResult2Event import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency
import xyz.alexcrea.cuanvil.dependency.gui.GenericExternGuiTester import xyz.alexcrea.cuanvil.dependency.gui.GenericExternGuiTester
@ -33,17 +30,16 @@ import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError
import java.lang.IllegalStateException import java.lang.reflect.Constructor
import java.util.logging.Level import java.util.logging.Level
@Suppress("UnstableApiUsage")
object DependencyManager { object DependencyManager {
lateinit var scheduler: TaskScheduler lateinit var scheduler: TaskScheduler
lateinit var packetManager: PacketManager lateinit var packetManager: PacketManager
var externGuiTester: GenericExternGuiTester = GenericExternGuiTester() var externGuiTester: GenericExternGuiTester = GenericExternGuiTester()
val inTesting = externGuiTester.isInTest()
var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null
var ecoEnchantCompatibility: EcoEnchantDependency? = null var ecoEnchantCompatibility: EcoEnchantDependency? = null
var hasEcoItem: Boolean = false var hasEcoItem: Boolean = false
@ -125,7 +121,7 @@ object DependencyManager {
genericDependencies.add(GenericPluginDependency(pluginManager.getPlugin("ItemsAdder")!!)) genericDependencies.add(GenericPluginDependency(pluginManager.getPlugin("ItemsAdder")!!))
if (pluginManager.isPluginEnabled("SuperEnchants")) { if (pluginManager.isPluginEnabled("SuperEnchants")) {
val compatibility = SuperEnchantDependency(pluginManager.getPlugin("SuperEnchants")!! as SuperEnchants) val compatibility = SuperEnchantDependency(pluginManager.getPlugin("SuperEnchants")!!)
if (compatibility.registerEnchantments()) if (compatibility.registerEnchantments())
genericDependencies.add(compatibility) genericDependencies.add(compatibility)
} }
@ -176,11 +172,11 @@ object DependencyManager {
) )
} }
private fun logExceptionAndClear(target: CommandSender, inventory: Inventory, e: Exception) { private fun logExceptionAndClear(view: AnvilView, e: Exception) {
// Just in case to avoid illegal items // Just in case to avoid illegal items
inventory.setItem(ANVIL_OUTPUT_SLOT, null) view.setItem(ANVIL_OUTPUT_SLOT, null)
logException(target, e) logException(view.player, e)
} }
// Return true if should bypass (either by a dependency or error) // Return true if should bypass (either by a dependency or error)
@ -189,7 +185,7 @@ object DependencyManager {
try { try {
return earlyUnsafeTryEventPreAnvilBypass(event, player) return earlyUnsafeTryEventPreAnvilBypass(event, player)
} catch (e: Exception) { } catch (e: Exception) {
logExceptionAndClear(event.view.player, event.inventory, e) logExceptionAndClear(event.view, e)
return true return true
} }
} }
@ -215,7 +211,7 @@ object DependencyManager {
try { try {
return unsafeTryEventPreAnvilBypass(event, player) return unsafeTryEventPreAnvilBypass(event, player)
} catch (e: Exception) { } catch (e: Exception) {
logExceptionAndClear(event.view.player, event.inventory, e) logExceptionAndClear(event.view, e)
return true return true
} }
} }
@ -245,40 +241,39 @@ object DependencyManager {
// Return null if there was an issue // Return null if there was an issue
fun tryTreatAnvilResult( fun tryTreatAnvilResult(
view: InventoryView, view: AnvilView,
inventory: Inventory, // TODO REMOVE, use view instead on legacy removal
player: HumanEntity, player: HumanEntity,
result: ItemStack, result: ItemStack,
useType: AnvilUseType, useType: AnvilUseType,
cost: AnvilCost cost: AnvilCost
): ItemStack? { ): ItemStack? {
val treatEvent = CATreatAnvilResult2Event(view, inventory, useType, result, cost) val treatEvent = CATreatAnvilResultEvent(view, useType, result, cost)
try { try {
unsafeTryTreatAnvilResult(treatEvent) unsafeTryTreatAnvilResult(treatEvent)
return treatEvent.result return treatEvent.result
} catch (e: Exception) { } catch (e: Exception) {
logExceptionAndClear(player, inventory, e) logExceptionAndClear(view, e)
return null return null
} }
} }
private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResult2Event) { private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResultEvent) {
Bukkit.getPluginManager().callEvent(event) Bukkit.getPluginManager().callEvent(event)
excellentEnchantsCompatibility?.treatAnvilResult(event) excellentEnchantsCompatibility?.treatAnvilResult(event)
} }
// Return true if should bypass (either by a dependency or error) // Return true if should bypass (either by a dependency or error)
fun tryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean { fun tryClickAnvilResultBypass(event: InventoryClickEvent, view: AnvilView): Boolean {
try { try {
return unsafeTryClickAnvilResultBypass(event, inventory) return unsafeTryClickAnvilResultBypass(event, view)
} catch (e: Exception) { } catch (e: Exception) {
logExceptionAndClear(event.view.player, event.inventory, e) logExceptionAndClear(view, e)
return true return true
} }
} }
private fun unsafeTryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean { private fun unsafeTryClickAnvilResultBypass(event: InventoryClickEvent, view: AnvilView): Boolean {
// Run the event // Run the event
val bypassEvent = CAClickResultBypassEvent(event) val bypassEvent = CAClickResultBypassEvent(event)
Bukkit.getPluginManager().callEvent(bypassEvent) Bukkit.getPluginManager().callEvent(bypassEvent)
@ -286,10 +281,10 @@ object DependencyManager {
var bypass = bypassEvent.isCancelled var bypass = bypassEvent.isCancelled
// Test if disenchantment used event click // Test if disenchantment used event click
if (!bypass && (disenchantmentCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true if (!bypass && (disenchantmentCompatibility?.testAnvilResult(event, view) == true)) bypass = true
// Test if haven bag used event click // Test if haven bag used event click
if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, view) == true)) bypass = true
// Test if disenchantment used event click // Test if disenchantment used event click
if (!bypass && (excellentEnchantsCompatibility?.testAnvilResult(event) == true)) bypass = true if (!bypass && (excellentEnchantsCompatibility?.testAnvilResult(event) == true)) bypass = true
@ -299,10 +294,10 @@ object DependencyManager {
} }
// Test if the inventory is a gui(version specific) // Test if the inventory is a gui(version specific)
if (!bypass && externGuiTester.testIfGui(event.view)) bypass = true if (!bypass && externGuiTester.testIfGui(view)) bypass = true
// Test if in an ax player warp rating gui // Test if in an ax player warp rating gui
if (!bypass && (axPlayerWarpsCompatibility?.testIfGui(event.view.player) == true)) bypass = true if (!bypass && (axPlayerWarpsCompatibility?.testIfGui(view.player) == true)) bypass = true
return bypass return bypass
} }
@ -342,14 +337,10 @@ object DependencyManager {
private val prepareAnvilConstructor = private val prepareAnvilConstructor =
PrepareAnvilEvent::class.java.constructors.first() PrepareAnvilEvent::class.java.constructors.first() as Constructor<PrepareAnvilEvent>
fun createFakeEvent(view: InventoryView, result: ItemStack?): PrepareAnvilEvent { fun createFakeEvent(view: AnvilView, result: ItemStack?): PrepareAnvilEvent {
val result = prepareAnvilConstructor.newInstance(view, result) return prepareAnvilConstructor.newInstance(view, result)
if(result !is PrepareAnvilEvent)
throw IllegalStateException("Could not create a PrepareAnvilEvent ?")
return result
} }
} }

View file

@ -10,32 +10,6 @@ object MinecraftVersionUtil {
if (version.major != 1) return null if (version.major != 1) return null
return when (version.minor) { return when (version.minor) {
17 -> when (version.patch) {
0, 1 -> "1_17R1"
else -> null
}
18 -> when (version.patch) {
0, 1 -> "1_18R1"
2 -> "1_18R2"
else -> null
}
19 -> when (version.patch) {
0, 1, 2 -> "1_19R1"
3 -> "1_19R2"
4 -> "1_19R3"
else -> null
}
20 -> when (version.patch) {
0, 1 -> "1_20R1"
2 -> "1_20R2"
3, 4 -> "1_20R3"
5, 6 -> "1_20R4"
else -> null
}
21 -> when (version.patch) { 21 -> when (version.patch) {
0, 1 -> "1_21R1" 0, 1 -> "1_21R1"
2, 3 -> "1_21R2" 2, 3 -> "1_21R2"
@ -46,9 +20,16 @@ object MinecraftVersionUtil {
11 -> "1_21R7" 11 -> "1_21R7"
else -> null else -> null
} }
//TODO need to continue updating that for anvil gui test dependency....
else -> null else -> null
} }
} }
val isTooNewForSpigot: Boolean
get() {
return UpdateUtils.currentMinecraftVersion().major != 1
}
} }

View file

@ -1,10 +1,11 @@
package xyz.alexcrea.cuanvil.dependency.gui package xyz.alexcrea.cuanvil.dependency.gui
import org.bukkit.inventory.InventoryView import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
import java.lang.reflect.Method import java.lang.reflect.Method
@Suppress("UnstableApiUsage")
class GenericExternGuiTester { class GenericExternGuiTester {
companion object { companion object {
@ -21,7 +22,7 @@ class GenericExternGuiTester {
var testedClass: String? = null var testedClass: String? = null
lateinit var getHandleMethod: Method lateinit var getHandleMethod: Method
private fun getContainerClass(view: InventoryView): Class<Any>? { private fun getContainerClass(view: AnvilView): Class<Any>? {
if(!testedClass.contentEquals(view.javaClass.name)) if(!testedClass.contentEquals(view.javaClass.name))
return null return null
@ -64,11 +65,11 @@ class GenericExternGuiTester {
} }
// Try if were in another plugin anvil inventory // Try if were in another plugin anvil inventory
fun testIfGui(inventory: InventoryView): Boolean { fun testIfGui(view: AnvilView): Boolean {
// In case we are in a test environment // In case we are in a test environment
if(isInTest()) return false if(isInTest()) return false
val clazz = getContainerClass(inventory) ?: return false val clazz = getContainerClass(view) ?: return false
val clazzName = clazz.name val clazzName = clazz.name
if(!PlatformUtil.isPaper){ if(!PlatformUtil.isPaper){

View file

@ -3,7 +3,7 @@ package xyz.alexcrea.cuanvil.dependency.packet
import org.bukkit.Bukkit import org.bukkit.Bukkit
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil
import xyz.alexcrea.cuanvil.dependency.packet.versions.* import xyz.alexcrea.cuanvil.dependency.packet.versions.PaperPacketManager
import xyz.alexcrea.cuanvil.update.UpdateUtils import xyz.alexcrea.cuanvil.update.UpdateUtils
object PacketManagerSelector { object PacketManagerSelector {
@ -12,7 +12,7 @@ object PacketManagerSelector {
fun selectPacketManager(forceProtocolib: Boolean): PacketManager { fun selectPacketManager(forceProtocolib: Boolean): PacketManager {
// Try to find version // Try to find version
if(DependencyManager.inTesting) if(DependencyManager.externGuiTester.isInTest())
return NoPacketManager() return NoPacketManager()
return if (forceProtocolib) return if (forceProtocolib)

View file

@ -12,8 +12,8 @@ import org.bukkit.entity.Player
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.anvil.AnvilCost import xyz.alexcrea.cuanvil.anvil.AnvilCost
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError
@ -21,6 +21,7 @@ import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import java.util.logging.Level import java.util.logging.Level
import kotlin.reflect.KClass import kotlin.reflect.KClass
@Suppress("UnstableApiUsage")
class DisenchantmentDependency { class DisenchantmentDependency {
init { init {
@ -59,14 +60,14 @@ class DisenchantmentDependency {
DisenchantEvent.onEvent(event) DisenchantEvent.onEvent(event)
if (event.result != null) { if (event.result != null) {
CustomAnvil.log("Detected pre anvil item extract bypass.") CustomAnvil.log("Detected pre anvil item extract bypass.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost)) AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true return true
} }
ShatterEvent.onEvent(event) ShatterEvent.onEvent(event)
if (event.result != null) { if (event.result != null) {
CustomAnvil.log("Detected pre anvil split enchant bypass.") CustomAnvil.log("Detected pre anvil split enchant bypass.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost)) AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true return true
} }
@ -74,18 +75,18 @@ class DisenchantmentDependency {
return false return false
} }
fun testAnvilResult(event: InventoryClickEvent, inventory: AnvilInventory): Boolean { fun testAnvilResult(event: InventoryClickEvent, view: AnvilView): Boolean {
val previousResultSlot = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone() val previousResultSlot = view.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
// Test event if change the result // Test event if change the result
DisenchantClickEvent.onEvent(event) DisenchantClickEvent.onEvent(event)
if (!testAnvilInventoryChange(inventory, previousResultSlot) || event.isCancelled) { if (!testAnvilChange(view, previousResultSlot) || event.isCancelled) {
CustomAnvil.log("Detected anvil click item extract bypass.") CustomAnvil.log("Detected anvil click item extract bypass.")
return true return true
} }
ShatterClickEvent.onEvent(event) ShatterClickEvent.onEvent(event)
if (!testAnvilInventoryChange(inventory, previousResultSlot) || event.isCancelled) { if (!testAnvilChange(view, previousResultSlot) || event.isCancelled) {
CustomAnvil.log("Detected anvil click split enchant bypass.") CustomAnvil.log("Detected anvil click split enchant bypass.")
return true return true
} }
@ -93,8 +94,8 @@ class DisenchantmentDependency {
return false return false
} }
private fun testAnvilInventoryChange(inventory: AnvilInventory, previous: ItemStack?): Boolean { private fun testAnvilChange(view: AnvilView, previous: ItemStack?): Boolean {
val currentResult = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT) val currentResult = view.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)
return currentResult == previous return currentResult == previous
} }

View file

@ -5,6 +5,7 @@ import com.willfp.ecoenchants.enchant.EcoEnchant
import com.willfp.ecoenchants.enchant.EcoEnchants import com.willfp.ecoenchants.enchant.EcoEnchants
import com.willfp.ecoenchants.enchant.UtilKt import com.willfp.ecoenchants.enchant.UtilKt
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.Bukkit
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.plugin.Plugin import org.bukkit.plugin.Plugin
import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.api.EnchantmentApi
@ -22,11 +23,11 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) {
try { try {
Class.forName("com.willfp.ecoenchants.enchant.EcoEnchants") Class.forName("com.willfp.ecoenchants.enchant.EcoEnchants")
isLegacy = false isLegacy = false
} catch (_: ClassNotFoundException) { } catch(_: ClassNotFoundException) {
} }
this.isLegacy = isLegacy; this.isLegacy = isLegacy;
if (isLegacy) { if(isLegacy) {
this.legacyDependency = LegacyEcoEnchantDependency() this.legacyDependency = LegacyEcoEnchantDependency()
} else { } else {
this.legacyDependency = null this.legacyDependency = null
@ -34,25 +35,27 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) {
} }
public fun getEcoLevelLimit(): Int { fun getEcoLevelLimit(): Int {
return UtilKt.infiniteIfNegative((ecoEnchantPlugin as EcoPlugin).configYml.getInt("anvil.enchant-limit")) return UtilKt.infiniteIfNegative((ecoEnchantPlugin as EcoPlugin).configYml.getInt("anvil.enchant-limit"))
} }
fun disableAnvilListener() { fun disableAnvilListener() {
PrepareAnvilEvent.getHandlerList().unregister(this.ecoEnchantPlugin) PrepareAnvilEvent.getHandlerList().unregister(this.ecoEnchantPlugin)
// I don't like that but modern ee use eco prepare anvil event
PrepareAnvilEvent.getHandlerList().unregister(Bukkit.getPluginManager().getPlugin("eco")!!)
} }
private var ecoEnchantOldEnchantments: MutableSet<EcoEnchant>? = null private var ecoEnchantOldEnchantments: MutableSet<EcoEnchant>? = null
fun registerEnchantments() { fun registerEnchantments() {
CustomAnvil.instance.logger.info("Preparing Eco Enchant compatibility...") CustomAnvil.instance.logger.info("Preparing Eco Enchant compatibility...")
if (isLegacy) { if(isLegacy) {
legacyDependency!!.registerEnchantments(); legacyDependency!!.registerEnchantments();
return return
} }
val enchantments = EcoEnchants.INSTANCE.values() val enchantments = EcoEnchants.INSTANCE.values()
for (ecoEnchant in enchantments) { 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.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)) EnchantmentApi.registerEnchantment(CAEcoEnchant(ecoEnchant))
} }
@ -63,24 +66,24 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) {
} }
fun handleConfigReload() { fun handleConfigReload() {
if (isLegacy) { if(isLegacy) {
legacyDependency!!.handleConfigReload() legacyDependency!!.handleConfigReload()
return return
} }
// Should not happen in known case. // Should not happen in known case.
if (this.ecoEnchantOldEnchantments == null) return if(this.ecoEnchantOldEnchantments == null) return
val newEnchantments = EcoEnchants.INSTANCE.values() val newEnchantments = EcoEnchants.INSTANCE.values()
// Add new enchantments // Add new enchantments
for (ecoEnchant in newEnchantments) for(ecoEnchant in newEnchantments)
if (!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant)) if(!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant))
EnchantmentApi.registerEnchantment(CAEcoEnchant(ecoEnchant)) EnchantmentApi.registerEnchantment(CAEcoEnchant(ecoEnchant))
// Remove old enchantments that not now currently used // Remove old enchantments that not now currently used
this.ecoEnchantOldEnchantments!!.removeAll(newEnchantments) this.ecoEnchantOldEnchantments!!.removeAll(newEnchantments)
for (oldEnchantment in this.ecoEnchantOldEnchantments!!) { for(oldEnchantment in this.ecoEnchantOldEnchantments!!) {
EnchantmentApi.unregisterEnchantment(oldEnchantment.enchantment) EnchantmentApi.unregisterEnchantment(oldEnchantment.enchantment)
} }

View file

@ -2,15 +2,17 @@ package xyz.alexcrea.cuanvil.dependency.plugins
import org.bukkit.event.Event import org.bukkit.event.Event
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.inventory.view.AnvilView
import org.bukkit.plugin.Plugin import org.bukkit.plugin.Plugin
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
@Suppress("UnstableApiUsage")
class EnchantedBookDependency(plugin: Plugin) : GenericPluginDependency(plugin) { class EnchantedBookDependency(plugin: Plugin) : GenericPluginDependency(plugin) {
override fun testAnvilResult(event: InventoryClickEvent): Boolean { override fun testAnvilResult(event: InventoryClickEvent): Boolean {
val view = event.view val view = event.view as? AnvilView ?: return false
val inv = event.inventory val inv = event.inventory
//TODO use view here (v2) //TODO use view here (v2)

View file

@ -30,28 +30,29 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
"disable_anvil, " + "disable_anvil, " +
"incompatible_vanilla_enchantments, " + "incompatible_vanilla_enchantments, " +
"incompatible_custom_enchantments and max_level " + "incompatible_custom_enchantments and max_level " +
"configuration values.") "configuration values."
)
} }
fun disableAnvilListener(){ fun disableAnvilListener() {
PrepareAnvilEvent.getHandlerList().unregister(this.enchantmentSquaredPlugin) PrepareAnvilEvent.getHandlerList().unregister(this.enchantmentSquaredPlugin)
// Find the anvil click event // Find the anvil click event
var toRemove: AnvilListener? = null var toRemove: AnvilListener? = null
for (registered in InventoryClickEvent.getHandlerList().registeredListeners) { for (registered in InventoryClickEvent.getHandlerList().registeredListeners) {
val listener = registered.listener val listener = registered.listener
if(listener is AnvilListener) { if (listener is AnvilListener) {
toRemove = listener toRemove = listener
break break
} }
} }
if(toRemove != null) if (toRemove != null)
InventoryClickEvent.getHandlerList().unregister(toRemove) InventoryClickEvent.getHandlerList().unregister(toRemove)
} }
fun registerEnchantments(){ fun registerEnchantments() {
CustomAnvil.instance.logger.info("Preparing Enchantment Squared compatibility...") CustomAnvil.instance.logger.info("Preparing Enchantment Squared compatibility...")
// Register enchantments // Register enchantments
@ -69,20 +70,21 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
fun getEnchantmentsSquared(item: ItemStack, enchantments: MutableMap<CAEnchantment, Int>) { fun getEnchantmentsSquared(item: ItemStack, enchantments: MutableMap<CAEnchantment, Int>) {
val customEnchants = CustomEnchantManager.getInstance().getItemsEnchantsFromPDC(item) val customEnchants = CustomEnchantManager.getInstance().getItemsEnchantsFromPDC(item)
customEnchants.forEach{ customEnchants.forEach { (enchantment, level) ->
(enchantment, level ) -> enchantments[getWrappedEnchant(enchantment)] = level enchantments[getWrappedEnchant(enchantment)] = level
} }
} }
fun getKeyFromEnchant(enchant: CustomEnchant): NamespacedKey{ fun getKeyFromEnchant(enchant: CustomEnchant): NamespacedKey {
return NamespacedKey.fromString(enchant.type.lowercase(Locale.getDefault()), this.enchantmentSquaredPlugin)!! return NamespacedKey.fromString(enchant.type.lowercase(Locale.getDefault()), this.enchantmentSquaredPlugin)!!
} }
private fun getWrappedEnchant(enchant: CustomEnchant): CAEnchantment { private fun getWrappedEnchant(enchant: CustomEnchant): CAEnchantment {
return CAEnchantment.getByKey(getKeyFromEnchant(enchant))!! return CAEnchantment.getByKey(getKeyFromEnchant(enchant))!!
} }
fun registerPluginConfiguration(){ fun registerPluginConfiguration() {
CustomAnvil.instance.logger.info("Preparing Enchantment Squared config...") CustomAnvil.instance.logger.info("Preparing Enchantment Squared config...")
// Prepare enchantments // Prepare enchantments
@ -99,7 +101,7 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
CustomAnvil.instance.logger.info("Enchantment Squared should now work as expected !") CustomAnvil.instance.logger.info("Enchantment Squared should now work as expected !")
} }
private fun writeMissingGroups(){ private fun writeMissingGroups() {
// Write group that do not exist on custom anvil. // Write group that do not exist on custom anvil.
val shield = IncludeGroup("shield") val shield = IncludeGroup("shield")
shield.addToPolicy(Material.SHIELD.key) shield.addToPolicy(Material.SHIELD.key)
@ -114,7 +116,7 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
MaterialGroupApi.addMaterialGroup(trinkets) MaterialGroupApi.addMaterialGroup(trinkets)
} }
private fun writeMaterialRestriction(esEnchantments: List<CAEnchantSquaredEnchantment>){ private fun writeMaterialRestriction(esEnchantments: List<CAEnchantSquaredEnchantment>) {
for (enchantment in esEnchantments) { for (enchantment in esEnchantments) {
val conflict = ConflictBuilder("restriction_${enchantment.key.key}", CustomAnvil.instance) val conflict = ConflictBuilder("restriction_${enchantment.key.key}", CustomAnvil.instance)
conflict.addEnchantment(enchantment) conflict.addEnchantment(enchantment)
@ -125,7 +127,7 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
// Get allowed groups // Get allowed groups
for (esGroup in enchantment.enchant.compatibleItems) { for (esGroup in enchantment.enchant.compatibleItems) {
val caGroup = esGroupToCAGroup(esGroup) val caGroup = esGroupToCAGroup(esGroup)
if(caGroup == null){ if (caGroup == null) {
CustomAnvil.instance.logger.info("Could not find equivalent custom anvil group for $esGroup") CustomAnvil.instance.logger.info("Could not find equivalent custom anvil group for $esGroup")
continue continue
} }
@ -136,7 +138,7 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
} }
} }
private fun writeEnchantmentConflicts(esEnchantments: List<CAEnchantSquaredEnchantment>){ private fun writeEnchantmentConflicts(esEnchantments: List<CAEnchantSquaredEnchantment>) {
val otherEnchants = ArrayList<CAEnchantment>() val otherEnchants = ArrayList<CAEnchantment>()
otherEnchants.addAll(CAEnchantmentRegistry.getInstance().values()) otherEnchants.addAll(CAEnchantmentRegistry.getInstance().values())
@ -145,14 +147,14 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
// find conflicting enchantment. // find conflicting enchantment.
for (otherEnchant in otherEnchants) { for (otherEnchant in otherEnchants) {
if(enchantment.enchant.conflictsWithEnchantment(otherEnchant.name)){ if (enchantment.enchant.conflictsWithEnchantment(otherEnchant.name)) {
writeConflict(enchantment, otherEnchant) writeConflict(enchantment, otherEnchant)
} }
} }
} }
} }
private fun writeConflict(enchantment1: CAEnchantment, enchantment2: CAEnchantment){ private fun writeConflict(enchantment1: CAEnchantment, enchantment2: CAEnchantment) {
val conflict = ConflictBuilder("${enchantment1.name}_with_${enchantment2.name}_conflict", CustomAnvil.instance) val conflict = ConflictBuilder("${enchantment1.name}_with_${enchantment2.name}_conflict", CustomAnvil.instance)
conflict.addEnchantment(enchantment1).addEnchantment(enchantment2) conflict.addEnchantment(enchantment1).addEnchantment(enchantment2)
@ -165,7 +167,7 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
* Transform an Enchantment Squared group to a Custom Anvil group * Transform an Enchantment Squared group to a Custom Anvil group
*/ */
private fun esGroupToCAGroup(esGroup: String): String? { private fun esGroupToCAGroup(esGroup: String): String? {
return when(esGroup){ return when (esGroup) {
"SWORDS" -> "swords" "SWORDS" -> "swords"
"BOWS" -> "bow" "BOWS" -> "bow"
"CROSSBOWS" -> "crossbow" "CROSSBOWS" -> "crossbow"

View file

@ -8,8 +8,8 @@ import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.RegisteredListener import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.api.EnchantmentApi
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResult2Event
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5_4Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5_4Enchantment
@ -17,10 +17,10 @@ import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEEEnchantment
import java.lang.reflect.Method import java.lang.reflect.Method
import su.nightexpress.excellentenchants.api.EnchantRegistry as V5EnchantRegistry import su.nightexpress.excellentenchants.api.EnchantRegistry as V5EnchantRegistry
import su.nightexpress.excellentenchants.enchantment.impl.universal.CurseOfFragilityEnchant as LegacyCurseOfFragilityEnchant import su.nightexpress.excellentenchants.enchantment.impl.universal.CurseOfFragilityEnchant as LegacyCurseOfFragilityEnchant
import su.nightexpress.excellentenchants.manager.listener.AnvilListener as V5AnvilListener
import su.nightexpress.excellentenchants.enchantment.listener.AnvilListener as PreV5AnvilListener import su.nightexpress.excellentenchants.enchantment.listener.AnvilListener as PreV5AnvilListener
import su.nightexpress.excellentenchants.enchantment.listener.EnchantAnvilListener as LegacyAnvilListener import su.nightexpress.excellentenchants.enchantment.listener.EnchantAnvilListener as LegacyAnvilListener
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry as LegacyEnchantRegistry import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry as LegacyEnchantRegistry
import su.nightexpress.excellentenchants.manager.listener.AnvilListener as V5AnvilListener
import su.nightexpress.excellentenchants.registry.EnchantRegistry as PreV5EnchantRegistry import su.nightexpress.excellentenchants.registry.EnchantRegistry as PreV5EnchantRegistry
// I don't like that I need to support older version. if I could just drop older support it would be sooo nice // I don't like that I need to support older version. if I could just drop older support it would be sooo nice
@ -53,7 +53,7 @@ class ExcellentEnchantsDependency {
if (listenerVersion == null) { if (listenerVersion == null) {
CustomAnvil.instance.logger.severe("Found issue with listener of Excellent Enchants. compatiblity is broken. please contact CustomAnvil devs") CustomAnvil.instance.logger.severe("Found issue with listener of Excellent Enchants. compatiblity is broken. please contact CustomAnvil devs")
} else{ } else {
CustomAnvil.log("Support version: " + listenerVersion.name) CustomAnvil.log("Support version: " + listenerVersion.name)
} }
@ -171,6 +171,7 @@ class ExcellentEnchantsDependency {
ListenerVersion.V5, ListenerVersion.V5,
ListenerVersion.V5_4, ListenerVersion.V5_4,
-> this.usedAnvilListener = v5AnvilListener!! -> this.usedAnvilListener = v5AnvilListener!!
ListenerVersion.PRE_V5 -> this.usedAnvilListener = preV5AnvilListener!! ListenerVersion.PRE_V5 -> this.usedAnvilListener = preV5AnvilListener!!
ListenerVersion.LEGACY -> this.usedAnvilListener = legacyAnvilListener!! ListenerVersion.LEGACY -> this.usedAnvilListener = legacyAnvilListener!!
null -> {} null -> {}
@ -219,7 +220,7 @@ class ExcellentEnchantsDependency {
return handleRechargeMethod.invoke(this.usedAnvilListener, event, first, second) as Boolean return handleRechargeMethod.invoke(this.usedAnvilListener, event, first, second) as Boolean
} }
fun treatAnvilResult(event: CATreatAnvilResult2Event) { fun treatAnvilResult(event: CATreatAnvilResultEvent) {
val result = event.result ?: return val result = event.result ?: return
val first: ItemStack = treatInput(event.leftItem) val first: ItemStack = treatInput(event.leftItem)
@ -238,6 +239,7 @@ class ExcellentEnchantsDependency {
ListenerVersion.V5_3, ListenerVersion.V5_3,
ListenerVersion.V5_4, ListenerVersion.V5_4,
-> v5AnvilListener!!.onClickAnvil(event) -> v5AnvilListener!!.onClickAnvil(event)
ListenerVersion.PRE_V5 -> preV5AnvilListener!!.onClickAnvil(event) ListenerVersion.PRE_V5 -> preV5AnvilListener!!.onClickAnvil(event)
ListenerVersion.LEGACY -> legacyAnvilListener!!.onClickAnvil(event) ListenerVersion.LEGACY -> legacyAnvilListener!!.onClickAnvil(event)
null -> {} null -> {}

View file

@ -24,7 +24,7 @@ open class GenericPluginDependency(protected open val plugin: Plugin, private va
} }
} }
open fun fillPreAnvil(preAnvil: ArrayList<RegisteredListener>){ open fun fillPreAnvil(preAnvil: ArrayList<RegisteredListener>) {
// get PreAnvil and PostAnvil listeners // get PreAnvil and PostAnvil listeners
for (registeredListener in PrepareAnvilEvent.getHandlerList().registeredListeners) { for (registeredListener in PrepareAnvilEvent.getHandlerList().registeredListeners) {
@ -35,12 +35,13 @@ open class GenericPluginDependency(protected open val plugin: Plugin, private va
protected open fun fillPostAnvil( protected open fun fillPostAnvil(
postAnvil: ArrayList<RegisteredListener>, postAnvil: ArrayList<RegisteredListener>,
preAnvil: ArrayList<RegisteredListener>) { preAnvil: ArrayList<RegisteredListener>
) {
} }
open fun testPrepareAnvil(event: PrepareAnvilEvent): Boolean { open fun testPrepareAnvil(event: PrepareAnvilEvent): Boolean {
if(!testPrepare) return false if (!testPrepare) return false
val previousResult = event.result val previousResult = event.result
event.result = null event.result = null
@ -61,7 +62,7 @@ open class GenericPluginDependency(protected open val plugin: Plugin, private va
} }
open fun testAnvilResult(event: InventoryClickEvent): Boolean { open fun testAnvilResult(event: InventoryClickEvent): Boolean {
if(!testPrepare) return false if (!testPrepare) return false
for (registeredListener in postAnvil) { for (registeredListener in postAnvil) {
// We do not want error from another plugin to be our fault // We do not want error from another plugin to be our fault

View file

@ -4,7 +4,7 @@ import io.delilaheve.CustomAnvil
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.view.AnvilView
import org.bukkit.plugin.RegisteredListener import org.bukkit.plugin.RegisteredListener
import valorless.havenbags.HavenBags import valorless.havenbags.HavenBags
import valorless.havenbags.features.BagSkin import valorless.havenbags.features.BagSkin
@ -13,6 +13,7 @@ import xyz.alexcrea.cuanvil.anvil.AnvilCost
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
@Suppress("UnstableApiUsage")
class HavenBagsDependency { class HavenBagsDependency {
init { init {
@ -54,14 +55,14 @@ class HavenBagsDependency {
bagSkin.onPrepareAnvil(event) bagSkin.onPrepareAnvil(event)
if (event.result != null) { if (event.result != null) {
CustomAnvil.log("Detected pre anvil heaven bag anvil skin.") CustomAnvil.log("Detected pre anvil heaven bag anvil skin.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost)) AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true return true
} }
bagUpgrade.onPrepareAnvil(event) bagUpgrade.onPrepareAnvil(event)
if (event.result != null) { if (event.result != null) {
CustomAnvil.log("Detected pre anvil heaven bag anvil upgrade.") CustomAnvil.log("Detected pre anvil heaven bag anvil upgrade.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost)) AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true return true
} }
@ -69,8 +70,8 @@ class HavenBagsDependency {
return false return false
} }
fun testAnvilResult(event: InventoryClickEvent, inventory: AnvilInventory): Boolean { fun testAnvilResult(event: InventoryClickEvent, view: AnvilView): Boolean {
val result = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone() val result = view.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
if (HavenBags.IsBag(result)) { if (HavenBags.IsBag(result)) {
CustomAnvil.log("Detected anvil click haven bag bypass.") CustomAnvil.log("Detected anvil click haven bag bypass.")

View file

@ -6,7 +6,6 @@ import org.bukkit.NamespacedKey
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.Plugin import org.bukkit.plugin.Plugin
@Suppress("DEPRECATION")
class ItemsAdderDependency(plugin: Plugin) : GenericPluginDependency(plugin) { class ItemsAdderDependency(plugin: Plugin) : GenericPluginDependency(plugin) {
var isLoaded: Boolean = false var isLoaded: Boolean = false
get() { get() {
@ -18,19 +17,19 @@ class ItemsAdderDependency(plugin: Plugin) : GenericPluginDependency(plugin) {
} }
fun tryClone(item: ItemStack): ItemStack? { fun tryClone(item: ItemStack): ItemStack? {
if(!isLoaded) return null if (!isLoaded) return null
val customItem = CustomStack.byItemStack(item) ?: return null val customItem = CustomStack.byItemStack(item) ?: return null
return CustomStack.getInstance(customItem.namespacedID)?.itemStack return CustomStack.getInstance(customItem.namespacedID)?.itemStack
} }
fun fromKey(key: NamespacedKey): ItemStack? { fun fromKey(key: NamespacedKey): ItemStack? {
if(!isLoaded) return null if (!isLoaded) return null
return CustomStack.getInstance(key.toString())?.itemStack return CustomStack.getInstance(key.toString())?.itemStack
} }
fun getKey(item: ItemStack) : NamespacedKey? { fun getKey(item: ItemStack): NamespacedKey? {
if(!isLoaded) return null if (!isLoaded) return null
val customItem = CustomStack.byItemStack(item) ?: return null val customItem = CustomStack.byItemStack(item) ?: return null
return NamespacedKey.fromString(customItem.namespacedID) return NamespacedKey.fromString(customItem.namespacedID)

View file

@ -10,20 +10,13 @@ class LegacyEcoEnchantDependency {
private var ecoEnchantOldEnchantments: MutableSet<EcoEnchant>? = null private var ecoEnchantOldEnchantments: MutableSet<EcoEnchant>? = 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() { fun registerEnchantments() {
val enchantments = EcoEnchants.values() val enchantments = EcoEnchants.values()
for (ecoEnchant in enchantments) { for (ecoEnchant in enchantments) {
// As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant. ecoEnchant as Enchantment
unregisterEnchantment(ecoEnchant)
registerEnchantment(ecoEnchant, ecoEnchant) 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))
} }
ecoEnchantOldEnchantments = HashSet(enchantments) ecoEnchantOldEnchantments = HashSet(enchantments)
@ -38,13 +31,13 @@ class LegacyEcoEnchantDependency {
// Add new enchantments // Add new enchantments
for (ecoEnchant in newEnchantments) for (ecoEnchant in newEnchantments)
if (!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant)) if (!this.ecoEnchantOldEnchantments!!.contains(ecoEnchant))
registerEnchantment(ecoEnchant, ecoEnchant) EnchantmentApi.registerEnchantment(CALegacyEcoEnchant(ecoEnchant, ecoEnchant as Enchantment))
// Remove old enchantments that not now currently used // Remove old enchantments that not now currently used
this.ecoEnchantOldEnchantments!!.removeAll(newEnchantments) this.ecoEnchantOldEnchantments!!.removeAll(newEnchantments)
for (oldEnchantment in this.ecoEnchantOldEnchantments!!) { for (oldEnchantment in this.ecoEnchantOldEnchantments!!) {
unregisterEnchantment(oldEnchantment) EnchantmentApi.unregisterEnchantment(oldEnchantment as Enchantment)
} }
this.ecoEnchantOldEnchantments = HashSet(newEnchantments) this.ecoEnchantOldEnchantments = HashSet(newEnchantments)

View file

@ -8,22 +8,28 @@ import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.plugin.Plugin
import org.bukkit.plugin.RegisteredListener import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.api.EnchantmentApi
import xyz.alexcrea.cuanvil.enchant.bulk.SuperEnchantBulkOperation import xyz.alexcrea.cuanvil.enchant.bulk.SuperEnchantBulkOperation
import xyz.alexcrea.cuanvil.enchant.wrapped.CASuperEnchantEnchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CASuperEnchantEnchantment
import java.util.logging.Level import java.util.logging.Level
class SuperEnchantDependency(override val plugin: SuperEnchants): GenericPluginDependency(plugin, false) { class SuperEnchantDependency : GenericPluginDependency {
override val plugin: SuperEnchants
lateinit var enchManager: EnchantManager lateinit var enchManager: EnchantManager
val enchantments = ArrayList<CASuperEnchantEnchantment>() val enchantments = ArrayList<CASuperEnchantEnchantment>()
fun registerEnchantments(): Boolean{ constructor(plugin: Plugin) : super(plugin) {
this.plugin = plugin as SuperEnchants
}
fun registerEnchantments(): Boolean {
CustomAnvil.instance.logger.info("Preparing Super Enchant compatibility...") CustomAnvil.instance.logger.info("Preparing Super Enchant compatibility...")
val field = SuperEnchants::class.java.getDeclaredField("enchantManager") val field = SuperEnchants::class.java.getDeclaredField("enchantManager")
if(field == null) { if (field == null) {
CustomAnvil.instance.logger.log(Level.SEVERE, "Failed to initialize Super Enchant compatibility") CustomAnvil.instance.logger.log(Level.SEVERE, "Failed to initialize Super Enchant compatibility")
return false return false
} }
@ -61,7 +67,7 @@ class SuperEnchantDependency(override val plugin: SuperEnchants): GenericPluginD
reload?.setExecutor(ReloadInterceptor(reload.executor)) reload?.setExecutor(ReloadInterceptor(reload.executor))
} }
inner class ReloadInterceptor(val other: CommandExecutor): CommandExecutor { inner class ReloadInterceptor(val other: CommandExecutor) : CommandExecutor {
override fun onCommand( override fun onCommand(
sender: CommandSender, sender: CommandSender,

View file

@ -18,13 +18,9 @@ class ToolStatsDependency(plugin: Plugin) : GenericPluginDependency(plugin) {
getTokenMethod.trySetAccessible() getTokenMethod.trySetAccessible()
} }
private fun ItemChecker.getTokenSafe(item: ItemStack?): Array<*> { private fun ItemChecker.getTokenSafe(item: ItemStack?): Array<String> {
if (item == null) return arrayOf<Any>() if (item == null) return arrayOf()
val result = getTokenMethod.invoke(this, item) return getTokenMethod.invoke(this, item) as Array<String>
if(result !is Array<*>)
throw IllegalStateException("Could not get token from ToolStats")
return result
} }
override fun testAnvilResult(event: InventoryClickEvent): Boolean { override fun testAnvilResult(event: InventoryClickEvent): Boolean {

View file

@ -18,18 +18,19 @@ class EnchantConflictGroup(
fun addEnchantment(enchant: CAEnchantment) { fun addEnchantment(enchant: CAEnchantment) {
enchantments.add(enchant) enchantments.add(enchant)
} }
fun addEnchantments(enchants: List<CAEnchantment>) { fun addEnchantments(enchants: List<CAEnchantment>) {
enchantments.addAll(enchants) enchantments.addAll(enchants)
} }
private fun canBypassByBeforeLevel(enchants: Map<CAEnchantment, Int>): Boolean { private fun canBypassByBeforeLevel(enchants: Map<CAEnchantment, Int>): Boolean {
// Either there no "conflict after" // Either there no "conflict after"
if(conflictsAfterLevel.isEmpty()) return false if (conflictsAfterLevel.isEmpty()) return false
// Or we check if any conflict after enchantment is true // Or we check if any conflict after enchantment is true
for (entry in conflictsAfterLevel) { for (entry in conflictsAfterLevel) {
val current = enchants.getOrDefault(entry.key, 0) val current = enchants.getOrDefault(entry.key, 0)
if(current > entry.value) if (current > entry.value)
return false return false
} }
@ -38,12 +39,12 @@ class EnchantConflictGroup(
private fun canBypassByAfterLevel(enchants: Map<CAEnchantment, Int>): Boolean { private fun canBypassByAfterLevel(enchants: Map<CAEnchantment, Int>): Boolean {
// Either there no "conflict after" // Either there no "conflict after"
if(conflictsBeforeLevel.isEmpty()) return false if (conflictsBeforeLevel.isEmpty()) return false
// Or we check if any conflict after enchantment is true // Or we check if any conflict after enchantment is true
for (entry in conflictsBeforeLevel) { for (entry in conflictsBeforeLevel) {
val current = enchants.getOrDefault(entry.key, 0) val current = enchants.getOrDefault(entry.key, 0)
if(current < entry.value) if (current < entry.value)
return false return false
} }
@ -64,7 +65,7 @@ class EnchantConflictGroup(
return true return true
// If empty we skip. else we // If empty we skip. else we
if(canBypassConflictByLevel(enchants)) if (canBypassConflictByLevel(enchants))
return true return true
// Count the amount of enchantment that are in the list // Count the amount of enchantment that are in the list
@ -102,7 +103,7 @@ class EnchantConflictGroup(
fun putConflictAfterLevel(enchantment: CAEnchantment, level: Int): Boolean { fun putConflictAfterLevel(enchantment: CAEnchantment, level: Int): Boolean {
return null != ( return null != (
if(level < 0) conflictsAfterLevel.remove(enchantment) if (level < 0) conflictsAfterLevel.remove(enchantment)
else conflictsAfterLevel.put(enchantment, level)) else conflictsAfterLevel.put(enchantment, level))
} }
@ -117,7 +118,7 @@ class EnchantConflictGroup(
fun putConflictsBeforeLevel(enchantment: CAEnchantment, level: Int): Boolean { fun putConflictsBeforeLevel(enchantment: CAEnchantment, level: Int): Boolean {
return null != ( return null != (
if(level < 0) conflictsBeforeLevel.remove(enchantment) if (level < 0) conflictsBeforeLevel.remove(enchantment)
else conflictsBeforeLevel.put(enchantment, level)) else conflictsBeforeLevel.put(enchantment, level))
} }

View file

@ -10,7 +10,6 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
import xyz.alexcrea.cuanvil.util.MaterialUtil.customType import xyz.alexcrea.cuanvil.util.MaterialUtil.customType
import java.util.* import java.util.*
import kotlin.collections.set
class EnchantConflictManager { class EnchantConflictManager {
@ -154,7 +153,7 @@ class EnchantConflictManager {
} }
return CAEnchantment.getListByName(enchantName) return CAEnchantment.getByName(enchantName)
} }

View file

@ -1,7 +1,6 @@
package xyz.alexcrea.cuanvil.group package xyz.alexcrea.cuanvil.group
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import java.util.*
class ExcludeGroup(name: String) : AbstractMaterialGroup(name) { class ExcludeGroup(name: String) : AbstractMaterialGroup(name) {

Some files were not shown because too many files have changed in this diff Show more