diff --git a/.gitattributes b/.gitattributes index f811f6a..0a711a0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,5 @@ # Disable autocrlf on generated files, they always generate with LF # Add any extra files or paths here to make git stop saying they # are changed when only line endings change. -src/generated/**/.cache/cache text eol=lf -src/generated/**/*.json text eol=lf +forge/src/generated/**/.cache/cache text eol=lf +forge/src/generated/**/*.json text eol=lf diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..2ca3795 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,40 @@ +# Automatically build the project and run any configured tests for every push +# and submitted pull request. This can help catch issues that only occur on +# certain platforms or Java versions, and provides a first line of defence +# against bad commits. + +name: build +on: [pull_request, push] + +jobs: + build: + strategy: + matrix: + # Use these Java versions + java: [ + 17, # Current Java LTS & minimum supported by Minecraft + ] + # and run on both Linux and Windows + os: [ubuntu-22.04, windows-2022] + runs-on: ${{ matrix.os }} + steps: + - name: checkout repository + uses: actions/checkout@v3 + - name: validate gradle wrapper + uses: gradle/wrapper-validation-action@v1 + - name: setup jdk ${{ matrix.java }} + uses: actions/setup-java@v3 + with: + java-version: ${{ matrix.java }} + distribution: 'microsoft' + - name: make gradle wrapper executable + if: ${{ runner.os != 'Windows' }} + run: chmod +x ./gradlew + - name: build + run: ./gradlew build + - name: capture build artifacts + if: ${{ runner.os == 'Linux' && matrix.java == '17' }} # Only upload artifacts built from latest java on one OS + uses: actions/upload-artifact@v3 + with: + name: Artifacts + path: build/libs/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 12f8644..669ca06 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,23 @@ -# eclipse -bin -*.launch -.settings -.metadata -.classpath -.project +* +!*/ +!.gitignore +!.github/** +.idea/.gitignore -# idea -out -*.ipr -*.iws -*.iml -.idea +!build.gradle +!gradle.properties +!gradlew +!gradlew.bat +!LICENSE +!README.md +!settings.gradle -# gradle -build -.gradle +!common/build.gradle +!forge/build.gradle +!fabric/build.gradle +!Resources/** -# other -eclipse -run - -# Files from Forge MDK -forge*changelog.txt +!gradle/wrapper/** +!forge/src/** +!fabric/src/** +!common/src/** diff --git a/README.md b/README.md index 8507d3e..88b55eb 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,36 @@ -![MCVer](https://img.shields.io/badge/MC-1.19.4-green) ![ModLoader](https://img.shields.io/badge/Mod_Loader-Forge-green)

HarmonyLinkMC

