From 3a17ce9f600570c706301da364b2e0fe98915894 Mon Sep 17 00:00:00 2001 From: turtletowerz Date: Sun, 29 Mar 2026 01:17:10 -0400 Subject: [PATCH] port to 26.1 part 1 --- .gitignore | 1 - build.gradle | 76 +----------- buildSrc/build.gradle | 3 + .../src/main/groovy/multiloader-common.gradle | 114 ++++++++++++++++++ .../src/main/groovy/multiloader-loader.gradle | 45 +++++++ common/build.gradle | 78 ++++++++---- .../optionsprofiles/Commands.java | 23 ++-- .../optionsprofiles/Keybinds.java | 24 ++-- .../optionsprofiles/OptionsProfilesMod.java | 55 +++------ .../gui/OptionsToggleList.java | 13 +- .../gui/OptionsToggleScreen.java | 1 - .../optionsprofiles/gui/ProfilesList.java | 13 +- .../optionsprofiles/platform/Services.java | 30 +++++ .../platform/services/IPlatformHelper.java | 7 ++ .../optionsprofiles/profiles/Profiles.java | 18 +-- .../profiles/loaders/SodiumExtraLoader.java | 3 +- .../profiles/loaders/SodiumLoader.java | 2 + .../resources/optionsprofiles.mixins.json | 5 +- common/src/main/resources/pack.mcmeta | 6 + fabric/build.gradle | 94 ++++++--------- .../fabric/OptionsProfilesModFabric.java | 21 +++- .../fabric/platform/FabricPlatformHelper.java | 16 +++ ...ficlunar.optionsprofiles.platform.services | 1 + fabric/src/main/resources/fabric.mod.json | 27 +++-- gradle.properties | 29 +++-- gradle/wrapper/gradle-wrapper.properties | 2 +- neoforge/build.gradle | 98 +++++++-------- .../neoforge/OptionsProfilesModNeoForge.java | 48 +++++++- .../platform/NeoForgePlatformHelper.java | 16 +++ .../resources/META-INF/neoforge.mods.toml | 33 ++--- ...ficlunar.optionsprofiles.platform.services | 1 + .../{icon.png => optionsprofiles.png} | Bin settings.gradle | 22 +++- 33 files changed, 581 insertions(+), 344 deletions(-) create mode 100644 buildSrc/build.gradle create mode 100644 buildSrc/src/main/groovy/multiloader-common.gradle create mode 100644 buildSrc/src/main/groovy/multiloader-loader.gradle create mode 100644 common/src/main/java/net/trafficlunar/optionsprofiles/platform/Services.java create mode 100644 common/src/main/java/net/trafficlunar/optionsprofiles/platform/services/IPlatformHelper.java create mode 100644 common/src/main/resources/pack.mcmeta create mode 100644 fabric/src/main/java/net/trafficlunar/optionsprofiles/fabric/platform/FabricPlatformHelper.java create mode 100644 fabric/src/main/resources/META-INF/services/net.trafficlunar.optionsprofiles.platform.services create mode 100644 neoforge/src/main/java/net/trafficlunar/optionsprofiles/neoforge/platform/NeoForgePlatformHelper.java create mode 100644 neoforge/src/main/resources/META-INF/services/net.trafficlunar.optionsprofiles.platform.services rename neoforge/src/main/resources/{icon.png => optionsprofiles.png} (100%) diff --git a/.gitignore b/.gitignore index 11253e7..ccb0c56 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -.architectury-transformer/ build/ *.ipr run/ diff --git a/build.gradle b/build.gradle index 4313e9a..d0b50f4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,74 +1,6 @@ plugins { - id 'dev.architectury.loom' version '1.11-SNAPSHOT' apply false - id 'architectury-plugin' version '3.4-SNAPSHOT' - id 'com.gradleup.shadow' version '8.3.6' apply false + // see https://fabricmc.net/develop/ for new versions + id 'net.fabricmc.fabric-loom' version '1.15-SNAPSHOT' apply false + // see https://projects.neoforged.net/neoforged/moddevgradle for new versions + id 'net.neoforged.moddev' version '2.0.141' apply false } - -architectury { - minecraft = project.minecraft_version -} - -allprojects { - group = rootProject.maven_group - version = rootProject.mod_version -} - -subprojects { - apply plugin: 'dev.architectury.loom' - apply plugin: 'architectury-plugin' - apply plugin: 'maven-publish' - - base { - // Set up a suffixed format for the mod jar names, e.g. `example-fabric`. - archivesName = "$rootProject.archives_name-$project.name" - } - - repositories { - // Add repositories to retrieve artifacts from in here. - // You should only use this when depending on other mods because - // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. - // See https://docs.gradle.org/current/userguide/declaring_repositories.html - // for more information about repositories. - } - - loom { - silentMojangMappingsLicense() - } - - dependencies { - minecraft "net.minecraft:minecraft:$rootProject.minecraft_version" - mappings loom.officialMojangMappings() - } - - java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 - } - - tasks.withType(JavaCompile).configureEach { - it.options.release = 21 - } - - // Configure Maven publishing. - publishing { - publications { - mavenJava(MavenPublication) { - artifactId = base.archivesName.get() - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } - } -} \ No newline at end of file diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 0000000..1957c33 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'groovy-gradle-plugin' +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/multiloader-common.gradle b/buildSrc/src/main/groovy/multiloader-common.gradle new file mode 100644 index 0000000..4e09d02 --- /dev/null +++ b/buildSrc/src/main/groovy/multiloader-common.gradle @@ -0,0 +1,114 @@ +plugins { + id 'java-library' + id 'maven-publish' +} + +base { + archivesName = "${mod_id}-${project.name}-${minecraft_version}" +} + +java { + toolchain.languageVersion = JavaLanguageVersion.of(java_version) + withSourcesJar() + withJavadocJar() +} + +repositories { + mavenCentral() + // https://docs.gradle.org/current/userguide/declaring_repositories.html#declaring_content_exclusively_found_in_one_repository + exclusiveContent { + forRepository { + maven { + name = 'Sponge' + url = 'https://repo.spongepowered.org/repository/maven-public' + } + } + filter { includeGroupAndSubgroups('org.spongepowered') } + } + exclusiveContent { + forRepository { + maven { + name = "Modrinth" + url = "https://api.modrinth.com/maven" + } + } + filter { + includeGroupAndSubgroups("maven.modrinth") + } + } + maven { + name = 'BlameJared' + url = 'https://maven.blamejared.com' + } +} + +sourcesJar { + from(rootProject.file('LICENSE')) { + rename { "${it}_${mod_name}" } + } +} + +jar { + from(rootProject.file('LICENSE')) { + rename { "${it}_${mod_name}" } + } + + manifest { + attributes([ + 'Specification-Title' : mod_name, + 'Specification-Vendor' : mod_author, + 'Specification-Version' : project.jar.archiveVersion, + 'Implementation-Title' : project.name, + 'Implementation-Version': project.jar.archiveVersion, + 'Implementation-Vendor' : mod_author, + 'Built-On-Minecraft' : minecraft_version + ]) + } +} + +processResources { + var expandProps = [ + 'mod_version' : mod_version, + 'group' : project.group, //Else we target the task's group. + 'minecraft_version' : minecraft_version, + 'minecraft_version_range' : minecraft_version_range, + 'fabric_loader_version' : fabric_loader_version, + 'fabric_api_version' : fabric_api_version, + 'mod_name' : mod_name, + 'mod_author' : mod_author, + 'mod_id' : mod_id, + 'license' : license, + 'description' : project.description, + 'neoforge_version' : neoforge_version, + 'neoforge_loader_version_range': neoforge_loader_version_range, + 'java_version' : java_version + ] + + var jsonExpandProps = expandProps.collectEntries { + key, value -> [(key): value instanceof String ? value.replace("\n", "\\\\n") : value] + } + + filesMatching(['META-INF/mods.toml', 'META-INF/neoforge.mods.toml']) { + expand expandProps + } + + filesMatching(['pack.mcmeta', 'fabric.mod.json', '*.mixins.json']) { + expand jsonExpandProps + } + + inputs.properties(expandProps) +} + +publishing { + publications { + register('mavenJava', MavenPublication) { + artifactId base.archivesName.get() + from components.java + } + } + repositories { + maven { + url System.getenv('local_maven_url') + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/multiloader-loader.gradle b/buildSrc/src/main/groovy/multiloader-loader.gradle new file mode 100644 index 0000000..c3f68c2 --- /dev/null +++ b/buildSrc/src/main/groovy/multiloader-loader.gradle @@ -0,0 +1,45 @@ +plugins { + id 'multiloader-common' +} + +configurations { + commonJava{ + canBeResolved = true + } + commonResources{ + canBeResolved = true + } +} + +dependencies { + compileOnly(project(':common')) { + def loaderAttribute = Attribute.of('io.github.mcgradleconventions.loader', String) + attributes { + attribute(loaderAttribute, 'common') + } + } + commonJava project(path: ':common', configuration: 'commonJava') + commonResources project(path: ':common', configuration: 'commonResources') +} + +tasks.named('compileJava', JavaCompile) { + dependsOn(configurations.commonJava) + source(configurations.commonJava) +} + +processResources { + dependsOn(configurations.commonResources) + from(configurations.commonResources) +} + +tasks.named('javadoc', Javadoc).configure { + dependsOn(configurations.commonJava) + source(configurations.commonJava) +} + +tasks.named('sourcesJar', Jar) { + dependsOn(configurations.commonJava) + from(configurations.commonJava) + dependsOn(configurations.commonResources) + from(configurations.commonResources) +} \ No newline at end of file diff --git a/common/build.gradle b/common/build.gradle index d7ae20f..02a4fab 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -1,34 +1,62 @@ -architectury { - common rootProject.enabled_platforms.split(',') +plugins { + id 'multiloader-common' + id 'net.neoforged.moddev' } -repositories { - exclusiveContent { - forRepository { - maven { - name = "Modrinth" - url = "https://api.modrinth.com/maven" - } - } - filter { - includeGroup "maven.modrinth" - } +neoForge { + neoFormVersion = neo_form_version + // Automatically enable AccessTransformers if the file exists + def at = file('src/main/resources/META-INF/accesstransformer.cfg') + if (at.exists()) { + accessTransformers.from(at.absolutePath) } } dependencies { - // We depend on Fabric Loader here to use the Fabric @Environment annotations, - // which get remapped to the correct annotations on each platform. - // Do NOT use other classes from Fabric Loader. - modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" - - // Architectury API - modImplementation "dev.architectury:architectury:$rootProject.architectury_api_version" + compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5' + // fabric and neoforge both bundle mixinextras, so it is safe to use it in common + compileOnly group: 'io.github.llamalad7', name: 'mixinextras-common', version: '0.3.5' + annotationProcessor group: 'io.github.llamalad7', name: 'mixinextras-common', version: '0.3.5' // Mod implementations - modImplementation "maven.modrinth:sodium:mc1.21.10-0.7.2-fabric" // Sodium - modImplementation "maven.modrinth:sodium-extra:mc1.21.9-0.7.0+fabric" // Sodium Extra - modImplementation "maven.modrinth:iris:1.9.6+1.21.10-fabric" // Iris - modImplementation "maven.modrinth:distanthorizons:2.3.6-b-1.21.10" // Distant Horizons - modImplementation "maven.modrinth:controlify:2.4.2-fabric,1.21.9" // Controlify + implementation "maven.modrinth:sodium:mc26.1-0.8.7-fabric" // Sodium + implementation "maven.modrinth:sodium-extra:mc26.1-0.8.5+fabric" // Sodium Extra + implementation "maven.modrinth:iris:1.10.8+26.1-fabric" // Iris + implementation "maven.modrinth:distanthorizons:2.4.5-b-1.21.11" // Distant Horizons + implementation "maven.modrinth:controlify:3.0.0-beta.3" // Controlify } + +configurations { + commonJava { + canBeResolved = false + canBeConsumed = true + } + commonResources { + canBeResolved = false + canBeConsumed = true + } +} + +artifacts { + commonJava sourceSets.main.java.sourceDirectories.singleFile + commonResources sourceSets.main.resources.sourceDirectories.singleFile +} + +// Implement mcgradleconventions loader attribute +def loaderAttribute = Attribute.of('io.github.mcgradleconventions.loader', String) +['apiElements', 'runtimeElements', 'sourcesElements', 'javadocElements'].each { variant -> + configurations.named("$variant") { + attributes { + attribute(loaderAttribute, 'common') + } + } +} +sourceSets.configureEach { + [it.compileClasspathConfigurationName, it.runtimeClasspathConfigurationName].each { variant-> + configurations.named("$variant") { + attributes { + attribute(loaderAttribute, 'common') + } + } + } +} \ No newline at end of file diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/Commands.java b/common/src/main/java/net/trafficlunar/optionsprofiles/Commands.java index 35e218f..d0a7771 100644 --- a/common/src/main/java/net/trafficlunar/optionsprofiles/Commands.java +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/Commands.java @@ -1,18 +1,21 @@ package net.trafficlunar.optionsprofiles; -import dev.architectury.event.events.common.CommandRegistrationEvent; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; import net.minecraft.client.Minecraft; +import net.minecraft.commands.CommandSourceStack; import net.trafficlunar.optionsprofiles.gui.ProfilesScreen; +import java.util.function.Consumer; + public class Commands { - public static void init() { - CommandRegistrationEvent.EVENT.register(((dispatcher, buildContext, selection) -> dispatcher.register( - net.minecraft.commands.Commands - .literal("optionsprofiles") - .executes(context -> { - Minecraft.getInstance().execute(() -> Minecraft.getInstance().setScreen(new ProfilesScreen(null))); - return 1; - }) - ))); + private static final LiteralArgumentBuilder PROFILE_COMMAND = net.minecraft.commands.Commands + .literal("optionsprofiles") + .executes(context -> { + Minecraft.getInstance().execute(() -> Minecraft.getInstance().setScreen(new ProfilesScreen(null))); + return 1; + }); + + public static void registerCommands(Consumer> consumer) { + consumer.accept(PROFILE_COMMAND); } } diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/Keybinds.java b/common/src/main/java/net/trafficlunar/optionsprofiles/Keybinds.java index 9e3f178..d06c175 100644 --- a/common/src/main/java/net/trafficlunar/optionsprofiles/Keybinds.java +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/Keybinds.java @@ -1,24 +1,22 @@ package net.trafficlunar.optionsprofiles; import com.mojang.blaze3d.platform.InputConstants; -import dev.architectury.event.events.client.ClientTickEvent; -import dev.architectury.registry.client.keymappings.KeyMappingRegistry; import net.minecraft.client.KeyMapping; -import net.minecraft.client.Minecraft; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.trafficlunar.optionsprofiles.profiles.ProfileConfiguration; import net.trafficlunar.optionsprofiles.profiles.Profiles; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.function.Consumer; import java.util.stream.Stream; public class Keybinds { private static final KeyMapping[] PROFILE_KEYMAPPINGS = new KeyMapping[3]; - public static void init() { - KeyMapping.Category category = KeyMapping.Category.register(ResourceLocation.fromNamespaceAndPath(OptionsProfilesMod.MOD_ID, "keys")); + public static void registerKeybinds(Consumer consumer) { + KeyMapping.Category category = KeyMapping.Category.register(Identifier.fromNamespaceAndPath(OptionsProfilesMod.MOD_ID, "keys")); for (int i = 0; i < PROFILE_KEYMAPPINGS.length; i++) { PROFILE_KEYMAPPINGS[i] = new KeyMapping( @@ -27,16 +25,16 @@ public class Keybinds { -1, category ); - KeyMappingRegistry.register(PROFILE_KEYMAPPINGS[i]); + consumer.accept(PROFILE_KEYMAPPINGS[i]); } + } - ClientTickEvent.CLIENT_POST.register(minecraft -> { - for (int i = 0; i < PROFILE_KEYMAPPINGS.length; i++) { - while (PROFILE_KEYMAPPINGS[i].consumeClick()) { - loadProfilesByKeybind(i + 1); - } + public static void tick() { + for (int i = 0; i < PROFILE_KEYMAPPINGS.length; i++) { + while (PROFILE_KEYMAPPINGS[i].consumeClick()) { + loadProfilesByKeybind(i + 1); } - }); + } } private static void loadProfilesByKeybind(int keybindIndex) { diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/OptionsProfilesMod.java b/common/src/main/java/net/trafficlunar/optionsprofiles/OptionsProfilesMod.java index e7b3357..6f56aed 100644 --- a/common/src/main/java/net/trafficlunar/optionsprofiles/OptionsProfilesMod.java +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/OptionsProfilesMod.java @@ -1,9 +1,8 @@ package net.trafficlunar.optionsprofiles; -import dev.architectury.event.events.client.ClientLifecycleEvent; -import dev.architectury.event.events.client.ClientPlayerEvent; import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.Connection; +import net.minecraft.world.entity.player.Player; import net.trafficlunar.optionsprofiles.profiles.ProfileConfiguration; import net.trafficlunar.optionsprofiles.profiles.Profiles; import org.apache.logging.log4j.LogManager; @@ -37,38 +36,6 @@ public class OptionsProfilesMod { // Load mod config CONFIG = OptionsProfilesModConfiguration.load(); - - // Load profiles marked to load on startup - ClientLifecycleEvent.CLIENT_STARTED.register(client -> { - try (Stream paths = Files.list(Profiles.PROFILES_DIRECTORY)) { - paths.filter(Files::isDirectory) - .forEach(path -> { - String profileName = path.getFileName().toString(); - - // This gets the configuration but also creates the configuration file if it is not there - ProfileConfiguration profileConfiguration = ProfileConfiguration.get(profileName); - if (profileConfiguration.shouldLoadOnStartup()) { - Profiles.loadProfile(profileName); - OptionsProfilesMod.LOGGER.info("[Profile '{}']: Loaded on startup", profileName); - } - }); - } catch (IOException e) { - OptionsProfilesMod.LOGGER.error("An error occurred when initializing", e); - } - }); - - // Load profiles marked to load on server join - ClientPlayerEvent.CLIENT_PLAYER_JOIN.register((LocalPlayer player) -> { - handleClientPlayerEvent(player, false); - }); - - // Load profiles marked to load on server leave - ClientPlayerEvent.CLIENT_PLAYER_QUIT.register((LocalPlayer player) -> { - handleClientPlayerEvent(player, true); - }); - - Keybinds.init(); - Commands.init(); } public static OptionsProfilesModConfiguration config() { @@ -79,7 +46,25 @@ public class OptionsProfilesMod { } } - private static void handleClientPlayerEvent(LocalPlayer player, boolean isOnLeave) { + public static void handleClientLoad() { + try (Stream paths = Files.list(Profiles.PROFILES_DIRECTORY)) { + paths.filter(Files::isDirectory) + .forEach(path -> { + String profileName = path.getFileName().toString(); + + // This gets the configuration but also creates the configuration file if it is not there + ProfileConfiguration profileConfiguration = ProfileConfiguration.get(profileName); + if (profileConfiguration.shouldLoadOnStartup()) { + Profiles.loadProfile(profileName); + OptionsProfilesMod.LOGGER.info("[Profile '{}']: Loaded on startup", profileName); + } + }); + } catch (IOException e) { + OptionsProfilesMod.LOGGER.error("An error occurred when initializing", e); + } + } + + public static void handleClientPlayerEvent(LocalPlayer player, boolean isOnLeave) { if (player == null) return; Connection connection = player.connection.getConnection(); diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/gui/OptionsToggleList.java b/common/src/main/java/net/trafficlunar/optionsprofiles/gui/OptionsToggleList.java index 7b07ce0..00a103e 100644 --- a/common/src/main/java/net/trafficlunar/optionsprofiles/gui/OptionsToggleList.java +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/gui/OptionsToggleList.java @@ -1,16 +1,12 @@ package net.trafficlunar.optionsprofiles.gui; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.gui.screens.options.controls.KeyBindsList; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.trafficlunar.optionsprofiles.OptionsProfilesMod; import net.trafficlunar.optionsprofiles.profiles.ProfileConfiguration; import net.trafficlunar.optionsprofiles.profiles.Profiles; import com.google.common.collect.ImmutableList; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.ContainerObjectSelectionList; import net.minecraft.client.gui.components.CycleButton; import net.minecraft.client.gui.components.EditBox; @@ -137,14 +133,15 @@ public class OptionsToggleList extends ContainerObjectSelectionList children() { diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/gui/OptionsToggleScreen.java b/common/src/main/java/net/trafficlunar/optionsprofiles/gui/OptionsToggleScreen.java index d483510..6e9f04d 100644 --- a/common/src/main/java/net/trafficlunar/optionsprofiles/gui/OptionsToggleScreen.java +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/gui/OptionsToggleScreen.java @@ -1,7 +1,6 @@ package net.trafficlunar.optionsprofiles.gui; import net.minecraft.ChatFormatting; -import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.components.StringWidget; diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/gui/ProfilesList.java b/common/src/main/java/net/trafficlunar/optionsprofiles/gui/ProfilesList.java index 27fa2ba..c7db7d6 100644 --- a/common/src/main/java/net/trafficlunar/optionsprofiles/gui/ProfilesList.java +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/gui/ProfilesList.java @@ -1,12 +1,10 @@ package net.trafficlunar.optionsprofiles.gui; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.trafficlunar.optionsprofiles.OptionsProfilesMod; -import net.trafficlunar.optionsprofiles.profiles.ProfileConfiguration; import net.trafficlunar.optionsprofiles.profiles.Profiles; import com.google.common.collect.ImmutableList; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.ContainerObjectSelectionList; import net.minecraft.client.gui.components.events.GuiEventListener; @@ -93,17 +91,18 @@ public class ProfilesList extends ContainerObjectSelectionList children() { diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/platform/Services.java b/common/src/main/java/net/trafficlunar/optionsprofiles/platform/Services.java new file mode 100644 index 0000000..97a8951 --- /dev/null +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/platform/Services.java @@ -0,0 +1,30 @@ +package net.trafficlunar.optionsprofiles.platform; + +import net.trafficlunar.optionsprofiles.OptionsProfilesMod; +import net.trafficlunar.optionsprofiles.platform.services.IPlatformHelper; + +import java.util.ServiceLoader; + +// Service loaders are a built-in Java feature that allow us to locate implementations of an interface that vary from one +// environment to another. In the context of MultiLoader we use this feature to access a mock API in the common code that +// is swapped out for the platform specific implementation at runtime. +public class Services { + + // In this example we provide a platform helper which provides information about what platform the mod is running on. + // For example this can be used to check if the code is running on NeoForge vs Fabric, or to ask the modloader if another + // mod is loaded. + public static final IPlatformHelper PLATFORM = load(IPlatformHelper.class); + + // This code is used to load a service for the current environment. Your implementation of the service must be defined + // manually by including a text file in META-INF/services named with the fully qualified class name of the service. + // Inside the file you should write the fully qualified class name of the implementation to load for the platform. For + // example our file on Forge points to ForgePlatformHelper while Fabric points to FabricPlatformHelper. + public static T load(Class clazz) { + + final T loadedService = ServiceLoader.load(clazz, Services.class.getClassLoader()) + .findFirst() + .orElseThrow(() -> new NullPointerException("Failed to load service for " + clazz.getName())); + OptionsProfilesMod.LOGGER.debug("Loaded {} for service {}", loadedService, clazz); + return loadedService; + } +} \ No newline at end of file diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/platform/services/IPlatformHelper.java b/common/src/main/java/net/trafficlunar/optionsprofiles/platform/services/IPlatformHelper.java new file mode 100644 index 0000000..2abe547 --- /dev/null +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/platform/services/IPlatformHelper.java @@ -0,0 +1,7 @@ +package net.trafficlunar.optionsprofiles.platform.services; + +public interface IPlatformHelper { + String getPlatformName(); + + boolean isModLoaded(String modId); +} diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/Profiles.java b/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/Profiles.java index 40a60ae..df7d983 100644 --- a/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/Profiles.java +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/Profiles.java @@ -1,8 +1,8 @@ package net.trafficlunar.optionsprofiles.profiles; -import dev.architectury.platform.Platform; import net.minecraft.client.Minecraft; import net.trafficlunar.optionsprofiles.OptionsProfilesMod; +import net.trafficlunar.optionsprofiles.platform.Services; import net.trafficlunar.optionsprofiles.profiles.loaders.DistantHorizonsLoader; import net.trafficlunar.optionsprofiles.profiles.loaders.IrisLoader; import net.trafficlunar.optionsprofiles.profiles.loaders.SodiumExtraLoader; @@ -88,13 +88,13 @@ public class Profiles { copyOptionFile(profile, OPTIONS_FILE); copyOptionFile(profile, OPTIFINE_OPTIONS_FILE); - if (Platform.isModLoaded("sodium")) + if (Services.PLATFORM.isModLoaded("sodium")) copyOptionFile(profile, SODIUM_OPTIONS_FILE); - if (Platform.isModLoaded("sodium-extra")) + if (Services.PLATFORM.isModLoaded("sodium-extra")) copyOptionFile(profile, SODIUM_EXTRA_OPTIONS_FILE); - if (Platform.isModLoaded("iris")) + if (Services.PLATFORM.isModLoaded("iris")) copyOptionFile(profile, IRIS_OPTIONS_FILE); - if (Platform.isModLoaded("distanthorizons")) + if (Services.PLATFORM.isModLoaded("distanthorizons")) copyOptionFile(profile, DISTANT_HORIZONS_OPTIONS_FILE); if (!overwriting) { @@ -255,13 +255,13 @@ public class Profiles { loadOptionFile(profileName, OPTIONS_FILE); loadOptionFile(profileName, OPTIFINE_OPTIONS_FILE); - if (Platform.isModLoaded("sodium")) + if (Services.PLATFORM.isModLoaded("sodium")) loadOptionFile(profileName, SODIUM_OPTIONS_FILE, SodiumLoader::load); - if (Platform.isModLoaded("sodium-extra")) + if (Services.PLATFORM.isModLoaded("sodium-extra")) loadOptionFile(profileName, SODIUM_EXTRA_OPTIONS_FILE, SodiumExtraLoader::load); - if (Platform.isModLoaded("iris")) + if (Services.PLATFORM.isModLoaded("iris")) loadOptionFile(profileName, IRIS_OPTIONS_FILE, IrisLoader::load); - if (Platform.isModLoaded("distanthorizons")) { + if (Services.PLATFORM.isModLoaded("distanthorizons")) { loadOptionFile(profileName, DISTANT_HORIZONS_OPTIONS_FILE); // Overwrite / load original Disant Horizons option file loadOptionFile(profileName, DISTANT_HORIZONS_OPTIONS_FILE, DistantHorizonsLoader::load); // Tell Distant Horizons mod to reload configuration } diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/loaders/SodiumExtraLoader.java b/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/loaders/SodiumExtraLoader.java index d523265..72041fd 100644 --- a/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/loaders/SodiumExtraLoader.java +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/loaders/SodiumExtraLoader.java @@ -6,6 +6,7 @@ import me.flashyreese.mods.sodiumextra.client.SodiumExtraClientMod; import me.flashyreese.mods.sodiumextra.client.gui.FogTypeConfig; import me.flashyreese.mods.sodiumextra.client.gui.SodiumExtraGameOptions; import me.flashyreese.mods.sodiumextra.common.util.ResourceLocationSerializer; +import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.material.FogType; import net.trafficlunar.optionsprofiles.OptionsProfilesMod; @@ -19,7 +20,7 @@ import java.util.Map; public class SodiumExtraLoader { public static void load(Path file) { try (FileReader reader = new FileReader(file.toFile())) { - Gson gson = new GsonBuilder().registerTypeAdapter(ResourceLocation.class, new ResourceLocationSerializer()).create(); + Gson gson = new GsonBuilder().registerTypeAdapter(Identifier.class, new IdentifierSerializer()).create(); Configuration configuration = gson.fromJson(reader, Configuration.class); apply(configuration); diff --git a/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/loaders/SodiumLoader.java b/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/loaders/SodiumLoader.java index f8d5f28..88ad10a 100644 --- a/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/loaders/SodiumLoader.java +++ b/common/src/main/java/net/trafficlunar/optionsprofiles/profiles/loaders/SodiumLoader.java @@ -1,5 +1,6 @@ package net.trafficlunar.optionsprofiles.profiles.loaders; +import me.flashyreese.mods.sodiumextra.client.config.SodiumExtraGameOptions; import net.caffeinemc.mods.sodium.client.render.chunk.DeferMode; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.QuadSplittingMode; import net.trafficlunar.optionsprofiles.OptionsProfilesMod; @@ -25,6 +26,7 @@ public class SodiumLoader { } private static void apply(Configuration configuration) { + SodiumExtraGameOptions SodiumClientMod.options().quality.weatherQuality = SodiumGameOptions.WeatherQuality.valueOf(configuration.quality.weather_quality); SodiumClientMod.options().quality.leavesQuality = SodiumGameOptions.LeavesQuality.valueOf(configuration.quality.leaves_quality); SodiumClientMod.options().quality.enableVignette = configuration.quality.enable_vignette; diff --git a/common/src/main/resources/optionsprofiles.mixins.json b/common/src/main/resources/optionsprofiles.mixins.json index 7dc8658..54b0820 100644 --- a/common/src/main/resources/optionsprofiles.mixins.json +++ b/common/src/main/resources/optionsprofiles.mixins.json @@ -1,13 +1,12 @@ { "required": true, + "minVersion": "0.8", "package": "net.trafficlunar.optionsprofiles.mixin", "compatibilityLevel": "JAVA_17", - "minVersion": "0.8", "client": [ "MixinOptionsScreen" ], - "mixins": [ - ], + "mixins": [], "injectors": { "defaultRequire": 1 } diff --git a/common/src/main/resources/pack.mcmeta b/common/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..a13d0c9 --- /dev/null +++ b/common/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "${mod_name}", + "pack_format": 8 + } +} \ No newline at end of file diff --git a/fabric/build.gradle b/fabric/build.gradle index 07b0555..c30bdd7 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -1,65 +1,49 @@ plugins { - id 'com.gradleup.shadow' + id 'multiloader-loader' + id 'net.fabricmc.fabric-loom' } - -architectury { - platformSetupLoomIde() - fabric() -} - -configurations { - common { - canBeResolved = true - canBeConsumed = false - } - compileClasspath.extendsFrom common - runtimeClasspath.extendsFrom common - developmentFabric.extendsFrom common - - // Files in this configuration will be bundled into your mod using the Shadow plugin. - // Don't use the `shadow` configuration from the plugin itself as it's meant for excluding files. - shadowBundle { - canBeResolved = true - canBeConsumed = false - } -} - -repositories { - maven { - name = "Terraformers" - url = "https://maven.terraformersmc.com/" - } -} - dependencies { - modImplementation "net.fabricmc:fabric-loader:$rootProject.fabric_loader_version" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:$rootProject.fabric_api_version" - - // Architectury API - modImplementation "dev.architectury:architectury-fabric:$rootProject.architectury_api_version" - - // Mod Menu API - modImplementation("com.terraformersmc:modmenu:16.0.0-rc.1") - - common(project(path: ':common', configuration: 'namedElements')) { transitive false } - shadowBundle project(path: ':common', configuration: 'transformProductionFabric') + minecraft "com.mojang:minecraft:${minecraft_version}" + implementation "net.fabricmc:fabric-loader:${fabric_loader_version}" + implementation "net.fabricmc.fabric-api:fabric-api:${fabric_api_version}" } -processResources { - inputs.property 'version', project.version - - filesMatching('fabric.mod.json') { - expand version: project.version +loom { + def aw = project(':common').file("src/main/resources/${mod_id}.accesswidener") + if (aw.exists()) { + accessWidenerPath.set(aw) + } + runs { + client { + client() + setConfigName('Fabric Client') + ideConfigGenerated(true) + runDir('runs/client') + } + server { + server() + setConfigName('Fabric Server') + ideConfigGenerated(true) + runDir('runs/server') + } } } -shadowJar { - configurations = [project.configurations.shadowBundle] - archiveClassifier = 'dev-shadow' +// Implement mcgradleconventions loader attribute +def loaderAttribute = Attribute.of('io.github.mcgradleconventions.loader', String) +['apiElements', 'runtimeElements', 'sourcesElements', 'javadocElements', 'includeInternal', 'modCompileClasspath'].each { variant -> + configurations.named("$variant") { + attributes { + attribute(loaderAttribute, 'fabric') + } + } } - -remapJar { - input.set shadowJar.archiveFile +sourceSets.configureEach { + [it.compileClasspathConfigurationName, it.runtimeClasspathConfigurationName].each { variant-> + configurations.named("$variant") { + attributes { + attribute(loaderAttribute, 'fabric') + } + } + } } \ No newline at end of file diff --git a/fabric/src/main/java/net/trafficlunar/optionsprofiles/fabric/OptionsProfilesModFabric.java b/fabric/src/main/java/net/trafficlunar/optionsprofiles/fabric/OptionsProfilesModFabric.java index 7b1a68d..8cf14ee 100644 --- a/fabric/src/main/java/net/trafficlunar/optionsprofiles/fabric/OptionsProfilesModFabric.java +++ b/fabric/src/main/java/net/trafficlunar/optionsprofiles/fabric/OptionsProfilesModFabric.java @@ -1,11 +1,26 @@ package net.trafficlunar.optionsprofiles.fabric; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.keymapping.v1.KeyMappingHelper; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.trafficlunar.optionsprofiles.Commands; +import net.trafficlunar.optionsprofiles.Keybinds; import net.trafficlunar.optionsprofiles.OptionsProfilesMod; -import net.fabricmc.api.ModInitializer; -public class OptionsProfilesModFabric implements ModInitializer { +public class OptionsProfilesModFabric implements ClientModInitializer { @Override - public void onInitialize() { + public void onInitializeClient() { OptionsProfilesMod.init(); + Keybinds.registerKeybinds(KeyMappingHelper::registerKeyMapping); + ClientTickEvents.END_CLIENT_TICK.register(_ -> Keybinds.tick()); + CommandRegistrationCallback.EVENT.register((dispatcher, _, _) -> Commands.registerCommands(dispatcher::register)); + + ClientLifecycleEvents.CLIENT_STARTED.register(_ -> OptionsProfilesMod.handleClientLoad()); + + ClientPlayConnectionEvents.JOIN.register((listener, sender, client) -> OptionsProfilesMod.handleClientPlayerEvent(client.player, false)); + ClientPlayConnectionEvents.DISCONNECT.register((listener, client) -> OptionsProfilesMod.handleClientPlayerEvent(client.player, true)); } } diff --git a/fabric/src/main/java/net/trafficlunar/optionsprofiles/fabric/platform/FabricPlatformHelper.java b/fabric/src/main/java/net/trafficlunar/optionsprofiles/fabric/platform/FabricPlatformHelper.java new file mode 100644 index 0000000..0747422 --- /dev/null +++ b/fabric/src/main/java/net/trafficlunar/optionsprofiles/fabric/platform/FabricPlatformHelper.java @@ -0,0 +1,16 @@ +package net.trafficlunar.optionsprofiles.fabric.platform; + +import net.fabricmc.loader.api.FabricLoader; +import net.trafficlunar.optionsprofiles.platform.services.IPlatformHelper; + +public class FabricPlatformHelper implements IPlatformHelper { + @Override + public String getPlatformName() { + return "Fabric"; + } + + @Override + public boolean isModLoaded(String modId) { + return FabricLoader.getInstance().isModLoaded(modId); + } +} diff --git a/fabric/src/main/resources/META-INF/services/net.trafficlunar.optionsprofiles.platform.services b/fabric/src/main/resources/META-INF/services/net.trafficlunar.optionsprofiles.platform.services new file mode 100644 index 0000000..58903be --- /dev/null +++ b/fabric/src/main/resources/META-INF/services/net.trafficlunar.optionsprofiles.platform.services @@ -0,0 +1 @@ +net.trafficlunar.optionsprofiles.fabric.platform.FabricPlatformHelper \ No newline at end of file diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index f71213c..fca853d 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -1,28 +1,29 @@ { "schemaVersion": 1, - "id": "optionsprofiles", - "version": "${version}", - "name": "Options Profiles", - "description": "Load and save your options from in-game.", - "authors": ["trafficlunar"], + "id": "${mod_id}", + "version": "${mod_version}", + "name": "${mod_name}", + "description": "${mod_description}", + "authors": ["${mod_author}"], "contact": { "homepage": "https://github.com/trafficlunar/options-profiles", "sources": "https://github.com/trafficlunar/options-profiles", "issues": "https://github.com/trafficlunar/options-profiles/issues" }, - "license": "GNU GPL 3.0", - "icon": "assets/optionsprofiles/icon.png", + "license": "${license}", + "icon": "assets/${mod_id}/icon.png", "environment": "*", "entrypoints": { "main": ["net.trafficlunar.optionsprofiles.fabric.OptionsProfilesModFabric"], "modmenu": ["net.trafficlunar.optionsprofiles.fabric.ModMenuApiImpl"] }, - "mixins": ["optionsprofiles.mixins.json"], + "mixins": [ + "${mod_id}.mixins.json" + ], "depends": { - "fabricloader": ">=0.17.2", - "minecraft": "~1.21", - "java": ">=21", - "architectury": ">=18.0.3", - "fabric-api": "*" + "fabricloader": ">=${fabric_loader_version}", + "fabric-api": "*", + "minecraft": "~${minecraft_version}", + "java": ">=${java_version}" } } diff --git a/gradle.properties b/gradle.properties index 7a5be0a..cae2733 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,20 +1,27 @@ org.gradle.jvmargs=-Xmx6G org.gradle.parallel=true -# Fixes errors caused by Loom version differences -loom.ignoreDependencyLoomVersionValidation=true +java_version=25 # Mod properties -mod_version=1.4.4 -maven_group=net.trafficlunar.optionsprofiles -archives_name=optionsprofiles -enabled_platforms=fabric,neoforge +mod_id=optionsprofiles +mod_version=1.4.5 +mod_name=Options Profiles +mod_description=Load and save your options from in-game. +mod_author=trafficlunar + +license=GNU GPL 3.0 +group=net.trafficlunar.optionsprofiles # Minecraft properties -minecraft_version=1.21.9 +minecraft_version=26.1 +minecraft_version_range=[26.1, 26.2) # Dependencies -architectury_api_version = 18.0.3 -fabric_loader_version=0.17.2 -fabric_api_version=0.134.0+1.21.9 -neoforge_version=21.9.0-beta \ No newline at end of file +fabric_loader_version=0.18.4 +fabric_api_version=0.144.3+26.1 +neoforge_version=26.1.0.8-beta +neoforge_loader_version_range=[4,) +## 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 +neo_form_version=26.1-1 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aa02b02..20413ca 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 8c3c5fd..dcaae8d 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -1,59 +1,61 @@ plugins { - id 'com.gradleup.shadow' + id 'multiloader-loader' + id 'net.neoforged.moddev' } -architectury { - platformSetupLoomIde() - neoForge() -} - -configurations { - common { - canBeResolved = true - canBeConsumed = false +neoForge { + version = neoforge_version + // Automatically enable neoforge AccessTransformers if the file exists + def at = project(':common').file('src/main/resources/META-INF/accesstransformer.cfg') + if (at.exists()) { + accessTransformers.from(at.absolutePath) } - compileClasspath.extendsFrom common - runtimeClasspath.extendsFrom common - developmentNeoForge.extendsFrom common - - // Files in this configuration will be bundled into your mod using the Shadow plugin. - // Don't use the `shadow` configuration from the plugin itself as it's meant for excluding files. - shadowBundle { - canBeResolved = true - canBeConsumed = false + runs { + configureEach { + systemProperty('neoforge.enabledGameTestNamespaces', mod_id) + ideName = "NeoForge ${it.name.capitalize()} (${project.path})" // Unify the run config names with fabric + } + client { + client() + gameDirectory = this.mkdir(this.file("runs/client")) + } + data { + clientData() + gameDirectory = this.mkdir(this.file("runs/data")) + // DataGen can be run by - "./gradlew :neoforge:runData" in Terminal. + // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. + programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() + } + server { + server() + this.file("runs/server").createParentDirectories() + gameDirectory = this.mkdir(this.file("runs/server")) + } + } + mods { + "${mod_id}" { + sourceSet sourceSets.main + } } } -repositories { - maven { - name = 'NeoForged' - url = 'https://maven.neoforged.net/releases' +sourceSets.main.resources { srcDir 'src/generated/resources' } + +// Implement mcgradleconventions loader attribute +def loaderAttribute = Attribute.of('io.github.mcgradleconventions.loader', String) +['apiElements', 'runtimeElements', 'sourcesElements', 'javadocElements'].each { variant -> + configurations.named("$variant") { + attributes { + attribute(loaderAttribute, 'neoforge') + } } } - -dependencies { - neoForge "net.neoforged:neoforge:$rootProject.neoforge_version" - - // Architectury API - modImplementation "dev.architectury:architectury-neoforge:$rootProject.architectury_api_version" - - common(project(path: ':common', configuration: 'namedElements')) { transitive false } - shadowBundle project(path: ':common', configuration: 'transformProductionNeoForge') -} - -processResources { - inputs.property 'version', project.version - - filesMatching('META-INF/neoforge.mods.toml') { - expand version: project.version +sourceSets.configureEach { + [it.compileClasspathConfigurationName, it.runtimeClasspathConfigurationName, it.getTaskName(null, 'jarJar')].each { variant -> + configurations.named("$variant") { + attributes { + attribute(loaderAttribute, 'neoforge') + } + } } -} - -shadowJar { - configurations = [project.configurations.shadowBundle] - archiveClassifier = 'dev-shadow' -} - -remapJar { - input.set shadowJar.archiveFile } \ No newline at end of file diff --git a/neoforge/src/main/java/net/trafficlunar/optionsprofiles/neoforge/OptionsProfilesModNeoForge.java b/neoforge/src/main/java/net/trafficlunar/optionsprofiles/neoforge/OptionsProfilesModNeoForge.java index 05c3c43..7bf2a77 100644 --- a/neoforge/src/main/java/net/trafficlunar/optionsprofiles/neoforge/OptionsProfilesModNeoForge.java +++ b/neoforge/src/main/java/net/trafficlunar/optionsprofiles/neoforge/OptionsProfilesModNeoForge.java @@ -1,11 +1,55 @@ package net.trafficlunar.optionsprofiles.neoforge; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent; +import net.neoforged.neoforge.client.event.ClientTickEvent; +import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; +import net.neoforged.neoforge.client.event.lifecycle.ClientStartedEvent; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.RegisterCommandsEvent; +import net.trafficlunar.optionsprofiles.Commands; +import net.trafficlunar.optionsprofiles.Keybinds; import net.trafficlunar.optionsprofiles.OptionsProfilesMod; import net.neoforged.fml.common.Mod; -@Mod(OptionsProfilesMod.MOD_ID) +@Mod(value = OptionsProfilesMod.MOD_ID, dist = Dist.CLIENT) public class OptionsProfilesModNeoForge { - public OptionsProfilesModNeoForge() { + public OptionsProfilesModNeoForge(IEventBus bus) { OptionsProfilesMod.init(); + + if (FMLEnvironment.getDist() == Dist.CLIENT) { + NeoForge.EVENT_BUS.addListener(OptionsProfilesModNeoForge::onClientStarted); + NeoForge.EVENT_BUS.addListener(OptionsProfilesModNeoForge::onClientPlayerJoin); + NeoForge.EVENT_BUS.addListener(OptionsProfilesModNeoForge::onClientPlayerQuit); + NeoForge.EVENT_BUS.addListener(OptionsProfilesModNeoForge::registerKeybinds); + NeoForge.EVENT_BUS.addListener(OptionsProfilesModNeoForge::registerKeybindTick); + NeoForge.EVENT_BUS.addListener(OptionsProfilesModNeoForge::registerCommands); + } + } + + private static void onClientStarted(ClientStartedEvent event) { + OptionsProfilesMod.handleClientLoad(); + } + + private static void onClientPlayerJoin(ClientPlayerNetworkEvent.LoggingIn event) { + OptionsProfilesMod.handleClientPlayerEvent(event.getPlayer(), false); + } + + private static void onClientPlayerQuit(ClientPlayerNetworkEvent.LoggingOut event) { + OptionsProfilesMod.handleClientPlayerEvent(event.getPlayer(), true); + } + + private static void registerKeybinds(RegisterKeyMappingsEvent event) { + Keybinds.registerKeybinds(event::register); + } + + private static void registerKeybindTick(ClientTickEvent.Post event) { + Keybinds.tick(); + } + + private static void registerCommands(RegisterCommandsEvent event) { + Commands.registerCommands(event.getDispatcher()::register); } } diff --git a/neoforge/src/main/java/net/trafficlunar/optionsprofiles/neoforge/platform/NeoForgePlatformHelper.java b/neoforge/src/main/java/net/trafficlunar/optionsprofiles/neoforge/platform/NeoForgePlatformHelper.java new file mode 100644 index 0000000..3781470 --- /dev/null +++ b/neoforge/src/main/java/net/trafficlunar/optionsprofiles/neoforge/platform/NeoForgePlatformHelper.java @@ -0,0 +1,16 @@ +package net.trafficlunar.optionsprofiles.neoforge.platform; + +import net.neoforged.fml.ModList; +import net.trafficlunar.optionsprofiles.platform.services.IPlatformHelper; + +public class NeoForgePlatformHelper implements IPlatformHelper { + @Override + public String getPlatformName() { + return "NeoForge"; + } + + @Override + public boolean isModLoaded(String modId) { + return ModList.get().isLoaded(modId); + } +} \ No newline at end of file diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 9f8bb45..9a75b7f 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -1,38 +1,29 @@ modLoader = "javafml" -loaderVersion = "[10,)" +loaderVersion = "${neoforge_loader_version_range}" issueTrackerURL = "https://github.com/trafficlunar/options-profiles/issues" license = "GNU GPL 3.0" [[mods]] -modId = "optionsprofiles" -version = "${version}" -displayName = "Options Profiles" -authors = "trafficlunar" -description = ''' -Load and save your options from in-game. -''' -logoFile = "icon.png" +modId = "${mod_id}" +version = "${mod_version}" +displayName = "${mod_name}" +authors = "${mod_author}" +description = '''${mod_description}''' +logoFile = "${mod_id}.png" -[[dependencies.optionsprofiles]] +[[dependencies.${mod_id}]] modId = "neoforge" type = "required" -versionRange = "[21.9.0-beta,)" +versionRange = "[${neoforge_version},)" ordering = "NONE" side = "BOTH" -[[dependencies.optionsprofiles]] +[[dependencies.${mod_id}]] modId = "minecraft" type = "required" -versionRange = "[1.21,)" +versionRange = "${minecraft_version_range}" ordering = "NONE" side = "BOTH" -[[dependencies.optionsprofiles]] -modId = "architectury" -type = "required" -versionRange = "[18.0.3,)" -ordering = "AFTER" -side = "BOTH" - [[mixins]] -config = "optionsprofiles.mixins.json" +config = "${mod_id}.mixins.json" diff --git a/neoforge/src/main/resources/META-INF/services/net.trafficlunar.optionsprofiles.platform.services b/neoforge/src/main/resources/META-INF/services/net.trafficlunar.optionsprofiles.platform.services new file mode 100644 index 0000000..4c9ff0b --- /dev/null +++ b/neoforge/src/main/resources/META-INF/services/net.trafficlunar.optionsprofiles.platform.services @@ -0,0 +1 @@ +net.trafficlunar.optionsprofiles.neoforge.platform.NeoForgePlatformHelper \ No newline at end of file diff --git a/neoforge/src/main/resources/icon.png b/neoforge/src/main/resources/optionsprofiles.png similarity index 100% rename from neoforge/src/main/resources/icon.png rename to neoforge/src/main/resources/optionsprofiles.png diff --git a/settings.gradle b/settings.gradle index 3f4b07a..ca27567 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,14 +1,26 @@ pluginManagement { repositories { - maven { url "https://maven.fabricmc.net/" } - maven { url "https://maven.architectury.dev/" } - maven { url "https://maven.minecraftforge.net/" } gradlePluginPortal() + mavenCentral() + exclusiveContent { + forRepository { + maven { + name = 'Fabric' + url = uri('https://maven.fabricmc.net') + } + } + filter { + includeGroupAndSubgroups('net.fabricmc') + } + } } } +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' +} + +rootProject.name = "options-profiles" include("common") include("fabric") include("neoforge") - -rootProject.name = "optionsprofiles-v1.4.4-1.21.9"