Compare commits

...

36 commits

Author SHA1 Message Date
539248f6b7
fix book on item 2026-08-22 07:54:44 +02:00
eeaa87ba98
fix bad handling for middle click 2026-08-19 15:27:18 +02:00
8e7153a746
use provider for hangar changelog 2026-08-16 19:15:54 +02:00
db9188607b
correct supported modrinth versions 2026-08-16 18:21:09 +02:00
1382c7a0fd
make configuration cache work 2026-08-16 18:19:43 +02:00
f32609bc68
suppress or remove most warnings 2026-08-16 10:48:31 +02:00
73134c81c2
update a bunch of stuff in gradle 2026-08-16 10:25:20 +02:00
55c0be20b4
fix spigot issue 2026-08-16 08:44:58 +02:00
142376573c
fix gradlew and up to 9.7.0, version bump to 1.19.1 [skip ci] 2026-08-16 08:33:10 +02:00
4e1ed9f1ea
remove ) 2026-08-12 23:13:57 +02:00
5ad3f1a7a2
Duplicate registered enchantment name warning as debug log 2026-08-12 19:01:54 +02:00
685e046063
proper eco item check 2026-08-12 07:27:22 +02:00
82b41fb1c1
fix eco enchant issue 2026-08-12 07:17:36 +02:00
f4202e2521
warn and cancel on datapack setEnchantAsAll enchantment not found 2026-08-12 06:52:41 +02:00
b2567f9176
fix anvil degradation not working for 2026-08-03 14:34:42 +02:00
c117357202
update faststats 2026-08-03 14:33:23 +02:00
d6af0e8b8f
fix some custom recipe not working 2026-08-03 14:33:23 +02:00
845bb4d94a
one last change 2026-07-17 02:40:59 +02:00
c2b793e1b9
do not use java setup to cache gradlew 2026-07-17 02:40:59 +02:00
d9624c17ba
fix paperweight cache 2026-07-17 02:40:59 +02:00
6fcc5bdf64
do not depend on nightexpress repo 2026-07-17 02:40:58 +02:00
17ee9902b5
upgrade actions 2026-07-17 02:40:57 +02:00
41d56ec949
trying better cache 2026-07-17 02:40:53 +02:00
9fc0203456
check isAir instead of null 2026-07-16 19:15:43 +02:00
8830b4c4ed
remove use of customname as not used under 1.21.4 2026-07-16 18:50:51 +02:00
7b232528f1
fix rename text not acting as vanilla 2026-07-16 18:44:23 +02:00
da10f0df5f
proper stop on legacy check & add env variable to bypass 2026-07-16 18:26:52 +02:00
37cd603575
back to java 21 (oops !) 2026-07-11 23:17:05 +02:00
a49044b522
Backport of anvil sound and degradation #122 (#123) 2026-07-11 22:54:45 +02:00
5bd78b4444
backport anvil mechanic 2026-07-11 22:51:24 +02:00
c38e8025cd
sound & anvil damage done 2026-07-11 22:45:44 +02:00
3dd706b4a8
add sound & degradation in config 2026-07-11 22:45:44 +02:00
015ca99475
anvil sound & degrade basic feature
# Conflicts:
#	src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt
2026-07-11 22:45:39 +02:00
52a58acd28
fix test issue 2026-07-11 13:56:29 +02:00
ae28c64647
change v1 release 2026-07-11 00:23:46 +02:00
fe63f489c9
disable load for v1 after 1.21 2026-07-10 23:33:08 +02:00
72 changed files with 522 additions and 698 deletions

View file

@ -8,12 +8,9 @@
name: Java CI with Gradle name: Java CI with Gradle
on: on:
push:
branches: [ "v1.x.x", "v2.x.x" ]
pull_request:
branches: [ "v1.x.x", "v2.x.x" ]
release: release:
types: [published] types: [published]
branches: [ "v1.x.x" ]
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
@ -26,46 +23,37 @@ jobs:
contents: write contents: write
env: env:
MODRINTH_VERSIONS: '["1.18.x", "1.19.x", "1.20.x", "1.21.x", "26.1.x", "26.2.x"]' MODRINTH_VERSIONS: '["1.18.x", "1.19.x", "1.20.x"]'
MODRINTH_PLATFORMS: '["spigot", "paper", "purpur", "folia"]' MODRINTH_PLATFORMS: '["spigot", "paper", "purpur", "folia"]'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Set up JDKs - name: Set up JDKs
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
java-version: | java-version: |
21 21
distribution: 'temurin' distribution: 'temurin'
cache: gradle
- name: Cache Gradle root and wrapper
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-root-${{ runner.os }}-${{ hashFiles('build.gradle*') }}
restore-keys: gradle-root-${{ runner.os }}-
# Setup paperweight cache
- name: Cache paperweight
uses: actions/cache@v3
with:
path: |
./nms/*/.gradle/caches/paperweight
key: paperweight-submodules-${{ runner.os }}-${{ hashFiles('nms/*/build.gradle*') }}
restore-keys: |
paperweight-submodules-${{ runner.os }}-
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v5 uses: gradle/actions/setup-gradle@v6
- name: Make gradlew executable - name: Make gradlew executable
run: chmod +x ./gradlew run: chmod +x ./gradlew
# Setup paperweight cache
- name: Cache paperweight
uses: actions/cache@v6
with:
path: |
./nms/*/.gradle/caches/paperweight
./.gradle/caches/paperweight
key: paperweight-submodules-${{ runner.os }}-${{ hashFiles('nms/*/build.gradle*') }}
restore-keys: |
paperweight-submodules-${{ runner.os }}-
- name: Get small commit hash - name: Get small commit hash
if: ${{ github.event_name != 'release' && success() }} if: ${{ github.event_name != 'release' && success() }}
run: echo "SMALL_COMMIT_HASH=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_ENV run: echo "SMALL_COMMIT_HASH=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_ENV
@ -75,7 +63,7 @@ jobs:
# only submit dependency on push # only submit dependency on push
- name: Generate and submit dependency graph - name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@v4 uses: gradle/actions/dependency-submission@v6
if: ${{ github.event_name == 'push' && success() }} if: ${{ github.event_name == 'push' && success() }}
continue-on-error: true continue-on-error: true
@ -91,16 +79,16 @@ jobs:
# upload the named jars as artifact # upload the named jars as artifact
- name: Upload online JAR artifact - name: Upload online JAR artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: CustomAnvil.jar
path: build/libs/${{ env.ONLINE_JAR_NAME }} path: build/libs/${{ env.ONLINE_JAR_NAME }}
archive: false
- name: Upload offline JAR file - name: Upload offline JAR file
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: CustomAnvil-offline.jar
path: build/libs/${{ env.OFFLINE_JAR_NAME }} path: build/libs/${{ env.OFFLINE_JAR_NAME }}
archive: false
- name: Summarize tests results - name: Summarize tests results
uses: jeantessier/test-summary-action@v1 uses: jeantessier/test-summary-action@v1
@ -109,33 +97,12 @@ jobs:
# upload the jar to release # upload the jar to release
- name: Upload jar to release - name: Upload jar to release
if: ${{ github.event_name == 'release' && success() }} if: ${{ github.event_name == 'release' && success() }}
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v3
with: with:
files: | files: |
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
@ -156,8 +123,7 @@ jobs:
with: with:
webhook-url: ${{ secrets.RELEASE_WEBHOOK_URL }} webhook-url: ${{ secrets.RELEASE_WEBHOOK_URL }}
content: | content: |
${{ github.event.release.prerelease == false && '<@&1338546156325568642>' || '<@&1352296092989001768>' }} <@&1525259349423947867>
# 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) # New bugfix for CustomAnvil v1 ! <:CustomAnvil:1262550667986342001> [Modrinth](https://modrinth.com/plugin/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

