From 4d367e4ab2f21d1604187c705c4a3ff548b0c71c Mon Sep 17 00:00:00 2001 From: Jared Date: Mon, 5 Aug 2024 23:46:16 -0600 Subject: [PATCH] Re-add forge support. Close #64 --- .../src/main/groovy/multiloader-common.gradle | 4 +- .../src/main/resources/examplemod.mixins.json | 2 +- forge/build.gradle | 89 +++++++++++++++++++ .../com/example/examplemod/ExampleMod.java | 19 ++++ .../examplemod/mixin/MixinTitleScreen.java | 20 +++++ .../platform/ForgePlatformHelper.java | 26 ++++++ forge/src/main/resources/META-INF/mods.toml | 27 ++++++ ...amplemod.platform.services.IPlatformHelper | 1 + .../resources/examplemod.forge.mixins.json | 14 +++ gradle.properties | 6 +- .../resources/META-INF/neoforge.mods.toml | 2 +- settings.gradle | 23 +++++ 12 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 forge/build.gradle create mode 100644 forge/src/main/java/com/example/examplemod/ExampleMod.java create mode 100644 forge/src/main/java/com/example/examplemod/mixin/MixinTitleScreen.java create mode 100644 forge/src/main/java/com/example/examplemod/platform/ForgePlatformHelper.java create mode 100644 forge/src/main/resources/META-INF/mods.toml create mode 100644 forge/src/main/resources/META-INF/services/com.example.examplemod.platform.services.IPlatformHelper create mode 100644 forge/src/main/resources/examplemod.forge.mixins.json diff --git a/buildSrc/src/main/groovy/multiloader-common.gradle b/buildSrc/src/main/groovy/multiloader-common.gradle index 127c8ab..e2b0047 100644 --- a/buildSrc/src/main/groovy/multiloader-common.gradle +++ b/buildSrc/src/main/groovy/multiloader-common.gradle @@ -82,7 +82,7 @@ jar { } processResources { - def expandProps = [ + var expandProps = [ 'version' : version, 'group' : project.group, //Else we target the task's group. 'minecraft_version' : minecraft_version, @@ -96,6 +96,8 @@ processResources { 'description' : project.description, 'neoforge_version' : neoforge_version, 'neoforge_loader_version_range': neoforge_loader_version_range, + "forge_version": forge_version, + "forge_loader_version_range": forge_loader_version_range, 'credits' : credits, 'java_version' : java_version ] diff --git a/common/src/main/resources/examplemod.mixins.json b/common/src/main/resources/examplemod.mixins.json index 0735c74..fd2e052 100644 --- a/common/src/main/resources/examplemod.mixins.json +++ b/common/src/main/resources/examplemod.mixins.json @@ -3,7 +3,7 @@ "minVersion": "0.8", "package": "com.example.examplemod.mixin", "refmap": "${mod_id}.refmap.json", - "compatibilityLevel": "JAVA_21", + "compatibilityLevel": "JAVA_18", "mixins": [], "client": [ "MixinMinecraft" diff --git a/forge/build.gradle b/forge/build.gradle new file mode 100644 index 0000000..712a2f9 --- /dev/null +++ b/forge/build.gradle @@ -0,0 +1,89 @@ +plugins { + id 'multiloader-loader' + id 'net.minecraftforge.gradle' version '[6.0.24,6.2)' + id 'org.spongepowered.mixin' version '0.7-SNAPSHOT' +} +base { + archivesName = "${mod_name}-forge-${minecraft_version}" +} +mixin { + config("${mod_id}.mixins.json") + config("${mod_id}.forge.mixins.json") +} + +minecraft { + mappings channel: 'official', version: minecraft_version + + copyIdeResources = true //Calls processResources when in dev + + reobf = false // Forge 1.20.6+ uses official mappings at runtime, so we shouldn't reobf from official to SRG + + // Automatically enable forge AccessTransformers if the file exists + // This location is hardcoded in Forge and can not be changed. + // https://github.com/MinecraftForge/MinecraftForge/blob/be1698bb1554f9c8fa2f58e32b9ab70bc4385e60/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java#L123 + // Forge still uses SRG names during compile time, so we cannot use the common AT's + def at = file('src/main/resources/META-INF/accesstransformer.cfg') + if (at.exists()) { + accessTransformer = at + } + + runs { + client { + workingDirectory file('runs/client') + ideaModule "${rootProject.name}.${project.name}.main" + taskName 'Client' + mods { + modClientRun { + source sourceSets.main + } + } + } + + server { + workingDirectory file('runs/server') + ideaModule "${rootProject.name}.${project.name}.main" + taskName 'Server' + mods { + modServerRun { + source sourceSets.main + } + } + } + + data { + workingDirectory file('runs/data') + ideaModule "${rootProject.name}.${project.name}.main" + args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') + taskName 'Data' + mods { + modDataRun { + source sourceSets.main + } + } + } + } +} + +sourceSets.main.resources.srcDir 'src/generated/resources' + +dependencies { + minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" + annotationProcessor("org.spongepowered:mixin:0.8.5-SNAPSHOT:processor") + + // Forge's hack fix + implementation('net.sf.jopt-simple:jopt-simple:5.0.4') { version { strictly '5.0.4' } } +} + +publishing { + publications { + mavenJava(MavenPublication) { + fg.component(it) + } + } +} + +sourceSets.each { + def dir = layout.buildDirectory.dir("sourcesSets/$it.name") + it.output.resourcesDir = dir + it.java.destinationDirectory = dir +} \ No newline at end of file diff --git a/forge/src/main/java/com/example/examplemod/ExampleMod.java b/forge/src/main/java/com/example/examplemod/ExampleMod.java new file mode 100644 index 0000000..9570a51 --- /dev/null +++ b/forge/src/main/java/com/example/examplemod/ExampleMod.java @@ -0,0 +1,19 @@ +package com.example.examplemod; + +import net.minecraftforge.fml.common.Mod; + +@Mod(Constants.MOD_ID) +public class ExampleMod { + + public ExampleMod() { + + // This method is invoked by the Forge mod loader when it is ready + // to load your mod. You can access Forge and Common code in this + // project. + + // Use Forge to bootstrap the Common mod. + Constants.LOG.info("Hello Forge world!"); + CommonClass.init(); + + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/example/examplemod/mixin/MixinTitleScreen.java b/forge/src/main/java/com/example/examplemod/mixin/MixinTitleScreen.java new file mode 100644 index 0000000..a2e0c4b --- /dev/null +++ b/forge/src/main/java/com/example/examplemod/mixin/MixinTitleScreen.java @@ -0,0 +1,20 @@ +package com.example.examplemod.mixin; + +import com.example.examplemod.Constants; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.TitleScreen; +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(TitleScreen.class) +public class MixinTitleScreen { + + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + + Constants.LOG.info("This line is printed by an example mod mixin from Forge!"); + Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType()); + } +} \ No newline at end of file diff --git a/forge/src/main/java/com/example/examplemod/platform/ForgePlatformHelper.java b/forge/src/main/java/com/example/examplemod/platform/ForgePlatformHelper.java new file mode 100644 index 0000000..22ef9e4 --- /dev/null +++ b/forge/src/main/java/com/example/examplemod/platform/ForgePlatformHelper.java @@ -0,0 +1,26 @@ +package com.example.examplemod.platform; + +import com.example.examplemod.platform.services.IPlatformHelper; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.loading.FMLLoader; + +public class ForgePlatformHelper implements IPlatformHelper { + + @Override + public String getPlatformName() { + + return "Forge"; + } + + @Override + public boolean isModLoaded(String modId) { + + return ModList.get().isLoaded(modId); + } + + @Override + public boolean isDevelopmentEnvironment() { + + return !FMLLoader.isProduction(); + } +} \ No newline at end of file diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..eed0909 --- /dev/null +++ b/forge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,27 @@ +modLoader = "javafml" #mandatory +loaderVersion = "${forge_loader_version_range}" #mandatory This is typically bumped every Minecraft version by Forge. See https://files.minecraftforge.net/ for a list of versions. +license = "${license}" # Review your options at https://choosealicense.com/. +#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional +#clientSideOnly=true #optional +[[mods]] #mandatory +modId = "${mod_id}" #mandatory +version = "${version}" #mandatory +displayName = "${mod_name}" #mandatory +#updateJSONURL="https://change.me.example.invalid/updates.json" #optional (see https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/) +#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional (displayed in the mod UI) +logoFile = "${mod_id}.png" #optional +credits = "${credits}" #optional +authors = "${mod_author}" #optional +description = '''${description}''' #mandatory (Supports multiline text) +[[dependencies.${mod_id}]] #optional +modId = "forge" #mandatory +mandatory = true #mandatory +versionRange = "[${forge_version},)" #mandatory +ordering = "NONE" # The order that this dependency should load in relation to your mod, required to be either 'BEFORE' or 'AFTER' if the dependency is not mandatory +side = "BOTH" # Side this dependency is applied on - 'BOTH', 'CLIENT' or 'SERVER' +[[dependencies.${mod_id}]] +modId = "minecraft" +mandatory = true +versionRange = "${minecraft_version_range}" +ordering = "NONE" +side = "BOTH" \ No newline at end of file diff --git a/forge/src/main/resources/META-INF/services/com.example.examplemod.platform.services.IPlatformHelper b/forge/src/main/resources/META-INF/services/com.example.examplemod.platform.services.IPlatformHelper new file mode 100644 index 0000000..ff2910d --- /dev/null +++ b/forge/src/main/resources/META-INF/services/com.example.examplemod.platform.services.IPlatformHelper @@ -0,0 +1 @@ +com.example.examplemod.platform.ForgePlatformHelper \ No newline at end of file diff --git a/forge/src/main/resources/examplemod.forge.mixins.json b/forge/src/main/resources/examplemod.forge.mixins.json new file mode 100644 index 0000000..5830052 --- /dev/null +++ b/forge/src/main/resources/examplemod.forge.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "com.example.examplemod.mixin", + "compatibilityLevel": "JAVA_18", + "mixins": [], + "client": [ + "MixinTitleScreen" + ], + "server": [], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index defa86b..38d4de5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ mod_author=Jared mod_id=examplemod license=CC0-1.0 credits= -description=The description of your mod. \\nAccepts multilines (but they must be double-escaped). +description=The description of your mod. \nAccepts multilines. minecraft_version_range=[1.21, 1.22) ## This is the version of minecraft that the 'common' project uses, you can find a list of all versions here ## https://projects.neoforged.net/neoforged/neoform @@ -26,6 +26,10 @@ parchment_version=2024.06.23 fabric_version=0.100.1+1.21 fabric_loader_version=0.15.11 +# Forge +forge_version=51.0.17 +forge_loader_version_range=[51,) + # NeoForge neoforge_version=21.0.37-beta neoforge_loader_version_range=[4,) diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 87cb869..b008f60 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -11,7 +11,7 @@ displayName = "${mod_name}" #mandatory logoFile="${mod_id}.png" #optional credits="${credits}" #optional authors = "${mod_author}" #optional -description = "${description}" #mandatory (Supports multiline text) +description = '''${description}''' #mandatory (Supports multiline text) [[mixins]] config = "${mod_id}.mixins.json" [[mixins]] diff --git a/settings.gradle b/settings.gradle index 50546d6..c9b8293 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,6 +14,28 @@ pluginManagement { includeGroup('fabric-loom') } } + exclusiveContent { + forRepository { + maven { + name = 'Sponge' + url = uri('https://repo.spongepowered.org/repository/maven-public') + } + } + filter { + includeGroupAndSubgroups("org.spongepowered") + } + } + exclusiveContent { + forRepository { + maven { + name = 'Forge' + url = uri('https://maven.minecraftforge.net') + } + } + filter { + includeGroupAndSubgroups('net.minecraftforge') + } + } } } @@ -26,3 +48,4 @@ rootProject.name = 'MultiLoader-Template' include('common') include('fabric') include('neoforge') +include('forge') \ No newline at end of file