diff --git a/buildSrc/src/main/kotlin/core-convention.gradle.kts b/buildSrc/src/main/kotlin/core-convention.gradle.kts index 815215862..24631c194 100644 --- a/buildSrc/src/main/kotlin/core-convention.gradle.kts +++ b/buildSrc/src/main/kotlin/core-convention.gradle.kts @@ -72,6 +72,7 @@ tasks { val relocationPrefix: String by project relocate("net.kyori.adventure.nbt", "$relocationPrefix.kyori.nbt") + relocate("org.spongepowered.configurate", "$relocationPrefix.configurate") } javadoc { diff --git a/gradle.properties b/gradle.properties index df3c41811..de8d5e8f9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,6 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled javaVersion=25 mcVersion=26.1.2 group=dev.slne.surf.api -version=3.11.1 +version=3.11.2 relocationPrefix=dev.slne.surf.api.libs snapshot=false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 26d7aedbf..62994d07b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -51,9 +51,9 @@ dazzleconf = "1.4.0-M2" reflection-remapper = "0.1.3" brigadier = "1.0.500" datafixerupper = "8.0.16" -configurate = "4.2.0" +configurate = "1.0.0" more-persistent-data-types = "2.4.0" -inventory-framework = "3.7.1" +inventory-framework = "1.0.4" flogger = "0.9" aide-reflection = "1.3" auto-service = "1.1.1" @@ -142,12 +142,12 @@ okhttp-kotlin = { module = "com.squareup.okhttp3:okhttp-coroutines", version.ref dazzleconf = { module = "space.arim.dazzleconf:dazzleconf-ext-snakeyaml", version.ref = "dazzleconf" } reflection-remapper = { module = "xyz.jpenilla:reflection-remapper", version.ref = "reflection-remapper" } brigadier = { module = "com.mojang:brigadier", version.ref = "brigadier" } -configurate-yaml = { module = "org.spongepowered:configurate-yaml", version.ref = "configurate" } -configurate-jackson = { module = "org.spongepowered:configurate-jackson", version.ref = "configurate" } -configurate-kotlin = { module = "org.spongepowered:configurate-extra-kotlin", version.ref = "configurate" } +configurate-yaml = { module = "dev.slne.forks.configurate:configurate-yaml", version.ref = "configurate" } +configurate-jackson = { module = "dev.slne.forks.configurate:configurate-jackson", version.ref = "configurate" } +configurate-kotlin = { module = "dev.slne.forks.configurate:configurate-extra-kotlin", version.ref = "configurate" } more-persistent-data-types = { module = "com.jeff-media:MorePersistentDataTypes", version.ref = "more-persistent-data-types" } -inventory-framework-platform-paper = { module = "me.devnatan:inventory-framework-platform-paper", version.ref = "inventory-framework" } -inventory-framework-platform-bukkit = { module = "me.devnatan:inventory-framework-platform-bukkit", version.ref = "inventory-framework" } +inventory-framework-platform-paper = { module = "dev.slne.forks.inventoryframework:inventory-framework-platform-paper", version.ref = "inventory-framework" } +inventory-framework-platform-bukkit = { module = "dev.slne.forks.inventoryframework:inventory-framework-platform-bukkit", version.ref = "inventory-framework" } flogger = { module = "com.google.flogger:flogger", version.ref = "flogger" } flogger-slf4j-backend = { module = "com.google.flogger:flogger-slf4j-backend", version.ref = "flogger" } aide-reflection = { module = "tech.hiddenproject:aide-reflection", version.ref = "aide-reflection" } diff --git a/surf-api-core/surf-api-core/build.gradle.kts b/surf-api-core/surf-api-core/build.gradle.kts index 961052634..29b6817af 100644 --- a/surf-api-core/surf-api-core/build.gradle.kts +++ b/surf-api-core/surf-api-core/build.gradle.kts @@ -15,8 +15,8 @@ dependencies { compileOnlyApi(libs.fastutil) compileOnlyApi(libs.commandapi.core) compileOnlyApi(libs.brigadier) - compileOnlyApi(libs.configurate.yaml) - compileOnlyApi(libs.configurate.jackson) + api(libs.configurate.yaml) + api(libs.configurate.jackson) api(libs.configurate.kotlin) compileOnlyApi(libs.flogger) compileOnlyApi(libs.commons.math4.core) diff --git a/surf-api-core/surf-api-core/src/main/java/dev/slne/surf/api/core/config/manager/OldSpongeReflections.java b/surf-api-core/surf-api-core/src/main/java/dev/slne/surf/api/core/config/manager/OldSpongeReflections.java new file mode 100644 index 000000000..661598d7c --- /dev/null +++ b/surf-api-core/surf-api-core/src/main/java/dev/slne/surf/api/core/config/manager/OldSpongeReflections.java @@ -0,0 +1,81 @@ +package dev.slne.surf.api.core.config.manager; + +import org.jspecify.annotations.NullMarked; + +import java.lang.annotation.Annotation; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +@SuppressWarnings("unchecked") +@NullMarked +final class OldSpongeReflections { + static final Class OLD_CONFIG_SERIALIZABLE_ANNOTATION; + static final Class OLD_COMMENT_ANNOTATION; + static final Class OLD_MATCHES_ANNOTATION; + static final Class OLD_REQUIRED_ANNOTATION; + static final Class OLD_SETTING_ANNOTATION; + + private static final MethodHandle OLD_COMMENT_OVERRIDE; + private static final MethodHandle OLD_COMMENT_VALUE; + + private static final MethodHandle OLD_MATCHES_VALUE; + private static final MethodHandle OLD_MATCHES_FLAGS; + private static final MethodHandle OLD_MATCHES_FAILURE_MESSAGE; + + private static final MethodHandle OLD_SETTING_VALUE; + private static final MethodHandle OLD_SETTING_NODE_FROM_PARENT; + + static boolean isCommentOverride(final Annotation annotation) throws Throwable { + return (boolean) OLD_COMMENT_OVERRIDE.invoke(annotation); + } + + static String getCommentValue(final Annotation annotation) throws Throwable { + return (String) OLD_COMMENT_VALUE.invoke(annotation); + } + + static String getMatchesValue(final Annotation annotation) throws Throwable { + return (String) OLD_MATCHES_VALUE.invoke(annotation); + } + + static int getMatchesFlags(final Annotation annotation) throws Throwable { + return (int) OLD_MATCHES_FLAGS.invoke(annotation); + } + + static String getMatchesFailureMessage(final Annotation annotation) throws Throwable { + return (String) OLD_MATCHES_FAILURE_MESSAGE.invoke(annotation); + } + + static String getSettingValue(final Annotation annotation) throws Throwable { + return (String) OLD_SETTING_VALUE.invoke(annotation); + } + + static boolean isSettingNodeFromParent(final Annotation annotation) throws Throwable { + return (boolean) OLD_SETTING_NODE_FROM_PARENT.invoke(annotation); + } + + static { + try { + final MethodHandles.Lookup lookup = MethodHandles.lookup(); + + OLD_CONFIG_SERIALIZABLE_ANNOTATION = (Class) Class.forName("org.spongepowered".concat(".configurate.objectmapping.ConfigSerializable")); + OLD_COMMENT_ANNOTATION = (Class) Class.forName("org.spongepowered".concat(".configurate.objectmapping.meta.Comment")); + OLD_MATCHES_ANNOTATION = (Class) Class.forName("org.spongepowered".concat(".configurate.objectmapping.meta.Matches")); + OLD_REQUIRED_ANNOTATION = (Class) Class.forName("org.spongepowered".concat(".configurate.objectmapping.meta.Required")); + OLD_SETTING_ANNOTATION = (Class) Class.forName("org.spongepowered".concat(".configurate.objectmapping.meta.Setting")); + + OLD_COMMENT_OVERRIDE = lookup.findVirtual(OLD_COMMENT_ANNOTATION, "override", MethodType.methodType(boolean.class)); + OLD_COMMENT_VALUE = lookup.findVirtual(OLD_COMMENT_ANNOTATION, "value", MethodType.methodType(String.class)); + + OLD_MATCHES_VALUE = lookup.findVirtual(OLD_MATCHES_ANNOTATION, "value", MethodType.methodType(String.class)); + OLD_MATCHES_FLAGS = lookup.findVirtual(OLD_MATCHES_ANNOTATION, "flags", MethodType.methodType(int.class)); + OLD_MATCHES_FAILURE_MESSAGE = lookup.findVirtual(OLD_MATCHES_ANNOTATION, "failureMessage", MethodType.methodType(String.class)); + + OLD_SETTING_VALUE = lookup.findVirtual(OLD_SETTING_ANNOTATION, "value", MethodType.methodType(String.class)); + OLD_SETTING_NODE_FROM_PARENT = lookup.findVirtual(OLD_SETTING_ANNOTATION, "nodeFromParent", MethodType.methodType(boolean.class)); + + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { + throw new ExceptionInInitializerError(e); + } + } +} diff --git a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/manager/SpongeConfigManager.kt b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/manager/SpongeConfigManager.kt index 0873b15a2..79dffc535 100644 --- a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/manager/SpongeConfigManager.kt +++ b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/manager/SpongeConfigManager.kt @@ -8,18 +8,28 @@ import dev.slne.surf.api.core.config.migration.ConfigMigration import dev.slne.surf.api.core.config.migration.ConfigMigrationBuilder import dev.slne.surf.api.core.config.serializer.surfSpongeConfigSerializers import dev.slne.surf.api.core.util.logger +import io.leangen.geantyref.GenericTypeReflector +import org.spongepowered.configurate.CommentedConfigurationNodeIntermediary import org.spongepowered.configurate.ConfigurateException import org.spongepowered.configurate.ConfigurationNode import org.spongepowered.configurate.ScopedConfigurationNode import org.spongepowered.configurate.jackson.JacksonConfigurationLoader +import org.spongepowered.configurate.kotlin.dataClassFieldDiscoverer import org.spongepowered.configurate.loader.AbstractConfigurationLoader import org.spongepowered.configurate.loader.ConfigurationLoader +import org.spongepowered.configurate.objectmapping.ObjectMapper +import org.spongepowered.configurate.objectmapping.meta.Constraint +import org.spongepowered.configurate.objectmapping.meta.NodeResolver import org.spongepowered.configurate.serialize.SerializationException +import org.spongepowered.configurate.serialize.TypeSerializerCollection import org.spongepowered.configurate.yaml.NodeStyle import org.spongepowered.configurate.yaml.YamlConfigurationLoader import java.io.Serial import java.io.UncheckedIOException import java.nio.file.Path +import java.text.MessageFormat +import java.util.* +import java.util.regex.Pattern /** * Manages configurations using Sponge's Configurate library, including loading, saving, and reloading configurations. @@ -186,7 +196,7 @@ class SpongeConfigManager private constructor( migrations: ConfigMigrationBuilder = ConfigMigrationBuilder() ): SpongeConfigManager = buildConfigManager( "https://yamlchecker.com/", - YamlConfigurationLoader.builder().nodeStyle(NodeStyle.BLOCK), + YamlConfigurationLoader.builder().nodeStyle(NodeStyle.BLOCK).commentsEnabled(true), configClass, configFolder, configFileName, @@ -229,8 +239,16 @@ class SpongeConfigManager private constructor( ): SpongeConfigManager { val loader = builder.path(configFolder.resolve(configFileName)) .defaultOptions { - it.serializers(surfSpongeConfigSerializers.buildSerializersModule()) - .shouldCopyDefaults(true) + it.serializers { serializers -> + surfSpongeConfigSerializers.buildSerializersModule().accept(serializers) + + try { + OldSpongeReflections.OLD_CONFIG_SERIALIZABLE_ANNOTATION // If this throws an exception, there are no none relocated annotations, no need to register — most likely the standalone version + serializers.registerBackwardsCompatibleSerializers() + } catch (_: Throwable) { + // no none relocated annotations, no need to register + } + }.shouldCopyDefaults(true) } .build() @@ -268,6 +286,75 @@ class SpongeConfigManager private constructor( throw LoadConfigException(e) } } + + private fun TypeSerializerCollection.Builder.registerBackwardsCompatibleSerializers() { + register( + { type -> + GenericTypeReflector.annotate(type) + .isAnnotationPresent(OldSpongeReflections.OLD_CONFIG_SERIALIZABLE_ANNOTATION) + }, + ObjectMapper.factoryBuilder() + .addDiscoverer(dataClassFieldDiscoverer()) + .addProcessor(OldSpongeReflections.OLD_COMMENT_ANNOTATION) { data, _ -> + { _, destination -> + if (destination is CommentedConfigurationNodeIntermediary<*>) { + if (OldSpongeReflections.isCommentOverride(data)) { + destination.comment(OldSpongeReflections.getCommentValue(data)) + } else { + destination.commentIfAbsent(OldSpongeReflections.getCommentValue(data)) + } + } + } + } + .addConstraint( + OldSpongeReflections.OLD_MATCHES_ANNOTATION, + String::class.java + ) { data, _ -> + val value = OldSpongeReflections.getMatchesValue(data) + val flags = OldSpongeReflections.getMatchesFlags(data) + val failureMessage = OldSpongeReflections.getMatchesFailureMessage(data) + + val test = Pattern.compile(value, flags) + val format = MessageFormat(failureMessage, Locale.getDefault()) + + Constraint { toValidate -> + if (toValidate != null) { + val match = test.matcher(toValidate) + if (!match.matches()) { + throw SerializationException(format.format(arrayOf(toValidate, value))) + } + } + } + } + .addConstraint(OldSpongeReflections.OLD_REQUIRED_ANNOTATION, Constraint.required()) + .addNodeResolver(fun(name, element): NodeResolver? { + if (element.isAnnotationPresent(OldSpongeReflections.OLD_SETTING_ANNOTATION)) { + val annotation = + element.getAnnotation(OldSpongeReflections.OLD_SETTING_ANNOTATION) + val key = OldSpongeReflections.getSettingValue(annotation) + if (key.isNotEmpty()) { + return { node -> node.node(key) } + } + } + + return null + }) + .addNodeResolver(fun(name, element): NodeResolver? { + if (element.isAnnotationPresent(OldSpongeReflections.OLD_SETTING_ANNOTATION)) { + val annotation = + element.getAnnotation(OldSpongeReflections.OLD_SETTING_ANNOTATION) + val nodeFromParent = OldSpongeReflections.isSettingNodeFromParent(annotation) + if (nodeFromParent) { + return { node -> node } + } + } + + return null + }) + .build() + .asTypeSerializer() + ) + } } } diff --git a/surf-api-gradle-plugin/src/main/kotlin/dev/slne/surf/api/gradle/platform/core/CoreSurfPlugin.kt b/surf-api-gradle-plugin/src/main/kotlin/dev/slne/surf/api/gradle/platform/core/CoreSurfPlugin.kt index 289d294d9..9f924f719 100644 --- a/surf-api-gradle-plugin/src/main/kotlin/dev/slne/surf/api/gradle/platform/core/CoreSurfPlugin.kt +++ b/surf-api-gradle-plugin/src/main/kotlin/dev/slne/surf/api/gradle/platform/core/CoreSurfPlugin.kt @@ -11,6 +11,7 @@ internal abstract class AbstractCoreSurfPlugin( "com.mojang.serialization" relocatesTo "mojang.serialization" "com.mojang.datafixers" relocatesTo "mojang.datafixers" "net.kyori.adventure.nbt" relocatesTo "kyori.nbt" + "org.spongepowered.configurate" relocatesTo "configurate" } final override fun Project.afterEvaluated0(extension: E) { diff --git a/surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/PaperPluginMain.kt b/surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/PaperPluginMain.kt index bdc61d7ce..c36793593 100644 --- a/surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/PaperPluginMain.kt +++ b/surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/PaperPluginMain.kt @@ -5,12 +5,14 @@ import com.destroystokyo.paper.event.server.ServerTickStartEvent import com.github.shynixn.mccoroutine.folia.SuspendingJavaPlugin import dev.jorel.commandapi.CommandAPI import dev.slne.surf.api.core.component.surfComponentApi +import dev.slne.surf.api.core.config.SurfConfigApi import dev.slne.surf.api.paper.event.listen import dev.slne.surf.api.paper.inventory.framework.register import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi import dev.slne.surf.api.paper.test.command.SurfApiTestCommand import dev.slne.surf.api.paper.test.command.subcommands.reflection.Reflection +import dev.slne.surf.api.paper.test.config.TestConfig2 import dev.slne.surf.api.paper.test.listener.ChatListener import dev.slne.surf.surfapi.bukkit.test.command.dialog.dialogTestCommand import dev.slne.surf.surfapi.bukkit.test.command.subcommands.inventory.TestInventoryView @@ -31,6 +33,8 @@ class PaperPluginMain : SuspendingJavaPlugin() { SurfPaperPacketListenerApi.registerListeners(ChatListener()) TestInventoryView.register() testInventoryViewDsl.register() + + SurfConfigApi.createSpongeYmlConfig(TestConfig2::class.java, dataPath, "test-config-2.yml") } override suspend fun onEnableAsync() { diff --git a/surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/config/ModernTestConfig.kt b/surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/config/ModernTestConfig.kt index 61af9d599..1091e13d1 100644 --- a/surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/config/ModernTestConfig.kt +++ b/surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/config/ModernTestConfig.kt @@ -3,9 +3,11 @@ package dev.slne.surf.surfapi.bukkit.test.config import dev.slne.surf.api.core.config.SpongeYmlConfigClass import dev.slne.surf.surfapi.bukkit.test.plugin import org.spongepowered.configurate.objectmapping.ConfigSerializable +import org.spongepowered.configurate.objectmapping.meta.Comment @ConfigSerializable data class ModernTestConfig( + @Comment("This is a modern config!") var message: String = "Hello from Modern Config!", var number: Int = 42, var enabled: Boolean = true diff --git a/surf-api-paper/surf-api-paper-server/build.gradle.kts b/surf-api-paper/surf-api-paper-server/build.gradle.kts index 9f927eacc..e2a7770f6 100644 --- a/surf-api-paper/surf-api-paper-server/build.gradle.kts +++ b/surf-api-paper/surf-api-paper-server/build.gradle.kts @@ -39,8 +39,6 @@ dependencies { paperLibrary(libs.okhttp) paperLibrary(libs.fastutil) paperLibrary(libs.reflection.remapper) - paperLibrary(libs.configurate.yaml) - paperLibrary(libs.configurate.jackson) paperLibrary(libs.more.persistent.data.types) paperLibrary(libs.flogger) paperLibrary(libs.flogger.slf4j.backend) diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/inventory/framework/InventoryLoader.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/inventory/framework/InventoryLoader.kt index b4374f5e5..bdc23cd67 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/inventory/framework/InventoryLoader.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/inventory/framework/InventoryLoader.kt @@ -4,11 +4,12 @@ import dev.slne.surf.api.paper.server.plugin import me.devnatan.inventoryframework.ViewFrame object InventoryLoader { - init { - McVersionRemapper.remap() - InventoryViewRemapper.remap() - CloseContextRemapper.remap() - } + // Currently not needed due to fork +// init { +// McVersionRemapper.remap() +// InventoryViewRemapper.remap() +// CloseContextRemapper.remap() +// } lateinit var viewFrame: ViewFrame diff --git a/surf-api-standalone/build.gradle.kts b/surf-api-standalone/build.gradle.kts index 0fea67fe7..753f6fe1b 100644 --- a/surf-api-standalone/build.gradle.kts +++ b/surf-api-standalone/build.gradle.kts @@ -24,8 +24,6 @@ dependencies { api(libs.commons.text) api(libs.okhttp) api(libs.fastutil) - api(libs.configurate.yaml) - api(libs.configurate.jackson) api(libs.flogger) api(libs.commons.math4.core) api(libs.commons.math3)