@ -5,24 +5,23 @@ 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.3.0" kotlin("jvm") version "2.4.0"
java java
id("org.jetbrains.dokka").version("1.9.20") id("org.jetbrains.dokka").version("2.2.0")
id("com.gradleup.shadow").version("9.3.0") id("com.gradleup.shadow").version("9.6.1")
// Maven publish // Maven publish
`maven-publish` `maven-publish`
signing signing
id("cn.lalaki.central").version("1.2.8") id("cn.lalaki.central").version("2.0.8")
// Paper // Paper
id("io.papermc.paperweight.userdev") version "2.0.0-beta.17" apply false id("io.papermc.paperweight.userdev") version "2.0.0-beta.21" apply false
id("io.papermc.hangar-publish-plugin") version "0.1.2" id("io.papermc.hangar-publish-plugin") version "0.1.4"
} }
group = "xyz.alexcrea" group = "xyz.alexcrea"
version = "1.18.0" version = "1.20.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"
@ -34,9 +33,6 @@ repositories {
// EcoEnchants // EcoEnchants
maven(url = "https://repo.auxilor.io/repository/maven-public/") maven(url = "https://repo.auxilor.io/repository/maven-public/")
// ExcellentEnchants
maven(url = "https://repo.nightexpressdev.com/releases")
// ItemsAdder // ItemsAdder
maven(url = "https://maven.devs.beer/") maven(url = "https://maven.devs.beer/")
@ -58,7 +54,7 @@ dependencies {
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT") compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT")
// fast stats // fast stats
implementation("dev.faststats.metrics:bukkit:0.27.2") implementation("dev.faststats.metrics:bukkit:0.29.0")
// minimessage // minimessage
implementation("net.kyori:adventure-text-minimessage:4.25.0") implementation("net.kyori:adventure-text-minimessage:4.25.0")
@ -72,21 +68,22 @@ dependencies {
compileOnly(files("libs/EnchantsSquared.jar")) compileOnly(files("libs/EnchantsSquared.jar"))
// EcoEnchants & item // EcoEnchants & item
compileOnly("com.willfp:libreforge:4.79.0:all") compileOnly("com.willfp:libreforge:2026.32:all")
compileOnly("com.willfp:eco:6.74.5") compileOnly("com.willfp:eco:2026.32")
compileOnly("com.willfp:EcoEnchants:12.11.1") compileOnly("com.willfp:EcoEnchants:2026.32:all")
compileOnly(project(":impl:LegacyEcoEnchant")) compileOnly(project(":impl:LegacyEcoEnchant"))
compileOnly("com.willfp:EcoItems:5.66.0") compileOnly("com.willfp:EcoItems:5.66.0")
// ExcellentEnchants // ExcellentEnchants
implementation(project(":impl:ExcellentEnchant5_4")) implementation(project(":impl:ExcellentEnchant5_4"))
compileOnly("su.nightexpress.excellentenchants:Core:5.1.0") { compileOnly(files("libs/ExcellentEnchants/ExcellentEnchants-4.3.3-striped.jar")) // For pre v5 excellent enchants
exclude("org.spigotmc") compileOnly(files("libs/ExcellentEnchants/ExcellentEnchants-4.1.0-striped.jar")) // For legacy excellent enchants
} // early v5 excellent enchants
compileOnly(files("libs/ExcellentEnchants-4.3.3-striped.jar")) // For pre v5 excellent enchants compileOnly(files("libs/ExcellentEnchants/Core-5.1.0.jar"))
compileOnly(files("libs/ExcellentEnchants-4.1.0-striped.jar")) // For legacy excellent enchants compileOnly(files("libs/ExcellentEnchants/API-5.1.0.jar"))
compileOnly(files("libs/ExcellentEnchants/main-2.7.9.jar"))
// Disenchantment // Disenchantment
compileOnly(files("libs/Disenchantment-6.1.5.jar")) compileOnly(files("libs/Disenchantment-6.1.5.jar"))
@ -168,7 +165,7 @@ allprojects {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_16) jvmTarget.set(JvmTarget.JVM_16)
} }
} }
@ -180,7 +177,10 @@ 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 name = "${rootProject.name}-${effectiveVersion}${processedSuffix}.jar" val version = effectiveVersion
val name = "${rootProject.name}-${version}${processedSuffix}.jar"
val librariesExpendTo = libraries.joinToString(transform = { "\"$it\"" })
archiveFileName.set(name) archiveFileName.set(name)
// Shadow necessary dependency // Shadow necessary dependency
@ -189,8 +189,8 @@ tasks {
filesMatching("plugin.yml") { filesMatching("plugin.yml") {
expand( expand(
"version" to effectiveVersion + processedSuffix, "version" to version + processedSuffix,
"libraries" to libraries.joinToString(transform = { "\"$it\"" }), "libraries" to librariesExpendTo,
) )
} }
@ -202,7 +202,7 @@ tasks {
shadowJar { shadowJar {
configureBaseShadow("", configureBaseShadow("",
arrayOf( arrayOf(
"org.jetbrains.kotlin:kotlin-stdlib:2.3.0", "org.jetbrains.kotlin:kotlin-stdlib:2.4.0",
"net.kyori:adventure-text-minimessage:4.25.0", "net.kyori:adventure-text-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 +214,7 @@ tasks {
exclude("net/kyori/**") exclude("net/kyori/**")
} }
val offlineJar by registering(ShadowJar::class) { val offlineJar = register<ShadowJar>("offlineJar") {
configureBaseShadow("offline", emptyArray()) configureBaseShadow("offline", emptyArray())
from(sourceSets.main.get().output) from(sourceSets.main.get().output)
@ -228,12 +228,12 @@ tasks {
} }
val sourcesJar by tasks.registering(Jar::class) { val sourcesJar = tasks.register<Jar>("sourcesJar") {
archiveClassifier.set("sources") archiveClassifier.set("sources")
from(kotlin.sourceSets.main.get().kotlin) from(kotlin.sourceSets.main.get().kotlin)
} }
val javadocJar by tasks.registering(Jar::class, fun Jar.() { val javadocJar = tasks.register<Jar>("javadocJar", 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,36 +357,25 @@ publishing {
} }
// hangar publish // hangar publish
fun latestCommitMessage(): Provider<String> {
fun executeGitCommand(vararg command: String): String { return providers.exec {
val byteOut = ByteArrayOutputStream() commandLine("git", "log", "-1", "--pretty=%B")
exec { }.standardOutput.asText.map(String::trim)
commandLine = listOf("git", *command)
standardOutput = byteOut
}
return byteOut.toString(Charsets.UTF_8.name()).trim()
} }
fun changelog(isOnline: Boolean): Provider<String> {
fun latestCommitMessage(): String { val changelog = if(isDevBuild) latestCommitMessage()
return executeGitCommand("log", "-1", "--pretty=%B") else providers.environmentVariable("RELEASE_CHANGELOG")
}
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 {
@ -400,6 +389,7 @@ hangarPublish {
channel.set(if (isDevBuild || isPreRelease) devChannel else releaseChannel) channel.set(if (isDevBuild || isPreRelease) devChannel else 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"))

View file

@ -476,6 +476,32 @@ monetary_cost:
work_penalty: 1.0 # for work penalty (aka use penalty) work_penalty: 1.0 # for work penalty (aka use penalty)
recipe: 1.0 # for custom anvil recipe cost recipe: 1.0 # for custom anvil recipe cost
# Chance that an anvil get degraded
# set it to zero if you wish to disable it
anvil_degradation: 0.12
# see https://www.digminecraft.com/lists/sound_list_pc.php
# for a list of most of the sounds
anvil_sound:
enabled: true
# The sound are weighted so if there is multiples of them one is selected randomly
# so if you want to add a "rare sound" as an easter egg you can !
# If invalid, it will be removed from the list. and if empty it will use the default
use:
default:
sound: block.anvil.use
category: blocks
volume: 1.0
pitch: 1.0
weight: 1.0
destroy:
default:
sound: block.anvil.destroy
category: blocks
volume: 1.0
pitch: 1.0
weight: 1.0
# Whether to show debug logging # Whether to show debug logging
debug_log: false debug_log: false

View file

@ -468,6 +468,33 @@ monetary_cost:
work_penalty: 1.0 # for work penalty (aka use penalty) work_penalty: 1.0 # for work penalty (aka use penalty)
recipe: 1.0 # for custom anvil recipe cost recipe: 1.0 # for custom anvil recipe cost
# Chance that an anvil get degraded
# set it to zero if you wish to disable it
anvil_degradation: 0.12
# see https://www.digminecraft.com/lists/sound_list_pc.php
# for a list of most of the sounds
anvil_sound:
enabled: true
# The sound are weighted so if there is multiples of them one is selected randomly
# so if you want to add a "rare sound" as an easter egg you can !
# If invalid, it will be removed from the list. and if empty it will use the default
use:
default:
sound: block.anvil.use
category: blocks
volume: 1.0
pitch: 1.0
weight: 1.0
destroy:
default:
sound: block.anvil.destroy
category: blocks
volume: 1.0
pitch: 1.0
weight: 1.0
# Whether to show debug logging # Whether to show debug logging
debug_log: false debug_log: false

View file

@ -456,6 +456,33 @@ monetary_cost:
work_penalty: 1.0 # for work penalty (aka use penalty) work_penalty: 1.0 # for work penalty (aka use penalty)
recipe: 1.0 # for custom anvil recipe cost recipe: 1.0 # for custom anvil recipe cost
# Chance that an anvil get degraded
# set it to zero if you wish to disable it
anvil_degradation: 0.12
# see https://www.digminecraft.com/lists/sound_list_pc.php
# for a list of most of the sounds
anvil_sound:
enabled: true
# The sound are weighted so if there is multiples of them one is selected randomly
# so if you want to add a "rare sound" as an easter egg you can !
# If invalid, it will be removed from the list. and if empty it will use the default
use:
default:
sound: block.anvil.use
category: blocks
volume: 1.0
pitch: 1.0
weight: 1.0
destroy:
default:
sound: block.anvil.destroy
category: blocks
volume: 1.0
pitch: 1.0
weight: 1.0
# Whether to show debug logging # Whether to show debug logging
debug_log: false debug_log: false

View file

@ -1,4 +1,5 @@
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
@ -6,8 +7,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,v1_19R1,v1_19R2,v1_19R3,v1_20R1,v1_20R2,v1_20R3,v1_20R4,v1_21R1,v1_21R2,v1_21R3,v1_21R4,v1_21R5,v1_21R6,v1_21R7 subprojects.reobfnms=v1_17R1,v1_18R1,v1_18R2
# list of version for hangar release # list of version for hangar release
paperVersion=1.18-26.2 paperVersion=1.18-1.20.5

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-8.14.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.0-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.3.0" kotlin("jvm") version "2.4.0"
} }
repositories { repositories {

View file

@ -2,7 +2,7 @@ group = rootProject.group
version = rootProject.version version = rootProject.version
plugins { plugins {
kotlin("jvm") version "2.3.0" kotlin("jvm") version "2.4.0"
} }
// Imitate needed class and method to support legacy version of EcoEnchant // Imitate needed class and method to support legacy version of EcoEnchant

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_16) jvmTarget.set(JvmTarget.JVM_16)
} }
} }

View file

@ -37,7 +37,7 @@ object PlatformUtil {
// Lore // Lore
fun ItemMeta.componentLore(): MutableList<Component> { fun ItemMeta.componentLore(): MutableList<Component> {
val lore: List<Component>? val lore: List<Component>?
if(isPaper){ if (isPaper) {
lore = this.lore() lore = this.lore()
} else { } else {
val legacyLores = this.lore ?: return ArrayList() val legacyLores = this.lore ?: return ArrayList()
@ -52,49 +52,41 @@ object PlatformUtil {
} }
fun ItemMeta.setComponentLore(lore: List<Component?>) { fun ItemMeta.setComponentLore(lore: List<Component?>) {
if(isPaper){ if (isPaper) {
this.lore(lore) this.lore(lore)
} else { } else {
val legacyLore = ArrayList<String?>(lore.size) val legacyLore = ArrayList<String?>(lore.size)
for (component in lore) { for (component in lore) {
legacyLore.add(if(component == null) null legacyLore.add(
else legacy_mm.serialize(component)) if (component == null) null
else legacy_mm.serialize(component)
)
} }
this.lore = legacyLore this.lore = legacyLore
} }
} }
// Display name
private val useCustomName = hasMethod(ItemStack::class.java, "customName")
fun ItemMeta.componentDisplayName(): Component? { fun ItemMeta.componentDisplayName(): Component? {
if(useCustomName){ if (!this.hasDisplayName()) return null
if(!this.hasCustomName()) return null
return this.customName()
}else if(isPaper){
if(!this.hasDisplayName()) return null
return this.displayName()
} else {
if(!this.hasDisplayName()) return null
val legacy = this.displayName return if (isPaper) {
return legacy_mm.deserialize(legacy) this.displayName()
} else {
legacy_mm.deserialize(this.displayName)
} }
} }
fun ItemMeta.setComponentDisplayName(component: Component?) { fun ItemMeta.setComponentDisplayName(component: Component?, fallback: String? = null) {
if(useCustomName){ if (isPaper) {
this.customName(component)
}else if(isPaper){
this.displayName(component) this.displayName(component)
} else { } else {
if(component == null){ if (component == null) {
this.setDisplayName(null) this.setDisplayName(null)
return return
} }
val legacy = legacy_mm.serialize(component) val legacy = fallback ?: legacy_mm.serialize(component)
this.setDisplayName(legacy) this.setDisplayName(legacy)
} }
} }

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_18) jvmTarget.set(JvmTarget.JVM_18)
} }
} }

View file

@ -1,3 +1,4 @@
@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
@ -21,18 +22,21 @@ object DataPackTester {
return Bukkit.getDatapackManager().enabledPacks return Bukkit.getDatapackManager().enabledPacks
.stream().map { obj: Datapack -> obj.name } .stream().map { obj: Datapack -> obj.name }
.toList() .toList()
} catch (e: NoSuchMethodException) { } catch (_: NoSuchMethodException) {
try { try {
DataPack::class.java.getDeclaredMethod("getKey") DataPack::class.java.getDeclaredMethod("getKey")
} catch (e: NoSuchMethodException) { } catch (_: NoSuchMethodException) {
System.err.println("Could not find compatible datapack manager") 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...") System.err.println("If you are using a datapack that should be compatible with CustomAnvil. It will not get detected...")
return emptyList() return emptyList()
} }
return legacyNames return legacyNames
} catch (e: Exception){ } catch (_: Exception){
// Assume cause UnimplementedOperationException on mock server // Assume cause UnimplementedOperationException on mock server
return Collections.emptyList() return Collections.emptyList()
} catch(_: NoSuchMethodError) {
// Idk newer spigot may not have that ?
return Collections.emptyList()
} }
} }
} }

View file

@ -12,6 +12,7 @@ object AnvilTitleUtil {
private val runTaskMap = HashMap<UUID, ScheduledTask>() private val runTaskMap = HashMap<UUID, ScheduledTask>()
@Suppress("DEPRECATION")
private fun actualRename(view: InventoryView, 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

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_16) jvmTarget.set(JvmTarget.JVM_16)
} }
} }

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_17) jvmTarget.set(JvmTarget.JVM_17)
} }
} }

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_17) jvmTarget.set(JvmTarget.JVM_17)
} }
} }

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_17) jvmTarget.set(JvmTarget.JVM_17)
} }
} }

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_17) jvmTarget.set(JvmTarget.JVM_17)
} }
} }

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_17) jvmTarget.set(JvmTarget.JVM_17)
} }
} }

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_18) jvmTarget.set(JvmTarget.JVM_18)
} }
} }

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_18) jvmTarget.set(JvmTarget.JVM_18)
} }
} }

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_18) jvmTarget.set(JvmTarget.JVM_18)
} }
} }

