diff --git a/build.gradle.kts b/build.gradle.kts index e20ed6f3f67..05966a0368b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,6 +5,6 @@ plugins { allprojects { group = "me.kcra.takenaka" - version = "1.1.2" + version = "1.1.3" description = "A Kotlin library for reconciling multiple obfuscation mapping files from multiple versions of Minecraft: JE." } diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 1685d8a6139..7f539e5f239 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,28 +1,10 @@ -import kotlinx.benchmark.gradle.JvmBenchmarkTarget - plugins { id("takenaka.base-conventions") id("takenaka.publish-conventions") - alias(libs.plugins.kotlinx.benchmark) - alias(libs.plugins.kotlin.plugin.allopen) } apply(plugin = "org.jetbrains.kotlin.jvm") -sourceSets { - create("benchmark") { - compileClasspath += sourceSets.main.get().output - runtimeClasspath += sourceSets.main.get().output - } -} - -val benchmarkImplementation by configurations.getting { - extendsFrom(configurations.implementation.get()) -} -val benchmarkRuntimeOnly by configurations.getting { - extendsFrom(configurations.runtimeOnly.get()) -} - dependencies { api(libs.bundles.asm) api(libs.bundles.jackson) @@ -32,23 +14,8 @@ dependencies { implementation(libs.kotlinx.coroutines.core.jvm) testImplementation(kotlin("test")) testRuntimeOnly(libs.slf4j.simple) - benchmarkImplementation(libs.kotlinx.benchmark.runtime) - benchmarkRuntimeOnly(libs.slf4j.simple) -} - -allOpen { - annotation("org.openjdk.jmh.annotations.State") } tasks.withType { maxHeapSize = "2048m" } - -benchmark { - targets { - register("benchmark") { - this as JvmBenchmarkTarget - jmhVersion = libs.versions.jmh.get() - } - } -} diff --git a/core/src/benchmark/kotlin/me/kcra/takenaka/core/benchmark/mapping/analysis/impl/MappingAnalyzerImplBenchmark.kt b/core/src/benchmark/kotlin/me/kcra/takenaka/core/benchmark/mapping/analysis/impl/MappingAnalyzerImplBenchmark.kt deleted file mode 100644 index 6fb4d34df83..00000000000 --- a/core/src/benchmark/kotlin/me/kcra/takenaka/core/benchmark/mapping/analysis/impl/MappingAnalyzerImplBenchmark.kt +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of takenaka, licensed under the Apache License, Version 2.0 (the "License"). - * - * Copyright (c) 2023-2024 Matous Kucera - * - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package me.kcra.takenaka.core.benchmark.mapping.analysis.impl - -import kotlinx.benchmark.* -import me.kcra.takenaka.core.mapping.analysis.impl.MappingAnalyzerImpl -import me.kcra.takenaka.core.mapping.analysis.impl.StandardProblemKinds -import me.kcra.takenaka.core.mapping.resolve.impl.VanillaMappingContributor -import net.fabricmc.mappingio.MappedElementKind -import net.fabricmc.mappingio.MappingUtil -import net.fabricmc.mappingio.tree.MappingTree -import net.fabricmc.mappingio.tree.MemoryMappingTree -import org.openjdk.jmh.annotations.Level -import java.util.concurrent.TimeUnit - -@State(Scope.Benchmark) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(TimeUnit.NANOSECONDS) -class MappingAnalyzerImplBenchmark { - private lateinit var tree: MappingTree - - @Setup(Level.Invocation) - fun setup() { - tree = createMockTree() - } - - @Benchmark - fun acceptInheritanceCorrections() { - val analyzer = MappingAnalyzerImpl() - - analyzer.accept(tree) - analyzer.acceptResolutions(StandardProblemKinds.INHERITANCE_ERROR) - } - - private fun createMockTree(): MappingTree { - val tree = MemoryMappingTree() - - while (true) { - if (tree.visitHeader()) { - tree.visitNamespaces(MappingUtil.NS_SOURCE_FALLBACK, listOf("missing_namespace", "wrong_namespace", VanillaMappingContributor.NS_SUPER, VanillaMappingContributor.NS_INTERFACES)) - } - - if (tree.visitContent()) { - // class ConcreteClass extends SuperClass { - // @Override - // void overriddenMethod(test.Class arg0) { - // } - // } - if (tree.visitClass("ConcreteClass")) { - tree.visitDstName(MappedElementKind.CLASS, 2, "SuperClass") - if (tree.visitElementContent(MappedElementKind.CLASS)) { - if (tree.visitMethod("overriddenMethod", "(Ltest/Class;)V")) { - tree.visitDstName(MappedElementKind.METHOD, 1, "wrongMappedName") - tree.visitElementContent(MappedElementKind.METHOD) - } - } - } - - // class SuperClass { - // void overriddenMethod(test.Class arg0) { - // } - // } - if (tree.visitClass("SuperClass")) { - tree.visitDstName(MappedElementKind.CLASS, 2, "java/lang/Object") - if (tree.visitElementContent(MappedElementKind.CLASS)) { - if (tree.visitMethod("overriddenMethod", "(Ltest/Class;)V")) { - tree.visitDstName(MappedElementKind.METHOD, 0, "correctMappedName") - tree.visitDstName(MappedElementKind.METHOD, 1, "correctMappedName") - tree.visitElementContent(MappedElementKind.METHOD) - } - } - } - } - - if (tree.visitEnd()) { - break - } - } - - return tree - } -} diff --git a/core/src/benchmark/resources/simplelogger.properties b/core/src/benchmark/resources/simplelogger.properties deleted file mode 100644 index 33cdff7db04..00000000000 --- a/core/src/benchmark/resources/simplelogger.properties +++ /dev/null @@ -1 +0,0 @@ -org.slf4j.simpleLogger.defaultLogLevel=off \ No newline at end of file diff --git a/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/IntermediaryMappingResolver.kt b/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/IntermediaryMappingResolver.kt index 1d63b8bfab2..abc32cf7833 100644 --- a/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/IntermediaryMappingResolver.kt +++ b/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/IntermediaryMappingResolver.kt @@ -92,7 +92,7 @@ class IntermediaryMappingResolver( override val licenseOutput = lazyOutput { resolver { - licenseWorkspace.withLock("intermediary-license") { + licenseWorkspace.withLock(WORKSPACE_LOCK) { val file = licenseWorkspace[LICENSE] if (LICENSE in licenseWorkspace) { @@ -134,6 +134,8 @@ class IntermediaryMappingResolver( } companion object { + private val WORKSPACE_LOCK = object {} + /** * The file name of the cached mappings. */ diff --git a/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/MojangManifestAttributeProvider.kt b/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/MojangManifestAttributeProvider.kt index e1811b6a451..a8e1d8f0134 100644 --- a/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/MojangManifestAttributeProvider.kt +++ b/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/MojangManifestAttributeProvider.kt @@ -50,7 +50,7 @@ class MojangManifestAttributeProvider(val workspace: VersionedWorkspace, private * @return the attributes */ private fun readAttributes(): VersionAttributes { - return workspace.withLock("mojang-manifest") { + return workspace.withLock(WORKSPACE_LOCK) { val file = workspace[ATTRIBUTES] if (relaxedCache && ATTRIBUTES in workspace) { @@ -71,6 +71,8 @@ class MojangManifestAttributeProvider(val workspace: VersionedWorkspace, private } companion object { + private val WORKSPACE_LOCK = object {} + /** * The file name of the cached attributes. */ diff --git a/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SeargeMappingResolver.kt b/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SeargeMappingResolver.kt index 8a0e4ed3ba5..bd847e90e56 100644 --- a/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SeargeMappingResolver.kt +++ b/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SeargeMappingResolver.kt @@ -103,7 +103,7 @@ class SeargeMappingResolver( override val licenseOutput = lazyOutput { resolver { - licenseWorkspace.withLock("searge-license") { + licenseWorkspace.withLock(WORKSPACE_LOCK) { val file = licenseWorkspace[LICENSE] if (LICENSE in licenseWorkspace) { @@ -172,6 +172,8 @@ class SeargeMappingResolver( } companion object { + private val WORKSPACE_LOCK = object {} + /** * The file name of the cached zip file. */ diff --git a/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SpigotManifestProvider.kt b/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SpigotManifestProvider.kt index 8d6e24ccc7a..e6ade5aee6d 100644 --- a/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SpigotManifestProvider.kt +++ b/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SpigotManifestProvider.kt @@ -50,13 +50,19 @@ class SpigotManifestProvider(val workspace: VersionedWorkspace, private val obje */ val attributes by lazy(::readAttributes) + /** + * Whether the resolved manifest is of a different version than requested. + */ + val isAliased: Boolean + get() = attributes?.let { workspace.version.id != it.minecraftVersion } ?: false + /** * Reads the manifest of the targeted version from cache, fetching it if the cache missed. * * @return the manifest */ private fun readManifest(): SpigotVersionManifest? { - return workspace.withLock("spigot-manifest") { + return workspace.withLock(WORKSPACE_LOCK) { val file = workspace[MANIFEST] if (relaxedCache && MANIFEST in workspace) { @@ -92,7 +98,7 @@ class SpigotManifestProvider(val workspace: VersionedWorkspace, private val obje private fun readAttributes(): SpigotVersionAttributes? { if (manifest == null) return null - return workspace.withLock("spigot-manifest") { + return workspace.withLock(WORKSPACE_LOCK) { val file = workspace[BUILDDATA_INFO] if (relaxedCache && BUILDDATA_INFO in workspace) { @@ -113,6 +119,8 @@ class SpigotManifestProvider(val workspace: VersionedWorkspace, private val obje } companion object { + private val WORKSPACE_LOCK = object {} + /** * The file name of the cached version manifest. */ diff --git a/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SpigotMappingResolver.kt b/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SpigotMappingResolver.kt index 57aa211bb16..e20c120acdb 100644 --- a/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SpigotMappingResolver.kt +++ b/core/src/main/kotlin/me/kcra/takenaka/core/mapping/resolve/impl/SpigotMappingResolver.kt @@ -281,6 +281,10 @@ class SpigotClassMappingResolver( * @return the mapping attribute */ override fun resolveMappingAttribute(): MappingAttribute { + if (spigotProvider.isAliased) { + logger.warn { "expected ${workspace.version.id}, got ${spigotProvider.attributes?.minecraftVersion}; aliased manifest?" } + } + return MappingAttribute("classMappings", spigotProvider.attributes?.classMappings) } diff --git a/generator/accessor-runtime/src/main/java/me/kcra/takenaka/accessor/platform/MapperPlatforms.java b/generator/accessor-runtime/src/main/java/me/kcra/takenaka/accessor/platform/MapperPlatforms.java index 8d15463c21b..f72c29bd297 100644 --- a/generator/accessor-runtime/src/main/java/me/kcra/takenaka/accessor/platform/MapperPlatforms.java +++ b/generator/accessor-runtime/src/main/java/me/kcra/takenaka/accessor/platform/MapperPlatforms.java @@ -17,6 +17,7 @@ package me.kcra.takenaka.accessor.platform; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import java.lang.reflect.InvocationTargetException; @@ -33,6 +34,43 @@ * @author Matouš Kučera */ public enum MapperPlatforms implements MapperPlatform { + /** + * A generic abstraction for Mojang software derivatives (Mojang mappings). + */ + MOJANG { + private String minecraftVersion = null; + + { + try { + final Class constClass = Class.forName("net.minecraft.SharedConstants", true, getClassLoader()); + final Object gameVersion = constClass.getMethod("getCurrentVersion").invoke(null); + + minecraftVersion = (String) gameVersion.getClass().getMethod("getName").invoke(gameVersion); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException("Failed to get Minecraft version", e); + } catch (ClassNotFoundException | NoSuchMethodException ignored) { + } + } + + @Override + public boolean isSupported() { + return minecraftVersion != null; + } + + @Override + public @NotNull String getVersion() { + if (!isSupported()) { + throw new UnsupportedOperationException("Mojang is not supported by this environment"); + } + return minecraftVersion; + } + + @Override + public @NotNull String[] getMappingNamespaces() { + return new String[] { "mojang" }; + } + }, + /** * An abstraction for platforms that implement the Bukkit API (Spigot mappings). */ @@ -84,39 +122,25 @@ public boolean isSupported() { /** * An abstraction for NeoForge-based platforms (Mojang mappings). + * + * @deprecated use {@link #MOJANG} */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.0.0") NEOFORGE { - private String minecraftVersion = null; - - { - try { - final Class neoFormVersionClass = Class.forName( - "net.neoforged.neoforge.internal.versions.neoform.NeoFormVersion", - true, getClassLoader() - ); - minecraftVersion = (String) neoFormVersionClass.getMethod("getMCVersion").invoke(null); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException("Failed to get Minecraft version", e); - } catch (ClassNotFoundException ignored) { - } - } - @Override public boolean isSupported() { - return minecraftVersion != null; + return MOJANG.isSupported(); } @Override public @NotNull String getVersion() { - if (!isSupported()) { - throw new UnsupportedOperationException("NeoForge is not supported by this environment"); - } - return minecraftVersion; + return MOJANG.getVersion(); } @Override public @NotNull String[] getMappingNamespaces() { - return new String[] { "mojang" }; + return MOJANG.getMappingNamespaces(); } }, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f72f97df60a..4f21fdccded 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,9 +1,7 @@ [versions] kotlin = "1.9.22" asm = "9.7" -jackson = "2.17.0" -jmh = "1.37" -kotlinx-benchmark = "0.4.10" +jackson = "2.17.1" kotlinpoet = "1.16.0" [libraries] @@ -16,11 +14,10 @@ jackson-datatype-jsr310 = { group = "com.fasterxml.jackson.datatype", name = "ja jackson-dataformat-xml = { group = "com.fasterxml.jackson.dataformat", name = "jackson-dataformat-xml", version.ref = "jackson" } mapping-io = { group = "net.fabricmc", name = "mapping-io", version = "0.4.2" } kotlin-logging-jvm = { group = "io.github.microutils", name = "kotlin-logging-jvm", version = "3.0.5" } -slf4j-simple = { group = "org.slf4j", name = "slf4j-simple", version = "2.0.12" } +slf4j-simple = { group = "org.slf4j", name = "slf4j-simple", version = "2.0.13" } kotlinx-coroutines-core-jvm = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core-jvm", version = "1.8.0" } kotlinx-html-jvm = { group = "org.jetbrains.kotlinx", name = "kotlinx-html-jvm", version = "0.11.0" } kotlinx-cli-jvm = { group = "org.jetbrains.kotlinx", name = "kotlinx-cli-jvm", version = "0.3.6" } -kotlinx-benchmark-runtime = { group = "org.jetbrains.kotlinx", name = "kotlinx-benchmark-runtime", version.ref = "kotlinx-benchmark" } jb-annotations = { group = "org.jetbrains", name = "annotations", version = "24.1.0" } javapoet = { group = "com.squareup", name = "javapoet", version = "1.13.0" } kotlinpoet = { group = "com.squareup", name = "kotlinpoet", version.ref = "kotlinpoet" } @@ -36,7 +33,5 @@ jackson = ["jackson-module-kotlin", "jackson-datatype-jsr310", "jackson-dataform [plugins] kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } shadow = { id = "io.github.goooler.shadow", version = "8.1.7" } -kotlinx-benchmark = { id = "org.jetbrains.kotlinx.benchmark", version.ref = "kotlinx-benchmark" } -kotlin-plugin-allopen = { id = "org.jetbrains.kotlin.plugin.allopen", version.ref = "kotlin" } gradle-plugin-publish = { id = "com.gradle.plugin-publish", version = "1.2.1" } build-config = { id = "com.github.gmazzo.buildconfig", version = "5.3.5" }