From 9c64308b76e722dadb55c3a5643b42cb91b1c15e Mon Sep 17 00:00:00 2001 From: Aedial Date: Tue, 18 Aug 2026 19:03:31 +0200 Subject: [PATCH] Migrate kotlin fat build.gradle to ForgeDevEnv --- .github/ISSUE_TEMPLATE/bug_report.md | 36 ++ .github/ISSUE_TEMPLATE/config.yml | 5 + .github/ISSUE_TEMPLATE/feature_request.md | 20 + .github/pull_request_template.md | 38 ++ .github/workflows/build.yml | 103 ++++-- .gitignore | 8 +- build.gradle | 349 ++++++++++++++++++ build.gradle.kts | 346 ----------------- gradle.properties | 84 +++++ gradle/scripts/dependencies.gradle | 110 ++++++ gradle/scripts/extra.gradle | 43 +++ gradle/scripts/helpers.gradle | 96 +++++ gradle/scripts/publishing.gradle | 105 ++++++ gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle | 22 ++ settings.gradle.kts | 34 -- .../client/gui/AEBaseGuiContainerDynamic.java | 2 +- .../mmce/client/gui/GuiContainerDynamic.java | 2 +- tags.properties | 1 + 19 files changed, 1000 insertions(+), 406 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/pull_request_template.md create mode 100644 build.gradle delete mode 100644 build.gradle.kts create mode 100644 gradle.properties create mode 100644 gradle/scripts/dependencies.gradle create mode 100644 gradle/scripts/extra.gradle create mode 100644 gradle/scripts/helpers.gradle create mode 100644 gradle/scripts/publishing.gradle create mode 100644 settings.gradle delete mode 100644 settings.gradle.kts create mode 100644 tags.properties diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..16156336 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,36 @@ +--- +name: Bug report +about: Create a report to help us improve Modular Machinery: Community Edition +labels: bug +--- + +## Describe the bug +A clear and concise description of the problem. + +## To reproduce +1. Go to '...' +2. Click on '...' +3. Run command '...' +4. See error + +## Expected behavior +Describe what you expected to happen. + +## Logs and crash reports +- Attach `logs/latest.log` and any crash report from `crash-reports/`. + +## Checklist +- [ ] I can reproduce this on the latest released version. +- [ ] I searched for existing issues. +- [ ] I included the exact source for any added or replacement mods. + +## Environment +- Modular Machinery Community Edition version: +- Minecraft: 1.12.2 +- Forge: +- Java: 8u__ +- OS: Windows/Linux/macOS (version) +- Modpack and relevant integration mods: + +## Additional context +Add any other relevant information, screenshots, or configuration excerpts. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..c6b3a2da --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: README + url: https://github.com/???/ModularMachinery-Community-Edition#readme + about: Check the README and bundled documentation before filing an issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..e8f28316 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for Modular Machinery: Community Edition +labels: enhancement +--- + +## Is your feature request related to a problem? +Describe the problem or limitation. + +## Describe the solution you'd like +Describe the behavior you would like to see. + +## Alternatives you've considered +Describe other solutions or workarounds. + +## Affected components or integrations +- + +## Additional context +Add mockups, configuration examples, or related links. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..6e35bccf --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,38 @@ +# Summary +Explain the motivation and context for this change. + +## Type of change +- [ ] Bug fix (non-breaking change) +- [ ] New feature (non-breaking change) +- [ ] Breaking change +- [ ] Chore/refactor +- [ ] Documentation update only + +## Related issues +Closes # + +## What changed + +- + +## How to test +Provide steps and relevant commands. + +```cmd +rem From the repository root, using Java 21 for Gradle +gradle setupDecompWorkspace +gradle build +``` + +If this changes runtime behavior, include in-game verification steps. + +## Checklist +- [ ] I built the project locally with Gradle 8.14 and Java 21. +- [ ] I updated documentation when needed. +- [ ] I followed the existing code style. +- [ ] I did not include secrets or private data. +- [ ] If touching `mcmod.info`, it remains valid and accurate. +- [ ] I searched for existing PRs/issues that cover this change. + +## Additional context +Add anything reviewers should know. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 85fa6816..919fdca6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,27 +1,88 @@ -name: Build mod +name: build -on: [ push, pull_request, workflow_dispatch ] +on: + push: + branches: + - '**' + tags: + - '**' + pull_request: + branches: + - '**' + workflow_dispatch: + +permissions: + contents: write jobs: build: - name: Build mod runs-on: ubuntu-latest - + env: + CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} steps: - - uses: actions/checkout@v4 - - name: Set up JDK 1.8 - uses: actions/setup-java@v4 - with: - distribution: 'adopt' - java-version: '8' - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 - - name: Build with Gradle - run: ./gradlew -Pnet.minecraftforge.gradle.disableUpdateChecker=true build - - name: Upload artifacts - uses: actions/upload-artifact@v4 - with: - name: ModularMachinery-CE - path: build/libs + - name: Checkout + uses: actions/checkout@v4 + + # Gradle 8.14/RFG 1.4.9 needs Java 21 + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + distribution: zulu + java-version: '21' + + - name: Cache Gradle and RFG + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + ~/.gradle/jdks + key: gradle-${{ runner.os }}-rfg-1_12_2-${{ hashFiles('**/*.gradle*', 'gradle/wrapper/gradle-wrapper.properties') }} + restore-keys: | + gradle-${{ runner.os }}-rfg-1_12_2- + + - name: Make gradlew executable + run: chmod +x gradlew + + - name: Build + run: | + ./gradlew --version + ./gradlew setupDecompWorkspace --info + ./gradlew build --info + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: modularmachinery-community-edition-jar + path: build/libs/*.jar + + - name: Publish GitHub Release (tags only) + if: ${{ startsWith(github.ref, 'refs/tags/') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TAG="${GITHUB_REF##*/}" + VERSION=$(./gradlew -q printVersion) + FULL_VERSION=$(./gradlew -q printFullVersion) + RELEASE_TYPE=$(./gradlew -q printReleaseType) + NOTES_FILE="/tmp/release_notes.md" + + if [[ -f CHANGELOG.md ]]; then + ./gradlew -q printChangelog > "$NOTES_FILE" + else + printf 'Release %s\n' "$FULL_VERSION" > "$NOTES_FILE" + fi + + gh release create "$TAG" build/libs/*.jar \ + --title "$FULL_VERSION" \ + --notes-file "$NOTES_FILE" \ + $(if [[ "$RELEASE_TYPE" != "release" ]]; then echo "--prerelease"; fi) + + - name: Publish to CurseForge (configured tags only) + if: ${{ env.CURSEFORGE_TOKEN != '' && vars.CURSEFORGE_PROJECT_ID != '' && startsWith(github.ref, 'refs/tags/') }} + run: | + RELEASE_TYPE=$(./gradlew -q printReleaseType) + ./gradlew curseforge --no-daemon \ + -Ppublish_to_curseforge=true \ + -Pcurseforge_project_id="${{ vars.CURSEFORGE_PROJECT_ID }}" \ + -Prelease_type="$RELEASE_TYPE" diff --git a/.gitignore b/.gitignore index 96a09920..aecadbe0 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,11 @@ hs_err_pid* # For good measure... *.jks -gradle.properties + +.vscode /libs/* -.gradle \ No newline at end of file +.gradle +.kotlin +*.patch +*.zip diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..bafbc391 --- /dev/null +++ b/build.gradle @@ -0,0 +1,349 @@ +import com.gtnewhorizons.retrofuturagradle.mcp.InjectTagsTask +import net.darkhax.curseforgegradle.TaskPublishCurseForge +import org.jetbrains.changelog.Changelog +import org.jetbrains.gradle.ext.Gradle +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile + +plugins { + id 'java' + id 'java-library' + id 'maven-publish' + id 'org.jetbrains.kotlin.jvm' version '2.2.0' + id 'org.jetbrains.kotlin.plugin.serialization' version '2.2.0' + id 'org.jetbrains.gradle.plugin.idea-ext' version '1.4.1' + // Need 1.4.X for Kotlin / Gradle 8.14 (2.X.X needs Gradle 9) + id 'com.gtnewhorizons.retrofuturagradle' version '1.4.9' + // Need 1.1.X for Gradle 8.14 (1.2.X needs Gradle 9) + id 'net.darkhax.curseforgegradle' version '1.1.28' apply false + id 'com.modrinth.minotaur' version '2.+' apply false + id 'org.jetbrains.changelog' version '2.5.0' +} + +apply from: 'gradle/scripts/helpers.gradle' + +// Required project metadata. +assertProperty 'mod_version' +assertProperty 'root_package' +assertProperty 'mod_id' +assertProperty 'mod_name' + +assertSubProperties 'use_tags', 'tag_class_name' +assertSubProperties 'use_access_transformer', 'access_transformer_locations' +assertSubProperties 'use_mixins', 'mixin_booter_version', 'mixin_refmap' +assertSubProperties 'is_coremod', 'coremod_includes_mod', 'coremod_plugin_class_name' +assertSubProperties 'use_asset_mover', 'asset_mover_version' + +setDefaultProperty 'use_modern_java_syntax', false, false +setDefaultProperty 'generate_sources_jar', true, false +setDefaultProperty 'generate_javadocs_jar', true, false +setDefaultProperty 'mapping_channel', true, 'stable' +setDefaultProperty 'mapping_version', true, '39' +setDefaultProperty 'use_dependency_at_files', true, true +setDefaultProperty 'minecraft_username', true, 'Developer' +setDefaultProperty 'extra_jvm_args', false, '' +setDefaultProperty 'extra_tweak_classes', false, '' +setDefaultProperty 'change_minecraft_sources', false, false +setDefaultProperty 'publish_to_curseforge', true, false + +version = propertyString('mod_version') +group = propertyString('root_package') + +base { + archivesName.set(propertyString('mod_id')) +} + +tasks.named('decompressDecompiledSources').configure { + enabled = !propertyBool('change_minecraft_sources') || !layout.buildDirectory.dir('rfg/minecraft-src').get().asFile.exists() +} + +// Gradle/RFG run on Java 21, but the Java compiler stays on 17 so Jabel can lower mod bytecode to Java 8. +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + vendor.set(JvmVendorSpec.AZUL) + } + if (propertyBool('generate_sources_jar')) { + withSourcesJar() + } + if (propertyBool('generate_javadocs_jar')) { + withJavadocJar() + } +} + +// Kotlin needs Java 8 game bytecode/runtime baseline. +kotlin { + jvmToolchain(8) + compilerOptions.jvmTarget.set(JvmTarget.JVM_1_8) +} + +tasks.withType(KotlinJvmCompile).configureEach { + compilerOptions.jvmTarget.set(JvmTarget.JVM_1_8) +} + +minecraft { + mcVersion.set('1.12.2') + + mcpMappingChannel.set(propertyString('mapping_channel')) + mcpMappingVersion.set(propertyString('mapping_version')) + useDependencyAccessTransformers.set(propertyBool('use_dependency_at_files')) + + username.set(propertyString('minecraft_username')) + extraTweakClasses.addAll(propertyStringList('extra_tweak_classes')) + + def args = ['-ea:' + group] + if (propertyBool('use_mixins')) { + args << '-Dmixin.checks.interfaces=true' + args << '-Dmixin.debug.export=true' + } + extraRunJvmArguments.addAll(args) + extraRunJvmArguments.addAll(propertyStringList('extra_jvm_args')) + + // These third-party libraries contain classes that must not be remapped into the release jar. + groupsToExcludeFromAutoReobfMapping.addAll('com.diffplug', 'com.diffplug.durian', 'net.industrial-craft') + + if (propertyBool('use_tags') && file('tags.properties').exists()) { + Properties props = new Properties().tap { it.load(file('tags.properties').newInputStream()); it } + if (!props.isEmpty()) { + injectedTags.set(props.collectEntries { k, v -> + def interpolated = interpolate(v) + if (interpolated == null || interpolated.isEmpty()) { + throw new GradleException("Empty tag value found for key: $k") + } + [(k): interpolated] + }) + } + } +} + +repositories { + maven { + name 'CleanroomMC Maven' + url 'https://maven.cleanroommc.com' + } +} + +dependencies { + if (propertyBool('use_modern_java_syntax')) { + annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0' + // Work around Jabel issue #174. + annotationProcessor 'net.java.dev.jna:jna-platform:5.13.0' + compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') { + transitive = false + } + // Allows jdk.unsupported classes such as sun.misc.Unsafe in the patched Minecraft runtime. + patchedMinecraft 'me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0' + testAnnotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0' + testCompileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') { + transitive = false + } + testCompileOnly 'me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0' + } + + if (propertyBool('use_asset_mover')) { + implementation "com.cleanroommc:assetmover:${propertyString('asset_mover_version')}" + } + + if (propertyBool('use_mixins')) { + String mixin = modUtils.enableMixins("zone.rong:mixinbooter:${propertyString('mixin_booter_version')}", propertyString('mixin_refmap')) + api(mixin) { + transitive = false + } + annotationProcessor 'org.ow2.asm:asm-debug-all:5.2' + annotationProcessor 'com.google.guava:guava:30.0-jre' + annotationProcessor 'com.google.code.gson:gson:2.8.9' + annotationProcessor(mixin) { + transitive = false + } + } + + if (propertyBool('enable_junit_testing')) { + testImplementation 'org.junit.jupiter:junit-jupiter:5.7.1' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + } +} + +apply from: 'gradle/scripts/dependencies.gradle' + +if (propertyBool('use_access_transformer')) { + def atFiles = propertyStringList('access_transformer_locations').collect { location -> + def atFile = file("src/main/resources/${location}") + if (!atFile.exists()) { + throw new GradleException("Access Transformer file [$atFile] does not exist!") + } + atFile + } + tasks.named('applyJST').configure { + accessTransformerFiles.from(atFiles) + } +} + +processResources { + inputs.property 'mod_id', propertyString('mod_id') + inputs.property 'mod_name', propertyString('mod_name') + inputs.property 'mod_version', propertyString('mod_version') + inputs.property 'mcversion', minecraft.mcVersion.get() + inputs.property 'mod_description', propertyString('mod_description') + inputs.property 'mod_authors', propertyStringList('mod_authors', ',').join(', ') + inputs.property 'mod_credits', propertyString('mod_credits') + inputs.property 'mod_url', propertyString('mod_url') + inputs.property 'mod_update_json', propertyString('mod_update_json') + inputs.property 'mod_logo_path', propertyString('mod_logo_path') + inputs.property 'mixin_refmap', propertyString('mixin_refmap') + + // Retain the existing mcmod.info placeholders while exposing the template-style names too. + filesMatching(['mcmod.info', 'pack.mcmeta']) { + expand( + 'mod_id': propertyString('mod_id'), + 'mod_name': propertyString('mod_name'), + 'mod_version': propertyString('mod_version'), + 'version': propertyString('mod_version'), + 'mcversion': minecraft.mcVersion.get(), + 'mod_description': propertyString('mod_description'), + 'mod_authors': propertyStringList('mod_authors', ',').join(', '), + 'mod_credits': propertyString('mod_credits'), + 'mod_url': propertyString('mod_url'), + 'mod_update_json': propertyString('mod_update_json'), + 'mod_logo_path': propertyString('mod_logo_path'), + 'mixin_refmap': propertyString('mixin_refmap') + ) + } + + if (propertyBool('use_access_transformer')) { + rename '(.+_at.cfg)', 'META-INF/$1' + } +} + +jar { + manifest { + def attributeMap = [:] + if (propertyBool('is_coremod')) { + attributeMap['FMLCorePlugin'] = propertyString('coremod_plugin_class_name') + if (propertyBool('coremod_includes_mod')) { + attributeMap['FMLCorePluginContainsFMLMod'] = true + if (gradle.startParameter.taskNames.any { it in ['build', 'prepareObfModsFolder', 'runObfClient'] }) { + attributeMap['ForceLoadAsMod'] = true + } + } + } + if (propertyBool('use_access_transformer')) { + attributeMap['FMLAT'] = propertyString('access_transformer_locations') + } + + // Do not add MixinConfigs here: the early and late loaders select configs conditionally. + attributes(attributeMap) + } +} + +idea { + module { + inheritOutputDirs = true + } + project { + settings { + runConfigurations { + '1. Run Client'(Gradle) { + taskNames = ['runClient'] + } + '2. Run Server'(Gradle) { + taskNames = ['runServer'] + } + '3. Run Obfuscated Client'(Gradle) { + taskNames = ['runObfClient'] + } + '4. Run Obfuscated Server'(Gradle) { + taskNames = ['runObfServer'] + } + } + compiler.javac { + afterEvaluate { + javacAdditionalOptions = '-encoding utf8' + moduleJavacAdditionalOptions = [ + (project.name + '.main'): tasks.compileJava.options.compilerArgs.collect { '"' + it + '"' }.join(' ') + ] + } + } + } + } +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' + if (propertyBool('use_modern_java_syntax')) { + if (name in ['compileMcLauncherJava', 'compilePatchedMcJava']) { + return + } + sourceCompatibility = '17' + targetCompatibility = '8' + options.release.set(8) + javaCompiler.set(javaToolchains.compilerFor { + languageVersion.set(JavaLanguageVersion.of(17)) + vendor.set(JvmVendorSpec.AZUL) + }) + } +} + +tasks.withType(Javadoc).configureEach { + if (propertyBool('use_modern_java_syntax')) { + sourceCompatibility = '17' + } +} + +tasks.named('injectTags', InjectTagsTask).configure { + onlyIf { + propertyBool('use_tags') && !tags.get().isEmpty() + } + outputClassName.set(propertyString('tag_class_name')) +} + +tasks.register('cleanroomAfterSync') { + group 'cleanroom helpers' + dependsOn 'injectTags' +} + +idea.project.settings { + taskTriggers { + afterSync 'cleanroomAfterSync' + } +} + +tasks.named('prepareObfModsFolder').configure { + finalizedBy 'prioritizeCoremods' +} + +tasks.register('prioritizeCoremods') { + dependsOn 'prepareObfModsFolder' + doLast { + fileTree('run/obfuscated').forEach { + if (it.isFile() && it.name =~ '(mixinbooter|configanytime)(-)([0-9])+\\.+([0-9])+(.jar)') { + it.renameTo(new File(it.parentFile, "!${it.name}")) + } + } + } +} + +String parserChangelog() { + if (!file('CHANGELOG.md').exists()) { + throw new GradleException('publish_with_changelog is true, but CHANGELOG.md does not exist in the workspace!') + } + String parsedChangelog = changelog.renderItem( + changelog.get(propertyString('mod_version')).withHeader(false).withEmptySections(false), + Changelog.OutputType.MARKDOWN) + if (parsedChangelog.isEmpty()) { + throw new GradleException('publish_with_changelog is true, but the changelog for the latest version is empty!') + } + parsedChangelog +} + +if (propertyBool('publish_to_curseforge')) { + assertProperty 'curseforge_project_id' + apply plugin: 'net.darkhax.curseforgegradle' + tasks.register('curseforge', TaskPublishCurseForge) { + disableVersionDetection() + group = 'publishing' + description = "Uploads CurseForge project ${propertyString('curseforge_project_id')}" + } +} + +apply from: 'gradle/scripts/publishing.gradle' +apply from: 'gradle/scripts/extra.gradle' diff --git a/build.gradle.kts b/build.gradle.kts deleted file mode 100644 index b5da34a4..00000000 --- a/build.gradle.kts +++ /dev/null @@ -1,346 +0,0 @@ -import org.jetbrains.gradle.ext.Gradle -import org.jetbrains.gradle.ext.RunConfigurationContainer -import java.util.* - -plugins { - kotlin("jvm") version "2.2.0" - kotlin("plugin.serialization") version "2.2.0" - id("java-library") - id("maven-publish") - id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.7" - id("eclipse") - id("com.gtnewhorizons.retrofuturagradle") version "1.4.0" -} - -// Project properties -group = "hellfirepvp.modularmachinery" -version = "2.3.2" - -// Set the toolchain version to decouple the Java we run Gradle with from the Java used to compile and run the mod -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) - // Azul covers the most platforms for Java 8 toolchains, crucially including MacOS arm64 - vendor.set(JvmVendorSpec.AZUL) - } - // Generate sources and javadocs jars when building and publishing - withSourcesJar() - withJavadocJar() -} - -kotlin { - jvmToolchain(8) -} - -// Most RFG configuration lives here, see the JavaDoc for com.gtnewhorizons.retrofuturagradle.MinecraftExtension -minecraft { - mcVersion.set("1.12.2") - - // Username for client run configurations - username.set("Kasumi_Nova") - - // Generate a field named VERSION with the mod version in the injected Tags class - injectedTags.put("VERSION", project.version) - - // If you need the old replaceIn mechanism, prefer the injectTags task because it doesn't inject a javac plugin. - // tagReplacementFiles.add("RfgExampleMod.java") - - // Enable assertions in the mod's package when running the client or server - val args = mutableListOf("-ea:${project.group}") - - // Mixin args - args.add("-Dfml.coreMods.load=github.kasuminova.mmce.mixin.MMCEEarlyMixinLoader") - args.add("-Dmixin.hotSwap=true") - args.add("-Dmixin.checks.interfaces=true") - args.add("-Dmixin.debug.export=true") - extraRunJvmArguments.addAll(args) - - // If needed, add extra tweaker classes like for mixins. - // extraTweakClasses.add("org.spongepowered.asm.launch.MixinTweaker") - - // Exclude some Maven dependency groups from being automatically included in the reobfuscated runs - groupsToExcludeFromAutoReobfMapping.addAll("com.diffplug", "com.diffplug.durian", "net.industrial-craft") -} - -// Generates a class named rfg.examplemod.Tags with the mod version in it, you can find it at -tasks.injectTags.configure { - outputClassName.set("${project.group}.Tags") -} - -// Put the version from gradle into mcmod.info -tasks.processResources.configure { - inputs.property("version", project.version) - inputs.property("mcversion", minecraft.mcVersion.get()) - - filesMatching("mcmod.info") { - expand(mapOf("version" to project.version, "mcversion" to minecraft.mcVersion.get())) - } -} - -tasks.compileJava.configure { - sourceCompatibility = "17" - options.release = 8 - options.encoding = "UTF-8" // Use the UTF-8 charset for Java compilation - - javaCompiler = javaToolchains.compilerFor { - languageVersion = JavaLanguageVersion.of(17) - } -} - -tasks.jar.configure { - manifest { - val attributes = manifest.attributes - attributes["FMLCorePlugin"] = "github.kasuminova.mmce.mixin.MMCEEarlyMixinLoader" - attributes["FMLCorePluginContainsFMLMod"] = true - } -} - -tasks.javadoc.configure { - // No need for JavaDoc. - actions = Collections.emptyList() -} - -// Create a new dependency type for runtime-only dependencies that don't get included in the maven publication -val runtimeOnlyNonPublishable: Configuration by configurations.creating { - description = "Runtime only dependencies that are not published alongside the jar" - isCanBeConsumed = false - isCanBeResolved = false -} -listOf(configurations.runtimeClasspath, configurations.testRuntimeClasspath).forEach { - it.configure { - extendsFrom( - runtimeOnlyNonPublishable - ) - } -} - -// Add an access tranformer -// tasks.deobfuscateMergedJarToSrg.configure {accessTransformerFiles.from("src/main/resources/META-INF/mymod_at.cfg")} - -// Dependencies -repositories { - flatDir { - dirs("libs") - } - maven { - url = uri("https://maven.aliyun.com/nexus/content/groups/public/") - } - maven { - url = uri("https://maven.aliyun.com/nexus/content/repositories/jcenter") - } - maven { - url = uri("https://maven.cleanroommc.com") - } - maven { - url = uri("https://cfa2.cursemaven.com") - } - maven { - url = uri("https://cursemaven.com") - } - maven { - url = uri("https://maven.blamejared.com/") - } - maven { - url = uri("https://repo.spongepowered.org/maven") - } - maven { - name = "OvermindDL1 Maven" - url = uri("https://gregtech.overminddl1.com/") - mavenContent { - excludeGroup("net.minecraftforge") // missing the `universal` artefact - } - } - maven { - name = "GeckoLib" - url = uri("https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/") - } - maven { - name = "GTNH Maven" - url = uri("https://nexus.gtnewhorizons.com/repository/public/") - } -} - -dependencies { - annotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.4.2") - compileOnly("com.github.bsideup.jabel:jabel-javac-plugin:0.4.2") - // workaround for https://github.com/bsideup/jabel/issues/174 - annotationProcessor("net.java.dev.jna:jna-platform:5.13.0") - // Allow jdk.unsupported classes like sun.misc.Unsafe, workaround for JDK-8206937 and fixes Forge crashes in tests. - patchedMinecraft("me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0") - // allow Jabel to work in tests - testAnnotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:1.0.0") - testCompileOnly("com.github.bsideup.jabel:jabel-javac-plugin:1.0.0") { - isTransitive = false // We only care about the 1 annotation class - } - testCompileOnly("me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0") - - // Mixins - val mixin : String = modUtils.enableMixins("zone.rong:mixinbooter:8.9", "mixins.mmce.refmap.json").toString() - api (mixin) { - isTransitive = false - } - annotationProcessor("org.ow2.asm:asm-debug-all:5.2") - annotationProcessor("com.google.guava:guava:30.0-jre") - annotationProcessor("com.google.code.gson:gson:2.8.9") - annotationProcessor (mixin) { - isTransitive = false - } - - // Kotlin Support - runtimeOnly("io.github.chaosunity.forgelin:Forgelin-Continuous:2.2.0.0") { - isTransitive = false - } - compileOnly("org.jetbrains.kotlin:kotlin-stdlib:2.2.0") - compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1") - - implementation("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.+") - implementation(rfg.deobf("curse.maven:had-enough-items-557549:4810661")) - implementation(rfg.deobf("curse.maven:zenutil-401178:5056679")) - implementation(rfg.deobf("curse.maven:RedstoneFlux-270789:2920436")) - implementation(rfg.deobf("curse.maven:CodeChickenLib-242818:2779848")) - implementation(rfg.deobf("curse.maven:brandonscore-231382:3051539")) - implementation(rfg.deobf("curse.maven:draconicevolution-223565:3051542")) - implementation(rfg.deobf("curse.maven:the-one-probe-245211:2667280")) - implementation(rfg.deobf("curse.maven:Mekanism-268560:2835175")) - compileOnly(rfg.deobf("curse.maven:industrialcraft-2-242638:3078604")) - compileOnly(rfg.deobf("curse.maven:nuclearcraft-overhauled-336895:3862197")) - compileOnly(rfg.deobf("curse.maven:flux-networks-248020:3178199")) - compileOnly(rfg.deobf("curse.maven:tinkers-construct-74072:2902483")) - compileOnly(rfg.deobf("curse.maven:mantle-74924:2713386")) - implementation(rfg.deobf("curse.maven:tx-loader-706505:4515357")) - implementation(rfg.deobf("curse.maven:cofh-core-69162:2920433")) - implementation(rfg.deobf("curse.maven:cofh-world-271384:2920434")) - implementation(rfg.deobf("curse.maven:thermal-foundation-222880:2926428")) - implementation(rfg.deobf("curse.maven:thermal-expansion-69163:2926431")) - - // AE2 Compat - // implementation(rfg.deobf("curse.maven:applied-energistics-2-223794:2747063")) - implementation(rfg.deobf("curse.maven:ae2-extended-life-570458:6302098")) - implementation(rfg.deobf("curse.maven:ae2-fluid-crafting-rework-623955:5504001")) - implementation(rfg.deobf("curse.maven:mekanism-energistics-1027681:5408319")) - implementation(rfg.deobf("curse.maven:nae2-884359:5380800")) - - // GeckoLib - implementation("software.bernie.geckolib:geckolib-forge-1.12.2:3.0.31") - // GTCEu / Bloom Effect Support - compileOnly(rfg.deobf("curse.maven:gregtech-ce-unofficial-557242:5322654")) - // Bloom Effect Support - implementation(rfg.deobf("kasuminova:lumenized:1.0.3:dev")) - - // Multiblocked - implementation(rfg.deobf("curse.maven:multiblocked-604054:4753960")) - - // Modular Magic compact - compileOnly(rfg.deobf("curse.maven:astral-sorcery-241721:3044416")) - implementation(rfg.deobf("curse.maven:blood-magic-224791:2822288")) - compileOnly(rfg.deobf("curse.maven:thaumcraft-223628:2629023")) - compileOnly(rfg.deobf("curse.maven:extrautils2-225561:2678374")) - compileOnly(rfg.deobf("curse.maven:naturesaura-306626:2882138")) - compileOnly(rfg.deobf("curse.maven:botania-225643:3330934")) - compileOnly(rfg.deobf("curse.maven:baubles-227083:2518667")) - implementation(rfg.deobf("curse.maven:guideapi-228832:2645992")) - compileOnly(rfg.deobf("curse.maven:patchouli-306770:3162874")) - compileOnly(rfg.deobf("curse.maven:thaumic-augmentation-319441:4486505")) - // Performance Test Tool - runtimeOnly(rfg.deobf("curse.maven:spark-361579:3542217")) - // Optimization - implementation(rfg.deobf("curse.maven:stellarcore-1064321:5560444")) - implementation(rfg.deobf("curse.maven:configanytime-870276:5212709")) -} - -// Publishing to a Maven repository -publishing { - publications { - create("maven") { - from(components["java"]) - } - } - repositories { -// // Example: publishing to the GTNH Maven repository -// maven { -// url = uri("http://jenkins.usrv.eu:8081/nexus/content/repositories/releases") -// isAllowInsecureProtocol = true -// credentials { -// username = System.getenv("MAVEN_USER") ?: "NONE" -// password = System.getenv("MAVEN_PASSWORD") ?: "NONE" -// } -// } - } -} - -// IDE Settings -//eclipse { -// classpath { -// isDownloadSources = true -// isDownloadJavadoc = true -// } -//} - -idea { - module { - isDownloadJavadoc = true - isDownloadSources = true - inheritOutputDirs = true // Fix resources in IJ-Native runs - } - project { - this.withGroovyBuilder { - "settings" { - "runConfigurations" { - val self = this.delegate as RunConfigurationContainer - self.add(Gradle("1. Run Client").apply { - setProperty("taskNames", listOf("runClient")) - }) - self.add(Gradle("2. Run Server").apply { - setProperty("taskNames", listOf("runServer")) - }) - self.add(Gradle("3. Run Obfuscated Client").apply { - setProperty("taskNames", listOf("runObfClient")) - }) - self.add(Gradle("4. Run Obfuscated Server").apply { - setProperty("taskNames", listOf("runObfServer")) - }) - /* - These require extra configuration in IntelliJ, so are not enabled by default - self.add(Application("Run Client (IJ Native, Deprecated)", project).apply { - mainClass = "GradleStart" - moduleName = project.name + ".ideVirtualMain" - afterEvaluate { - val runClient = tasks.runClient.get() - workingDirectory = runClient.workingDir.absolutePath - programParameters = runClient.calculateArgs(project).map { '"' + it + '"' }.joinToString(" ") - jvmArgs = runClient.calculateJvmArgs(project).map { '"' + it + '"' }.joinToString(" ") + - ' ' + runClient.systemProperties.map { "\"-D" + it.key + '=' + it.value.toString() + '"' } - .joinToString(" ") - } - }) - self.add(Application("Run Server (IJ Native, Deprecated)", project).apply { - mainClass = "GradleStartServer" - moduleName = project.name + ".ideVirtualMain" - afterEvaluate { - val runServer = tasks.runServer.get() - workingDirectory = runServer.workingDir.absolutePath - programParameters = runServer.calculateArgs(project).map { '"' + it + '"' }.joinToString(" ") - jvmArgs = runServer.calculateJvmArgs(project).map { '"' + it + '"' }.joinToString(" ") + - ' ' + runServer.systemProperties.map { "\"-D" + it.key + '=' + it.value.toString() + '"' } - .joinToString(" ") - } - }) - */ - } - "compiler" { - val self = this.delegate as org.jetbrains.gradle.ext.IdeaCompilerConfiguration - afterEvaluate { - self.javac.moduleJavacAdditionalOptions = mapOf( - (project.name + ".main") to - tasks.compileJava.get().options.compilerArgs.map { '"' + it + '"' }.joinToString(" ") - ) - } - } - } - } - } -} - -tasks.processIdeaSettings.configure { - dependsOn(tasks.injectTags) -} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..577a5fcd --- /dev/null +++ b/gradle.properties @@ -0,0 +1,84 @@ +# Gradle +org.gradle.jvmargs = -Xmx3G +org.gradle.parallel = true +org.gradle.caching = true + +# The Kotlin plugin otherwise adds kotlin-stdlib as an implementation dependency. The mod supplies it through Forgelin. +kotlin.stdlib.default.dependency = false + +# Source and test options +use_modern_java_syntax = true +generate_sources_jar = true +generate_javadocs_jar = false +enable_junit_testing = false +show_testing_output = false + +# Mod information +mod_version = 2.3.2 +root_package = hellfirepvp.modularmachinery +mod_id = modularmachinery +mod_name = Modular Machinery: Community Edition +mod_description = A modpack-maker toolset to create custom, massive, unique and complex machines and recipes from scratch with JSON. +mod_url = https://www.curseforge.com/minecraft/mc-mods/modularmachinery-community-edition +mod_update_json = +mod_authors = HellFirePvP, wiiv, KasumiNova, youyihj, ikexing +mod_credits = HellFirePvP code, wiiv ALL THE TEXTURES :3, and KasumiNova Improvements! And more community edition contributors! +mod_logo_path = assets/modularmachinery/textures/logo.png + +# Minecraft and run configurations +mapping_channel = stable +mapping_version = 39 +use_dependency_at_files = true +minecraft_username = Kasumi_Nova +extra_jvm_args = -Dfml.coreMods.load=github.kasuminova.mmce.mixin.MMCEEarlyMixinLoader -Dmixin.hotSwap=true +extra_tweak_classes = +change_minecraft_sources = false + +# Build-time tags +use_tags = true +tag_class_name = hellfirepvp.modularmachinery.Tags + +# Access transformers +use_access_transformer = false +access_transformer_locations = ${mod_id}_at.cfg + +# MixinBooter. Config loading remains in MMCEEarlyMixinLoader/MMCELateMixinLoader, so no manifest config list is used. +use_mixins = true +mixin_booter_version = 8.9 +generate_mixins_json = false +mixin_configs = +mixin_refmap = mixins.mmce.refmap.json + +# Coremod +is_coremod = true +coremod_includes_mod = true +coremod_plugin_class_name = github.kasuminova.mmce.mixin.MMCEEarlyMixinLoader + +# Optional AssetMover support +use_asset_mover = false +asset_mover_version = 2.5 + +# Maven publishing (provide MAVEN_USER and MAVEN_PASS) +publish_to_maven = false +publish_to_local_maven = false +maven_name = ${mod_name} +maven_url = + +# Release publishing +release_type = release +publish_with_changelog = ${{ it.file('CHANGELOG.md').exists() }} +client_side = true +server_side = true + +# CurseForge (provide CURSEFORGE_TOKEN) +publish_to_curseforge = false +curseforge_project_id = +curseforge_debug = false +curseforge_changelog = +curseforge_display_name = + +# Modrinth (provide MODRINTH_TOKEN) +publish_to_modrinth = false +modrinth_project_id = +modrinth_sync_readme = false +modrinth_debug = false diff --git a/gradle/scripts/dependencies.gradle b/gradle/scripts/dependencies.gradle new file mode 100644 index 00000000..670564b8 --- /dev/null +++ b/gradle/scripts/dependencies.gradle @@ -0,0 +1,110 @@ +apply from: 'gradle/scripts/helpers.gradle' + +repositories { + flatDir { + dirs 'libs' + } + maven { + name 'Aliyun Public' + url 'https://maven.aliyun.com/nexus/content/groups/public/' + } + maven { + name 'Aliyun JCenter' + url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' + } + maven { + name 'CleanroomMC Maven' + url 'https://maven.cleanroommc.com' + } + // Keep both endpoints used by the legacy build: some historical files resolve through the CFA mirror. + maven { + name 'CFA2 CurseMaven' + url 'https://cfa2.cursemaven.com' + } + maven { + name 'CurseMaven' + url 'https://cursemaven.com' + } + maven { + name 'BlameJared Maven' + url 'https://maven.blamejared.com/' + } + maven { + name 'SpongePowered Maven' + url 'https://repo.spongepowered.org/maven' + } + maven { + name 'OvermindDL1 Maven' + url 'https://gregtech.overminddl1.com/' + mavenContent { + excludeGroup 'net.minecraftforge' // This repository lacks the Forge universal artifact. + } + } + maven { + name 'GeckoLib Maven' + url 'https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/' + } + maven { + name 'GTNH Maven' + url 'https://nexus.gtnewhorizons.com/repository/public/' + } + mavenLocal() // Keep last so normal repository caches win. +} + +dependencies { + // Kotlin is supplied at runtime by Forgelin-Continuous. Its default Kotlin stdlib dependency is disabled in gradle.properties. + runtimeOnly('io.github.chaosunity.forgelin:Forgelin-Continuous:2.2.0.0') { + transitive = false + } + compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:2.2.0' + compileOnly 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1' + + implementation 'CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.+' + implementation rfg.deobf('curse.maven:had-enough-items-557549:4810661') + implementation rfg.deobf('curse.maven:zenutil-401178:5056679') + implementation rfg.deobf('curse.maven:RedstoneFlux-270789:2920436') + implementation rfg.deobf('curse.maven:CodeChickenLib-242818:2779848') + implementation rfg.deobf('curse.maven:brandonscore-231382:3051539') + implementation rfg.deobf('curse.maven:draconicevolution-223565:3051542') + implementation rfg.deobf('curse.maven:the-one-probe-245211:2667280') + implementation rfg.deobf('curse.maven:Mekanism-268560:2835175') + compileOnly rfg.deobf('curse.maven:industrialcraft-2-242638:3078604') + compileOnly rfg.deobf('curse.maven:nuclearcraft-overhauled-336895:3862197') + compileOnly rfg.deobf('curse.maven:flux-networks-248020:3178199') + compileOnly rfg.deobf('curse.maven:tinkers-construct-74072:2902483') + compileOnly rfg.deobf('curse.maven:mantle-74924:2713386') + implementation rfg.deobf('curse.maven:tx-loader-706505:4515357') + implementation rfg.deobf('curse.maven:cofh-core-69162:2920433') + implementation rfg.deobf('curse.maven:cofh-world-271384:2920434') + implementation rfg.deobf('curse.maven:thermal-foundation-222880:2926428') + implementation rfg.deobf('curse.maven:thermal-expansion-69163:2926431') + + // AE2 compatibility + // implementation rfg.deobf('curse.maven:applied-energistics-2-223794:2747063') + implementation rfg.deobf('curse.maven:ae2-extended-life-570458:6302098') + implementation rfg.deobf('curse.maven:ae2-fluid-crafting-rework-623955:5504001') + implementation rfg.deobf('curse.maven:mekanism-energistics-1027681:5408319') + implementation rfg.deobf('curse.maven:nae2-884359:5380800') + + implementation 'software.bernie.geckolib:geckolib-forge-1.12.2:3.0.31' + compileOnly rfg.deobf('curse.maven:gregtech-ce-unofficial-557242:5322654') + implementation rfg.deobf('kasuminova:lumenized:1.0.3:dev') + implementation rfg.deobf('curse.maven:multiblocked-604054:4753960') + + // Modular Magic compatibility + compileOnly rfg.deobf('curse.maven:astral-sorcery-241721:3044416') + implementation rfg.deobf('curse.maven:blood-magic-224791:2822288') + compileOnly rfg.deobf('curse.maven:thaumcraft-223628:2629023') + compileOnly rfg.deobf('curse.maven:extrautils2-225561:2678374') + compileOnly rfg.deobf('curse.maven:naturesaura-306626:2882138') + compileOnly rfg.deobf('curse.maven:botania-225643:3330934') + compileOnly rfg.deobf('curse.maven:baubles-227083:2518667') + implementation rfg.deobf('curse.maven:guideapi-228832:2645992') + compileOnly rfg.deobf('curse.maven:patchouli-306770:3162874') + compileOnly rfg.deobf('curse.maven:thaumic-augmentation-319441:4486505') + + // Developer-only runtime tools and optimizations from the previous RFG build. + runtimeOnly rfg.deobf('curse.maven:spark-361579:3542217') + implementation rfg.deobf('curse.maven:stellarcore-1064321:5560444') + implementation rfg.deobf('curse.maven:configanytime-870276:5212709') +} diff --git a/gradle/scripts/extra.gradle b/gradle/scripts/extra.gradle new file mode 100644 index 00000000..9f3a595b --- /dev/null +++ b/gradle/scripts/extra.gradle @@ -0,0 +1,43 @@ +// CI helpers, modelled after AE2-PowerTools. They do not alter ordinary local builds. + +tasks.register('printChangelog') { + group 'publishing' + description 'Prints the changelog for the current mod_version to stdout' + doLast { + if (!file('CHANGELOG.md').exists()) { + throw new GradleException('CHANGELOG.md does not exist!') + } + println parserChangelog() + } +} + +tasks.register('printVersion') { + group 'publishing' + description 'Prints the mod_version to stdout' + doLast { + println propertyString('mod_version') + } +} + +tasks.register('printFullVersion') { + group 'publishing' + description 'Prints the full mod version to stdout' + doLast { + println "${propertyString('mod_name')} ${propertyString('mod_version')}" + } +} + +tasks.register('printReleaseType') { + group 'publishing' + description 'Infers release, beta, or alpha from mod_version' + doLast { + def version = propertyString('mod_version').toLowerCase() + def releaseType = 'release' + if (version.contains('alpha') || version =~ /^\\d+(\\.\\d+)*a\\d*$/) { + releaseType = 'alpha' + } else if (version.contains('beta') || version.contains('rc') || version.contains('pre') || version =~ /^\\d+(\\.\\d+)*b\\d*$/) { + releaseType = 'beta' + } + println releaseType + } +} diff --git a/gradle/scripts/helpers.gradle b/gradle/scripts/helpers.gradle new file mode 100644 index 00000000..0b3f2ee7 --- /dev/null +++ b/gradle/scripts/helpers.gradle @@ -0,0 +1,96 @@ +import groovy.text.SimpleTemplateEngine +import org.codehaus.groovy.runtime.MethodClosure + +ext.propertyString = this.&propertyString as MethodClosure +ext.propertyBool = this.&propertyBool as MethodClosure +ext.propertyStringList = this.&propertyStringList as MethodClosure +ext.interpolate = this.&interpolate as MethodClosure +ext.assertProperty = this.&assertProperty as MethodClosure +ext.assertSubProperties = this.&assertSubProperties as MethodClosure +ext.setDefaultProperty = this.&setDefaultProperty as MethodClosure +ext.assertEnvironmentVariable = this.&assertEnvironmentVariable as MethodClosure + +String propertyString(String key) { + return $property(key).toString() +} + +boolean propertyBool(String key) { + return propertyString(key).toBoolean() +} + +Collection propertyStringList(String key) { + return propertyStringList(key, ' ') +} + +Collection propertyStringList(String key, String delimit) { + return propertyString(key).split(delimit).findAll { !it.isEmpty() } +} + +private Object $property(String key) { + def value = project.findProperty(key) + if (value instanceof String) { + return interpolate(value) + } + return value +} + +String interpolate(String value) { + if (value.startsWith('${{') && value.endsWith('}}')) { + value = value.substring(3, value.length() - 2) + Binding newBinding = new Binding(this.binding.getVariables()) + newBinding.setProperty('it', this) + return new GroovyShell(this.getClass().getClassLoader(), newBinding).evaluate(value) + } + if (value.contains('${')) { + return new SimpleTemplateEngine().createTemplate(value).make(project.properties).toString() + } + return value +} + +void assertProperty(String propertyName) { + def property = property(propertyName) + if (property == null) { + throw new GradleException("Property ${propertyName} is not defined!") + } + if (property.isEmpty()) { + throw new GradleException("Property ${propertyName} is empty!") + } +} + +void assertSubProperties(String propertyName, String... subPropertyNames) { + assertProperty(propertyName) + if (propertyBool(propertyName)) { + for (String subPropertyName : subPropertyNames) { + assertProperty(subPropertyName) + } + } +} + +void setDefaultProperty(String propertyName, boolean warn, defaultValue) { + def property = property(propertyName) + def exists = true + if (property == null) { + exists = false + if (warn) { + project.logger.log(LogLevel.WARN, "Property ${propertyName} is not defined!") + } + } else if (property.isEmpty()) { + exists = false + if (warn) { + project.logger.log(LogLevel.WARN, "Property ${propertyName} is empty!") + } + } + if (!exists) { + project.setProperty(propertyName, defaultValue.toString()) + } +} + +void assertEnvironmentVariable(String propertyName) { + def property = System.getenv(propertyName) + if (property == null) { + throw new GradleException("System Environment Variable $propertyName is not defined!") + } + if (property.isEmpty()) { + throw new GradleException("Property $propertyName is empty!") + } +} diff --git a/gradle/scripts/publishing.gradle b/gradle/scripts/publishing.gradle new file mode 100644 index 00000000..ca7503ea --- /dev/null +++ b/gradle/scripts/publishing.gradle @@ -0,0 +1,105 @@ +apply from: 'gradle/scripts/helpers.gradle' + +setDefaultProperty('publish_to_maven', true, false) +setDefaultProperty('publish_to_curseforge', true, false) +setDefaultProperty('publish_to_modrinth', true, false) + +// CI may override these for release-candidate tags whose changelog header differs from mod_version. +setDefaultProperty('curseforge_changelog', false, '') +setDefaultProperty('curseforge_display_name', false, '') + +if (propertyBool('publish_to_maven')) { + assertProperty('maven_name') + assertProperty('maven_url') + publishing { + repositories { + maven { + name propertyString('maven_name').replaceAll('\\s', '') + url propertyString('maven_url') + credentials(PasswordCredentials) + } + } + publications { + mavenJava(MavenPublication) { + from components.java + setGroupId(propertyString('root_package')) + setArtifactId(propertyString('mod_id')) + } + } + } +} + +if (propertyBool('publish_to_curseforge')) { + assertProperty('curseforge_project_id') + assertProperty('release_type') + setDefaultProperty('curseforge_debug', false, false) + setDefaultProperty('client_side', false, true) + setDefaultProperty('server_side', false, true) + + if (!propertyBool('client_side') && !propertyBool('server_side')) { + throw new GradleException('At least one of client_side and server_side must be true!') + } + + tasks.named('curseforge') { + debugMode = propertyBool('curseforge_debug') + apiToken = System.getenv('CURSEFORGE_TOKEN') == null ? '' : System.getenv('CURSEFORGE_TOKEN') + dependsOn(tasks.reobfJar) + + def mainFile = upload(propertyString('curseforge_project_id'), tasks.reobfJar) + def changelogOverride = propertyString('curseforge_changelog') + def changelogRaw = !changelogOverride.isEmpty() ? changelogOverride : + (propertyBool('publish_with_changelog') ? parserChangelog() : '') + def displayNameOverride = propertyString('curseforge_display_name') + + mainFile.displayName = !displayNameOverride.isEmpty() ? displayNameOverride : + "${propertyString('mod_name')} ${propertyString('mod_version')}" + mainFile.releaseType = propertyString('release_type') + if (!changelogRaw.isEmpty()) { + mainFile.changelog = changelogRaw + mainFile.changelogType = 'markdown' + } + mainFile.addJavaVersion('Java 8') + mainFile.addModLoader('Forge') + mainFile.addGameVersion('1.12.2') + if (propertyBool('client_side')) mainFile.addEnvironment('Client') + if (propertyBool('server_side')) mainFile.addEnvironment('Server') + + if (propertyBool('use_mixins')) { + mainFile.addRelation('mixin-booter', 'requiredDependency') + } + if (propertyBool('use_asset_mover')) { + mainFile.addRelation('assetmover', 'requiredDependency') + } + } +} + +if (propertyBool('publish_to_modrinth')) { + apply plugin: 'com.modrinth.minotaur' + assertProperty('modrinth_project_id') + assertProperty('release_type') + setDefaultProperty('modrinth_debug', false, false) + + modrinth { + token = System.getenv('MODRINTH_TOKEN') == null ? '' : System.getenv('MODRINTH_TOKEN') + projectId = propertyString('modrinth_project_id') + versionNumber = propertyString('mod_version') + versionType = propertyString('release_type') + uploadFile = tasks.reobfJar + gameVersions = ['1.12.2'] + loaders = ['forge'] + debugMode = propertyBool('modrinth_debug') + if (propertyBool('use_mixins') || propertyBool('use_asset_mover')) { + dependencies { + if (propertyBool('use_mixins')) required.project 'mixinbooter' + if (propertyBool('use_asset_mover')) required.project 'assetmover' + } + } + if (propertyBool('publish_with_changelog')) { + changelog = parserChangelog() + } + if (propertyBool('modrinth_sync_readme')) { + syncBodyFrom = file('README.md').text + tasks.modrinth.dependsOn(tasks.modrinthSyncBody) + } + } +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0817a5c9..48d593f4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ #Fri Mar 24 08:46:50 CST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists https.protocols=TLSv1.1,TLSv1.2,TLSv1.3 diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..0feb7f52 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,22 @@ +pluginManagement { + repositories { + maven { + name 'GTNH Maven' + url 'https://nexus.gtnewhorizons.com/repository/public/' + mavenContent { + includeGroup 'com.gtnewhorizons' + includeGroupByRegex 'com\\.gtnewhorizons\\..+' + } + } + gradlePluginPortal() + mavenCentral() + mavenLocal() + } +} + +plugins { + // Required for Java 8/17 toolchain provisioning when Gradle itself runs on another JDK. + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' +} + +rootProject.name = 'ModularMachinery-CE' diff --git a/settings.gradle.kts b/settings.gradle.kts deleted file mode 100644 index 151603a0..00000000 --- a/settings.gradle.kts +++ /dev/null @@ -1,34 +0,0 @@ -//pluginManagement { -// repositories { -// maven { url = 'https://maven.minecraftforge.net/' } -// maven { -// name 'Garden of Fancy' -// url 'https://maven.gofancy.wtf/releases' -// } -// gradlePluginPortal() -// } -//} -pluginManagement { - repositories { - maven { - // RetroFuturaGradle - name = "GTNH Maven" - url = uri("https://nexus.gtnewhorizons.com/repository/public/") - isAllowInsecureProtocol = true - mavenContent { - includeGroupByRegex("com\\.gtnewhorizons\\..+") - includeGroup("com.gtnewhorizons") - } - } - gradlePluginPortal() - mavenCentral() - mavenLocal() - } -} - -plugins { - // Automatic toolchain provisioning - id("org.gradle.toolchains.foojay-resolver-convention") version "0.4.0" -} - -rootProject.name = "ModularMachinery-CE" diff --git a/src/main/java/github/kasuminova/mmce/client/gui/AEBaseGuiContainerDynamic.java b/src/main/java/github/kasuminova/mmce/client/gui/AEBaseGuiContainerDynamic.java index 1c1dcedd..cdb99abd 100644 --- a/src/main/java/github/kasuminova/mmce/client/gui/AEBaseGuiContainerDynamic.java +++ b/src/main/java/github/kasuminova/mmce/client/gui/AEBaseGuiContainerDynamic.java @@ -115,7 +115,7 @@ protected void updateHoveredSlot(final int mouseX, final int mouseY) { .orElse(null); } - protected boolean isMouseOverSlot(Slot slotIn, int mouseX, int mouseY) { + public boolean isMouseOverSlot(Slot slotIn, int mouseX, int mouseY) { return this.isPointInRegion(slotIn.xPos, slotIn.yPos, 16, 16, mouseX, mouseY); } diff --git a/src/main/java/github/kasuminova/mmce/client/gui/GuiContainerDynamic.java b/src/main/java/github/kasuminova/mmce/client/gui/GuiContainerDynamic.java index 9ba4808a..3da0c03c 100644 --- a/src/main/java/github/kasuminova/mmce/client/gui/GuiContainerDynamic.java +++ b/src/main/java/github/kasuminova/mmce/client/gui/GuiContainerDynamic.java @@ -139,7 +139,7 @@ protected void updateHoveredSlot(final int mouseX, final int mouseY) { .orElse(null); } - protected boolean isMouseOverSlot(Slot slotIn, int mouseX, int mouseY) { + public boolean isMouseOverSlot(Slot slotIn, int mouseX, int mouseY) { return this.isPointInRegion(slotIn.xPos, slotIn.yPos, 16, 16, mouseX, mouseY); } diff --git a/tags.properties b/tags.properties new file mode 100644 index 00000000..3dd2c3c7 --- /dev/null +++ b/tags.properties @@ -0,0 +1 @@ +VERSION = ${mod_version} \ No newline at end of file