View file

@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
kotlin { kotlin {
compilerOptions { compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_4)
jvmTarget.set(JvmTarget.JVM_18) jvmTarget.set(JvmTarget.JVM_18)
} }
} }

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.21.1-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

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

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.21.3-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

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

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.21.4-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

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

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

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

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

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

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

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

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

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

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

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

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

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

View file

@ -99,8 +99,7 @@ public class CAEnchantmentRegistry {
if ((!hasWarnedRegistering) && byNameMap.containsKey(enchantment.getName())) { if ((!hasWarnedRegistering) && byNameMap.containsKey(enchantment.getName())) {
hasWarnedRegistering = true; hasWarnedRegistering = true;
CustomAnvil.instance.getLogger().log(Level.WARNING, CustomAnvil.Companion.log("Duplicate registered enchantment name. Please check that configuration is using namespace.");
"Duplicate registered enchantment name. Please check that configuration is using namespace.");
} }
byKeyMap.put(enchantment.getKey(), enchantment); byKeyMap.put(enchantment.getKey(), enchantment);

View file

@ -11,7 +11,6 @@ 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
@ -25,6 +24,7 @@ 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 {
legacyCheck() if(legacyCheck()) return
} 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)
@ -202,7 +202,16 @@ open class CustomAnvil : JavaPlugin() {
} }
} }
private fun legacyCheck() { private fun legacyCheck(): Boolean {
val currentVersion = UpdateUtils.currentMinecraftVersion()
if (currentVersion.greaterEqual(Version(1, 21, 0))
&& !DependencyManager.inTesting
&& !"true".equals(System.getenv("CUSTOM_ANVIL_BYPASS_LEGACY_CHECK"), true)) {
logger.warning("You are running a Minecraft version above or equal to 1.21.0")
logger.warning("Please use CustomAnvil v2 instead if you wish to use the plugin with this version.")
Bukkit.getPluginManager().disablePlugin(this)
return true
}
// Disable old plugin name if exist // Disable old plugin name if exist
val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus") val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus")
if (potentialPlugin != null) { if (potentialPlugin != null) {
@ -215,10 +224,6 @@ 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"
@ -238,6 +243,7 @@ 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() {

View file

@ -6,7 +6,6 @@ import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Damageable import org.bukkit.inventory.meta.Damageable
import xyz.alexcrea.cuanvil.update.UpdateUtils import xyz.alexcrea.cuanvil.update.UpdateUtils
import xyz.alexcrea.cuanvil.util.MaterialUtil.customType import xyz.alexcrea.cuanvil.util.MaterialUtil.customType
import xyz.alexcrea.cuanvil.util.MaxDamageCheckerUtil
import kotlin.math.ceil import kotlin.math.ceil
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@ -21,13 +20,6 @@ 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 MaxDamageCheckerUtil.getMaxDamage(type, damageable)
}
/** /**
* 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
@ -40,7 +32,7 @@ object ItemUtil {
val meta = itemMeta val meta = itemMeta
if(meta !is Damageable) return false if(meta !is Damageable) return false
val maxDamage = maxDamage(type, meta) val maxDamage = type.maxDurability.toInt()
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
@ -83,6 +75,6 @@ object ItemUtil {
* The two items should either be the same type, or, the [other] is a book * The two items should either be the same type, or, the [other] is a book
*/ */
fun ItemStack.canMergeWith( fun ItemStack.canMergeWith(
other: ItemStack? other: ItemStack
) = (other != null) && (customType == other.customType || (other.isEnchantedBook())) ) = customType == other.customType || (other.isEnchantedBook())
} }

View file

@ -6,6 +6,7 @@ import io.delilaheve.util.EnchantmentUtil.combineWith
import io.delilaheve.util.ItemUtil.isEnchantedBook import io.delilaheve.util.ItemUtil.isEnchantedBook
import io.delilaheve.util.ItemUtil.repairFrom import io.delilaheve.util.ItemUtil.repairFrom
import io.delilaheve.util.ItemUtil.unitRepair import io.delilaheve.util.ItemUtil.unitRepair
import net.kyori.adventure.text.Component
import org.bukkit.ChatColor import org.bukkit.ChatColor
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
@ -17,6 +18,7 @@ import org.bukkit.inventory.meta.ItemMeta
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
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
@ -139,11 +141,12 @@ object AnvilMergeLogic {
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int { private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int {
// Can be null // Can be null
var renameText = ChatColor.stripColor(inventory.renameText) var renameText = ChatColor.stripColor(inventory.renameText)
var component: Component? = null
var sumCost = 0 var sumCost = 0
var useColor = false var useColor = false
if (ConfigOptions.renameColorPossible && renameText != null) { if (ConfigOptions.renameColorPossible && renameText != null) {
val component = AnvilColorUtil.handleColor( component = AnvilColorUtil.handleColor(
renameText, renameText,
AnvilColorUtil.renamePermission(player) AnvilColorUtil.renamePermission(player)
) )
@ -170,7 +173,11 @@ object AnvilMergeLogic {
renameText == CasedStringUtil.snakeToUpperSpacedCase(resultItem.type.name.lowercase()) renameText == CasedStringUtil.snakeToUpperSpacedCase(resultItem.type.name.lowercase())
) )
) { ) {
it.setDisplayName(renameText) if (component == null)
component = if (renameText == null || renameText.isEmpty()) null
else Component.text(renameText)
it.setComponentDisplayName(component, renameText)
processDialogPCD(it, player) processDialogPCD(it, player)
resultItem.itemMeta = it resultItem.itemMeta = it

View file

@ -0,0 +1,146 @@
package xyz.alexcrea.cuanvil.config
import io.delilaheve.CustomAnvil
import org.bukkit.NamespacedKey
import org.bukkit.Registry
import org.bukkit.Sound
import org.bukkit.SoundCategory
import org.bukkit.configuration.ConfigurationSection
import java.util.Random
import java.util.logging.Level
object AnvilFinishOptions {
data class ConfiguredSound(
val sound: Sound,
val category: SoundCategory,
val volume: Float,
val pitch: Float,
val weight: Double,
)
// Paths
private const val SOUND_ENABLED = "anvil_sound.enabled"
private const val USE_SOUNDS_ROOT = "anvil_sound.use"
private const val DESTROY_SOUNDS_ROOT = "anvil_sound.destroy"
private const val ANVIL_DEGRADATION_PATH = "anvil_degradation"
// Defaults
private const val DEFAULT_SOUND_ENABLED = true
private val DEFAULT_USE_SOUND = ConfiguredSound(
Sound.BLOCK_ANVIL_USE,
SoundCategory.BLOCKS,
1.0f,
1.0f,
1.0,
)
private val DEFAULT_DESTROY_SOUND = ConfiguredSound(
Sound.BLOCK_ANVIL_DESTROY,
SoundCategory.BLOCKS,
1.0f,
1.0f,
1.0,
)
private const val DEFAULT_ANVIL_DEGRADATION_PATH = 0.12
// Others
private val RANDOM = Random()
// Fetch
val sound_enabled: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(SOUND_ENABLED, DEFAULT_SOUND_ENABLED)
}
fun getAnvilSound(wasDestroyed: Boolean): ConfiguredSound {
return if(wasDestroyed)
getRandomDestroySound()
else getRandomUseSound()
}
val degradation_chance: Double
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getDouble(ANVIL_DEGRADATION_PATH, DEFAULT_ANVIL_DEGRADATION_PATH)
}
// Utils
private fun getRandomUseSound(): ConfiguredSound {
return fromListing(USE_SOUNDS_ROOT, DEFAULT_USE_SOUND)
}
private fun getRandomDestroySound(): ConfiguredSound {
return fromListing(DESTROY_SOUNDS_ROOT, DEFAULT_DESTROY_SOUND)
}
private fun fromListing(path: String, default: ConfiguredSound): ConfiguredSound {
val section = ConfigHolder.DEFAULT_CONFIG
.config.getConfigurationSection(path) ?: return default
val list = readSounds(section)
return weightedRandom(list, default)
}
private fun readSounds(section: ConfigurationSection): List<ConfiguredSound> {
val sounds = ArrayList<ConfiguredSound>()
for (key in section.getKeys(false)) {
if(!section.isConfigurationSection(key)) continue
val result = readSound(section.getConfigurationSection(key)!!)
if(result == null) {
CustomAnvil.instance.logger.warning("Couldn't read sounds for key $key")
continue
}
sounds.add(result)
}
return sounds
}
private fun readSound(section: ConfigurationSection): ConfiguredSound? {
val name = section.getString("sound", null)?: return null
val key = NamespacedKey.fromString(name)?: return null
val sound = Registry.SOUNDS.get(key)?: return null
val categoryName = section.getString("category", null)?: return null
val category = try {
SoundCategory.valueOf(categoryName.uppercase())
} catch (_: IllegalArgumentException) {
return null
}
val volume = section.getDouble("volume", 1.0).toFloat()
val pitch = section.getDouble("pitch", 1.0).toFloat()
val weight = section.getDouble("weight", 1.0)
if(weight <= 0) return null
return ConfiguredSound(sound, category, volume, pitch, weight)
}
private fun weightedRandom(sounds: List<ConfiguredSound>, default: ConfiguredSound): ConfiguredSound {
if(sounds.isEmpty()) return default
val weightSum = sounds.sumOf { it.weight }
if(weightSum == .0) return sounds.first()
val selectedWeight = RANDOM.nextDouble(weightSum)
var currentSum = .0
sounds.forEach {
currentSum += it.weight
if(currentSum > selectedWeight) return it
}
// What ? how
CustomAnvil.instance.logger.log(Level.SEVERE, "Something very... very wrong happen on sound handling. please report this to the developer")
return default
}
}

View file

@ -33,7 +33,7 @@ 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.reflect.Constructor import java.lang.IllegalStateException
import java.util.logging.Level import java.util.logging.Level
object DependencyManager { object DependencyManager {
@ -42,8 +42,11 @@ object DependencyManager {
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 excellentEnchantsCompatibility: ExcellentEnchantsDependency? = null var excellentEnchantsCompatibility: ExcellentEnchantsDependency? = null
var disenchantmentCompatibility: DisenchantmentDependency? = null var disenchantmentCompatibility: DisenchantmentDependency? = null
@ -80,6 +83,10 @@ object DependencyManager {
ecoEnchantCompatibility = EcoEnchantDependency(pluginManager.getPlugin("EcoEnchants")!!) ecoEnchantCompatibility = EcoEnchantDependency(pluginManager.getPlugin("EcoEnchants")!!)
ecoEnchantCompatibility!!.disableAnvilListener() ecoEnchantCompatibility!!.disableAnvilListener()
} }
// EcoItem check
if (pluginManager.isPluginEnabled("EcoItems")) {
hasEcoItem = true
}
// Excellent Enchants dependency // Excellent Enchants dependency
if (pluginManager.isPluginEnabled("ExcellentEnchants")) { if (pluginManager.isPluginEnabled("ExcellentEnchants")) {
@ -335,10 +342,14 @@ object DependencyManager {
private val prepareAnvilConstructor = private val prepareAnvilConstructor =
PrepareAnvilEvent::class.java.constructors.first() as Constructor<PrepareAnvilEvent> PrepareAnvilEvent::class.java.constructors.first()
fun createFakeEvent(view: InventoryView, result: ItemStack?): PrepareAnvilEvent { fun createFakeEvent(view: InventoryView, result: ItemStack?): PrepareAnvilEvent {
return prepareAnvilConstructor.newInstance(view, result) val result = prepareAnvilConstructor.newInstance(view, result)
if(result !is PrepareAnvilEvent)
throw IllegalStateException("Could not create a PrepareAnvilEvent ?")
return result
} }
} }

View file

@ -51,8 +51,4 @@ object MinecraftVersionUtil {
} }
} }
val isTooNewForSpigot: Boolean get() {
return UpdateUtils.currentMinecraftVersion().major != 1
}
} }

View file

@ -223,7 +223,11 @@ object DataPackDependency {
private fun setEnchantAsAll(ench: String) { private fun setEnchantAsAll(ench: String) {
// We assume current is not null and of type CABukkitEnchantment // We assume current is not null and of type CABukkitEnchantment
val current = EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!) as CABukkitEnchantment val current = EnchantmentApi.getByKey(NamespacedKey.fromString(ench)!!) as? CABukkitEnchantment
if(current == null) {
CustomAnvil.instance.logger.warning("Could not find enchant $ench")
return
}
// We need to replace current wrapped enchantment with the all conflict wrapper // We need to replace current wrapped enchantment with the all conflict wrapper
EnchantmentApi.unregisterEnchantment(current) EnchantmentApi.unregisterEnchantment(current)

View file

@ -1,3 +1,5 @@
@file:Suppress("DEPRECATION")
package xyz.alexcrea.cuanvil.dependency.economy package xyz.alexcrea.cuanvil.dependency.economy
import net.milkbowl.vault.economy.Economy import net.milkbowl.vault.economy.Economy

View file

@ -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.externGuiTester.isInTest()) if(DependencyManager.inTesting)
return NoPacketManager() return NoPacketManager()
return if (forceProtocolib) return if (forceProtocolib)

View file

@ -3,7 +3,7 @@ package xyz.alexcrea.cuanvil.dependency.plugins
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.ecoenchants.enchant.EcoEnchant import com.willfp.ecoenchants.enchant.EcoEnchant
import com.willfp.ecoenchants.enchant.EcoEnchants import com.willfp.ecoenchants.enchant.EcoEnchants
import com.willfp.ecoenchants.mechanics.infiniteIfNegative import com.willfp.ecoenchants.enchant.UtilKt
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.plugin.Plugin import org.bukkit.plugin.Plugin
@ -35,7 +35,7 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) {
} }
public fun getEcoLevelLimit(): Int { public fun getEcoLevelLimit(): Int {
return (ecoEnchantPlugin as EcoPlugin).configYml.getInt("anvil.enchant-limit").infiniteIfNegative() return UtilKt.infiniteIfNegative((ecoEnchantPlugin as EcoPlugin).configYml.getInt("anvil.enchant-limit"))
} }
fun disableAnvilListener() { fun disableAnvilListener() {
@ -51,7 +51,7 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) {
return return
} }
val enchantments = EcoEnchants.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))
@ -71,7 +71,7 @@ class EcoEnchantDependency(private val ecoEnchantPlugin: Plugin) {
// 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.values() val newEnchantments = EcoEnchants.INSTANCE.values()
// Add new enchantments // Add new enchantments
for (ecoEnchant in newEnchantments) for (ecoEnchant in newEnchantments)

View file

@ -6,6 +6,7 @@ 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() {

View file

@ -10,13 +10,20 @@ 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) {
ecoEnchant as Enchantment // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant.
unregisterEnchantment(ecoEnchant)
EnchantmentApi.unregisterEnchantment(ecoEnchant) // As eco enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant. registerEnchantment(ecoEnchant, ecoEnchant)
EnchantmentApi.registerEnchantment(CALegacyEcoEnchant(ecoEnchant, ecoEnchant))
} }
ecoEnchantOldEnchantments = HashSet(enchantments) ecoEnchantOldEnchantments = HashSet(enchantments)
@ -31,13 +38,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))
EnchantmentApi.registerEnchantment(CALegacyEcoEnchant(ecoEnchant, ecoEnchant as Enchantment)) registerEnchantment(ecoEnchant, 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 as Enchantment) unregisterEnchantment(oldEnchantment)
} }
this.ecoEnchantOldEnchantments = HashSet(newEnchantments) this.ecoEnchantOldEnchantments = HashSet(newEnchantments)