+![MCVer](https://img.shields.io/badge/MC-1.19.4-blue) +![ModLoader](https://img.shields.io/badge/Mod_Loader-Forge_/_Fabric-blue) +![HLAPIVer](https://img.shields.io/badge/HarmonyLink_API_Version-V1-blue) + Welcome to the HarmonyLink Minecraft Mod! This mod integrates the HarmonyLink API into Minecraft, providing an enhanced gaming experience on handheld devices, including the Steam Deck. With HarmonyLink, you can access real-time system metrics and adapt your gameplay settings for a more personalized and immersive adventure. ### Features -- Real-Time Metrics: Gain access to critical system metrics, such as power usage and docking status, in real-time while playing Minecraft on handheld devices. -- Device Identification: Identify the specific handheld device you are playing Minecraft on, ensuring optimal compatibility and performance. -- Customized Gaming Experience: Adapt your game settings based on the power metrics and docking status, creating a tailored experience that suits your preferences and device capabilities. -- Cross-Platform Compatibility: Enjoy the benefits of HarmonyLink not only on native platforms but also on Windows games running through Proton/Wine, expanding its functionality to a wider range of handheld devices. +- **Automated Graphics Settings:** The mod can automatically adjust graphics settings based on your device's power source: battery, charging, or docked mode. +- **Docked Mode Option:** Docked mode is an optional feature. If you prefer, you can choose to turn it off. +- **Customizable Settings:** Change a variety of settings to suit your preferences, including Graphics mode (Fast, Fancy, Fabulous), Render distance, Simulation distance, Biome blend radius, and GUI scale. +- **Full User Control:** As a user, you maintain complete control over all settings. Whether your device is running on battery or charging, you can define the graphics quality and other settings as you wish. ### Getting Started -To get started with the HarmonyLink Minecraft Mod, follow these steps: +Follow these detailed steps to set up and start using the HarmonyLink Minecraft Mod: -1. Install Minecraft Forge: Make sure you have Minecraft Forge installed on your device. -2. Download HarmonyLink Mod: Download the latest version of the HarmonyLink Minecraft Mod from the [GitHub repository](https://github.com/Jordonbc/HarmonyLink-MC/releases). -3. Install HarmonyLink Mod: Place the downloaded mod file into the "mods" folder in your Minecraft directory. -4. Download and run [HarmonyLinkServer](https://github.com/Jordonbc/HarmonyLinkServer). -4. Launch Minecraft: Start Minecraft with the HarmonyLink Mod installed. -5. Enjoy the Enhanced Experience: Play Minecraft on your handheld device and witness the real-time system metrics and adaptive gameplay features provided by HarmonyLink. +1. **Install Minecraft Forge / Fabric:** The first step is to ensure you have Minecraft Forge or Fabric installed on your device. These are mod loaders that allow Minecraft to use mods like HarmonyLink. You can download these from their official websites. +2. **Download HarmonyLink Mod:** Next, navigate to the HarmonyLink Minecraft Mod page on the [modrinth](https://modrinth.com/mod/harmonylinkmc) website. Select the latest version of the mod and download it to your device. +3. **Install HarmonyLink Mod:** Once downloaded, move the HarmonyLink Mod file into the "mods" folder in your Minecraft directory. If you can't find this folder, it's typically located within the '.minecraft' folder. +4. **Install HarmonyLinkServer:** To take full advantage of HarmonyLink's features, you need to install the HarmonyLinkServer. You can download it from [here](https://github.com/Jordonbc/HarmonyLinkServer/releases/latest/download/harmonylink_installer.desktop). Follow the instructions on the website to install it correctly. +5. **Launch Minecraft:** Now that everything is set up, it's time to launch Minecraft. Ensure that the game is launched with Forge or Fabric, which will then load the HarmonyLink Mod. +6. **Configure Settings:** Once in the game, navigate to the mod settings to configure the graphics settings for different power modes (battery, charging, docked). Remember, docked mode can be turned off if you prefer. +7. **Enjoy the Enhanced Experience:** You're all set! Now you can enjoy a more personalized Minecraft gaming experience with adaptive gameplay settings provided by HarmonyLink. -Note: To get this working in gamemode, HarmonyLinkServer needs to be installed as a service to run in the background. ### Contributing -We welcome contributions from the Minecraft and programming community to further improve the HarmonyLink Minecraft Mod. If you have any suggestions, bug reports, or feature requests, please open an issue in the [GitHub repository](https://github.com/Jordonbc/HarmonyLink-MC/issues). +We welcome contributions from the Minecraft and programming community to further improve the HarmonyLink Minecraft Mod. If you have any suggestions, bug reports, or feature requests, please open an issue in the [GitHub repository](https://github.com/Jordonbc/HarmonyLinkMC/issues). ### License diff --git a/build.gradle b/build.gradle index 328df68..3104e55 100644 --- a/build.gradle +++ b/build.gradle @@ -1,181 +1,51 @@ plugins { - id 'eclipse' - id 'maven-publish' - id 'net.minecraftforge.gradle' version '5.1.+' + id "architectury-plugin" version "3.4-SNAPSHOT" + id "dev.architectury.loom" version "1.1-SNAPSHOT" apply false } -version = '0.0.1-1.19-Forge' -group = 'net.jordon.harmonylink' // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = 'harmonylink' - -// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. -java.toolchain.languageVersion = JavaLanguageVersion.of(17) - -println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" -minecraft { - // The mappings can be changed at any time and must be in the following format. - // Channel: Version: - // official MCVersion Official field/method names from Mojang mapping files - // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official - // - // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. - // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md - // - // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge - // Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started - // - // Use non-default mappings at your own risk. They may not always work. - // Simply re-run your setup task after changing the mappings to update your workspace. - mappings channel: 'official', version: '1.19.4' - - // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. - - // Default run configurations. - // These can be tweaked, removed, or duplicated as needed. - runs { - client { - workingDirectory project.file('run') - - // Recommended logging data for a userdev environment - // The markers can be added/remove as needed separated by commas. - // "SCAN": For mods scan. - // "REGISTRIES": For firing of registry events. - // "REGISTRYDUMP": For getting the contents of all registries. - property 'forge.logging.markers', 'REGISTRIES' - - // Recommended logging level for the console - // You can set various levels here. - // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels - property 'forge.logging.console.level', 'debug' - - // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. - property 'forge.enabledGameTestNamespaces', 'harmonylink' - - mods { - harmonylink { - source sourceSets.main - } - } - } - - server { - workingDirectory project.file('run') - - property 'forge.logging.markers', 'REGISTRIES' - - property 'forge.logging.console.level', 'debug' - - property 'forge.enabledGameTestNamespaces', 'harmonylink' - - mods { - harmonylink { - source sourceSets.main - } - } - } - - // This run config launches GameTestServer and runs all registered gametests, then exits. - // By default, the server will crash when no gametests are provided. - // The gametest system is also enabled by default for other run configs under the /test command. - gameTestServer { - workingDirectory project.file('run') - - property 'forge.logging.markers', 'REGISTRIES' - - property 'forge.logging.console.level', 'debug' - - property 'forge.enabledGameTestNamespaces', 'harmonylink' - - mods { - harmonylink { - source sourceSets.main - } - } - } - - data { - workingDirectory project.file('run') - - property 'forge.logging.markers', 'REGISTRIES' - - property 'forge.logging.console.level', 'debug' - - // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. - args '--mod', 'harmonylink', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') - - mods { - harmonylink { - source sourceSets.main - } - } - } - } +architectury { + minecraft = rootProject.minecraft_version } -// Include resources generated by data generators. -sourceSets.main.resources { srcDir 'src/generated/resources' } +subprojects { + apply plugin: "dev.architectury.loom" -repositories { - // Put repositories for dependencies here - // ForgeGradle automatically adds the Forge maven and Maven Central for you + loom { + silentMojangMappingsLicense() + } - // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: - // flatDir { - // dir 'libs' - // } + dependencies { + minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" + // The following line declares the mojmap mappings, you may use other mappings as well + mappings loom.officialMojangMappings() + // The following line declares the yarn mappings you may select this one as well. + // mappings "net.fabricmc:yarn:1.19.4+build.2:v2" + } } -dependencies { - // Specify the version of Minecraft to use. If this is any group other than 'net.minecraft', it is assumed - // that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied. - // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:1.19.4-45.1.0' - - // Real mod deobf dependency examples - these get remapped to your current mappings - // implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency +allprojects { + apply plugin: "java" + apply plugin: "architectury-plugin" + apply plugin: "maven-publish" - // Examples using mod jars from ./libs - // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") + archivesBaseName = rootProject.archives_base_name + version = rootProject.mod_version + group = rootProject.maven_group - // For more info... - // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html - // http://www.gradle.org/docs/current/userguide/dependency_management.html -} - -// Example for how to get properties into the manifest for reading at runtime. -jar { - manifest { - attributes([ - "Specification-Title" : "harmonylink", - "Specification-Vendor" : "harmonylinksareus", - "Specification-Version" : "1", // We are version 1 of ourselves - "Implementation-Title" : project.name, - "Implementation-Version" : project.jar.archiveVersion, - "Implementation-Vendor" : "harmonylinksareus", - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") - ]) + 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. } -} - -// Example configuration to allow publishing using the maven-publish plugin -// This is the preferred method to reobfuscate your jar file -jar.finalizedBy('reobfJar') -// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing -// publish.dependsOn('reobfJar') -publishing { - publications { - mavenJava(MavenPublication) { - artifact jar - } + tasks.withType(JavaCompile) { + options.encoding = "UTF-8" + options.release = 17 } - repositories { - maven { - url "file://${project.projectDir}/mcmodsrepo" - } - } -} -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation + java { + withSourcesJar() + } } diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 0000000..1ad1d61 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,29 @@ +architectury { + common(rootProject.enabled_platforms.split(",")) +} + +loom { + accessWidenerPath = file("src/main/resources/harmonylink.accesswidener") +} + +dependencies { + // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies + // Do NOT use other classes from fabric loader + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + // Remove the next line if you don't want to depend on the API + modApi "dev.architectury:architectury:${rootProject.architectury_version}" +} + +publishing { + publications { + mavenCommon(MavenPublication) { + artifactId = rootProject.archives_base_name + 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. + } +} diff --git a/src/main/java/net/jordon/harmonylink/BatteryInfo.java b/common/src/main/java/net/harmonylink/API/BatteryInfo.java similarity index 69% rename from src/main/java/net/jordon/harmonylink/BatteryInfo.java rename to common/src/main/java/net/harmonylink/API/BatteryInfo.java index 1049392..8acc128 100644 --- a/src/main/java/net/jordon/harmonylink/BatteryInfo.java +++ b/common/src/main/java/net/harmonylink/API/BatteryInfo.java @@ -1,10 +1,10 @@ -package net.jordon.harmonylink; +package net.harmonylink.API; public class BatteryInfo { - boolean hasBattery; - int batteryPercent; - ChargingStatus chargingStatus; + public boolean hasBattery; + public int batteryPercent; + public ChargingStatus chargingStatus; @Override public String toString() { diff --git a/common/src/main/java/net/harmonylink/API/ChargingStatus.java b/common/src/main/java/net/harmonylink/API/ChargingStatus.java new file mode 100644 index 0000000..9cff23d --- /dev/null +++ b/common/src/main/java/net/harmonylink/API/ChargingStatus.java @@ -0,0 +1,7 @@ +package net.harmonylink.API; + +public enum ChargingStatus { + Battery, + Charging, + Unknown +} diff --git a/src/main/java/net/jordon/harmonylink/DockInfo.java b/common/src/main/java/net/harmonylink/API/DockInfo.java similarity index 69% rename from src/main/java/net/jordon/harmonylink/DockInfo.java rename to common/src/main/java/net/harmonylink/API/DockInfo.java index e66b74c..ffb5520 100644 --- a/src/main/java/net/jordon/harmonylink/DockInfo.java +++ b/common/src/main/java/net/harmonylink/API/DockInfo.java @@ -1,9 +1,9 @@ -package net.jordon.harmonylink; +package net.harmonylink.API; public class DockInfo { - String dockModel; - boolean isDocked; - boolean fallbackDetection; + public String dockModel; + public Boolean isDocked; + public Boolean fallbackDetection; @Override public String toString() { diff --git a/src/main/java/net/jordon/harmonylink/OSInfo.java b/common/src/main/java/net/harmonylink/API/OSInfo.java similarity index 92% rename from src/main/java/net/jordon/harmonylink/OSInfo.java rename to common/src/main/java/net/harmonylink/API/OSInfo.java index f38e9d9..3d9488f 100644 --- a/src/main/java/net/jordon/harmonylink/OSInfo.java +++ b/common/src/main/java/net/harmonylink/API/OSInfo.java @@ -1,4 +1,4 @@ -package net.jordon.harmonylink; +package net.harmonylink.API; public class OSInfo { String osType; diff --git a/src/main/java/net/jordon/harmonylink/SystemInfo.java b/common/src/main/java/net/harmonylink/API/SystemInfo.java similarity index 91% rename from src/main/java/net/jordon/harmonylink/SystemInfo.java rename to common/src/main/java/net/harmonylink/API/SystemInfo.java index e1f35cf..42a1d74 100644 --- a/src/main/java/net/jordon/harmonylink/SystemInfo.java +++ b/common/src/main/java/net/harmonylink/API/SystemInfo.java @@ -1,4 +1,4 @@ -package net.jordon.harmonylink; +package net.harmonylink.API; public class SystemInfo { OSInfo os_info; diff --git a/common/src/main/java/net/harmonylink/GraphicsSettings.java b/common/src/main/java/net/harmonylink/GraphicsSettings.java new file mode 100644 index 0000000..3527198 --- /dev/null +++ b/common/src/main/java/net/harmonylink/GraphicsSettings.java @@ -0,0 +1,110 @@ +package net.harmonylink; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.SerializedName; +import net.minecraft.client.GraphicsStatus; +import net.minecraft.client.Minecraft; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +public class GraphicsSettings { + public transient File file; + + @SerializedName("renderDistance") + public HLSimpleOption renderDistance; + @SerializedName("simulationDistance") + public HLSimpleOption simulationDistance; + @SerializedName("GraphicsMode") + public HLSimpleOption GraphicsMode; + @SerializedName("BiomeBlendRadius") + public HLSimpleOption BiomeBlendRadius; + @SerializedName("guiScale") + public HLSimpleOption guiScale; + + public GraphicsSettings(String FileName) { + + file = new File(HarmonyLinkExpectPlatform.getConfigDirectory() + "/HarmonyLink/" + FileName); + + this.renderDistance = new HLSimpleOption<>(Minecraft.getInstance().options.renderDistance().get()); + this.simulationDistance = new HLSimpleOption<>(Minecraft.getInstance().options.simulationDistance().get()); + this.GraphicsMode = new HLSimpleOption<>(Minecraft.getInstance().options.graphicsMode().get()); + this.BiomeBlendRadius = new HLSimpleOption<>(Minecraft.getInstance().options.biomeBlendRadius().get()); + this.guiScale = new HLSimpleOption<>(Minecraft.getInstance().options.guiScale().get()); + + createFileIfNotExists(file); + loadOptions(file); + } + + public void loadOptions(File configFile) { + Gson gson = new Gson(); + + try (FileReader reader = new FileReader(configFile)) { + GraphicsSettings loadedSettings = gson.fromJson(reader, GraphicsSettings.class); + + if (loadedSettings == null) { + HarmonyLink.LOGGER.error("Error loading options: Unable to deserialize settings from JSON."); + return; + } + + // Copy values from loadedSettings to the current instance + this.renderDistance = loadedSettings.renderDistance; + this.simulationDistance = loadedSettings.simulationDistance; + this.GraphicsMode = loadedSettings.GraphicsMode; + this.BiomeBlendRadius = loadedSettings.BiomeBlendRadius; + this.guiScale = loadedSettings.guiScale; + + HarmonyLink.LOGGER.info("Options loaded successfully."); + + } catch (IOException e) { + HarmonyLink.LOGGER.error("Error loading options: " + e.getMessage()); + } + } + + + + public void saveSettingsToFile() { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + try (FileWriter writer = new FileWriter(file)) { + gson.toJson(this, writer); + HarmonyLink.LOGGER.info("Options saved successfully."); + } catch (IOException e) { + HarmonyLink.LOGGER.error("Error saving options: " + e.getMessage()); + } + } + + public void saveAndApply() { + saveSettingsToFile(); + ApplySettings(); + } + + private void createFileIfNotExists(File filePath) { + File parentDirectory = filePath.getParentFile(); + if (!parentDirectory.exists()) { + if (!parentDirectory.mkdirs()) { + throw new RuntimeException("Error creating directories: " + parentDirectory.getAbsolutePath()); + } + } + + if (!filePath.exists()) { + try { + filePath.createNewFile(); + } catch (IOException e) { + throw new RuntimeException("Error creating file: " + filePath.getAbsolutePath(), e); + } + } + } + + public void ApplySettings() { + Minecraft.getInstance().options.renderDistance().set(renderDistance.get()); + Minecraft.getInstance().options.simulationDistance().set(simulationDistance.get()); + Minecraft.getInstance().options.biomeBlendRadius().set(BiomeBlendRadius.get()); + Minecraft.getInstance().options.graphicsMode().set(GraphicsMode.get()); + Minecraft.getInstance().options.guiScale().set(guiScale.get()); + } + +} diff --git a/common/src/main/java/net/harmonylink/HLSettings.java b/common/src/main/java/net/harmonylink/HLSettings.java new file mode 100644 index 0000000..7d9119f --- /dev/null +++ b/common/src/main/java/net/harmonylink/HLSettings.java @@ -0,0 +1,81 @@ +package net.harmonylink; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.SerializedName; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +public class HLSettings { + public transient File file; + + @SerializedName("EnableDocked") + public HLSimpleOption EnableDocked; + + public HLSettings(String FileName) { + + file = new File(HarmonyLinkExpectPlatform.getConfigDirectory() + "/HarmonyLink/" + FileName); + + this.EnableDocked = new HLSimpleOption(false); + + createFileIfNotExists(file); + loadOptions(file); + } + + public void loadOptions(File configFile) { + Gson gson = new Gson(); + + try (FileReader reader = new FileReader(configFile)) { + HLSettings loadedSettings = gson.fromJson(reader, HLSettings.class); + + if (loadedSettings == null) { + HarmonyLink.LOGGER.error("Error loading options: Unable to deserialize settings from JSON."); + return; + } + + // Copy values from loadedSettings to the current instance + this.EnableDocked = loadedSettings.EnableDocked; + + HarmonyLink.LOGGER.info("Options loaded successfully."); + + } catch (IOException e) { + HarmonyLink.LOGGER.error("Error loading options: " + e.getMessage()); + } + } + + + + public boolean saveSettingsToFile() { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + try (FileWriter writer = new FileWriter(file)) { + gson.toJson(this, writer); + HarmonyLink.LOGGER.info("Options saved successfully."); + return true; + } catch (IOException e) { + HarmonyLink.LOGGER.error("Error saving options: " + e.getMessage()); + return false; + } + } + + private void createFileIfNotExists(File filePath) { + File parentDirectory = filePath.getParentFile(); + if (!parentDirectory.exists()) { + if (!parentDirectory.mkdirs()) { + throw new RuntimeException("Error creating directories: " + parentDirectory.getAbsolutePath()); + } + } + + if (!filePath.exists()) { + try { + filePath.createNewFile(); + } catch (IOException e) { + throw new RuntimeException("Error creating file: " + filePath.getAbsolutePath(), e); + } + } + } + +} diff --git a/common/src/main/java/net/harmonylink/HLSimpleOption.java b/common/src/main/java/net/harmonylink/HLSimpleOption.java new file mode 100644 index 0000000..c06c1e9 --- /dev/null +++ b/common/src/main/java/net/harmonylink/HLSimpleOption.java @@ -0,0 +1,19 @@ +package net.harmonylink; + +public class HLSimpleOption { + private T optionValue; + + public HLSimpleOption(T optionValue) { + this.optionValue = optionValue; + } + + // Getter method + public T get() { + return optionValue; + } + + // Setter method + public void set(T value) { + optionValue = value; + } +} diff --git a/common/src/main/java/net/harmonylink/HarmonyLink.java b/common/src/main/java/net/harmonylink/HarmonyLink.java new file mode 100644 index 0000000..064b84a --- /dev/null +++ b/common/src/main/java/net/harmonylink/HarmonyLink.java @@ -0,0 +1,160 @@ +package net.harmonylink; + +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import net.harmonylink.API.BatteryInfo; +import net.harmonylink.API.ChargingStatus; +import net.harmonylink.API.DockInfo; +import net.minecraft.client.Minecraft; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +public class HarmonyLink { + public static final String MOD_ID = "harmonylink"; + + public static final Logger LOGGER = LogManager.getLogger(MOD_ID); + + public static HLSettings HLSETTINGS; + public static GraphicsSettings batterySettings; + public static GraphicsSettings chargingSettings; + public static GraphicsSettings dockedSettings; + + private static Boolean isConnected; + private BatteryInfo batteryInfo; + private DockInfo dockInfo; + private int tickCount = 0; + + public static HarmonyLink init() { + HarmonyLink HL = new HarmonyLink(); + + HLSETTINGS = new HLSettings("HarmonyLink.json"); + isConnected = false; + + LOGGER.info(HarmonyLinkExpectPlatform.getConfigDirectory().toAbsolutePath().normalize().toString()); + return HL; + } + + public void OnTick(Minecraft Client) { + if (++tickCount >= 20) { // Increase the tick count and check if we've reached 20 yet (1-second timer) + tickCount = 0; // Reset the tick count for next time + + HttpClient httpclient = HttpClient.newHttpClient(); + + HttpRequest checkConnectionRequest = HttpRequest.newBuilder() + .uri(URI.create("http://127.0.0.1:9000/v1/are_you_there")) + .build(); + + httpclient.sendAsync(checkConnectionRequest, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body) + .thenAcceptAsync(this::handleConnectedResponse) + .exceptionally(this::handleConnectedFailure); + + if (getIsConnected() && !Client.isPaused() && Client.level != null) { // We don't want to execute the code if the game is paused + + HttpRequest batteryRequest = HttpRequest.newBuilder() + .uri(URI.create("http://127.0.0.1:9000/v1/battery_info")) + .build(); + + httpclient.sendAsync(batteryRequest, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body) + .thenAcceptAsync(this::handleBatteryResponse); + + + HttpRequest dockedRequest = HttpRequest.newBuilder() + .uri(URI.create("http://127.0.0.1:9000/v1/dock_info")) + .build(); + + httpclient.sendAsync(dockedRequest, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body) + .thenAcceptAsync(this::handleDockResponse); + } + } + } + + public void initializeSettings(Minecraft client) { + batterySettings = new GraphicsSettings("Battery.json"); + chargingSettings = new GraphicsSettings("Charging.json"); + dockedSettings = new GraphicsSettings("Docked.json"); + } + + private void handleConnectedResponse(String Response) + { + LOGGER.info("Received String: {}", Response); + if (Response != null && !Response.equals("")) + { + isConnected = Response.equals("yes"); + }else { + isConnected = false; + } + + LOGGER.info("setting isConnected: {}", isConnected); + } + + public Void handleConnectedFailure(Throwable ex) { + // Handle the connection failure exception + //System.err.println("Failed to connect: " + ex.getMessage()); + // Perform any additional error handling or fallback actions + isConnected = false; + return null; + } + + private void handleBatteryResponse(String jsonResponse) + { + Gson gson = new GsonBuilder() + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .create(); + + LOGGER.info("JSON Response: {}", this.batteryInfo); + + if (this.batteryInfo != gson.fromJson(jsonResponse, BatteryInfo.class)) + { + BatteryInfo newBatteryInfo = gson.fromJson(jsonResponse, BatteryInfo.class); + if (newBatteryInfo.hasBattery) + { + if (newBatteryInfo.chargingStatus == ChargingStatus.Battery) + { + batterySettings.ApplySettings(); + } + + else if (newBatteryInfo.chargingStatus == ChargingStatus.Charging) + { + chargingSettings.ApplySettings(); + } + } + + this.batteryInfo = newBatteryInfo; + } + } + + private void handleDockResponse(String jsonResponse) + { + Gson gson = new GsonBuilder() + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .create(); + + LOGGER.info("JSON Response: {}", this.dockInfo); + + if (this.dockInfo != gson.fromJson(jsonResponse, DockInfo.class)) + { + DockInfo newDockInfo = gson.fromJson(jsonResponse, DockInfo.class); + + if (newDockInfo.isDocked) + { + dockedSettings.ApplySettings(); + } + + this.dockInfo = newDockInfo; + } + } + + public static Boolean getIsConnected() + { + return isConnected; + } +} diff --git a/common/src/main/java/net/harmonylink/HarmonyLinkExpectPlatform.java b/common/src/main/java/net/harmonylink/HarmonyLinkExpectPlatform.java new file mode 100644 index 0000000..70e766e --- /dev/null +++ b/common/src/main/java/net/harmonylink/HarmonyLinkExpectPlatform.java @@ -0,0 +1,27 @@ +package net.harmonylink; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import dev.architectury.platform.Platform; + +import java.nio.file.Path; + +public class HarmonyLinkExpectPlatform { + /** + * We can use {@link Platform#getConfigFolder()} but this is just an example of {@link ExpectPlatform}. + *

+ * This must be a public static method. The platform-implemented solution must be placed under a + * platform sub-package, with its class suffixed with {@code Impl}. + *

+ * Example: + * Expect: net.harmonylink.ExampleExpectPlatform#getConfigDirectory() + * Actual Fabric: net.harmonylink.fabric.HarmonyLinkExpectPlatformImpl#getConfigDirectory() + * Actual Forge: net.harmonylink.forge.HarmonyLinkExpectPlatformImpl#getConfigDirectory() + *

+ * You should also get the IntelliJ plugin to help with @ExpectPlatform. + */ + @ExpectPlatform + public static Path getConfigDirectory() { + // Just throw an error, the content should get replaced at runtime. + throw new AssertionError(); + } +} diff --git a/common/src/main/java/net/harmonylink/RangedValue.java b/common/src/main/java/net/harmonylink/RangedValue.java new file mode 100644 index 0000000..184e333 --- /dev/null +++ b/common/src/main/java/net/harmonylink/RangedValue.java @@ -0,0 +1,37 @@ +package net.harmonylink; + +public class RangedValue { + private double min; + private double max; + private double value; + + public RangedValue(double min, double max, double value) { + this.min = min; + this.max = max; + this.value = value; + } + + public double getNormalizedValue() { + return calculateNormalizedValue(this.value); + } + + public double getAbsoluteValue() { + return this.value; + } + + public void setValue(double absoluteValue) { + this.value = absoluteValue; + } + + private double calculateNormalizedValue(double absoluteValue) { + return (absoluteValue - min) / (max - min); + } + + public void setNormalizedValue(double normalizedValue) { + this.value = calculateAbsoluteValue(normalizedValue); + } + + private double calculateAbsoluteValue(double normalizedValue) { + return min + (max - min) * normalizedValue; + } +} diff --git a/common/src/main/java/net/harmonylink/mixin/OptionsScreenMixin.java b/common/src/main/java/net/harmonylink/mixin/OptionsScreenMixin.java new file mode 100644 index 0000000..92d63c9 --- /dev/null +++ b/common/src/main/java/net/harmonylink/mixin/OptionsScreenMixin.java @@ -0,0 +1,44 @@ +package net.harmonylink.mixin; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.Options; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.OptionsScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import net.harmonylink.screen.SettingsMenu; +import net.harmonylink.HarmonyLink; + +@Mixin(OptionsScreen.class) +public class OptionsScreenMixin extends Screen { + @Shadow @Final private Screen lastScreen; + @Shadow @Final private Options options; + + protected int tickCount = 0; + + protected OptionsScreenMixin(Component component) { + super(component); + } + + @Inject(at = @At("RETURN"), method = "init") + private void init(CallbackInfo info) { + System.out.println("Hello from example architectury common mixin!"); + + if (this.lastScreen != null && !(this.lastScreen instanceof SettingsMenu)) + { + if (HarmonyLink.getIsConnected()) + { + this.addRenderableWidget(Button.builder(Component.literal("HL"), button -> { + Minecraft.getInstance().setScreen(new SettingsMenu(this)); + }).size(25, 25).build()); + } + } + + } +} \ No newline at end of file diff --git a/common/src/main/java/net/harmonylink/screen/OptionsMenu.java b/common/src/main/java/net/harmonylink/screen/OptionsMenu.java new file mode 100644 index 0000000..2d51904 --- /dev/null +++ b/common/src/main/java/net/harmonylink/screen/OptionsMenu.java @@ -0,0 +1,170 @@ +package net.harmonylink.screen; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.harmonylink.HarmonyLink; +import net.harmonylink.RangedValue; +import net.harmonylink.GraphicsSettings; +import net.harmonylink.screen.widgets.HLSliderWidget; +import net.minecraft.client.GraphicsStatus; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.Renderable; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.layouts.GridLayout; +import net.minecraft.client.gui.narration.NarratableEntry; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; + +public class OptionsMenu extends Screen { + private final Screen lastScreen; + private final Component title; + + private GraphicsSettings settings; + + public OptionsMenu(Screen parent, String title, String fileName) { + super(Component.literal("Options Menu")); + this.lastScreen = parent; + this.title = Component.literal(title + " Options"); + } + + public OptionsMenu(Screen parent, String title, GraphicsSettings settings) { + super(Component.literal("Options Menu")); + this.lastScreen = parent; + this.settings = settings; + this.title = Component.literal(title + " Options"); + } + + @Override + protected void init() { + super.init(); + initWidgets(); + } + + private void initWidgets() { + int buttonWidth = 150; + + HarmonyLink.LOGGER.info("Initialising Widgets"); + + Button backButton = Button.builder(Component.literal("Back"), button -> Minecraft.getInstance().setScreen(lastScreen)) + .size(30, 20) + .pos(0, 0) + .build(); + this.addRenderableWidget(backButton); + + GridLayout gridWidget = new GridLayout(); + + gridWidget.columnSpacing(20); + gridWidget.rowSpacing(5); + + gridWidget.addChild(Button.builder(Component.literal("Graphics: " + settings.GraphicsMode.get().toString()), button -> { + GraphicsStatus currentMode = settings.GraphicsMode.get(); + switch (currentMode) { + case FABULOUS -> settings.GraphicsMode.set(GraphicsStatus.FAST); + case FANCY -> settings.GraphicsMode.set(GraphicsStatus.FABULOUS); + case FAST -> settings.GraphicsMode.set(GraphicsStatus.FANCY); + } + + String newMode = settings.GraphicsMode.get().toString(); + newMode = newMode.substring(0, 1).toUpperCase() + newMode.substring(1).toLowerCase(); + + button.setMessage(Component.literal("Graphics: " + newMode)); + settings.saveAndApply(); + }) + .build(), 0, 0); + + + HLSliderWidget renderDistanceSlider = new HLSliderWidget(0, 0, 150, 20, Component.literal("Render Distance: " + settings.renderDistance.get()), + new RangedValue(2, 32, settings.renderDistance.get().doubleValue()), + (slider, value) -> { + int intValue = (int) Math.round(value); + HarmonyLink.LOGGER.info("Value: {}", intValue); + slider.setMessage(Component.literal("Render Distance: " + intValue)); + settings.renderDistance.set(intValue); + settings.saveAndApply(); + } + ); + + + gridWidget.addChild(renderDistanceSlider, 1, 0); + + HLSliderWidget simulationDistanceSlider = new HLSliderWidget(0, 0, 150, 20, Component.literal("Simulation Distance: " + settings.simulationDistance.get()), + new RangedValue(5, 32, settings.simulationDistance.get().doubleValue()), + (slider, value) -> { + int intValue = (int) Math.round(value); + HarmonyLink.LOGGER.info("Value: {}", intValue); + slider.setMessage(Component.literal("Simulation Distance: " + intValue)); + settings.simulationDistance.set(intValue); + settings.saveAndApply(); + } + ); + gridWidget.addChild(simulationDistanceSlider, 0, 1); + + HLSliderWidget biomeBlendRadiusSlider = new HLSliderWidget(0, 0, 150, 20, Component.literal("Biomes Blend Range: " + settings.BiomeBlendRadius.get()), + new RangedValue(0, 7, settings.BiomeBlendRadius.get().doubleValue()), + (slider, value) -> { + int intValue = (int) Math.round(value); + HarmonyLink.LOGGER.info("Value: {}", intValue); + if (intValue == 0) { + slider.setMessage(Component.literal("Biomes Blend Range: OFF")); + } else { + slider.setMessage(Component.literal("Biomes Blend Range: " + intValue)); + } + + settings.BiomeBlendRadius.set(intValue); + settings.saveAndApply(); + } + ); + gridWidget.addChild(biomeBlendRadiusSlider, 1, 1); + + HLSliderWidget guiSlider = new HLSliderWidget(0, 0, 150, 20, Component.literal("GUI Scale: " + settings.guiScale.get()), + new RangedValue(0, 2, settings.guiScale.get().doubleValue()), + (slider, value) -> { + int intValue = (int) Math.round(value); + HarmonyLink.LOGGER.info("Value: {}", intValue); + if (intValue == 0) { + slider.setMessage(Component.literal("GUI Scale: AUTO")); + } else { + slider.setMessage(Component.literal("GUI Scale: " + intValue)); + } + settings.guiScale.set(intValue); + settings.saveAndApply(); + } + ); + gridWidget.addChild(guiSlider, 2, 1); + + + // Position and add the grid to the screen + gridWidget.arrangeElements(); + int gridWidth = gridWidget.getWidth(); + int gridX = (width - gridWidth) / 2; // Calculate the x-position to center the grid + gridWidget.setPosition(gridX, 40); + + // Remove this line: this.addRenderableWidget(gridWidget); + + // Add the child widgets directly to the screen + gridWidget.visitChildren(child -> { + if (child instanceof GuiEventListener && child instanceof Renderable && child instanceof NarratableEntry) { + this.addRenderableWidget((GuiEventListener & Renderable & NarratableEntry) child); + } + }); + + HarmonyLink.LOGGER.info("Widgets Initialised!"); + } + + @Override + public void resize(Minecraft client, int width, int height) { + super.resize(client, width, height); + initWidgets(); + } + + @Override + public void render(PoseStack poseStack, int mouseX, int mouseY, float delta) { + renderBackground(poseStack); // Renders the default screen background + super.render(poseStack, mouseX, mouseY, delta); + + int titleX = width / 2; + int titleY = 20; + + drawCenteredString(poseStack, this.font, title, titleX, titleY, 0xFFFFFF); + } +} diff --git a/common/src/main/java/net/harmonylink/screen/SettingsMenu.java b/common/src/main/java/net/harmonylink/screen/SettingsMenu.java new file mode 100644 index 0000000..8af776d --- /dev/null +++ b/common/src/main/java/net/harmonylink/screen/SettingsMenu.java @@ -0,0 +1,137 @@ +package net.harmonylink.screen; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.Renderable; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.layouts.GridLayout; +import net.minecraft.client.gui.narration.NarratableEntry; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; + +import net.harmonylink.HarmonyLink; + +/** + * This is the Settings Menu screen class. + * It extends the Screen class of Minecraft. + */ +public class SettingsMenu extends Screen { + private final Screen lastScreen; // The parent screen + private final Component title; // Title text of the settings menu + + /** + * SettingsMenu constructor. + * @param parent The parent screen. + */ + public SettingsMenu(Screen parent) { + super(Component.literal("Settings Menu")); + this.lastScreen = parent; + this.title = Component.literal("HarmonyLink Settings"); + } + + /** + * Overriding the init method from the Screen class to initialize the widgets. + */ + @Override + protected void init() { + super.init(); + initWidgets(); // Initialize the settings menu widgets + } + + /** + * Method to initialize the widgets of the settings menu. + */ + private void initWidgets() { + int buttonWidth = 150; + + // Initialize back button + Button backButton = Button.builder(Component.literal("Back"), button -> Minecraft.getInstance().setScreen(lastScreen)) + .size(30, 20) + .pos(0, 0) + .build(); + + this.addRenderableWidget(backButton); + + // Initialize grid widget + GridLayout gridWidget = new GridLayout(); + + gridWidget.columnSpacing(20); + gridWidget.rowSpacing(5); + + // Add various buttons to the grid + + gridWidget.addChild(Button.builder(Component.literal("Docked Settings: " + HarmonyLink.HLSETTINGS.EnableDocked.get()), button -> { + Boolean isDocked = HarmonyLink.HLSETTINGS.EnableDocked.get(); + if (isDocked) { + HarmonyLink.HLSETTINGS.EnableDocked.set(false); + }else { + HarmonyLink.HLSETTINGS.EnableDocked.set(true); + } + //button.setMessage(Text.of("Docked Settings: " + HarmonyLinkClient.HLSETTINGS.EnableDocked.getValue())); + HarmonyLink.HLSETTINGS.saveSettingsToFile(); + clearWidgets(); + initWidgets(); + }).build(), 0, 0); + + gridWidget.addChild(Button.builder(Component.literal("Battery"), button -> { + Minecraft.getInstance().setScreen(new OptionsMenu(this, "Battery", HarmonyLink.batterySettings)); + }).build(), 1, 0); + + gridWidget.addChild(Button.builder(Component.literal("Charging"), button -> { + Minecraft.getInstance().setScreen(new OptionsMenu(this, "Charging", HarmonyLink.chargingSettings)); + }).build(), 0, 1); + + if (HarmonyLink.HLSETTINGS.EnableDocked.get()) { + gridWidget.addChild(Button.builder(Component.literal("Docked"), button -> { + Minecraft.getInstance().setScreen(new OptionsMenu(this, "Docked", HarmonyLink.dockedSettings)); + }).build(), 1, 1); + } + + // Position and add the grid to the screen + gridWidget.arrangeElements(); + int gridWidth = gridWidget.getWidth(); + int gridX = (width - gridWidth) / 2; // Calculate the x-position to center the grid + gridWidget.setPosition(gridX, 40); + + // Add the child widgets directly to the screen + gridWidget.visitChildren(child -> { + if (child instanceof GuiEventListener && child instanceof Renderable && child instanceof NarratableEntry) { + this.addRenderableWidget((GuiEventListener & Renderable & NarratableEntry) child); + } + }); + } + + /** + * Resize method is called when the window size changes. + * It calls the super method and re-initializes the widgets. + * @param client The Minecraft client instance. + * @param width The new width of the window. + * @param height The new height of the window. + */ + @Override + public void resize(Minecraft client, int width, int height) { + super.resize(client, width, height); + initWidgets(); + } + + /** + * Overriding the render method from the Screen class to draw this screen. + * @param poseStack The MatrixStack instance. + * @param mouseX The x-coordinate of the mouse cursor. + * @param mouseY The y-coordinate of the mouse cursor. + * @param delta The amount of time since the last frame. + */ + @Override + public void render(PoseStack poseStack, int mouseX, int mouseY, float delta) { + renderBackground(poseStack); // Renders the default screen background + super.render(poseStack, mouseX, mouseY, delta); + + int titleX = width / 2; + int titleY = 20; + + drawCenteredString(poseStack, this.font, title, titleX, titleY, 0xFFFFFF); + + //drawCenteredTextWithShadow(matrices, textRenderer, title, titleX, titleY, 0xFFFFFF); + } +} diff --git a/common/src/main/java/net/harmonylink/screen/widgets/HLSliderWidget.java b/common/src/main/java/net/harmonylink/screen/widgets/HLSliderWidget.java new file mode 100644 index 0000000..2aaa168 --- /dev/null +++ b/common/src/main/java/net/harmonylink/screen/widgets/HLSliderWidget.java @@ -0,0 +1,59 @@ +package net.harmonylink.screen.widgets; + +import net.minecraft.client.gui.components.AbstractSliderButton; +import net.minecraft.network.chat.Component; +import net.harmonylink.RangedValue; + +import static net.minecraft.util.Mth.clamp; + +public class HLSliderWidget extends AbstractSliderButton { + private final SliderCallback valueCallback; + private final SliderCallback textCallback; + private final RangedValue rangedValue; + + public HLSliderWidget(int x, int y, int width, int height, Component label, RangedValue rangedValue, SliderCallback valueCallback, SliderCallback textCallback) { + super(x, y, width, height, label, rangedValue.getNormalizedValue()); + this.valueCallback = valueCallback; + this.textCallback = textCallback; + this.rangedValue = rangedValue; + } + + public HLSliderWidget(int x, int y, int width, int height, Component label, RangedValue rangedValue, SliderCallback valueCallback) { + this(x, y, width, height, label, rangedValue, valueCallback, null); + } + + public HLSliderWidget(int x, int y, int width, int height, Component label, RangedValue rangedValue) { + this(x, y, width, height, label, rangedValue, null, null); + } + + @Override + protected void updateMessage() { + if (textCallback != null) { + textCallback.setSliderText(this, rangedValue.getAbsoluteValue()); + } + } + + @Override + protected void onDrag(double mouseX, double mouseY, double deltaX, double deltaY) { + super.onDrag(mouseX, mouseY, deltaX, deltaY); + double width = getWidth(); + double percentage = clamp((mouseX - (double)(getX() + 4)) / (width - 8), 0.0, 1.0); + rangedValue.setNormalizedValue(percentage); + updateMessage(); + } + + @Override + protected void applyValue() { + if (valueCallback != null) { + valueCallback.onSliderValueChanged(this, rangedValue.getAbsoluteValue()); + } + } + + public interface SliderCallback { + void onSliderValueChanged(HLSliderWidget slider, double value); + + default void setSliderText(HLSliderWidget slider, double value) { + // Default implementation does nothing + } + } +} diff --git a/common/src/main/resources/architectury.common.json b/common/src/main/resources/architectury.common.json new file mode 100644 index 0000000..3942ba4 --- /dev/null +++ b/common/src/main/resources/architectury.common.json @@ -0,0 +1,3 @@ +{ + "accessWidener": "harmonylink.accesswidener" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/harmonylink/lang/en_us.json b/common/src/main/resources/assets/harmonylink/lang/en_us.json new file mode 100644 index 0000000..6bcd60e --- /dev/null +++ b/common/src/main/resources/assets/harmonylink/lang/en_us.json @@ -0,0 +1,3 @@ +{ + "item.examplemod.example_item": "Example Item" +} \ No newline at end of file diff --git a/common/src/main/resources/harmonylink-common.mixins.json b/common/src/main/resources/harmonylink-common.mixins.json new file mode 100644 index 0000000..d98b0b4 --- /dev/null +++ b/common/src/main/resources/harmonylink-common.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "package": "net.harmonylink.mixin", + "compatibilityLevel": "JAVA_17", + "minVersion": "0.8", + "client": [ + "OptionsScreenMixin" + ], + "mixins": [ + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/common/src/main/resources/harmonylink.accesswidener b/common/src/main/resources/harmonylink.accesswidener new file mode 100644 index 0000000..13268c3 --- /dev/null +++ b/common/src/main/resources/harmonylink.accesswidener @@ -0,0 +1 @@ +accessWidener v2 named \ No newline at end of file diff --git a/fabric/build.gradle b/fabric/build.gradle new file mode 100644 index 0000000..0b4c0e8 --- /dev/null +++ b/fabric/build.gradle @@ -0,0 +1,90 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" +} + +archivesBaseName = rootProject.archives_base_name + "-" + rootProject.mod_version + "-" + rootProject.minecraft_version + "-Fabric" + +architectury { + platformSetupLoomIde() + fabric() +} + +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentFabric.extendsFrom common +} + +dependencies { + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" + // Remove the next line if you don't want to depend on the API + modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}" + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +shadowJar { + exclude "architectury.common.json" + + configurations = [project.configurations.shadowCommon] + classifier "dev-shadow" + + version = null // Add this line +} + +remapJar { + injectAccessWidener = true + input.set shadowJar.archiveFile + dependsOn shadowJar + classifier null + + version = null // Add this line +} + +jar { + classifier = 'dev' + + version = null // Add this line +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenFabric(MavenPublication) { + artifactId = rootProject.archives_base_name + "-" + project.name + 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. + } +} diff --git a/fabric/src/main/java/net/harmonylink/fabric/HarmonyLinkExpectPlatformImpl.java b/fabric/src/main/java/net/harmonylink/fabric/HarmonyLinkExpectPlatformImpl.java new file mode 100644 index 0000000..5253987 --- /dev/null +++ b/fabric/src/main/java/net/harmonylink/fabric/HarmonyLinkExpectPlatformImpl.java @@ -0,0 +1,15 @@ +package net.harmonylink.fabric; + +import net.harmonylink.HarmonyLinkExpectPlatform; +import net.fabricmc.loader.api.FabricLoader; + +import java.nio.file.Path; + +public class HarmonyLinkExpectPlatformImpl { + /** + * This is our actual method to {@link HarmonyLinkExpectPlatform#getConfigDirectory()}. + */ + public static Path getConfigDirectory() { + return FabricLoader.getInstance().getConfigDir(); + } +} diff --git a/fabric/src/main/java/net/harmonylink/fabric/HarmonyLinkFabric.java b/fabric/src/main/java/net/harmonylink/fabric/HarmonyLinkFabric.java new file mode 100644 index 0000000..e5e16a0 --- /dev/null +++ b/fabric/src/main/java/net/harmonylink/fabric/HarmonyLinkFabric.java @@ -0,0 +1,17 @@ +package net.harmonylink.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.harmonylink.HarmonyLink; + +public class HarmonyLinkFabric implements ClientModInitializer { + + @Override + public void onInitializeClient() { + HarmonyLink HL = HarmonyLink.init(); + + ClientLifecycleEvents.CLIENT_STARTED.register(HL::initializeSettings); + ClientTickEvents.END_CLIENT_TICK.register(HL::OnTick); + } +} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..787cd21 --- /dev/null +++ b/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,31 @@ +{ + "schemaVersion": 1, + "id": "harmonylink", + "version": "${version}", + "name": "HarmonyLink", + "description": "This is an example description! Tell everyone what your mod is about!", + "authors": [ + "Me!" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + "license": "Insert License Here", + "icon": "assets/harmonylink/icon.png", + "environment": "*", + "entrypoints": { + "client": [ + "net.harmonylink.fabric.HarmonyLinkFabric" + ] + }, + "mixins": [ + "harmonylink.mixins.json", + "harmonylink-common.mixins.json" + ], + "depends": { + "fabric": "*", + "minecraft": ">=1.19.4", + "architectury": ">=8.1.79" + } +} \ No newline at end of file diff --git a/fabric/src/main/resources/harmonylink.mixins.json b/fabric/src/main/resources/harmonylink.mixins.json new file mode 100644 index 0000000..80f0494 --- /dev/null +++ b/fabric/src/main/resources/harmonylink.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "package": "net.harmonylink.mixin.fabric", + "compatibilityLevel": "JAVA_17", + "minVersion": "0.8", + "client": [ + ], + "mixins": [ + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/forge/build.gradle b/forge/build.gradle new file mode 100644 index 0000000..7664fa0 --- /dev/null +++ b/forge/build.gradle @@ -0,0 +1,97 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" +} + +archivesBaseName = rootProject.archives_base_name + "-" + rootProject.mod_version + "-" + rootProject.minecraft_version + "-Forge" + +architectury { + platformSetupLoomIde() + forge() +} + +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath + + forge { + convertAccessWideners = true + extraAccessWideners.add loom.accessWidenerPath.get().asFile.name + + mixinConfig "harmonylink-common.mixins.json" + mixinConfig "harmonylink.mixins.json" + } +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentForge.extendsFrom common +} + +dependencies { + forge "net.minecraftforge:forge:${rootProject.forge_version}" + // Remove the next line if you don't want to depend on the API + modApi "dev.architectury:architectury-forge:${rootProject.architectury_version}" + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } +} + +processResources { + inputs.property "version", project.version + + filesMatching("META-INF/mods.toml") { + expand "version": project.version + } +} + +shadowJar { + exclude "fabric.mod.json" + exclude "architectury.common.json" + + configurations = [project.configurations.shadowCommon] + classifier "dev-shadow" + + version = null +} + +remapJar { + input.set shadowJar.archiveFile + dependsOn shadowJar + classifier null + + version = null // Add this line +} + +jar { + classifier = 'dev' + + version = null // Add this line +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenForge(MavenPublication) { + artifactId = rootProject.archives_base_name + "-" + project.name + 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. + } +} diff --git a/forge/gradle.properties b/forge/gradle.properties new file mode 100644 index 0000000..32f842a --- /dev/null +++ b/forge/gradle.properties @@ -0,0 +1 @@ +loom.platform=forge \ No newline at end of file diff --git a/forge/src/main/java/net/harmonylink/forge/HarmonyLinkExpectPlatformImpl.java b/forge/src/main/java/net/harmonylink/forge/HarmonyLinkExpectPlatformImpl.java new file mode 100644 index 0000000..645546c --- /dev/null +++ b/forge/src/main/java/net/harmonylink/forge/HarmonyLinkExpectPlatformImpl.java @@ -0,0 +1,15 @@ +package net.harmonylink.forge; + +import net.harmonylink.HarmonyLinkExpectPlatform; +import net.minecraftforge.fml.loading.FMLPaths; + +import java.nio.file.Path; + +public class HarmonyLinkExpectPlatformImpl { + /** + * This is our actual method to {@link HarmonyLinkExpectPlatform#getConfigDirectory()}. + */ + public static Path getConfigDirectory() { + return FMLPaths.CONFIGDIR.get(); + } +} diff --git a/forge/src/main/java/net/harmonylink/forge/HarmonyLinkForge.java b/forge/src/main/java/net/harmonylink/forge/HarmonyLinkForge.java new file mode 100644 index 0000000..86aa65c --- /dev/null +++ b/forge/src/main/java/net/harmonylink/forge/HarmonyLinkForge.java @@ -0,0 +1,36 @@ +package net.harmonylink.forge; + +import dev.architectury.platform.forge.EventBuses; +import net.harmonylink.HarmonyLink; +import net.minecraft.client.Minecraft; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; + +@Mod(HarmonyLink.MOD_ID) +public class HarmonyLinkForge { + private final HarmonyLink harmonyLink; + public HarmonyLinkForge() { + // Submit our event bus to let architectury register our content on the right time + EventBuses.registerModEventBus(HarmonyLink.MOD_ID, FMLJavaModLoadingContext.get().getModEventBus()); + harmonyLink = HarmonyLink.init(); + // Register the setup method for modloading + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); + // Register ourselves for server and other game events we are interested in + MinecraftForge.EVENT_BUS.register(this); + } + + private void setup(final FMLClientSetupEvent event) { + harmonyLink.initializeSettings(Minecraft.getInstance()); + } + + @SubscribeEvent + public void onTick(final TickEvent.ClientTickEvent event) { + if (event.phase == TickEvent.Phase.END) { + harmonyLink.OnTick(Minecraft.getInstance()); + } + } +} 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..662386c --- /dev/null +++ b/forge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,35 @@ +modLoader = "javafml" +loaderVersion = "[45,)" +#issueTrackerURL = "" +license = "Insert License Here" + +[[mods]] +modId = "harmonylink" +version = "${version}" +displayName = "HarmonyLink" +authors = "Me!" +description = ''' +This is an example description! Tell everyone what your mod is about! +''' +#logoFile = "" + +[[dependencies.harmonylink]] +modId = "forge" +mandatory = true +versionRange = "[45,)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.harmonylink]] +modId = "minecraft" +mandatory = true +versionRange = "[1.19.4,)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.harmonylink]] +modId = "architectury" +mandatory = true +versionRange = "[8.1.79,)" +ordering = "AFTER" +side = "BOTH" \ No newline at end of file diff --git a/forge/src/main/resources/harmonylink.mixins.json b/forge/src/main/resources/harmonylink.mixins.json new file mode 100644 index 0000000..a9258b6 --- /dev/null +++ b/forge/src/main/resources/harmonylink.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "package": "net.harmonylink.mixin.forge", + "compatibilityLevel": "JAVA_17", + "minVersion": "0.8", + "client": [ + ], + "mixins": [ + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/forge/src/main/resources/pack.mcmeta b/forge/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..8528593 --- /dev/null +++ b/forge/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "HarmonyLink", + "pack_format": 13 + } +} diff --git a/gradle.properties b/gradle.properties index 878bf1f..8d9178c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,18 @@ -# Sets default memory used for gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. -org.gradle.jvmargs=-Xmx3G -org.gradle.daemon=false \ No newline at end of file +org.gradle.jvmargs=-Xmx2048M + +minecraft_version=1.19.4 +enabled_platforms=fabric,forge + +archives_base_name=harmonylink +mod_version=0.1.0 +maven_group=net.harmonylink + +architectury_version=8.1.79 + +fabric_loader_version=0.14.19 +fabric_api_version=0.78.0+1.19.4 + +forge_version=1.19.4-45.0.43 + + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e583..41d9927 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae04661..41dfb87 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index a69d9cb..1b6c787 100644 --- a/gradlew +++ b/gradlew @@ -205,12 +205,6 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index f127cfd..107acd3 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%"=="" @echo off +@if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. +if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,15 +75,13 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd +if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/settings.gradle b/settings.gradle index 3703f36..4b6935a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,14 @@ pluginManagement { repositories { + maven { url "https://maven.fabricmc.net/" } + maven { url "https://maven.architectury.dev/" } + maven { url "https://maven.minecraftforge.net/" } gradlePluginPortal() - maven { url = 'https://maven.minecraftforge.net/' } } -} \ No newline at end of file +} + +include("common") +include("fabric") +include("forge") + +rootProject.name = "HarmonyLinkMC" diff --git a/src/main/java/net/jordon/harmonylink/ChargingStatus.java b/src/main/java/net/jordon/harmonylink/ChargingStatus.java deleted file mode 100644 index a42b403..0000000 --- a/src/main/java/net/jordon/harmonylink/ChargingStatus.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.jordon.harmonylink; - -public enum ChargingStatus { - Battery, - Charging, - Unknown - // add any other statuses you might receive -} diff --git a/src/main/java/net/jordon/harmonylink/HarmonyLink.java b/src/main/java/net/jordon/harmonylink/HarmonyLink.java deleted file mode 100644 index 8e54443..0000000 --- a/src/main/java/net/jordon/harmonylink/HarmonyLink.java +++ /dev/null @@ -1,129 +0,0 @@ -package net.jordon.harmonylink; - -import com.mojang.authlib.minecraft.client.MinecraftClient; -import com.mojang.logging.LogUtils; -import net.minecraft.client.GraphicsStatus; -import net.minecraft.client.Minecraft; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.fml.loading.FMLLoader; -import org.slf4j.Logger; - -import net.minecraftforge.client.*; - -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.FieldNamingPolicy; -import com.google.gson.GsonBuilder; - - - -@Mod(HarmonyLink.MOD_ID) -public class HarmonyLink -{ - private SystemInfo systemInfo; - - - public static final String MOD_ID = "harmonylink"; - private static final Logger LOGGER = LogUtils.getLogger(); - - private int tickCount = 0; - - public HarmonyLink() - { - IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); - - modEventBus.addListener(this::commonSetup); - - MinecraftForge.EVENT_BUS.register(this); - } - - private void commonSetup(final FMLCommonSetupEvent event) - { - - } - - @SubscribeEvent - public void onPlayerTick(TickEvent.PlayerTickEvent event) - { - if (event.player.level.isClientSide) // We only want to do this on the client side - { - if (++tickCount >= 20) // Increase the tick count and check if we've reached 20 yet (1-second timer) - { - tickCount = 0; // Reset the tick count for next time - - HttpClient client = HttpClient.newHttpClient(); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create("http://127.0.0.1:9000/all_info")) - .build(); - - client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(HttpResponse::body) - .thenAccept(this::handleResponse); - } - } - } - - - private void handleResponse(String jsonResponse) - { - Gson gson = new GsonBuilder() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) - .create(); - - LOGGER.info("JSON Response: {}", this.systemInfo); - - if (this.systemInfo != gson.fromJson(jsonResponse, SystemInfo.class)) - { - SystemInfo newSystemInfo = gson.fromJson(jsonResponse, SystemInfo.class); - if (newSystemInfo.battery_info.hasBattery) - { - if (newSystemInfo.battery_info.chargingStatus == ChargingStatus.Battery) - { setRenderDistance(4); Minecraft.getInstance().options.simulationDistance().set(4); Minecraft.getInstance().options.graphicsMode().set(GraphicsStatus.FAST); Minecraft.getInstance().options.biomeBlendRadius().set(0); } - - else if (newSystemInfo.battery_info.chargingStatus == ChargingStatus.Charging) - { setRenderDistance(12); Minecraft.getInstance().options.simulationDistance().set(12); Minecraft.getInstance().options.graphicsMode().set(GraphicsStatus.FANCY); Minecraft.getInstance().options.biomeBlendRadius().set(2); } - } - - this.systemInfo = newSystemInfo; - } - } - - private void setRenderDistance(int distance) - { - // Check if the game is running on the client side - if(Minecraft.getInstance().player != null && Minecraft.getInstance().player.level.isClientSide) - { - LOGGER.info("Setting render distance to {}", distance); - Minecraft.getInstance().options.renderDistance().set(distance); - } - else - { - LOGGER.warn("Attempted to set render distance from server side, this is not supported."); - } - } - - - @Mod.EventBusSubscriber(modid = MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) - public static class ClientModEvents - { - @SubscribeEvent - public static void onClientSetup(FMLClientSetupEvent event) - { - LOGGER.info("HELLO FROM CLIENT SETUP"); - LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName()); - } - } -} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml deleted file mode 100644 index f321472..0000000 --- a/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,66 +0,0 @@ -# This is an example mods.toml file. It contains the data relating to the loading mods. -# There are several mandatory fields (#mandatory), and many more that are optional (#optional). -# The overall format is standard TOML format, v0.5.0. -# Note that there are a couple of TOML lists in this file. -# Find more information on toml format here: https://github.com/toml-lang/toml -# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml -modLoader="javafml" #mandatory -# A version range to match for said mod loader - for regular FML @Mod it will be the forge version -loaderVersion="[45,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. -# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. -# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. -license="MIT License" -# A URL to refer people to when problems occur with this mod -#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional -# A list of mods - how many allowed here is determined by the individual mod loader -[[mods]] #mandatory -# The modid of the mod -modId="harmonylink" #mandatory -# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it -# ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata -# see the associated build.gradle script for how to populate this completely automatically during a build -version="0.0.1-1.19" #mandatory - # A display name for the mod -displayName="Harmony Link" #mandatory -# A URL to query for updates for this mod. See the JSON update specification https://docs.minecraftforge.net/en/latest/misc/updatechecker/ -#updateJSONURL="https://change.me.example.invalid/updates.json" #optional -# A URL for the "homepage" for this mod, displayed in the mod UI -displayURL="https://jordongamedev.co.uk/blog/harmonylink-unleashing-new-potentials-of-the-steam-deck-with-optimisation/" #optional -# A file name (in the root of the mod JAR) containing a logo for display -logoFile="logo.png" #optional -# A text field displayed in the mod UI -credits="" #optional -# A text field displayed in the mod UI -authors="Jordon Brooks" #optional -# Display Test controls the display for your mod in the server connection screen -# MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod. -# IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod. -# IGNORE_ALL_VERSION means that your mod will not cause a red X if it's present on the client or the server. This is a special case and should only be used if your mod has no server component. -# NONE means that no display test is set on your mod. You need to do this yourself, see IExtensionPoint.DisplayTest for more information. You can define any scheme you wish with this value. -# IMPORTANT NOTE: this is NOT an instruction as to which environments (CLIENT or DEDICATED SERVER) your mod loads on. Your mod should load (and maybe do nothing!) whereever it finds itself. -#displayTest="MATCH_VERSION" # MATCH_VERSION is the default if nothing is specified (#optional) - -# The description text for the mod (multi line!) (#mandatory) -description=''' -The HarmonyLink Integration Mod revolutionizes your Minecraft gaming experience on handheld devices. This mod seamlessly integrates with HarmonyLink, providing real-time device metrics and optimization for enhanced gameplay. With HarmonyLink Integration, Minecraft adapts to your specific handheld device, adjusts graphical settings, and optimizes performance based on power usage and docking status. Enjoy a truly immersive and customized Minecraft adventure on the Steam Deck and other handheld platforms. Unleash the full potential of Minecraft with HarmonyLink Integration Mod. -''' -# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. -[[dependencies.harmonylink]] #optional - # the modid of the dependency - modId="forge" #mandatory - # Does this dependency have to exist - if not, ordering below must be specified - mandatory=true #mandatory - # The version range of the dependency - versionRange="[45,)" #mandatory - # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory - ordering="NONE" - # Side this dependency is applied on - BOTH, CLIENT or SERVER - side="BOTH" -# Here's another dependency -[[dependencies.harmonylink]] - modId="minecraft" - mandatory=true -# This version range declares a minimum of the current minecraft version up to but not including the next major version - versionRange="[1.19.4,1.20)" - ordering="NONE" - side="BOTH" diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png deleted file mode 100644 index 8937543..0000000 Binary files a/src/main/resources/logo.png and /dev/null differ diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta deleted file mode 100644 index 22d1390..0000000 --- a/src/main/resources/pack.mcmeta +++ /dev/null @@ -1,9 +0,0 @@ -{ - "pack": { - "description": { - "text": "examplemod resources" - }, - "forge:server_data_pack_format": 12, - "pack_format": 13 - } -} \ No newline at end of file