diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6effbc9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +# This is the universal Text Editor Configuration +# for all GTNewHorizons projects +# See: https://editorconfig.org/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{bat,ini}] +end_of_line = crlf + +[*.{dtd,json,info,mcmeta,md,sh,svg,xml,xsd,xsl,yaml,yml}] +indent_size = 2 diff --git a/.github/scripts/test-no-crash-reports.sh b/.github/scripts/test-no-crash-reports.sh deleted file mode 100644 index c67e342..0000000 --- a/.github/scripts/test-no-crash-reports.sh +++ /dev/null @@ -1,9 +0,0 @@ -directory="run/crash-reports" -if [ -d $directory ]; then - echo "Crash reports detected:" - cat $directory/* - exit 1 -else - echo "No crash reports detected" - exit 0 -fi diff --git a/.github/scripts/test_no_error_reports b/.github/scripts/test_no_error_reports new file mode 100755 index 0000000..1fcc739 --- /dev/null +++ b/.github/scripts/test_no_error_reports @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# bashsupport disable=BP5006 # Global environment variables +RUNDIR="run" \ + CRASH="crash-reports" \ + SERVERLOG="server.log" + +# enable nullglob to get 0 results when no match rather than the pattern +shopt -s nullglob + +# store matches in array +crash_reports=("$RUNDIR/$CRASH/crash"*.txt) + +# if array not empty there are crash_reports +if [ "${#crash_reports[@]}" -gt 0 ]; then + # get the latest crash_report from array + latest_crash_report="${crash_reports[-1]}" + { + printf 'Latest crash report detected %s:\n' "${latest_crash_report##*/}" + cat "$latest_crash_report" + } >&2 + exit 1 +fi + +if grep --quiet --fixed-strings 'Fatal errors were detected' "$SERVERLOG"; then + { + printf 'Fatal errors detected:\n' + cat server.log + } >&2 + exit 1 +fi + +if grep --quiet --fixed-strings 'The state engine was in incorrect state ERRORED and forced into state SERVER_STOPPED' \ + "$SERVERLOG"; then + { + printf 'Server force stopped:' + cat server.log + } >&2 + exit 1 +fi + +if ! grep --quiet --perl-regexp --only-matching '.+Done \(.+\)\! For help, type "help" or "\?"' "$SERVERLOG"; then + { + printf 'Server did not finish startup:' + cat server.log + } >&2 + exit 1 +fi + +printf 'No crash reports detected' +exit 0 diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 6c9b3cb..56a1ad5 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -14,32 +14,32 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - with: + with: fetch-depth: 0 - + - name: Set up JDK 8 uses: actions/setup-java@v2 with: java-version: '8' distribution: 'adopt' cache: gradle - + - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Setup the workspace run: ./gradlew setupCIWorkspace - + - name: Build the mod run: ./gradlew build - - name: Run server for 1 minute + - name: Run server for 1.5 minutes run: | mkdir run - echo "eula=true" > run/eula.txt - timeout 10 ./gradlew runServer || true + echo "eula=true" > run/eula.txt + timeout 90 ./gradlew runServer 2>&1 | tee -a server.log || true - - name: Test no crashes happend + - name: Test no errors reported during server run run: | - chmod +x .github/scripts/test-no-crash-reports.sh - .github/scripts/test-no-crash-reports.sh + chmod +x .github/scripts/test_no_error_reports + .github/scripts/test_no_error_reports diff --git a/build.gradle b/build.gradle index 3d3fd92..c8cf37c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1644510936 +//version: 1644894948 /* DO NOT CHANGE THIS FILE! @@ -6,7 +6,7 @@ Also, you may replace this file at any time if there is an update available. Please check https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/build.gradle for updates. */ -import org.gradle.internal.logging.text.StyledTextOutput +import org.gradle.internal.logging.text.StyledTextOutput import org.gradle.internal.logging.text.StyledTextOutputFactory import org.gradle.internal.logging.text.StyledTextOutput.Style @@ -45,18 +45,20 @@ plugins { id 'eclipse' id 'scala' id 'maven-publish' - id('org.jetbrains.kotlin.jvm') version ('1.6.10') apply false - id('org.ajoberstar.grgit') version('4.1.1') - id('com.github.johnrengelman.shadow') version('4.0.4') - id('com.palantir.git-version') version('0.13.0') apply false - id('de.undercouch.download') version('5.0.1') + id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false + id 'org.jetbrains.kotlin.kapt' version '1.5.30' apply false + id 'org.ajoberstar.grgit' version '4.1.1' + id 'com.github.johnrengelman.shadow' version '4.0.4' + id 'com.palantir.git-version' version '0.13.0' apply false + id 'de.undercouch.download' version '5.0.1' + id 'com.github.gmazzo.buildconfig' version '3.0.3' apply false } if (project.file('.git/HEAD').isFile()) { apply plugin: 'com.palantir.git-version' } -def out = services.get(StyledTextOutputFactory).create("an-output") +def out = services.get(StyledTextOutputFactory).create('an-output') apply plugin: 'forge' @@ -173,7 +175,7 @@ configurations.all { try { 'git config core.fileMode false'.execute() } -catch (Exception e) { +catch (Exception ignored) { out.style(Style.Failure).println("git isn't installed at all") } @@ -183,19 +185,21 @@ String versionOverride = System.getenv("VERSION") ?: null try { identifiedVersion = versionOverride == null ? gitVersion() : versionOverride } -catch (Exception e) { +catch (Exception ignored) { out.style(Style.Failure).text( 'This mod must be version controlled by Git AND the repository must provide at least one tag,\n' + - 'or the VERSION override must be set! ').style(Style.SuccessHeader).text('(Do NOT download from GitHub using the ZIP option, instead\n' + + 'or the VERSION override must be set! ').style(Style.SuccessHeader).text('(Do NOT download from GitHub using the ZIP option, instead\n' + 'clone the repository, see ').style(Style.Info).text('https://gtnh.miraheze.org/wiki/Development').style(Style.SuccessHeader).println(' for details.)' ) versionOverride = 'NO-GIT-TAG-SET' identifiedVersion = versionOverride } version = minecraftVersion + '-' + identifiedVersion -String modVersion = identifiedVersion +ext { + modVersion = identifiedVersion +} -if( identifiedVersion.equals(versionOverride) ) { +if(identifiedVersion == versionOverride) { out.style(Style.Failure).text('Override version to ').style(Style.Identifier).text(modVersion).style(Style.Failure).println('!\7') } @@ -207,7 +211,6 @@ else { archivesBaseName = modId } - def arguments = [] def jvmArguments = [] @@ -221,8 +224,8 @@ if(usesMixins.toBoolean()) { } minecraft { - version = minecraftVersion + "-" + forgeVersion + "-" + minecraftVersion - runDir = "run" + version = minecraftVersion + '-' + forgeVersion + '-' + minecraftVersion + runDir = 'run' if (replaceGradleTokenInFile) { replaceIn replaceGradleTokenInFile @@ -255,8 +258,8 @@ minecraft { } } -if(file("addon.gradle").exists()) { - apply from: "addon.gradle" +if(file('addon.gradle').exists()) { + apply from: 'addon.gradle' } apply from: 'repositories.gradle' @@ -304,7 +307,7 @@ dependencies { apply from: 'dependencies.gradle' -def mixingConfigRefMap = "mixins." + modId + ".refmap.json" +def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json' def refMap = "${tasks.compileJava.temporaryDir}" + File.separator + mixingConfigRefMap def mixinSrg = "${tasks.reobf.temporaryDir}" + File.separator + "mixins.srg" @@ -408,12 +411,11 @@ tasks.withType(JavaExec).configureEach { ) } -processResources -{ +processResources { // this will ensure that this task is redone when the versions change. inputs.property "version", project.version inputs.property "mcversion", project.minecraft.version - + // replace stuff in mcmod.info, nothing else from(sourceSets.main.resources.srcDirs) { include 'mcmod.info' @@ -437,7 +439,7 @@ processResources def getManifestAttributes() { def manifestAttributes = [:] - if(containsMixinsAndOrCoreModOnly.toBoolean() == false && (usesMixins.toBoolean() || coreModClass)) { + if(!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) { manifestAttributes += ["FMLCorePluginContainsFMLMod": true] } @@ -453,7 +455,7 @@ def getManifestAttributes() { manifestAttributes += [ "TweakClass" : "org.spongepowered.asm.launch.MixinTweaker", "MixinConfigs" : "mixins." + modId + ".json", - "ForceLoadAsMod" : containsMixinsAndOrCoreModOnly.toBoolean() == false + "ForceLoadAsMod" : !containsMixinsAndOrCoreModOnly.toBoolean() ] } return manifestAttributes @@ -540,12 +542,15 @@ artifacts { } } -// The gradle metadata includes all of the additional deps that we disabled from POM generation (including forgeBin with no groupID), +// The gradle metadata includes all of the additional deps that we disabled from POM generation (including forgeBin with no groupID), // and isn't strictly needed with the POM so just disable it. tasks.withType(GenerateModuleMetadata) { enabled = false } +// workaround variable hiding in pom processing +def projectConfigs = project.configurations + publishing { publications { maven(MavenPublication) { @@ -565,17 +570,21 @@ publishing { artifactId = System.getenv("ARTIFACT_ID") ?: project.name // Using the identified version, not project.version as it has the prepended 1.7.10 version = System.getenv("RELEASE_VERSION") ?: identifiedVersion - - // remove extra garbage from who knows where + + // remove extra garbage from minecraft and minecraftDeps configuration pom.withXml { - def badPomGroup = ['net.minecraft', 'com.google.code.findbugs', 'org.ow2.asm', 'com.typesafe.akka', 'com.typesafe', 'org.scala-lang', - 'org.scala-lang.plugins', 'net.sf.jopt-simple', 'lzma', 'com.mojang', 'org.apache.commons', 'org.apache.httpcomponents', - 'commons-logging', 'java3d', 'net.sf.trove4j', 'com.ibm.icu', 'com.paulscode', 'io.netty', 'com.google.guava', - 'commons-io', 'commons-codec', 'net.java.jinput', 'net.java.jutils', 'com.google.code.gson', 'org.apache.logging.log4j', - 'org.lwjgl.lwjgl', 'tv.twitch', ''] + def badArtifacts = [:].withDefault {[] as Set} + for (configuration in [projectConfigs.minecraft, projectConfigs.minecraftDeps]) { + for (dependency in configuration.allDependencies) { + badArtifacts[dependency.group == null ? "" : dependency.group] += dependency.name + } + } + // example for specifying extra stuff to ignore + // badArtifacts["org.example.group"] += "artifactName" + Node pomNode = asNode() pomNode.dependencies.'*'.findAll() { - badPomGroup.contains(it.groupId.text()) + badArtifacts[it.groupId.text()].contains(it.artifactId.text()) }.each() { it.parent().remove(it) } @@ -688,7 +697,7 @@ def deobf(String sourceURL, String fileName) { String bon2File = bon2Dir + "/BON2-2.5.0.jar" String obfFile = cacheDir + "modules-2/files-2.1/" + fileName + ".jar" String deobfFile = cacheDir + "modules-2/files-2.1/" + fileName + "-deobf.jar" - + if(file(deobfFile).exists()) { return files(deobfFile) } @@ -719,7 +728,7 @@ def deobf(String sourceURL, String fileName) { // Helper methods def checkPropertyExists(String propertyName) { - if (project.hasProperty(propertyName) == false) { + if (!project.hasProperty(propertyName)) { throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/gradle.properties") } } diff --git a/gradle.properties b/gradle.properties index 55f3a6d..5e76708 100644 --- a/gradle.properties +++ b/gradle.properties @@ -37,7 +37,7 @@ gradleTokenGroupName = # Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api apiPackage = -# Specify the configuration file for Forge's access transformers here. I must be placed into /src/main/resources/META-INF/ +# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/ # Example value: mymodid_at.cfg accessTransformersFile = diff --git a/src/main/java/codechicken/core/launch/CodeChickenCorePlugin.java b/src/main/java/codechicken/core/launch/CodeChickenCorePlugin.java index 34614ae..7f01222 100644 --- a/src/main/java/codechicken/core/launch/CodeChickenCorePlugin.java +++ b/src/main/java/codechicken/core/launch/CodeChickenCorePlugin.java @@ -18,6 +18,7 @@ import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import codechicken.core.asm.*; +import codechicken.lib.config.ConfigTag; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.CoreModManager; @@ -36,7 +37,8 @@ import org.apache.logging.log4j.Logger; public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook { public static final String mcVersion = "[1.7.10]"; - public static final String version = "GRADLETOKEN_VERSION"; + @Deprecated + public static final String version = "1.1.3-unused"; public static File minecraftDir; public static String currentMcVersion; @@ -122,17 +124,17 @@ public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook return String.format("%.1f %cB", value / 1024.0, ci.current()); } - public static void systemCheck(String minRAM) { - long minBytes = parseSize(minRAM); + public static void systemCheck(ConfigTag checkRAM) { + long minBytes = parseSize(checkRAM.getTag("minRAM").setComment("Amount of RAM minimum this modpack needs to load").getValue("3GB")); if (Runtime.getRuntime().maxMemory() < minBytes) { - String err = "You should have at least " + minRAM + " of RAM but you have only allocated " + humanReadableByteCountBin(Runtime.getRuntime().maxMemory()) + "."; + String err = "You should have at least " + humanReadableByteCountBin(minBytes) + " of RAM but you have only allocated " + humanReadableByteCountBin(Runtime.getRuntime().maxMemory()) + "."; logger.error(err); JEditorPane ep = new JEditorPane("text/html", - "" + - err + - "
GTNH seriously won't run without enough RAM. See the Wiki for details." + - "
Recommended values are between 4GB and 6GB. Check your launcher's JVM arguments." + + "" + err + "
" + checkRAM.getTag("modPack").setComment("Name of the modpack").getValue("Unidentified ModPack") + + " seriously won't run without enough RAM. " + checkRAM.getTag("wiki").setComment("Webpage describing RAM settings").getValue("See DownloadMoreRam.com for details.") + + "
Recommended values are between " + checkRAM.getTag("recRAM").setComment("Lower bound of recommended RAM").getValue("4GB") + " and " + + checkRAM.getTag("recRAMUpper").setComment("Upper bound of recommended RAM").getValue("6GB") + ". Check your launcher's JVM arguments." + ""); ep.setEditable(false); @@ -187,7 +189,11 @@ public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook @Override public Void call() { CodeChickenCoreModContainer.loadConfig(); - systemCheck(CodeChickenCoreModContainer.config.getTag("minRAM").getValue("3GB")); + ConfigTag checkRAM; + checkRAM = CodeChickenCoreModContainer.config.getTag("checks") + .setComment("Configuration options for checking various requirements for a modpack.").useBraces(); + if(checkRAM.getTag("checkRAM").setComment("If set to true, check RAM available for Minecraft before continuing to load").getBooleanValue(false)) + systemCheck(checkRAM); TweakTransformer.load(); scanCodeChickenMods(); diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 058b8a5..e5c2574 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -1,11 +1,12 @@ -[ { -"modid": "${modId}", -"name": "${modName}", -"description": "Base common code for all chickenbones mods. Supporters: JBoyJr", -"version": "${modVersion}", -"mcversion": "${minecraftVersion}", -"url": "http://www.minecraftforum.net/topic/909223", -"authorList": [ "ChickenBones" ] + "modListVersion": 2, + "modList": [{ + "modid": "${modId}", + "name": "${modName}", + "description": "Base common code for all chickenbones mods. Supporters: JBoyJr", + "version": "${modVersion}", + "mcversion": "${minecraftVersion}", + "url": "http://www.minecraftforum.net/topic/909223", + "authorList": ["ChickenBones"] + }] } -] \ No newline at end of file