View file

@ -5,7 +5,6 @@ import lol.hyper.toolstats.tools.ItemChecker
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.Plugin import org.bukkit.plugin.Plugin
import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import java.lang.reflect.Method import java.lang.reflect.Method
@ -19,9 +18,13 @@ class ToolStatsDependency(plugin: Plugin) : GenericPluginDependency(plugin) {
getTokenMethod.trySetAccessible() getTokenMethod.trySetAccessible()
} }
private fun ItemChecker.getTokenSafe(item: ItemStack?): Array<String> { private fun ItemChecker.getTokenSafe(item: ItemStack?): Array<*> {
if (item == null) return arrayOf() if (item == null) return arrayOf<Any>()
return getTokenMethod.invoke(this, item) as Array<String> val result = getTokenMethod.invoke(this, item)
if(result !is Array<*>)
throw IllegalStateException("Could not get token from ToolStats")
return result
} }
override fun testAnvilResult(event: InventoryClickEvent): Boolean { override fun testAnvilResult(event: InventoryClickEvent): Boolean {

View file

@ -4,7 +4,9 @@ import io.delilaheve.CustomAnvil
import io.delilaheve.util.ConfigOptions import io.delilaheve.util.ConfigOptions
import io.delilaheve.util.ItemUtil.canMergeWith import io.delilaheve.util.ItemUtil.canMergeWith
import org.bukkit.GameMode import org.bukkit.GameMode
import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.Event import org.bukkit.event.Event
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
@ -21,6 +23,7 @@ import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.AnvilResult
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.CustomCraftResult import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.CustomCraftResult
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.LoreEditResult import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.LoreEditResult
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.UnitRepairResult import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.UnitRepairResult
import xyz.alexcrea.cuanvil.config.AnvilFinishOptions
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName
@ -28,6 +31,7 @@ import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT
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.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
import xyz.alexcrea.cuanvil.util.MiniMessageUtil import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
@ -89,7 +93,7 @@ class AnvilResultListener : Listener {
} }
// Rename // Rename
if (rightItem == null) { if (rightItem.isAir) {
val result = AnvilMergeLogic.doRenaming(view, inventory, player, leftItem) val result = AnvilMergeLogic.doRenaming(view, inventory, player, leftItem)
if (result.isEmpty()) return if (result.isEmpty()) return
@ -103,7 +107,7 @@ class AnvilResultListener : Listener {
} }
// Merge // Merge
val canMerge = leftItem.canMergeWith(rightItem) val canMerge = leftItem.canMergeWith(rightItem!!)
if (canMerge) { if (canMerge) {
val result = AnvilMergeLogic.doMerge(view, inventory, player, leftItem, rightItem) val result = AnvilMergeLogic.doMerge(view, inventory, player, leftItem, rightItem)
@ -193,6 +197,9 @@ class AnvilResultListener : Listener {
result result
) )
) return ) return
else if(player.gameMode != GameMode.CREATIVE) {
return
}
// Finally, we add the item to the player // Finally, we add the item to the player
if (slotDestination.type == SlotType.CURSOR) { if (slotDestination.type == SlotType.CURSOR) {
@ -212,10 +219,10 @@ class AnvilResultListener : Listener {
val recipe = result.recipe!! val recipe = result.recipe!!
// We remove what should be removed // We remove what should be removed
if (rightItem != null) { if (!rightItem.isAir) {
if (recipe.rightItem == null) return false// in case it changed if (recipe.rightItem.isAir) return false// in case it changed
rightItem.amount -= amount * recipe.rightItem!!.amount rightItem!!.amount -= amount * recipe.rightItem!!.amount
inventory.setItem(ANVIL_INPUT_RIGHT, rightItem) inventory.setItem(ANVIL_INPUT_RIGHT, rightItem)
} }
@ -243,6 +250,8 @@ class AnvilResultListener : Listener {
player.updateInventory() player.updateInventory()
} }
handleAnvilMechanic(player, inventory)
return true return true
} }
@ -345,6 +354,8 @@ class AnvilResultListener : Listener {
inventory.setItem(ANVIL_OUTPUT_SLOT, null) inventory.setItem(ANVIL_OUTPUT_SLOT, null)
} else if(player.gameMode != GameMode.CREATIVE) {
return false
} }
// Finally, we add the item to the player // Finally, we add the item to the player
@ -354,7 +365,9 @@ class AnvilResultListener : Listener {
player.inventory.setItem(slotDestination.slot, result.item) player.inventory.setItem(slotDestination.slot, result.item)
} }
// TODO probably anvil damage & sound here ?? if (event.click != ClickType.MIDDLE)
handleAnvilMechanic(player, inventory)
return true return true
} }
@ -382,6 +395,61 @@ class AnvilResultListener : Listener {
} }
} }
// Process both sound & degradation
private fun handleAnvilMechanic(player: HumanEntity, inventory: AnvilInventory) {
return handleAnvilMechanic(player, inventory, player.gameMode != GameMode.CREATIVE)
}
// Process both sound & degradation
private fun handleAnvilMechanic(player: HumanEntity, inventory: AnvilInventory, canDegrade: Boolean) {
// ok so we do not provide a getLocation on view ?
val location = inventory.location
val wasDestroyed = canDegrade && tryDegradeAnvil(player, location)
tryPlaySound(location, wasDestroyed)
}
private fun tryDegradeAnvil(player: HumanEntity, location: Location?): Boolean {
val world = location?.world ?: return false
if (Math.random() > AnvilFinishOptions.degradation_chance) return false
val block = world.getBlockAt(location)
val next = when (block.type) {
Material.ANVIL -> Material.CHIPPED_ANVIL
Material.CHIPPED_ANVIL -> Material.DAMAGED_ANVIL
Material.DAMAGED_ANVIL -> Material.AIR
else -> return false
}
block.type = next
if (next == Material.AIR) {
player.closeInventory()
return true
}
return false
}
private fun tryPlaySound(
location: Location?,
wasDestroyed: Boolean,
) {
val world = location?.world
if (!AnvilFinishOptions.sound_enabled) return
val sound = AnvilFinishOptions.getAnvilSound(wasDestroyed)
world?.playSound(
location,
sound.sound,
sound.category,
sound.volume,
sound.pitch,
)
}
private fun onUnitRepairExtract( private fun onUnitRepairExtract(
rightItem: ItemStack, rightItem: ItemStack,
event: InventoryClickEvent, event: InventoryClickEvent,

View file

@ -176,8 +176,8 @@ class AnvilCustomRecipe(
CustomAnvil.verboseLog("Left item passed !") CustomAnvil.verboseLog("Left item passed !")
// we don't know if right item can be // we don't know if right item can be
if (rightItem == null) { // null test if (rightItem.isAir) { // null test
if (item2 != null) return false if (!item2.isAir) return false
} else { } else {
val rightSimilar = rightItem!!.isSimilar(item2) val rightSimilar = rightItem!!.isSimilar(item2)
CustomAnvil.verboseLog("Right similar: $rightSimilar") CustomAnvil.verboseLog("Right similar: $rightSimilar")

View file

@ -4,6 +4,7 @@ import io.delilaheve.CustomAnvil
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
import kotlin.math.min import kotlin.math.min
object CustomRecipeUtil { object CustomRecipeUtil {
@ -32,7 +33,7 @@ object CustomRecipeUtil {
return if(recipe.exactCount) { return if(recipe.exactCount) {
if(leftItem.amount != recipe.leftItem!!.amount){ if(leftItem.amount != recipe.leftItem!!.amount){
0 0
}else if(rightItem != null && rightItem.amount != recipe.rightItem!!.amount){ }else if(!rightItem.isAir && rightItem!!.amount != recipe.rightItem!!.amount){
0 0
}else{ }else{
1 1
@ -43,7 +44,7 @@ object CustomRecipeUtil {
val resultItem = recipe.resultItem!! // we know exist as the recipe was returned to us val resultItem = recipe.resultItem!! // we know exist as the recipe was returned to us
val maxResultAmount = resultItem.maxStackSize/resultItem.amount val maxResultAmount = resultItem.maxStackSize/resultItem.amount
val maxLeftAmount = leftItem.amount/recipe.leftItem!!.amount val maxLeftAmount = leftItem.amount/recipe.leftItem!!.amount
val maxRightAmount = if(rightItem == null){ maxLeftAmount } else{ rightItem.amount/recipe.rightItem!!.amount } val maxRightAmount = if(rightItem.isAir){ maxLeftAmount } else{ rightItem!!.amount/recipe.rightItem!!.amount }
CustomAnvil.verboseLog("resultItem: $resultItem, maxResultAmount: $maxResultAmount, maxLeftAmount: $maxLeftAmount, maxRightAmount: $maxRightAmount") CustomAnvil.verboseLog("resultItem: $resultItem, maxResultAmount: $maxResultAmount, maxLeftAmount: $maxLeftAmount, maxRightAmount: $maxRightAmount")

View file

@ -1,6 +1,5 @@
package xyz.alexcrea.cuanvil.util package xyz.alexcrea.cuanvil.util
import org.bukkit.Bukkit
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
@ -22,7 +21,7 @@ object MaterialUtil {
val ItemStack.customType: NamespacedKey val ItemStack.customType: NamespacedKey
get() { get() {
if(DependencyManager.ecoEnchantCompatibility != null) { if(DependencyManager.hasEcoItem) {
val result = EcoItemDependencyUtil.ecoItemNamespace(this) val result = EcoItemDependencyUtil.ecoItemNamespace(this)
if(result != null) return result if(result != null) return result
} }
@ -44,7 +43,7 @@ object MaterialUtil {
@Nullable @Nullable
fun getMatFromKey(key: NamespacedKey): Material? { fun getMatFromKey(key: NamespacedKey): Material? {
if(DependencyManager.ecoEnchantCompatibility != null) { if(DependencyManager.hasEcoItem) {
val result = EcoItemDependencyUtil.ecoItemMaterialFromKey(key) val result = EcoItemDependencyUtil.ecoItemMaterialFromKey(key)
if(result != null) return result if(result != null) return result
} }
@ -59,7 +58,7 @@ object MaterialUtil {
} }
fun itemFromKey(key: NamespacedKey): ItemStack { fun itemFromKey(key: NamespacedKey): ItemStack {
if(DependencyManager.ecoEnchantCompatibility != null) { if(DependencyManager.hasEcoItem) {
val result = EcoItemDependencyUtil.newEcoItemstack(key) val result = EcoItemDependencyUtil.newEcoItemstack(key)
if(result != null) return result if(result != null) return result
} }
@ -79,7 +78,7 @@ object MaterialUtil {
fun getMaterialCount(): Int { fun getMaterialCount(): Int {
var count = Material.entries.size var count = Material.entries.size
if(DependencyManager.ecoEnchantCompatibility != null) { if(DependencyManager.hasEcoItem) {
count += EcoItemDependencyUtil.getItems().size count += EcoItemDependencyUtil.getItems().size
} }
@ -93,7 +92,7 @@ object MaterialUtil {
fun getMaterials(): MutableList<NamespacedKey> { fun getMaterials(): MutableList<NamespacedKey> {
val all = ArrayList(Material.entries.map { it.key }) val all = ArrayList(Material.entries.map { it.key })
if(DependencyManager.ecoEnchantCompatibility != null) { if(DependencyManager.hasEcoItem) {
all.addAll(EcoItemDependencyUtil.getItems()) all.addAll(EcoItemDependencyUtil.getItems())
} }

View file

@ -18,7 +18,7 @@ object MetricsUtil {
private var FAST_STATS_METRICS: BukkitContext? = null private var FAST_STATS_METRICS: BukkitContext? = null
fun loadMetrics(plugin: CustomAnvil) { fun loadMetrics(plugin: CustomAnvil) {
if(DependencyManager.externGuiTester.isInTest()) return if(DependencyManager.inTesting) return
val config = ConfigHolder.DEFAULT_CONFIG.config val config = ConfigHolder.DEFAULT_CONFIG.config
val metricString = config.getString(ConfigOptions.METRIC_TYPE, MetricType.AUTO.value)!! val metricString = config.getString(ConfigOptions.METRIC_TYPE, MetricType.AUTO.value)!!

View file

@ -277,7 +277,7 @@ object AnvilXpUtil {
// We know "enchantment.key in resultEnchs" true // We know "enchantment.key in resultEnchs" true
val resultLevel = resultEnchs[enchantment.key]!! val resultLevel = resultEnchs[enchantment.key]!!
val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, isFromBook, isToBook) val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, isToBook, isFromBook)
val value = resultLevel * enchantmentMultiplier val value = resultLevel * enchantmentMultiplier
CustomAnvil.log("Value for sacrifice item ${enchantment.key.enchantmentName} level ${enchantment.value} is $value ($resultLevel * $enchantmentMultiplier)") CustomAnvil.log("Value for sacrifice item ${enchantment.key.enchantmentName} level ${enchantment.value} is $value ($resultLevel * $enchantmentMultiplier)")
rightValue += value rightValue += value
@ -291,7 +291,7 @@ object AnvilXpUtil {
val resultLevel = resultEnchs.getOrDefault(enchantment.key, 0) val resultLevel = resultEnchs.getOrDefault(enchantment.key, 0)
val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, isFromBook, isToBook) val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, isToBook, isFromBook)
val value = resultLevel * enchantmentMultiplier val value = resultLevel * enchantmentMultiplier
CustomAnvil.log("Value for left item ${enchantment.key.enchantmentName} level ${enchantment.value} is $value ($resultLevel * $enchantmentMultiplier)") CustomAnvil.log("Value for left item ${enchantment.key.enchantmentName} level ${enchantment.value} is $value ($resultLevel * $enchantmentMultiplier)")
leftValue += value leftValue += value

View file

@ -463,6 +463,32 @@ monetary_cost:
work_penalty: 1.0 # for work penalty (aka use penalty) work_penalty: 1.0 # for work penalty (aka use penalty)
recipe: 1.0 # for custom anvil recipe cost recipe: 1.0 # for custom anvil recipe cost
# Chance that an anvil get degraded
# set it to zero if you wish to disable it
anvil_degradation: 0.12
# see https://www.digminecraft.com/lists/sound_list_pc.php
# for a list of most of the sounds
anvil_sound:
enabled: true
# The sound are weighted so if there is multiples of them one is selected randomly
# so if you want to add a "rare sound" as an easter egg you can !
# If invalid, it will be removed from the list. and if empty it will use the default
use:
default:
sound: block.anvil.use
category: blocks
volume: 1.0
pitch: 1.0
weight: 1.0
destroy:
default:
sound: block.anvil.destroy
category: blocks
volume: 1.0
pitch: 1.0
weight: 1.0
# Whether to show debug logging # Whether to show debug logging
debug_log: false debug_log: false

View file

@ -80,6 +80,7 @@ softdepend:
- Disenchantment - Disenchantment
- EnchantsSquared - EnchantsSquared
- EcoEnchants - EcoEnchants
- EcoItems
- eco - eco
- ExcellentEnchants - ExcellentEnchants
- HavenBags - HavenBags