From 12ed5bc360e3fa934dd7af02b1a9b1da2150dc96 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 27 Jan 2024 18:40:16 +0200 Subject: [PATCH 01/15] Testing setup --- .github/workflows/build.yml | 6 ++- build.gradle.kts | 45 ++++++++++++++++++- .../sinytra/connector/test/ConnectorTest.java | 30 +++++++++++++ .../test/mixin/client/MinecraftMixin.java | 19 ++++++++ .../test/mixin/client/QuickPlayMixin.java | 27 +++++++++++ src/test/resources/META-INF/MANIFEST.MF | 2 + src/test/resources/META-INF/mods.toml | 11 +++++ src/test/resources/connectortest.mixins.json | 15 +++++++ src/test/resources/pack.mcmeta | 8 ++++ testmods.txt | 1 + 10 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/sinytra/connector/test/ConnectorTest.java create mode 100644 src/test/java/org/sinytra/connector/test/mixin/client/MinecraftMixin.java create mode 100644 src/test/java/org/sinytra/connector/test/mixin/client/QuickPlayMixin.java create mode 100644 src/test/resources/META-INF/MANIFEST.MF create mode 100644 src/test/resources/META-INF/mods.toml create mode 100644 src/test/resources/connectortest.mixins.json create mode 100644 src/test/resources/pack.mcmeta create mode 100644 testmods.txt diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7c0c8b3e..e7e4be9f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,8 +18,10 @@ jobs: gradle-home-cache-cleanup: true gradle-home-cache-excludes: | gradle.properties - - run: ./gradlew clean build publishToMavenLocal --stacktrace + - run: ./gradlew clean build --stacktrace + - run: ./gradlew runTestModClient + - run: ./gradlew publishToMavenLocal --stacktrace - uses: actions/upload-artifact@v3 with: name: Maven Local - path: ~/.m2/repository \ No newline at end of file + path: ~/.m2/repository diff --git a/build.gradle.kts b/build.gradle.kts index 504dd7a3..769823b9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,6 +22,7 @@ plugins { id("me.modmuss50.mod-publish-plugin") version "0.3.+" id("net.neoforged.gradleutils") version "2.0.+" id("org.parchmentmc.librarian.forgegradle") version "1.+" + id ("de.undercouch.download") version "5.5.0" } val versionConnector: String by project @@ -56,6 +57,7 @@ if (!PUBLISH_RELEASE_TYPE.isPresent) { println("Project version: $version") val mod: SourceSet by sourceSets.creating +val test: SourceSet by sourceSets val shade: Configuration by configurations.creating { isTransitive = false } val adapterData: Configuration by configurations.creating @@ -231,8 +233,20 @@ minecraft { } } - create("client", config) + val clientConfig = create("client", config) create("server", config) + + create("testModClient") { + mods { + create("testconnector") { + sources(test) + } + } + args("--mixin.config", "connectortest.mixins.json") + args("--quickPlaySingleplayer", "ctest") + parent(clientConfig) + workingDirectory = project.file("run/test").canonicalPath + } } } @@ -312,6 +326,12 @@ tasks { dependsOn("reobfModJar", fullJar) } + val modDownload = register("downloadMods") { + doLast { + downloadMods() + } + } + configureEach { if (name == "prepareRuns") { dependsOn(fullJar) @@ -322,6 +342,29 @@ tasks { if (name == "reobfModJar") { mustRunAfter(modJar) } + if (name == "runTestModClient") { + dependsOn(modDownload) + } + } +} + +fun downloadMods() { + val dir = project.file("run/test/mods") + if (dir.exists()) { + dir.deleteRecursively() + } + dir.mkdirs() + + file("testmods.txt").forEachLine { + if (it.isBlank() || it.startsWith("#")) return@forEachLine + + val split = it.split(" ") + if (split.isEmpty()) return@forEachLine + + download.run { + dest(dir) + src(split[0]) + } } } diff --git a/src/test/java/org/sinytra/connector/test/ConnectorTest.java b/src/test/java/org/sinytra/connector/test/ConnectorTest.java new file mode 100644 index 00000000..1c37ea40 --- /dev/null +++ b/src/test/java/org/sinytra/connector/test/ConnectorTest.java @@ -0,0 +1,30 @@ +package org.sinytra.connector.test; + +import com.mojang.logging.LogUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.PauseScreen; +import net.minecraft.client.gui.screens.ReceivingLevelScreen; +import net.minecraftforge.client.event.ScreenEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.Mod; + +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +@Mod("testconnector") +public class ConnectorTest { + public ConnectorTest() { + MinecraftForge.EVENT_BUS.addListener((final ScreenEvent.Opening event) -> { + if (event.getNewScreen() instanceof PauseScreen) { + Minecraft.getInstance().setScreen(null); + Minecraft.getInstance().mouseHandler.grabMouse(); + } + }); + MinecraftForge.EVENT_BUS.addListener((final ScreenEvent.Closing event) -> { + if (event.getScreen() instanceof PauseScreen || event.getScreen() instanceof ReceivingLevelScreen) { + LogUtils.getLogger().info("Screen reset, scheduling shutdown in 5 seconds"); + Executors.newSingleThreadScheduledExecutor().schedule(() -> System.exit(0), 5, TimeUnit.SECONDS); + } + }); + } +} diff --git a/src/test/java/org/sinytra/connector/test/mixin/client/MinecraftMixin.java b/src/test/java/org/sinytra/connector/test/mixin/client/MinecraftMixin.java new file mode 100644 index 00000000..6e828ba5 --- /dev/null +++ b/src/test/java/org/sinytra/connector/test/mixin/client/MinecraftMixin.java @@ -0,0 +1,19 @@ +package org.sinytra.connector.test.mixin.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.ErrorScreen; +import net.minecraft.client.gui.screens.Screen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Minecraft.class) +public class MinecraftMixin { + @Inject(method = "setScreen", at = @At("HEAD")) + private void onSetScreen(Screen screen, CallbackInfo ci) { + if (screen instanceof ErrorScreen) { + System.exit(1); + } + } +} diff --git a/src/test/java/org/sinytra/connector/test/mixin/client/QuickPlayMixin.java b/src/test/java/org/sinytra/connector/test/mixin/client/QuickPlayMixin.java new file mode 100644 index 00000000..be66e6f3 --- /dev/null +++ b/src/test/java/org/sinytra/connector/test/mixin/client/QuickPlayMixin.java @@ -0,0 +1,27 @@ +package org.sinytra.connector.test.mixin.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.quickplay.QuickPlay; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.Difficulty; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.LevelSettings; +import net.minecraft.world.level.WorldDataConfiguration; +import net.minecraft.world.level.levelgen.WorldOptions; +import net.minecraft.world.level.levelgen.presets.WorldPresets; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(QuickPlay.class) +public class QuickPlayMixin { + @Inject(method = "joinSingleplayerWorld", at = @At("HEAD")) + private static void createWorld(Minecraft pMinecraft, String pLevelName, CallbackInfo ci) { + if (!pMinecraft.getLevelSource().levelExists(pLevelName)) { + pMinecraft.createWorldOpenFlows().createFreshLevel(pLevelName, new LevelSettings("Connector test", GameType.SURVIVAL, false, Difficulty.NORMAL, false, new GameRules(), WorldDataConfiguration.DEFAULT), + new WorldOptions("Connector Test".hashCode(), true, true), WorldPresets::createNormalWorldDimensions); + } + } +} diff --git a/src/test/resources/META-INF/MANIFEST.MF b/src/test/resources/META-INF/MANIFEST.MF new file mode 100644 index 00000000..0dea672f --- /dev/null +++ b/src/test/resources/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1 +MixinConfigs: connectortest.mixins.json diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/META-INF/mods.toml new file mode 100644 index 00000000..b50f9a07 --- /dev/null +++ b/src/test/resources/META-INF/mods.toml @@ -0,0 +1,11 @@ +modLoader="javafml" +loaderVersion="[47,)" +license="MIT" +issueTrackerURL="https://github.com/Sinytra/Connector/issues" + +[[mods]] +modId="testconnector" +version="${file.jarVersion}" +displayName="Connector Test" +description=''' +''' diff --git a/src/test/resources/connectortest.mixins.json b/src/test/resources/connectortest.mixins.json new file mode 100644 index 00000000..cc53789a --- /dev/null +++ b/src/test/resources/connectortest.mixins.json @@ -0,0 +1,15 @@ +{ + "required": true, + "minVersion": "0.8.4", + "package": "org.sinytra.connector.test.mixin", + "compatibilityLevel": "JAVA_17", + "mixins": [ + ], + "client": [ + "client.MinecraftMixin", + "client.QuickPlayMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/test/resources/pack.mcmeta b/src/test/resources/pack.mcmeta new file mode 100644 index 00000000..d9989eb8 --- /dev/null +++ b/src/test/resources/pack.mcmeta @@ -0,0 +1,8 @@ +{ + "pack": { + "description": { + "text": "connector test resources" + }, + "pack_format": 15 + } +} diff --git a/testmods.txt b/testmods.txt new file mode 100644 index 00000000..14ef8199 --- /dev/null +++ b/testmods.txt @@ -0,0 +1 @@ +https://cdn.modrinth.com/data/ZHKrK8Rp/versions/Q8JSGhdj/fastback-0.15.6%2B1.20.1-fabric.jar https://modrinth.com/mod/fastback From 363f1440805bbd89895c8aa007cfd45bd11d49ea Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 27 Jan 2024 18:51:54 +0200 Subject: [PATCH 02/15] Disable `downloadAssets` on CI --- build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 769823b9..b360a0f4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -345,6 +345,10 @@ tasks { if (name == "runTestModClient") { dependsOn(modDownload) } + + if (name == "downloadAssets" && providers.environmentVariable("CI").isPresent) { + enabled = false + } } } From 69c6e2cdc8c9df274ac147d328a8e568248e36b2 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 27 Jan 2024 18:56:11 +0200 Subject: [PATCH 03/15] Disable early window --- build.gradle.kts | 4 ---- run/test/config/fml.toml | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 run/test/config/fml.toml diff --git a/build.gradle.kts b/build.gradle.kts index b360a0f4..769823b9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -345,10 +345,6 @@ tasks { if (name == "runTestModClient") { dependsOn(modDownload) } - - if (name == "downloadAssets" && providers.environmentVariable("CI").isPresent) { - enabled = false - } } } diff --git a/run/test/config/fml.toml b/run/test/config/fml.toml new file mode 100644 index 00000000..a7ef7888 --- /dev/null +++ b/run/test/config/fml.toml @@ -0,0 +1,25 @@ +#Early window height +earlyWindowHeight = 480 +#Early window framebuffer scale +earlyWindowFBScale = 1 +#Enable forge global version checking +versionCheck = true +#Early window provider +earlyWindowProvider = "fmlearlywindow" +#Early window width +earlyWindowWidth = 854 +#Early window starts maximized +earlyWindowMaximized = false +#Default config path for servers +defaultConfigPath = "defaultconfigs" +#Disables Optimized DFU client-side - already disabled on servers +disableOptimizedDFU = true +#Skip specific GL versions, may help with buggy graphics card drivers +earlyWindowSkipGLVersions = [] +#Should we control the window. Disabling this disables new GL features and can be bad for mods that rely on them. +earlyWindowControl = false +#Max threads for early initialization parallelism, -1 is based on processor count +maxThreads = -1 +#Squir? +earlyWindowSquir = false + From 3367c377d613f5977f9f605ec92e4cce5543f42e Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 27 Jan 2024 19:01:03 +0200 Subject: [PATCH 04/15] Disable asset download on CI again --- build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 769823b9..0ac53370 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -345,6 +345,9 @@ tasks { if (name == "runTestModClient") { dependsOn(modDownload) } + if (name == "downloadAssets" && providers.environmentVariable("CI").isPresent) { + enabled = false + } } } From 73d83789860d8f3f7ae0d53fa7ed409cf57c8d9a Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 27 Jan 2024 19:07:28 +0200 Subject: [PATCH 05/15] Create download assets dir on CI --- build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 0ac53370..9ede2d12 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,6 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import me.modmuss50.mpp.ReleaseType +import net.minecraftforge.gradle.common.tasks.DownloadAssets import net.minecraftforge.gradle.common.util.MavenArtifactDownloader import net.minecraftforge.gradle.common.util.RunConfig import net.minecraftforge.gradle.userdev.tasks.JarJar @@ -347,6 +348,7 @@ tasks { } if (name == "downloadAssets" && providers.environmentVariable("CI").isPresent) { enabled = false + (this as DownloadAssets).output.mkdirs() } } } From d403cc2ebb73f2f0b1d3b4a2debafb138772835f Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 27 Jan 2024 19:11:55 +0200 Subject: [PATCH 06/15] Run client with xvfb action --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e7e4be9f..7a225f21 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,10 @@ jobs: gradle-home-cache-excludes: | gradle.properties - run: ./gradlew clean build --stacktrace - - run: ./gradlew runTestModClient + - name: Run Auto test Client + uses: modmuss50/xvfb-action@v1 + with: + run: ./gradlew runTestModClient - run: ./gradlew publishToMavenLocal --stacktrace - uses: actions/upload-artifact@v3 with: From 2d766635d15ccac27010bcd60eb16becce4a5827 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 27 Jan 2024 19:19:19 +0200 Subject: [PATCH 07/15] Update build.yml --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7a225f21..6af25592 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,11 +18,11 @@ jobs: gradle-home-cache-cleanup: true gradle-home-cache-excludes: | gradle.properties - - run: ./gradlew clean build --stacktrace - name: Run Auto test Client uses: modmuss50/xvfb-action@v1 - with: + with: run: ./gradlew runTestModClient + - run: ./gradlew clean build --stacktrace - run: ./gradlew publishToMavenLocal --stacktrace - uses: actions/upload-artifact@v3 with: From 5083196cd77272ebe535571e1f40ffb110647276 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 27 Jan 2024 22:47:54 +0200 Subject: [PATCH 08/15] Fix compatibility with the Replay mod Fixes #589 --- gradle.properties | 2 +- .../connector/transformer/MixinPatches.java | 28 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 423f4eb0..d7908299 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=true # Versions -versionConnector=1.0.0-beta.35 +versionConnector=1.0.0-beta.36 versionAdapter=1.11.19-1.20.1-20240126.215012 versionAdapterDefinition=1.11.22 diff --git a/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java b/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java index 4e0c3813..24b1f807 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java +++ b/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java @@ -500,7 +500,9 @@ public static List getPatches() { methodNode.desc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getArgumentTypes(methodNode.desc)); return Patch.Result.APPLY; }) - .build()); + .build(), + + buildReplayModPatches()); return patches.stream() .flatMap(p -> p instanceof List lst ? lst.stream() : Stream.of(p)) @@ -525,4 +527,28 @@ private static Patch buildGuiPatch(int minOrdinal, int maxOrdinal, String target }) .build(); } + + private static List buildReplayModPatches() { + return List.of( + Patch.builder() + .targetClass("net/minecraft/client/KeyboardHandler") + .targetMethod("method_1473") + .modifyTarget("lambda$charTyped$7(Lnet/minecraft/client/gui/screens/Screen;CI)V") + .modifyParams(builder -> builder.replace(0, Type.getType("Lnet/minecraft/client/gui/screens/Screen;"))) + .build(), + Patch.builder() + .targetClass("net/minecraft/client/KeyboardHandler") + .targetMethod("method_1458") + .modifyTarget("lambda$charTyped$6(Lnet/minecraft/client/gui/screens/Screen;II)V") + .modifyParams(builder -> builder.replace(0, Type.getType("Lnet/minecraft/client/gui/screens/Screen;"))) + .build(), + Patch.builder() + .targetClass("net/minecraft/client/KeyboardHandler") + .targetMethod("method_1454") + // lambda$keyPress$5 + .modifyTarget("m_260734_(ILnet/minecraft/client/gui/screens/Screen;[ZIII)V") + .transformParams(builder -> builder.swap(1, 2)) + .build() + ); + } } From 0ba06c4dfad913bcd74fc42afd54c7a4b0f9ebd5 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 27 Jan 2024 23:49:26 +0200 Subject: [PATCH 09/15] Fix BeaconOverhaul compatibility Fixes #607 --- build.gradle.kts | 16 ++++++++++ .../connector/transformer/MixinPatches.java | 32 +++++++++++++++++++ testmods.txt | 3 ++ 3 files changed, 51 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 9ede2d12..4f8503f2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -201,6 +201,20 @@ configurations { } } +repositories { + exclusiveContent { + forRepository { + maven { + url = uri("https://cursemaven.com") + } + } + forRepositories(fg.repository) + filter { + includeGroup("curse.maven") + } + } +} + sourceSets { main { runtimeClasspath = runtimeClasspath.minus(output).plus(files(fullJar)) @@ -297,6 +311,8 @@ dependencies { "modCompileOnly"(sourceSets.main.get().output) "modCompileOnly"("io.github.llamalad7:mixinextras-common:${mixinextrasVersion}") + + runtimeOnly(fg.deobf("curse.maven:connector-extras-913445:5027683")) } tasks { diff --git a/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java b/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java index 24b1f807..95866760 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java +++ b/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java @@ -348,6 +348,38 @@ public static List getPatches() { .ignoreOffset()) .targetMixinType(MixinConstants.REDIRECT) .build(), + Patch.builder() + .targetClass("net/minecraft/world/entity/LivingEntity") + .targetMethod("m_7023_") // travel + .targetMixinType(MixinConstants.MODIFY_VAR) + .targetAnnotationValues(handle -> handle.getNested("at") + .filter(at -> at.getValue("value") + .filter(h -> h.get().equals("CONSTANT")) + .isPresent()) + .flatMap(at -> at.getValue("args")) + .map(v -> (List) v.get()) + .map(v -> v.size() == 1 && v.get(0).equals("doubleValue=0.01")) + .orElse(false)) + .modifyMixinType(MixinConstants.WRAP_OPERATION, builder -> builder + .sameTarget() + .injectionPoint("INVOKE", "Lnet/minecraft/world/entity/ai/attributes/AttributeInstance;m_22135_()D") // getValue + .putValue("ordinal", 0)) + .transformParams(builder -> + builder.inject(0, Type.getType("Lnet/minecraft/world/entity/ai/attributes/AttributeInstance;")) + .inject(1, Type.getObjectType(MixinConstants.OPERATION_INTERNAL_NAME)) + .inline(2, adapter -> { + adapter.visitVarInsn(Opcodes.ALOAD, 2); + adapter.visitInsn(Opcodes.ICONST_1); + adapter.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); + adapter.visitInsn(Opcodes.DUP); + adapter.visitInsn(Opcodes.ICONST_0); + adapter.visitVarInsn(Opcodes.ALOAD, 1); + adapter.visitInsn(Opcodes.AASTORE); + adapter.visitMethodInsn(Opcodes.INVOKEINTERFACE, "com/llamalad7/mixinextras/injector/wrapoperation/Operation", "call", "([Ljava/lang/Object;)Ljava/lang/Object;", true); + adapter.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Double"); + adapter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false); + })) + .build(), Patch.builder() .targetClass("net/minecraft/server/level/ServerPlayerGameMode") .targetMethod("m_9280_") diff --git a/testmods.txt b/testmods.txt index 14ef8199..f67cbbf1 100644 --- a/testmods.txt +++ b/testmods.txt @@ -1 +1,4 @@ https://cdn.modrinth.com/data/ZHKrK8Rp/versions/Q8JSGhdj/fastback-0.15.6%2B1.20.1-fabric.jar https://modrinth.com/mod/fastback + +# Requiring connector extras: +https://edge.forgecdn.net/files/4715/716/BeaconOverhaul-1.8.4+1.20.jar https://www.curseforge.com/minecraft/mc-mods/beaconoverhaul From 48bfdfd34d47bfff10943b25574e7b2d0d40dfa1 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sun, 28 Jan 2024 00:37:08 +0200 Subject: [PATCH 10/15] Fix replay mod buttons --- .../connector/transformer/MixinPatches.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java b/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java index 95866760..f1ebde88 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java +++ b/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatches.java @@ -2,6 +2,7 @@ import dev.su5ed.sinytra.adapter.patch.api.MixinConstants; import dev.su5ed.sinytra.adapter.patch.api.Patch; +import dev.su5ed.sinytra.adapter.patch.transformer.ModifyMethodAccess; import dev.su5ed.sinytra.adapter.patch.transformer.ModifyMethodParams; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; @@ -577,9 +578,27 @@ private static List buildReplayModPatches() { Patch.builder() .targetClass("net/minecraft/client/KeyboardHandler") .targetMethod("method_1454") - // lambda$keyPress$5 - .modifyTarget("m_260734_(ILnet/minecraft/client/gui/screens/Screen;[ZIII)V") + .modifyTarget("lambda$keyPress$5(ILnet/minecraft/client/gui/screens/Screen;[ZIII)V") .transformParams(builder -> builder.swap(1, 2)) + .build(), + + // Their refmaps are so broken... + Patch.builder() + .targetClass("net/minecraft/client/MouseHandler") + .targetMethod("method_1611") + .modifyMethodAccess(new ModifyMethodAccess.AccessChange(false, Opcodes.ACC_STATIC)) + .modifyTarget("m_168084_") // lambda$onPress$0 + .build(), + Patch.builder() + .targetClass("net/minecraft/client/MouseHandler") + .targetMethod("method_1605") + .modifyMethodAccess(new ModifyMethodAccess.AccessChange(false, Opcodes.ACC_STATIC)) + .modifyTarget("m_168078_") // lambda$onPress$1 + .build(), + Patch.builder() + .targetClass("net/minecraft/client/MouseHandler") + .targetMethod("method_1602") + .modifyTarget("m_168072_") // lambda$onMove$11 .build() ); } From e24ca51bb4658b15a1ffb86135049bbd2e0fa55a Mon Sep 17 00:00:00 2001 From: Su5eD Date: Sun, 28 Jan 2024 11:13:32 +0100 Subject: [PATCH 11/15] Skip applying mixins in invalid loading states Fixes #786 --- .../dev/su5ed/sinytra/connector/mod/ConnectorBootstrap.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorBootstrap.java b/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorBootstrap.java index d330ad2c..842baf29 100644 --- a/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorBootstrap.java +++ b/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorBootstrap.java @@ -52,11 +52,15 @@ private static void registerCrashLogInfo() { }); } + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + return !ConnectorEarlyLoader.hasEncounteredException(); + } + // We don't need any of the mixin stuff //@formatter:off @Override public void onLoad(String mixinPackage) {} @Override public String getRefMapperConfig() {return null;} - @Override public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {return true;} @Override public void acceptTargets(Set myTargets, Set otherTargets) {} @Override public List getMixins() {return null;} @Override public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} From 8fed6d3133efaf5342d995c389a93ff8b140175c Mon Sep 17 00:00:00 2001 From: Su5eD Date: Sun, 28 Jan 2024 12:46:06 +0100 Subject: [PATCH 12/15] Improve mixin extraction Update adapter definition to 1.11.23 Fixes #781 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d7908299..7176caf3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.daemon=true # Versions versionConnector=1.0.0-beta.36 versionAdapter=1.11.19-1.20.1-20240126.215012 -versionAdapterDefinition=1.11.22 +versionAdapterDefinition=1.11.23 versionMc=1.20.1 versionForge=47.1.3 From f1134d1486e37194831e2dac53f19af860a383be Mon Sep 17 00:00:00 2001 From: Su5eD Date: Mon, 29 Jan 2024 22:18:11 +0100 Subject: [PATCH 13/15] Fix cryptic global mod alias config error --- .../connector/locator/DependencyResolver.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/dev/su5ed/sinytra/connector/locator/DependencyResolver.java b/src/main/java/dev/su5ed/sinytra/connector/locator/DependencyResolver.java index 5f2e9567..115ec8da 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/locator/DependencyResolver.java +++ b/src/main/java/dev/su5ed/sinytra/connector/locator/DependencyResolver.java @@ -45,12 +45,12 @@ public final class DependencyResolver { private static final Logger LOGGER = LogUtils.getLogger(); public static final VersionOverrides VERSION_OVERRIDES = new VersionOverrides(); - public static final Supplier DEPENDENCY_OVERRIDES = Suppliers.memoize(DependencyResolver::loadDependencyOverrides); - private static final GlobalModAliases GLOBAL_MOD_ALIASES = new GlobalModAliases(FMLPaths.CONFIGDIR.get(), ConnectorUtil.DEFAULT_GLOBAL_MOD_ALIASES); + public static final Supplier DEPENDENCY_OVERRIDES = Suppliers.memoize(() -> loadConfigFile("fabric_loader_dependencies.json", () -> new DependencyOverrides(FMLPaths.CONFIGDIR.get()))); + private static final Supplier GLOBAL_MOD_ALIASES = Suppliers.memoize(() -> loadConfigFile("connector_global_mod_aliases.json", () -> new GlobalModAliases(FMLPaths.CONFIGDIR.get(), ConnectorUtil.DEFAULT_GLOBAL_MOD_ALIASES))); public static List resolveDependencies(Collection keys, Multimap jars, Iterable loadedMods) { // Add global mod aliases - FabricLoaderImpl.INSTANCE.aliasMods(GLOBAL_MOD_ALIASES.getAliases()); + FabricLoaderImpl.INSTANCE.aliasMods(GLOBAL_MOD_ALIASES.get().getAliases()); BiMap jarToCandidate = HashBiMap.create(); // Fabric candidates List candidates = createCandidatesRecursive(keys, keys, jars, jarToCandidate); @@ -130,11 +130,11 @@ private static ModCandidate createFabricLoaderMod() { return ModCandidate.createBuiltin(builtinMod, VERSION_OVERRIDES, DEPENDENCY_OVERRIDES.get()); } - private static DependencyOverrides loadDependencyOverrides() { + private static T loadConfigFile(String name, Supplier supplier) { try { - return new DependencyOverrides(FMLPaths.CONFIGDIR.get()); - } catch (Exception e) { - throw ConnectorEarlyLoader.createGenericLoadingException(e, "Invalid config file fabric_loader_dependencies.json"); + return supplier.get(); + } catch (Throwable t) { + throw ConnectorEarlyLoader.createGenericLoadingException(t, "Invalid config file " + name); } } } From 1aebd6f2058af338f12ba090d310912a578a334d Mon Sep 17 00:00:00 2001 From: Su5eD Date: Tue, 30 Jan 2024 19:22:42 +0100 Subject: [PATCH 14/15] Improve testmods file format and resolution (#789) --- build.gradle.kts | 78 ++++++++++++++++++++++++++++++++---------------- testmods.txt | 4 --- testmods.yaml | 8 +++++ 3 files changed, 60 insertions(+), 30 deletions(-) delete mode 100644 testmods.txt create mode 100644 testmods.yaml diff --git a/build.gradle.kts b/build.gradle.kts index 4f8503f2..84dc700c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,15 +5,28 @@ import net.minecraftforge.gradle.common.util.MavenArtifactDownloader import net.minecraftforge.gradle.common.util.RunConfig import net.minecraftforge.gradle.userdev.tasks.JarJar import net.minecraftforge.gradle.userdev.util.MavenPomUtils -import net.minecraftforge.jarjar.metadata.* +import net.minecraftforge.jarjar.metadata.ContainedJarIdentifier +import net.minecraftforge.jarjar.metadata.ContainedJarMetadata +import net.minecraftforge.jarjar.metadata.ContainedVersion +import net.minecraftforge.jarjar.metadata.MetadataIOHandler import org.apache.maven.artifact.versioning.DefaultArtifactVersion import org.apache.maven.artifact.versioning.VersionRange +import org.yaml.snakeyaml.Yaml import java.nio.file.FileSystems import java.nio.file.Files import java.nio.file.StandardOpenOption import java.time.LocalDateTime import kotlin.io.path.inputStream +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath(group = "org.yaml", name = "snakeyaml", version = "2.2") + } +} + plugins { java `maven-publish` @@ -23,7 +36,6 @@ plugins { id("me.modmuss50.mod-publish-plugin") version "0.3.+" id("net.neoforged.gradleutils") version "2.0.+" id("org.parchmentmc.librarian.forgegradle") version "1.+" - id ("de.undercouch.download") version "5.5.0" } val versionConnector: String by project @@ -116,7 +128,7 @@ val modJar: JarJar by tasks.creating(JarJar::class) { false ) Files.deleteIfExists(metadataPath) - Files.write(metadataPath, MetadataIOHandler.toLines(metadata), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE) + Files.write(metadataPath, MetadataIOHandler.toLines(metadata), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE) } } manifest.attributes( @@ -284,6 +296,13 @@ repositories { name = "Su5eD" url = uri("https://maven.su5ed.dev/releases") } + exclusiveRepo("https://api.modrinth.com/maven/", "maven.modrinth") + maven { + url = uri("https://www.cursemaven.com") + content { + includeGroup("curse.maven") + } + } mavenLocal() } @@ -343,9 +362,20 @@ tasks { dependsOn("reobfModJar", fullJar) } - val modDownload = register("downloadMods") { - doLast { - downloadMods() + val modDownload = register("resolveTestMods") { + doFirst { + val configFile = rootProject.file("testmods.yaml") + val data: List> = configFile.reader().use(Yaml()::load) + val deps = data.map { project.dependencies.create(it["maven"] as String) } + + val config = configurations.detachedConfiguration(*deps.toTypedArray()) + val files = config.resolve() + + val dir = project.file("run/test/mods").apply { + if (exists()) deleteRecursively() + mkdirs() + } + files.forEach { it.copyTo(dir.resolve(it.name)) } } } @@ -369,26 +399,6 @@ tasks { } } -fun downloadMods() { - val dir = project.file("run/test/mods") - if (dir.exists()) { - dir.deleteRecursively() - } - dir.mkdirs() - - file("testmods.txt").forEachLine { - if (it.isBlank() || it.startsWith("#")) return@forEachLine - - val split = it.split(" ") - if (split.isEmpty()) return@forEachLine - - download.run { - dest(dir) - src(split[0]) - } - } -} - publishMods { file.set(fullJar.archiveFile) changelog.set(providers.environmentVariable("CHANGELOG").orElse("# $version")) @@ -452,3 +462,19 @@ publishing { } } } + +// Adapted from https://gist.github.com/pupnewfster/6c21401789ca6d74f9892be8c1c505c9 +fun RepositoryHandler.exclusiveRepo(location: String, vararg groups: String) { + exclusiveRepo(location) { + for (group in groups) { + includeGroup(group) + } + } +} + +fun RepositoryHandler.exclusiveRepo(location: String, config: Action) { + exclusiveContent { + forRepositories(maven(location), fg.repository) + filter(config) + } +} \ No newline at end of file diff --git a/testmods.txt b/testmods.txt deleted file mode 100644 index f67cbbf1..00000000 --- a/testmods.txt +++ /dev/null @@ -1,4 +0,0 @@ -https://cdn.modrinth.com/data/ZHKrK8Rp/versions/Q8JSGhdj/fastback-0.15.6%2B1.20.1-fabric.jar https://modrinth.com/mod/fastback - -# Requiring connector extras: -https://edge.forgecdn.net/files/4715/716/BeaconOverhaul-1.8.4+1.20.jar https://www.curseforge.com/minecraft/mc-mods/beaconoverhaul diff --git a/testmods.yaml b/testmods.yaml new file mode 100644 index 00000000..97a0fed5 --- /dev/null +++ b/testmods.yaml @@ -0,0 +1,8 @@ +- id: fastback + homepage: https://modrinth.com/mod/fastback + maven: maven.modrinth:fastback:0.15.6+1.20.1-fabric + +# Requiring connector extras: +- id: beaconoverhaul + homepage: https://www.curseforge.com/minecraft/mc-mods/beaconoverhaul + maven: curse.maven:beaconoverhaul-430382:4715716 From a3acabcc34c9d3ea3b0895805d2992472e3f2548 Mon Sep 17 00:00:00 2001 From: Su5eD Date: Tue, 30 Jan 2024 20:21:35 +0100 Subject: [PATCH 15/15] Pass fabric LVT compatibility to adapter Fixes #779 --- gradle.properties | 2 +- .../connector/service/FabricMixinBootstrap.java | 12 ++++++------ .../transformer/MixinPatchTransformer.java | 14 -------------- .../transformer/jar/JarTransformInstance.java | 4 +++- 4 files changed, 10 insertions(+), 22 deletions(-) diff --git a/gradle.properties b/gradle.properties index 7176caf3..679d0e07 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.daemon=true # Versions versionConnector=1.0.0-beta.36 versionAdapter=1.11.19-1.20.1-20240126.215012 -versionAdapterDefinition=1.11.23 +versionAdapterDefinition=1.11.24 versionMc=1.20.1 versionForge=47.1.3 diff --git a/src/main/java/dev/su5ed/sinytra/connector/service/FabricMixinBootstrap.java b/src/main/java/dev/su5ed/sinytra/connector/service/FabricMixinBootstrap.java index 678391cd..d5598e21 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/service/FabricMixinBootstrap.java +++ b/src/main/java/dev/su5ed/sinytra/connector/service/FabricMixinBootstrap.java @@ -18,10 +18,10 @@ import com.mojang.logging.LogUtils; import dev.su5ed.sinytra.connector.loader.ConnectorEarlyLoader; -import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.SemanticVersion; import net.fabricmc.loader.api.Version; import net.fabricmc.loader.api.metadata.ModDependency; +import net.fabricmc.loader.api.metadata.ModMetadata; import net.fabricmc.loader.api.metadata.version.VersionInterval; import net.fabricmc.loader.impl.FabricLoaderImpl; import net.minecraftforge.fml.loading.LoadingModList; @@ -72,7 +72,7 @@ public static void init() { } } - private static final class MixinConfigDecorator { + public static final class MixinConfigDecorator { private static final List VERSIONS = List.of( LoaderMixinVersionEntry.create("0.12.0-", FabricUtil.COMPATIBILITY_0_10_0) ); @@ -87,7 +87,7 @@ static void apply(Map configToModMap) { if (!mod.getMods().isEmpty()) { String modid = mod.getMods().get(0).getModId(); int compat = ConnectorEarlyLoader.isConnectorMod(modid) ? FabricLoaderImpl.INSTANCE.getModContainer(modid) - .map(MixinConfigDecorator::getMixinCompat) + .map(m -> getMixinCompat(m.getMetadata())) .orElse(FabricUtil.COMPATIBILITY_0_10_0) : FabricUtil.COMPATIBILITY_0_10_0; config.decorate(FabricUtil.KEY_COMPATIBILITY, compat); @@ -95,13 +95,13 @@ static void apply(Map configToModMap) { } } - private static int getMixinCompat(ModContainer mod) { + public static int getMixinCompat(ModMetadata metadata) { // infer from loader dependency by determining the least relevant loader version the mod accepts // AND any loader deps List reqIntervals = List.of(VersionInterval.INFINITE); - for (ModDependency dep : mod.getMetadata().getDependencies()) { + for (ModDependency dep : metadata.getDependencies()) { if (dep.getModId().equals("fabricloader") || dep.getModId().equals("fabric-loader")) { if (dep.getKind() == ModDependency.Kind.DEPENDS) { reqIntervals = VersionInterval.and(reqIntervals, dep.getVersionIntervals()); @@ -112,7 +112,7 @@ else if (dep.getKind() == ModDependency.Kind.BREAKS) { } } - if (reqIntervals.isEmpty()) throw new IllegalStateException("mod " + mod + " is incompatible with every loader version?"); // shouldn't get there + if (reqIntervals.isEmpty()) throw new IllegalStateException("mod " + metadata.getId() + " is incompatible with every loader version?"); // shouldn't get there Version minLoaderVersion = reqIntervals.get(0).getMin(); // it is sorted, to 0 has the absolute lower bound diff --git a/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatchTransformer.java b/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatchTransformer.java index b137b479..2851b55b 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatchTransformer.java +++ b/src/main/java/dev/su5ed/sinytra/connector/transformer/MixinPatchTransformer.java @@ -11,13 +11,11 @@ import dev.su5ed.sinytra.adapter.patch.LVTOffsets; import dev.su5ed.sinytra.adapter.patch.api.ClassTransform; import dev.su5ed.sinytra.adapter.patch.api.MixinClassGenerator; -import dev.su5ed.sinytra.adapter.patch.api.MixinConstants; import dev.su5ed.sinytra.adapter.patch.api.Patch; import dev.su5ed.sinytra.adapter.patch.api.PatchContext; import dev.su5ed.sinytra.adapter.patch.api.PatchEnvironment; import dev.su5ed.sinytra.adapter.patch.fixes.FieldTypePatchTransformer; import dev.su5ed.sinytra.adapter.patch.fixes.FieldTypeUsageTransformer; -import dev.su5ed.sinytra.adapter.patch.transformer.ModifyMethodParams; import dev.su5ed.sinytra.adapter.patch.transformer.dynamic.DynamicAnonymousShadowFieldTypePatch; import dev.su5ed.sinytra.adapter.patch.transformer.dynamic.DynamicInheritedInjectionPointPatch; import dev.su5ed.sinytra.adapter.patch.transformer.dynamic.DynamicInjectorOrdinalPatch; @@ -29,18 +27,7 @@ import net.minecraftforge.forgespi.locating.IModFile; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; -import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.FieldInsnNode; -import org.objectweb.asm.tree.InsnList; -import org.objectweb.asm.tree.InsnNode; -import org.objectweb.asm.tree.JumpInsnNode; -import org.objectweb.asm.tree.LabelNode; -import org.objectweb.asm.tree.MethodInsnNode; -import org.objectweb.asm.tree.TypeInsnNode; -import org.objectweb.asm.tree.VarInsnNode; import org.slf4j.Logger; import java.io.IOException; @@ -53,7 +40,6 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.Set; import java.util.stream.Stream; diff --git a/src/main/java/dev/su5ed/sinytra/connector/transformer/jar/JarTransformInstance.java b/src/main/java/dev/su5ed/sinytra/connector/transformer/jar/JarTransformInstance.java index f27489d2..d3530fe1 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/transformer/jar/JarTransformInstance.java +++ b/src/main/java/dev/su5ed/sinytra/connector/transformer/jar/JarTransformInstance.java @@ -13,6 +13,7 @@ import dev.su5ed.sinytra.adapter.patch.util.provider.ClassLookup; import dev.su5ed.sinytra.adapter.patch.util.provider.ZipClassLookup; import dev.su5ed.sinytra.connector.locator.EmbeddedDependencies; +import dev.su5ed.sinytra.connector.service.FabricMixinBootstrap; import dev.su5ed.sinytra.connector.transformer.AccessWidenerTransformer; import dev.su5ed.sinytra.connector.transformer.AccessorRedirectTransformer; import dev.su5ed.sinytra.connector.transformer.FieldToMethodTransformer; @@ -124,7 +125,8 @@ public void transformJar(File input, Path output, FabricModFileMetadata metadata List extraPatches = Stream.concat(this.adapterPatches.stream(), AccessorRedirectTransformer.PATCHES.stream()).toList(); ConnectorRefmapHolder refmapHolder = new ConnectorRefmapHolder(refmap.merged(), refmap.files()); - PatchEnvironment environment = PatchEnvironment.create(refmapHolder, this.cleanClassLookup, this.bfu.unwrap()); + int fabricLVTCompatibility = FabricMixinBootstrap.MixinConfigDecorator.getMixinCompat(metadata.modMetadata()); + PatchEnvironment environment = PatchEnvironment.create(refmapHolder, this.cleanClassLookup, this.bfu.unwrap(), fabricLVTCompatibility); MixinPatchTransformer patchTransformer = new MixinPatchTransformer(this.lvtOffsetsData, metadata.mixinPackages(), environment, extraPatches); RefmapRemapper refmapRemapper = new RefmapRemapper(metadata.visibleMixinConfigs(), refmap.files()); Renamer.Builder builder = Renamer.builder()