diff --git a/.gitignore b/.gitignore index 487c0ff2e..f8cd8af3e 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ build.properties *.sqlite-journal *.sqlite-shm *.sqlite-wal + +# Don't add access transformers to git as it's dynamically generated +accesstransformer.cfg diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ef07d29c4..79afe1193 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -47,12 +47,16 @@ build: exclude: # TODO: There is a lot of duplicate stuff here, try to maybe make it smaller - fabric/build/libs/*-all.jar + - fabric/build/libs/*-dev.jar - fabric/build/libs/*-sources.jar - quilt/build/libs/*-all.jar + - quilt/build/libs/*-dev.jar - quilt/build/libs/*-sources.jar - forge/build/libs/*-all.jar + - forge/build/libs/*-dev.jar - forge/build/libs/*-sources.jar - neoforge/build/libs/*-all.jar + - neoforge/build/libs/*-dev.jar - neoforge/build/libs/*-sources.jar expire_in: 14 days when: always diff --git a/Readme.md b/Readme.md index 16f4224c0..0e3ec6701 100644 --- a/Readme.md +++ b/Readme.md @@ -21,8 +21,8 @@ Below is a video demonstrating the system: #### 1.20.4, 1.20.3 (Default) Fabric: 0.15.1\ Fabric API: 0.91.2+1.20.4\ -Forge: 49.0.16\ -NeoForge: 20.4.83-beta\ +Forge: 49.0.30\ +NeoForge: 118-beta\ Parchment: 1.20.2:2023.12.10\ Modmenu: 9.0.0-pre.1 diff --git a/build.gradle b/build.gradle index 2ff04b96a..558f5b397 100644 --- a/build.gradle +++ b/build.gradle @@ -1,29 +1,32 @@ plugins { id "java" - // Plugin to handle dependencies + // Plugin to put dependencies inside our final jar id "com.github.johnrengelman.shadow" version '7.1.2' apply false // Plugin to create merged jars id "io.github.pacifistmc.forgix" version "1.2.6" - // Manifold preprocessor - id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha" - -// // Provides mc libraries to core -// id "org.spongepowered.gradle.vanilla" version '0.2.1-SNAPSHOT' apply false - - // Architectury is used here only as a replacement for forge's own loom - id "dev.architectury.loom" version "1.4-SNAPSHOT" apply false + // Unimined is our all in one solution to minecraft loaders +// id "xyz.wagyourtail.unimined" version "1.2.0-SNAPSHOT" apply false // Unstable Release (TODO: Check back to see when the unstable branch fixes forge run without the jank) + id "xyz.wagyourtail.unimined" version "1.1.2-SNAPSHOT" apply false // LTS Release } + +// Transfers the values set in settings.gradle to the rest of the project +project.gradle.ext.getProperties().each { prop -> + rootProject.ext.set(prop.key, prop.value) +// println "Added prop [key:" + prop.key + ", value:" + prop.value + "]" +} + + /** * Creates the list of preprocessors to use. * * @param mcVers array of all MC versions * @param mcIndex array index of the currently active MC version */ -def writeBuildGradlePredefine(List mcVers, int mcIndex) +def writeBuildGradlePredefine(List mcVers, int mcIndex) { // Build the list of preprocessors to use StringBuilder sb = new StringBuilder(); @@ -31,7 +34,7 @@ def writeBuildGradlePredefine(List mcVers, int mcIndex) sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n"); - for (int i = 0; i < mcVers.size(); i++) + for (int i = 0; i < mcVers.size(); i++) { String verStr = mcVers[i].replace(".", "_"); sb.append("MC_" + verStr + "=" + i.toString() + "\n"); @@ -42,23 +45,15 @@ def writeBuildGradlePredefine(List mcVers, int mcIndex) // Check if this is a development build - if (mod_version.toLowerCase().contains("dev")) + if (mod_version.toLowerCase().contains("dev")) { // WARNING: only use this for logging, we don't want to have confusion // when a method doesn't work correctly in the release build. sb.append("DEV_BUILD=\n"); } - + new File(projectDir, "build.properties").text = sb.toString() } - - -// Transfers the values set in settings.gradle to the rest of the project -project.gradle.ext.getProperties().each { prop -> - rootProject.ext.set(prop.key, prop.value) -// println "Added prop [key:" + prop.key + ", value:" + prop.value + "]" -} -// Sets up manifold stuff writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex) @@ -66,6 +61,7 @@ writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex) // Sets up the version string (the name we use for our jar) rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm") + // Forgix settings (used for merging jars) forgix { group = "com.seibel.distanthorizons" @@ -96,7 +92,7 @@ forgix { } subprojects { p -> - // Does the same as "p == project(":common") || p == project(":fabric") || p == project(":quilt") || p == project(":forge") || p == project("WhateverWeAddLaterOn")" + // Does the same as "p == project(":common") || p == project(":fabric") || p == project(":forge") || p == project("WhateverLoaderWeAddLaterOn")" // Useful later on so we dont have duplicated code def isMinecraftSubProject = p != project(":core") && p != project(":api") @@ -104,73 +100,68 @@ subprojects { p -> // Apply plugins apply plugin: "java" apply plugin: "com.github.johnrengelman.shadow" - if (isMinecraftSubProject) - apply plugin: "systems.manifold.manifold-gradle-plugin" - if (p == project(":core")) + if (p == project(":core")) apply plugin: "application" -// apply plugin: "org.spongepowered.gradle.vanilla" // Provides minecraft libraries + + if (isMinecraftSubProject) { + apply plugin: "xyz.wagyourtail.unimined" - // Apply forge's loom - if ( - (findProject(":forge") && p == project(":forge")) || - (findProject(":neoforge") && p == project(":neoforge")) - ) - apply plugin: "dev.architectury.loom" + unimined.minecraft(sourceSets.main, true) { + version = rootProject.minecraft_version + + def parchmentVersionParts = rootProject.parchment_version.split(":") + mappings { + mojmap() + parchment(parchmentVersionParts[0], parchmentVersionParts[1]) + devNamespace "mojmap" + } + + runs { + config("client") { + workingDir = rootProject.file("run") + } + config("server") { + workingDir = rootProject.file("run") // TODO: When running the server, would it be a better idea to change this to a different dir? + disabled = true // TODO: Once server-side support is added, remove this + } + } + } - - // Set the manifold version (may not be required tough) - manifold { - manifoldVersion = rootProject.manifold_version + if (p != project(":common")) { + tasks.withType(JavaCompile).configureEach { + source(project(":common").sourceSets.main.java) + source(project(":api").sourceSets.main.java) + source(project(":core").sourceSets.main.java) + } + } } + tasks.withType(GenerateModuleMetadata) { + enabled = false + } + + // Disable testing for projects that aren't the core or api project. + // If not done compiling will fail due to an issue with Manifold + if (isMinecraftSubProject) { + test { + enabled = false + } + compileTestJava { + enabled = false + } + } + // set up custom configurations (configurations are a way to handle dependencies) configurations { // extends the shadowJar configuration - shadowMe + shadowMc // Configuration that doesn't contain coreProjects + // have implemented dependencies automatically embedded in the final jar - implementation.extendsFrom(shadowMe) + implementation.extendsFrom(shadowMc) - // Configuration fpr core & api - coreProjects - shadowMe.extendsFrom(coreProjects) - - - // FIXME this additional configuration is necessary because forge - // needs forgeRuntimeLibrary, although adding it to shadowMe - // causes runtime issues where the libraries aren't properly added - forgeShadowMe - // this should match shadowMe pretty closely - implementation.extendsFrom(forgeShadowMe) - shadowMe.extendsFrom(forgeShadowMe) - forgeRuntimeLibrary.extendsFrom(forgeShadowMe) - - - if (isMinecraftSubProject && p != project(":common")) { - // Shadow common - common - shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. - compileClasspath.extendsFrom common - runtimeClasspath.extendsFrom common - if (findProject(":forge")) - developmentForge.extendsFrom common - if (findProject(":neoforge")) - developmentNeoForge.extendsFrom common - compileClasspath.extendsFrom coreProjects - runtimeClasspath.extendsFrom coreProjects - if (findProject(":forge")) - developmentForge.extendsFrom coreProjects - if (findProject(":neoforge")) - developmentNeoForge.extendsFrom coreProjects - - if (findProject(":fabricLike") && p != project(":fabricLike")) { - // Shadow fabricLike - fabricLike - shadowFabricLike - compileClasspath.extendsFrom fabricLike - runtimeClasspath.extendsFrom fabricLike - } - } + // Add shaded libraries very early in the classpath (excluding coreProjects as that's added in a different way) + minecraftLibraries.extendsFrom(shadowMc) } @@ -187,53 +178,52 @@ subprojects { p -> // shared dependencies // //=====================// - // Manifold if (isMinecraftSubProject) { annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}") } // Log4j - // TODO: Change to shadowMe later to work in the standalone jar + // TODO: Change to shadowCore later to work in the standalone jar // We cannot do this now as it would break Quilt implementation("org.apache.logging.log4j:log4j-api:${rootProject.log4j_version}") implementation("org.apache.logging.log4j:log4j-core:${rootProject.log4j_version}") - // JOML - if (project.hasProperty("embed_joml") && embed_joml == "true") - forgeShadowMe("org.joml:joml:${rootProject.joml_version}") - else - implementation("org.joml:joml:${rootProject.joml_version}") - // JUnit tests implementation("org.junit.jupiter:junit-jupiter:5.8.2") implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2") implementation("junit:junit:4.13") + + // JOML + if (project.hasProperty("embed_joml") && embed_joml == "true") + shadowMc("org.joml:joml:${rootProject.joml_version}") + else + implementation("org.joml:joml:${rootProject.joml_version}") // Compression - forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4 - forgeShadowMe("com.github.luben:zstd-jni:${rootProject.zstd_version}") // Zstd - forgeShadowMe("org.tukaani:xz:${rootProject.xz_version}") // LZMA + shadowMc("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4 + shadowMc("com.github.luben:zstd-jni:${rootProject.zstd_version}") // Zstd + shadowMc("org.tukaani:xz:${rootProject.xz_version}") // LZMA // Sqlite Database - forgeShadowMe("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}") + shadowMc("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}") // NightConfig (includes Toml & Json) - forgeShadowMe("com.electronwill.night-config:toml:${rootProject.nightconfig_version}") - forgeShadowMe("com.electronwill.night-config:json:${rootProject.nightconfig_version}") + shadowMc("com.electronwill.night-config:toml:${rootProject.nightconfig_version}") + shadowMc("com.electronwill.night-config:json:${rootProject.nightconfig_version}") // Fastutil - forgeShadowMe("it.unimi.dsi:fastutil:${rootProject.fastutil_version}") + shadowMc("it.unimi.dsi:fastutil:${rootProject.fastutil_version}") // SVG (not needed atm) -// forgeShadowMe("com.formdev:svgSalamander:${rootProject.svgSalamander_version}") + //shadowMc("com.formdev:svgSalamander:${rootProject.svgSalamander_version}") // Netty // Breaks 1.16.5 - //forgeShadowMe("io.netty:netty-all:${rootProject.netty_version}") + //shadowMc("io.netty:netty-all:${rootProject.netty_version}") // Remember, for lwjgl dependencies that arent included in Minecraft, you need to also need to add it to the ShadowJar thing - forgeShadowMe("org.lwjgl:lwjgl-jawt:${rootProject.lwjgl_version}") { + shadowMc("org.lwjgl:lwjgl-jawt:${rootProject.lwjgl_version}") { exclude group: "org.lwjgl", module: "lwjgl" // This module is imported by Minecraft so exclude it } @@ -246,11 +236,12 @@ subprojects { p -> // Add core if (isMinecraftSubProject) { - coreProjects(project(":core")) { + compileOnly(project(":core")) { // Remove Junit test libraries exclude group: "org.junit.jupiter", module: "junit-jupiter" exclude group: "org.junit.jupiter", module: "junit-jupiter-engine" exclude group: "junit", module: "junit" + // Removed dependencies transitive false } @@ -258,11 +249,12 @@ subprojects { p -> // Add the api if (p != project(":api")) { - coreProjects(project(":api")) { + implementation(project(":api")) { // Remove Junit test libraries exclude group: "org.junit.jupiter", module: "junit-jupiter" exclude group: "org.junit.jupiter", module: "junit-jupiter-engine" exclude group: "junit", module: "junit" + // Removed dependencies transitive false } @@ -271,29 +263,19 @@ subprojects { p -> // Add common if (isMinecraftSubProject && p != project(":common")) { // Common - common(project(":common")) { transitive false } - shadowCommon(project(":common")) { transitive false } - - // FabricLike - if (findProject(":fabricLike") && p != project(":fabricLike")) { - fabricLike(project(path: ":fabricLike")) { transitive false } - shadowFabricLike(project(path: ":fabricLike")) { transitive false } - } + compileOnly(project(":common")) { transitive false } } } shadowJar { - configurations = [project.configurations.shadowMe] + configurations = [project.configurations.shadowMc] + if (isMinecraftSubProject && p != project(":common")) { - configurations.push(project.configurations.shadowCommon) // Shadow the common subproject relocate "com.seibel.distanthorizons.common", "loaderCommon.${p.name}.com.seibel.distanthorizons.common" // Move the loader files to a different location - - if (findProject(":fabricLike") && p != project(":fabricLike")) { - configurations.push(project.configurations.shadowFabricLike) // Shadow the fabricLike subproject - relocate "com.seibel.distanthorizons.fabriclike", "loaderCommon.${p.name}.com.seibel.distanthorizons.fabriclike" // Move the loader files to a different location - } } + + def librariesLocation = "distanthorizons.libraries" // LWJGL @@ -331,7 +313,20 @@ subprojects { p -> // Put stuff from gradle.properties into the mod info processResources { - def resourceTargets = [ // Location of where to inject the properties + duplicatesStrategy = DuplicatesStrategy.WARN + // Include all the resources + from project(":common").sourceSets.main.resources + from project(":core").sourceSets.main.resources + from project(":api").sourceSets.main.resources + + // Copy accessWideners + // FIXME: remove copyCommonLoaderResources and use this instead (and if you are removing that task, also remove copyCoreResources while your at it) +// from project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener") +// into(file(p.file("build/resources/main"))) + rename "${accessWidenerVersion}.distanthorizons.accesswidener", "distanthorizons.accesswidener" + + // Location of where to inject the properties + def resourceTargets = [ // Holds info like git commit // TODO: For some reason this script doesnt work with the core project "build_info.json", @@ -344,7 +339,7 @@ subprojects { p -> // The mixins for each of the loaders "DistantHorizons."+ p.name +".fabricLike.mixins.json" ] - def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder + def buildResourceTargets = ["$buildDir/resources/main/"] // Location of the built resources folder // Fix forge version numbering system as it is weird // For whatever reason forge uses [1.18, 1.18.1, 1.18.2) instead of the standard ["1.18", "1.18.1", "1.18.2"] @@ -352,7 +347,7 @@ subprojects { p -> // println compatible_forgemc_versions // Quilt's custom contributors system - // This has to be like + // has to be in the format: // "Person": "Developer", "Another person": "Developer" def quilt_contributors = [] def mod_author_list = mod_authors.replaceAll("\"", "").replace("[", "").replace("]", "").split(",") @@ -360,9 +355,9 @@ subprojects { p -> quilt_contributors.push("\"${dev.strip()}\": \"Developer\"") } quilt_contributors.reverse() -// println quilt_contributors.join(", ") + //println quilt_contributors.join(", ") - // TODOI: Find something we can use so we can basically re-map only when the jar is shadowed and relocated + // TODO: Find something we can use so we can basically re-map only when the jar is shadowed and relocated // println p.tasks.findByName('shadowJar') @@ -377,6 +372,7 @@ subprojects { p -> println "Git or Git project not found" } + // The left side is what gets replaced in the mod info and the right side is where to get it from in the gradle.properties def replaceProperties = [ version : mod_version, mod_name : mod_readable_name, @@ -400,15 +396,17 @@ subprojects { p -> fabric_incompatibility_list : fabric_incompatibility_list, fabric_recommend_list : fabric_recommend_list, ] - // The left side is what gets replaced in the mod info and the right side is where to get it from in the gradle.properties - + + // replace any properties in the sub-projects with the values defined here inputs.properties replaceProperties - replaceProperties.put "project", project + replaceProperties.put("project", project) filesMatching(resourceTargets) { expand replaceProperties } - - intoTargets.each { target -> + + + // copy all our resources into the loader specific resource directory + buildResourceTargets.each { target -> if (file(target).exists()) { copy { from(sourceSets.main.resources) { @@ -465,13 +463,6 @@ subprojects { p -> } } */ - - // Run mergeJars when running build - // TODO: Fix later -// if (isMinecraftSubProject) { -// build.finalizedBy(mergeJars) -// assemble.finalizedBy(mergeJars) -// } } allprojects { p -> @@ -579,6 +570,7 @@ allprojects { p -> // Set the OS lwjgl is using to the current os project.ext.lwjglNatives = "natives-" + os.toFamilyName() + // TODO: Include Minecraft in core-projects but dont include MC code stuff dependencies { // All of these dependencies are in Vanilla Minecraft, but we need to depend on it as we arent importing Minecraft in the core // Imports most of lwjgl's libraries (well, only the ones that we need) implementation platform("org.lwjgl:lwjgl-bom:${rootProject.lwjgl_version}") // TODO: Use Minecraft's version for lwjgl_version (which changes in nearly every version) instead of a hard defined version for all versions @@ -610,26 +602,22 @@ allprojects { p -> } + // TODO: Remove this as no loader needs this + // - Fabric can rename which aw they use + // - (Neo)Forge converts the aw to their own at, which is stored at a different place task copyCommonLoaderResources(type: Copy) { from project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener") into(file(p.file("build/resources/main"))) rename "${accessWidenerVersion}.distanthorizons.accesswidener", "distanthorizons.accesswidener" - - - // Move the fabricLike mixin to its different places for each subproject - if (findProject(":fabricLike")) { - from project(":fabricLike").file("src/main/resources/DistantHorizons.fabricLike.mixins.json") - into(file(p.file("build/resources/main"))) - rename "DistantHorizons.fabricLike.mixins.json", "DistantHorizons." + p.name + ".fabricLike.mixins.json" - } } + // TODO: Remove this later as we no longer need this. We are now including the resources in the processResources section task copyCoreResources(type: Copy) { from fileTree(project(":core").file("src/main/resources")) into p.file("build/resources/main") } - tasks.withType(JavaCompile) { + compileJava { if (isMinecraftSubProject) { options.release = rootProject.java_version as Integer options.compilerArgs += ["-Xplugin:Manifold"] diff --git a/buildSrc/src/main/java/AWToAT.java b/buildSrc/src/main/java/AWToAT.java new file mode 100644 index 000000000..2f851b264 --- /dev/null +++ b/buildSrc/src/main/java/AWToAT.java @@ -0,0 +1,239 @@ +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class AWToAT { + private static final Map ACCESS_POINT_MAP = new HashMap<>(); + + static { + ACCESS_POINT_MAP.put("accessible", "public"); + ACCESS_POINT_MAP.put("extendable", "public-f"); + ACCESS_POINT_MAP.put("mutable", "public-f"); + } + + public String minecraftVersion; + + public File remap(File file, String minecraftVersion) { + this.minecraftVersion = minecraftVersion.replace("_", "."); + File atFile = createATFile(file); + processFile(file, atFile); + return atFile; + } + + private File createATFile(File file) { + File metaInf = new File(file.getParentFile(), "META-INF"); + if (!metaInf.exists() && !metaInf.mkdir()) throw new RuntimeException("Error creating META-INF folder"); + File atFile = new File(metaInf, "accesstransformer.cfg"); + try { + atFile.createNewFile(); + } catch (IOException e) { + throw new RuntimeException("Error creating new file", e); + } + return atFile; + } + + private void processFile(File file, File atFile) { + /* Validates if we need to recreate the Access Transformer file if it's out of date */ + // Get the hash of the file + String fileHash = getFileHash(file); + try (Scanner atScanner = new Scanner(atFile)) { + // Check if the AT file is up-to-date by comparing the hash of the file with the hash stored in the AT file + boolean hashFound = false; + while (atScanner.hasNextLine()) { + String line = atScanner.nextLine(); + if (hashCheck(line, fileHash)) { + hashFound = true; + } + } + + // If the AT file is up-to-date, print a message and return + if (hashFound) { + System.out.println("Access Transformer file is already up to date."); + return; + } + } catch (FileNotFoundException ignored) { + // If the AT file does not exist, continue + } + + /* Creates the Access Transformer file */ + // Opens a scanner for reading the Access Widener file and a writer for writing to the Access Transformer file + try (Scanner scanner = new Scanner(file); FileWriter writer = new FileWriter(atFile)) { + // Create an ExecutorService with a fixed thread pool size equal to the number of available processors + ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + // List to hold Future objects representing results of computation + List> futures = new ArrayList<>(); + + // Write the hash of the file to the AT file + writer.write("#DH_MAPPING_HASH:" + fileHash + "\n"); + + // Read each line from the file + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + // Skip lines starting with "accessWidener", "#" or blank lines + if (line.startsWith("accessWidener") || line.startsWith("#") || line.isBlank()) continue; + + // Submit the line to the executor service for processing + // The processing is done by the processLine method + futures.add(executor.submit(() -> processLine(line.split(" ")))); + } + + // Write the results to the output file + // The results are obtained by calling the get method on each Future + for (Future future : futures) { + writer.write(future.get()); + } + + // Shutdown the executor service to free up resources + executor.shutdown(); + } catch (Exception e) { + throw new RuntimeException("Error reading or writing to file", e); + } + } + + private String processLine(String[] fields) { + // fields[0] = access point like "accessible", "extendable", "mutable" + // fields[1] = type like "field", "method", "class" + // fields[2] = class name + // fields[3] = field/method name + // fields[4] = field/method descriptor + + try { + // Store the original field/method name + String originalName = ""; + + // If there is a class name, replace the slashes with dots in the package name + if (fields.length > 2) fields[2] = fields[2].replace("/", "."); + + // If there is a field/method name, store the original name and remap it to SRG + if (fields.length > 3) { + originalName = fields[3]; + fields[3] = remapToSRG(fields[2], fields[3]); + } + + StringBuilder line = new StringBuilder(ACCESS_POINT_MAP.getOrDefault(fields[0], "public")).append(" "); + switch (fields[1]) { + case "field": + line.append(fields[2]).append(" ").append(fields[3]).append(" #").append(originalName); + // It'll be like: access-point class-name field-name-SRG # field-name-Mojmap + // Eg: public net.minecraft.client.Minecraft f_90981_ # instance + break; + case "method": + line.append(fields[2]).append(" ").append(fields[3]).append(fields[4]).append(" #").append(originalName); + // It'll be like: access-point class-name method-name-SRG method-descriptor # method-name-Mojmap + // Eg: public net.minecraft.client.Minecraft m_172797_()Lnet/minecraft/client/Minecraft; # getInstance + break; + default: + line.append(fields[2]); + // It'll be like: access-point class-name + // Eg: public net.minecraft.client.Minecraft + break; + } + line.append("\n"); + return line.toString(); + } catch (Exception e) { + throw new RuntimeException("Error processing line", e); + } + } + + private boolean hashCheck(String line, String fileHash) { + if (line.startsWith("#DH_MAPPING_HASH:")) { + String hash = line.substring(17); + return hash.equals(fileHash); + } + return false; + } + + public String getFileHash(File file) { + try { + MessageDigest shaDigest = MessageDigest.getInstance("SHA-256"); + try (InputStream fis = new FileInputStream(file)) { + byte[] byteArray = new byte[1024]; + int bytesCount; + + // Read file data and update in message digest + while ((bytesCount = fis.read(byteArray)) != -1) { + shaDigest.update(byteArray, 0, bytesCount); + } + } + + byte[] bytes = shaDigest.digest(); + + // Convert byte array into signum representation + StringBuilder sb = new StringBuilder(); + for (byte aByte : bytes) { + sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1)); + } + + // Return complete hash + return sb.toString(); + } catch (NoSuchAlgorithmException | IOException e) { + throw new RuntimeException(e); + } + } + + + + // WARNING: BELOW LIES HIGHLY CURSED CODE AND MIGHT EVEN BE ILLEGAL + + + + + // Flag to track if there was an error in the GET request + boolean error = false; + + /** + * This method returns a field or method name from Mojang mappings as SRG mappings. + * It makes a GET request to the Linkie API to fetch the SRG name. + * + * @param clazz The class name + * @param name The field or method name + * @return The SRG name + * @throws Exception If there is an error in the GET request or the SRG name is not found in the response + */ + private String remapToSRG(String clazz, String name) throws Exception { + // Encode the class and field/method name to be used in the URL + String query = URLEncoder.encode(clazz + "." + name, StandardCharsets.UTF_8); + // Construct the URL for the GET request + String urlString = "https://linkieapi.shedaniel.me/api/search?namespace=mojang&query=" + query + "&version=" + this.minecraftVersion + "&limit=1&allowClasses=false&allowFields=true&allowMethods=true&translate=mojang_srg"; + URL url = new URI(urlString).toURL(); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + int responseCode = conn.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String inputLine; + StringBuilder content = new StringBuilder(); + // Read the response line by line + while ((inputLine = in.readLine()) != null) { + content.append(inputLine); + } + in.close(); + conn.disconnect(); + // Regex to find the SRG name in the response + Pattern pattern = Pattern.compile("\"l\"\\s*:\\s*\\{[^}]*\"i\"\\s*:\\s*\"([^\"]*)\""); + Matcher matcher = pattern.matcher(content.toString()); + if (matcher.find()) return matcher.group(1); + else throw new Exception("Couldn't find the SRG mapping for name: " + name + "\nCould not find 'i' in 'l' object in the response"); // `i` is the SRG name which is stored in the `l` JSON object + } else { + if (error) { + // If there was an error in the GET request, and we already tried again, throw an exception + throw new Exception("The GET request failed"); + } + // If there was an error in the GET request, wait 2.5 seconds and try again as we probably got rate limited + error = true; + Thread.sleep(2500); + return remapToSRG(clazz, name); + } + } +} \ No newline at end of file diff --git a/common/build.gradle b/common/build.gradle index b61221fda..d4bf54ebe 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -1,32 +1,16 @@ -plugins { - id "org.spongepowered.gradle.vanilla" version "0.2.1-SNAPSHOT" -} +// Use Unimined's implimentation for MC as we can use Parchment mappings in common now! :tada: +// With Sponge's vanilla gradle, we cannot change the mappings to anything out of mojmaps +unimined.minecraft { + fabric { // TODO: Find a way to only include the mc stuff, not fabric's loader + loader rootProject.fabric_loader_version + accessWidener(project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")) -minecraft { - accessWideners(project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")) - version(rootProject.minecraft_version) + skipInsertAw = true + } + + defaultRemapJar = false } 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}" - - // So mixins can be written in common - compileOnly group:'org.spongepowered', name:'mixin', version:'0.8.5' -} - - -publishing { - publications { - mavenCommon(MavenPublication) { - artifactId = rootProject.mod_readable_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. - } -} + +} \ No newline at end of file diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/mimicObject/RegionFileStorageExternalCache.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/mimicObject/RegionFileStorageExternalCache.java index a181e2253..628f52cad 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/mimicObject/RegionFileStorageExternalCache.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/mimicObject/RegionFileStorageExternalCache.java @@ -9,7 +9,7 @@ import net.minecraft.world.level.chunk.storage.RegionFile; import net.minecraft.world.level.chunk.storage.RegionFileStorage; import org.apache.logging.log4j.Logger; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.io.DataInputStream; import java.io.IOException; import java.nio.file.Files; diff --git a/fabric/build.gradle b/fabric/build.gradle index ee52d6df3..1e0a557bb 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -1,65 +1,49 @@ -plugins { - id "fabric-loom" version "1.4-SNAPSHOT" -} +unimined.minecraft { + fabric { + loader rootProject.fabric_loader_version + accessWidener(project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")) -loom { - accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener") - - // "runs" isn't required, but when we do need it then it can be useful - runs { - client { - client() - setConfigName("Fabric Client") - ideConfigGenerated(true) - runDir("../run") - } - server { - server() - setConfigName("Fabric Server") - ideConfigGenerated(true) - runDir("../run") - } + skipInsertAw = true } } -remapJar { - inputFile = shadowJar.archiveFile - dependsOn shadowJar -// classifier null -} - configurations { // The addModJar basically embeds the mod to the built jar addModJar include.extendsFrom addModJar modImplementation.extendsFrom addModJar + dummy } def addMod(path, enabled) { if (enabled == "2") dependencies { modImplementation(path) } else if (enabled == "1") - dependencies { modCompileOnly(path) } + dependencies { compileOnly(path) } +} + +// TODO: There currently seems to be a bug which causes the regular addModJar to not work, swap back to the regular addModJar when fixed +def addModJar_(path) { + dependencies { + modImplementation(path) + include(path) + } } dependencies { - minecraft "com.mojang:minecraft:${minecraft_version}" - mappings loom.layered() { - // Mojmap mappings - officialMojangMappings() - // Parchment mappings (it adds parameter mappings & javadoc) - parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip") - } - // Fabric loader - modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" - + annotationProcessor "javax.annotation:javax.annotation-api:1.3.2" + implementation("javax.annotation:javax.annotation-api:1.3.2") + runtimeOnly "javax.annotation:javax.annotation-api:1.3.2" + compileOnly "javax.annotation:javax.annotation-api:1.3.2" + modImplementation "javax.annotation:javax.annotation-api:1.3.2" + // Fabric API - addModJar(fabricApi.module("fabric-api-base", rootProject.fabric_api_version)) - addModJar(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version)) - addModJar(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) - addModJar(fabricApi.module("fabric-events-interaction-v0", rootProject.fabric_api_version)) - addModJar(fabricApi.module("fabric-rendering-v1", rootProject.fabric_api_version)) // TODO: Remove this as it is only needed in 1 line (FabricClientProxy) - addModJar(fabricApi.module("fabric-networking-api-v1", rootProject.fabric_api_version)) + addModJar_(fabricApi.fabricModule("fabric-api-base", rootProject.fabric_api_version)) + addModJar_(fabricApi.fabricModule("fabric-lifecycle-events-v1", rootProject.fabric_api_version)) + addModJar_(fabricApi.fabricModule("fabric-resource-loader-v0", rootProject.fabric_api_version)) + addModJar_(fabricApi.fabricModule("fabric-events-interaction-v0", rootProject.fabric_api_version)) + addModJar_(fabricApi.fabricModule("fabric-rendering-v1", rootProject.fabric_api_version)) // TODO: Remove this as it is only needed in 1 line (FabricClientProxy) + addModJar_(fabricApi.fabricModule("fabric-networking-api-v1", rootProject.fabric_api_version)) // Mod Menu modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}") @@ -114,6 +98,12 @@ dependencies { } } +remapJar { + inputFile = shadowJar.archiveFile + dependsOn shadowJar +// classifier null +} + task deleteResources(type: Delete) { delete file("build/resources/main") @@ -124,11 +114,13 @@ processResources { dependsOn(copyCommonLoaderResources) } -runClient { - dependsOn(copyCoreResources) - dependsOn(copyCommonLoaderResources) +afterEvaluate { + runClient { + dependsOn(copyCoreResources) + dependsOn(copyCommonLoaderResources) // jvmArgs([ "-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg ]) - finalizedBy(deleteResources) + finalizedBy(deleteResources) + } } //jar { diff --git a/forge/build.gradle b/forge/build.gradle index 9c159a519..18ae90bde 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -1,80 +1,24 @@ -plugins { - // Note: This is only needed for multi-loader projects - // The main architectury loom version is set at the start of the root build.gradle - id "architectury-plugin" version "3.4-SNAPSHOT" -} +unimined.minecraft { + minecraftForge { + loader forge_version + mixinConfig("DistantHorizons.forge.mixins.json") -sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17 - -architectury { - platformSetupLoomIde() - forge() -} - -//loom { -// forge { -// convertAccessWideners.set(true) -// extraAccessWideners.add("lod.accesswidener") -// mixinConfigs("DistantHorizons.mixins.json") -// } -//} - -loom { - silentMojangMappingsLicense() // Shut the licencing warning - accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener") - - forge { - convertAccessWideners = true - extraAccessWideners.add loom.accessWidenerPath.get().asFile.name - - mixinConfigs = [ - "DistantHorizons.forge.mixins.json" - ] + file("build/sourcesSets/main/META-INF/").mkdirs() + accessTransformer(aw2at( + project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener"), + file("build/sourcesSets/main/META-INF/accesstransformer.cfg") // We'd wanna output the access transformer to somewhere where it'll only appear in the final jar + )) } - - // "runs" isn't required, but when we do need it then it can be useful - runs { - client { - client() - setConfigName("Forge Client") - ideConfigGenerated(true) - runDir("../run") -// vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg) - } - server { - server() - setConfigName("Forge Server") - ideConfigGenerated(true) - runDir("../run") - } - } -} - -remapJar { - inputFile = shadowJar.archiveFile - dependsOn shadowJar -// classifier null } def addMod(path, enabled) { if (enabled == "2") - dependencies { implementation(path) } + dependencies { modImplementation(path) } else if (enabled == "1") - dependencies { modCompileOnly(path) } + dependencies { compileOnly(path) } } dependencies { - minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" - mappings loom.layered() { - // Mojmap mappings - officialMojangMappings() - // Parchment mappings (it adds parameter mappings & javadoc) - parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip") - } - - // Forge - forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}" - // Architectury API // if (minecraft_version == "1.16.5") { // implementation("me.shedaniel:architectury-forge:${rootProject.architectury_version}") @@ -89,28 +33,45 @@ dependencies { addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged) addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft) + +// annotationProcessor "org.spongepowered:mixin:0.8.5:processor" // if (System.getProperty("idea.sync.active") != "true") { // annotationProcessor "org.spongepowered:mixin:0.8.4:processor" // } } -task deleteResources(type: Delete) { - delete file("build/resources/main") -} - tasks.register('copyAllResources') { dependsOn(copyCoreResources) dependsOn(copyCommonLoaderResources) } + + processResources { dependsOn(tasks.named('copyAllResources')) } -tasks.named('runClient') { - dependsOn(tasks.named('copyAllResources')) - finalizedBy(deleteResources) +afterEvaluate { + runClient { + dependsOn(tasks.named('copyAllResources')) + } + + // TODO this isn't a great place for these, but `tasks.build.doLast` doesn't always work and I'm not sure of a better place right now + tasks.runClient.doFirst { + // TODO can we just ignore these folders instead? + // deleting them may cause issues if the OS locks the files + // and it feels hacky + delete file("../common/build/libs") + delete file("../coreSubProjects/core/build/libs") + delete file("../coreSubProjects/api/build/libs") + } +} + +remapJar { + inputFile = shadowJar.archiveFile + dependsOn shadowJar +// classifier null } @@ -124,4 +85,31 @@ sourcesJar { // withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { // skip() // } -//} \ No newline at end of file +//} + + + +// TODO this was specifically added for MC 1.20.4 and should not be used on MC versions prior to it +// source: https://github.com/MinecraftForge/MinecraftForge/blob/5d0047753dfac0caaf5d97cc3f5c9a8b0990cb44/mdk/build.gradle#L209-L217 +// +// Merge the resources and classes into the same directory. +// This is done because java expects modules to be in a single directory. +// And if we have it in multiple we have to do performance intensive hacks like having the UnionFileSystem +// This will eventually be migrated to ForgeGradle so modders don't need to manually do it. But that is later. +sourceSets.each { + if ( // Only run on MC 1.20.4 or later + // FIXME: Add an environment variable for the Major, Minor, and Patch version number of Minecraft + minecraft_version.split("\\.")[1].toInteger() >= 20 && + ( + minecraft_version.split("\\.").length > 1 && // Incase there isn't a minor version + minecraft_version.split("\\.")[2].toInteger() >= 4 + ) + ) { + // all of our code and resources should be in the sourceSets/main/ folder for Forge 1.20.4+ + def dir = layout.buildDirectory.dir("sourcesSets/$it.name") + println "source name: [" + it.name + "]"// as of 2024-2-4 "it.name" only returned "main" and "test" + it.output.resourcesDir = dir + it.java.destinationDirectory = dir + } +} + diff --git a/forge/src/main/java/com/seibel/distanthorizons/forge/ForgeMain.java b/forge/src/main/java/com/seibel/distanthorizons/forge/ForgeMain.java index 3a853f08e..c7d531521 100644 --- a/forge/src/main/java/com/seibel/distanthorizons/forge/ForgeMain.java +++ b/forge/src/main/java/com/seibel/distanthorizons/forge/ForgeMain.java @@ -70,7 +70,7 @@ import java.util.function.Consumer; * If you are looking for the real start of the mod * check out the ClientProxy. */ -@Mod(ModInfo.ID) +@Mod("distanthorizons") // TODO: Change it back to ModInfo.ID when forge works public class ForgeMain extends AbstractModInitializer { public ForgeMain() diff --git a/forge/src/main/java/com/seibel/distanthorizons/forge/mixins/client/MixinDynamicTexture.java b/forge/src/main/java/com/seibel/distanthorizons/forge/mixins/client/MixinDynamicTexture.java index 7117e7063..36bf97035 100644 --- a/forge/src/main/java/com/seibel/distanthorizons/forge/mixins/client/MixinDynamicTexture.java +++ b/forge/src/main/java/com/seibel/distanthorizons/forge/mixins/client/MixinDynamicTexture.java @@ -38,7 +38,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Mixin(DynamicTexture.class) public abstract class MixinDynamicTexture implements ILightTextureMarker diff --git a/forge/src/main/resources/DistantHorizons.forge.mixins.json b/forge/src/main/resources/DistantHorizons.forge.mixins.json index b30ef91ed..c7326a9e4 100644 --- a/forge/src/main/resources/DistantHorizons.forge.mixins.json +++ b/forge/src/main/resources/DistantHorizons.forge.mixins.json @@ -19,6 +19,5 @@ "client.MixinOptionsScreen", "client.MixinTextureUtil" ], - "server": [], - "plugin": "com.seibel.distanthorizons.forge.mixins.ForgeMixinPlugin" + "server": [] } diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml index 983a89cde..0f86a948e 100644 --- a/forge/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -23,11 +23,16 @@ issueTrackerURL = "${issues}" #// Allow any version to be present (or not) on the server acceptableRemoteVersions = "*" +[[dependencies.distanthorizons]] + modId="forge" #mandatory + mandatory = true # Forge syntax + versionRange="[0,)" #mandatory + ordering="NONE" + side="BOTH" [[dependencies.distanthorizons]] modId = "minecraft" mandatory = true # Forge syntax - type = "required" # Neoforge syntax versionRange = "${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for - ordering = "NONE" + ordering = "AFTER" side = "BOTH" \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 868c64943..4636bc7cd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,6 +2,7 @@ org.gradle.jvmargs=-Xmx4096M org.gradle.parallel=true org.gradle.caching=true +fabric.loom.multiProjectOptimisation=true # Mod Info mod_name=DistantHorizons diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e6aba2515..1af9e0930 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.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/neoforge/build.gradle b/neoforge/build.gradle index dd98c015a..5703ea19f 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -1,100 +1,24 @@ -plugins { - // Note: This is only needed for multi-loader projects - // The main architectury loom version is set at the start of the root build.gradle - id "architectury-plugin" version "3.4-SNAPSHOT" -} - -sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17 - -architectury { - platformSetupLoomIde() - neoForge() -} - -repositories { - maven { - name "Neoforge" - url "https://maven.neoforged.net/releases/" - } -} - -//loom { -// forge { -// convertAccessWideners.set(true) -// extraAccessWideners.add("lod.accesswidener") -// mixinConfigs("DistantHorizons.mixins.json") -// } -//} - -loom { - silentMojangMappingsLicense() // Shut the licencing warning - accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener") - - neoForge { - // Access wideners are now defined in the `remapJar.atAccessWideners` -// convertAccessWideners = true -// extraAccessWideners.add loom.accessWidenerPath.get().asFile.name +unimined.minecraft { + neoForged { + loader neoforge_version + mixinConfig("DistantHorizons.neoforge.mixins.json") - // Mixins are now defined in the `mods.toml` -// mixinConfigs = [ -// "DistantHorizons.mixins.json" -// ] + file("build/sourcesSets/main/META-INF/").mkdirs() + accessTransformer(aw2at( + project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener"), + file("build/sourcesSets/main/META-INF/accesstransformer.cfg") // We'd wanna output the access transformer to somewhere where it'll only appear in the final jar + )) } - mixin { - // Mixins are now defined in the `mods.toml` -// mixinConfigs = [ -// "DistantHorizons.mixins.json" -// ] - } - - // "runs" isn't required, but when we do need it then it can be useful - runs { - client { - client() - setConfigName("NeoForge Client") - ideConfigGenerated(true) - runDir("../run") -// vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg) - } - server { - server() - setConfigName("NeoForge Server") - ideConfigGenerated(true) - runDir("../run") - } - } -} - -remapJar { - inputFile = shadowJar.archiveFile - dependsOn shadowJar -// classifier null - - atAccessWideners.add("distanthorizons.accesswidener") } def addMod(path, enabled) { if (enabled == "2") - dependencies { implementation(path) } + dependencies { modImplementation(path) } else if (enabled == "1") - dependencies { modCompileOnly(path) } + dependencies { compileOnly(path) } } dependencies { - minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" - mappings loom.layered() { - // Mojmap mappings - officialMojangMappings() - // Parchment mappings (it adds parameter mappings & javadoc) - parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip") - - // Architectury hackishness -// it.mappings "dev.architectury:yarn-mappings-patch-forge:${rootProject.mappings_patch}" - } - - // Neoforge - neoForge "net.neoforged:neoforge:${rootProject.neoforge_version}" - // Architectury API // if (minecraft_version == "1.16.5") { // implementation("me.shedaniel:architectury-forge:${rootProject.architectury_version}") @@ -110,6 +34,8 @@ dependencies { addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft) +// annotationProcessor "org.spongepowered:mixin:0.8.5:processor" + // if (System.getProperty("idea.sync.active") != "true") { // annotationProcessor "org.spongepowered:mixin:0.8.4:processor" // } @@ -128,9 +54,17 @@ processResources { dependsOn(tasks.named('copyAllResources')) } -tasks.named('runClient') { - dependsOn(tasks.named('copyAllResources')) - finalizedBy(deleteResources) +afterEvaluate { + runClient { + dependsOn(tasks.named('copyAllResources')) + finalizedBy(deleteResources) + } +} + +remapJar { + inputFile = shadowJar.archiveFile + dependsOn shadowJar +// classifier null } diff --git a/neoforge/src/main/resources/META-INF/mods.toml b/neoforge/src/main/resources/META-INF/mods.toml index dd5a9fa74..2a295c5ad 100644 --- a/neoforge/src/main/resources/META-INF/mods.toml +++ b/neoforge/src/main/resources/META-INF/mods.toml @@ -23,10 +23,9 @@ issueTrackerURL = "${issues}" #// Allow any version to be present (or not) on the server acceptableRemoteVersions = "*" -# TODO: Once there is a way to move this to the `META-INF/MANIFEST.MF` with architectury, DO SO! -# (currently, this only works cus neoforge's mods.toml is added to the jar after forge's mods.toml, so this can work -[[mixins]] - config = "DistantHorizons.neoforge.mixins.json" +# We may need this to make forge (lexforge) & neoforge work together +#[[mixins]] +# config = "DistantHorizons.neoforge.mixins.json" [[dependencies.distanthorizons]] modId = "minecraft" diff --git a/settings.gradle b/settings.gradle index 5e8900e42..8579a3916 100644 --- a/settings.gradle +++ b/settings.gradle @@ -25,6 +25,16 @@ pluginManagement { name "Sponge" url "https://repo.spongepowered.org/repository/maven-public/" } + maven { + name "ParchmentMC" + url "https://maven.parchmentmc.org" + } + maven { + url = "https://maven.wagyourtail.xyz/releases" + } + maven { + url = "https://maven.wagyourtail.xyz/snapshots" + } mavenCentral() gradlePluginPortal() @@ -33,9 +43,29 @@ pluginManagement { } } +plugins { + // handles JVM and toolchain downloading + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0' +} -// Loads the version.properties + +// Throw an error and a little help message if the user forgot to clone the core sub-project +if (!file("./coreSubProjects/LICENSE.txt").exists()) { // the LICENCE.txt file should always, and only exist if the core-sub-project was cloned + println(''' +It seems that the core sub project was not included... + please make sure that when you were cloning the repo, you were using the `--recurse-submodules` flag on git. + and if its too late now to re-clone the project, please grab the core sub project in whatever way you can from https://gitlab.com/jeseibel/distant-horizons-core.git + +If you still need help with compiling, please read the Readme.md + ''') + throw new GradleException("coreSubProject not found") +} + + + + +/** Loads the VersionProperties fiel for the currently selected Minecraft version. */ def loadProperties() { def defaultMcVersion = "1.20.1" // 1.20.1 is our current most stable version so we use that if no version was defined @@ -72,7 +102,6 @@ def loadProperties() { gradle.ext.mcVers = mcVers gradle.ext.mcIndex = mcIndex } - loadProperties() @@ -88,9 +117,9 @@ project(":api").projectDir = file('coreSubProjects/api') include("common") // Enables or disables the subprojects depending on whats in the versionProperties/mcVer.properties for (loader in ((String) gradle.builds_for).split(",")) { - def l = loader.strip() // Strip it in case a space is added before or after the comma - println "Adding loader " + l - include(l) + def loaderName = loader.strip() // Strip it in case a space is added before or after the comma + println "Adding loader " + loaderName + include(loaderName) } //if (gradle.builds_for.contains("fabric") || gradle.builds_for.contains("quilt")) // include("fabricLike") diff --git a/versionProperties/1.20.4.properties b/versionProperties/1.20.4.properties index e8e2d6125..a7a9fb886 100644 --- a/versionProperties/1.20.4.properties +++ b/versionProperties/1.20.4.properties @@ -4,7 +4,7 @@ minecraft_version=1.20.4 parchment_version=1.20.2:2023.12.10 compatible_minecraft_versions=["1.20.3", "1.20.4"] accessWidenerVersion=1_20_2 -builds_for=fabric,forge,neoforge +builds_for=fabric,neoforge,forge # Fabric loader fabric_loader_version=0.15.1 @@ -37,8 +37,8 @@ fabric_api_version=0.91.2+1.20.4 enable_canvas=0 # (Neo)Forge loader -forge_version=49.0.16 -neoforge_version=20.4.83-beta +forge_version=49.0.30 +neoforge_version=118-beta # (Neo)Forge mod versions starlight_version_forge= terraforged_version=