commit 32c32df053363a7bb276f040f146805b8b4abb44 Author: FalsePattern <30945458+FalsePattern@users.noreply.github.com> Date: Thu Mar 9 20:06:44 2023 +0100 Initial Commit diff --git a/.github/scripts/test-no-error-reports.sh b/.github/scripts/test-no-error-reports.sh new file mode 100755 index 0000000..1fcc739 --- /dev/null +++ b/.github/scripts/test-no-error-reports.sh @@ -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 new file mode 100644 index 0000000..08df9fe --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,45 @@ +# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Build and test + +on: + pull_request: + branches: [ master, main ] + push: + branches: [ master, main ] + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + 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.5 minutes + run: | + mkdir run + echo "eula=true" > run/eula.txt + timeout 90 ./gradlew runServer | tee --append server.log || true + + - name: Test no errors reported during server run + run: | + chmod +x .github/scripts/test-no-error-reports.sh + .github/scripts/test-no-error-reports.sh diff --git a/.github/workflows/release-tags.yml b/.github/workflows/release-tags.yml new file mode 100644 index 0000000..dffb841 --- /dev/null +++ b/.github/workflows/release-tags.yml @@ -0,0 +1,50 @@ +# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Release tagged build + +on: + push: + tags: + - '*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set release version + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV + + - 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: Publish to Maven, Modrinth, and CurseForge + run: ./gradlew publish + env: + MAVEN_DEPLOY_USER: ${{ secrets.MAVEN_DEPLOY_USER }} + MAVEN_DEPLOY_PASSWORD: ${{ secrets.MAVEN_DEPLOY_PASSWORD }} + MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} + CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} + + - name: Release under current tag + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: "${{ env.RELEASE_VERSION }}" + prerelease: false + title: "${{ env.RELEASE_VERSION }}" + files: build/libs/*.jar diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf03ff1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,225 @@ +# Created by https://www.toptal.com/developers/gitignore/api/intellij+all,gradle,forgegradle,java,eclipse,netbeans +# Edit at https://www.toptal.com/developers/gitignore?templates=intellij+all,gradle,forgegradle,java,eclipse,netbeans + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project + +### Eclipse Patch ### +# Spring Boot Tooling +.sts4-cache/ + +### ForgeGradle ### +# Minecraft client/server files +run/ + +### Intellij+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +.idea/artifacts +.idea/compiler.xml +.idea/jarRepositories.xml +.idea/modules.xml +.idea/*.iml +.idea/modules +*.iml +*.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij+all Patch ### +# Ignore everything but code style settings and run configurations +# that are supposed to be shared within teams. + +.idea/* + +!.idea/codeStyles +!.idea/runConfigurations + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +### NetBeans ### +**/nbproject/private/ +**/nbproject/Makefile-*.mk +**/nbproject/Package-*.bash +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### Gradle ### +.gradle +**/build/ +!src/**/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Avoid ignore Gradle wrappper properties +!gradle-wrapper.properties + +# Cache of project +.gradletasknamecache + +# Eclipse Gradle plugin generated files +# Eclipse Core +.project +# JDT-specific (Eclipse Java Development Tools) +.classpath + +### Gradle Patch ### +# Java heap dump +*.hprof + +# End of https://www.toptal.com/developers/gitignore/api/intellij+all,gradle,forgegradle,java,eclipse,netbeans diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..ad03daa --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,73 @@ + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cf3b250 --- /dev/null +++ b/LICENSE @@ -0,0 +1,63 @@ +#------------------------------------------------------------------------------- +# @author FalsePattern +# +# Copyright 2023 +# +# All rights reserved. +# Distribution of the software in any form is only allowed with +# explicit, prior permission from the owner. +#------------------------------------------------------------------------------- +@author FalsePattern + + +This code is the property of and owned and copyrighted by FalsePattern. +This code is provided under a modified visible-source license +that is as follows: + + +API Code: +============================== +API code is identifiable as being in an "API" package in the respective +repository or mod, and is intended to allow some level of inter-mod +interactions without creating hard dependencies on the mod proper. This code +is exempt from the below restrictions for "Mod Code", as it by nature will +require some level of copying and redistribution. + +The only restrictions imposed on API code are that it remain clearly marked +with its original authorship and source, that it be used for the purpose +described previously, and that it not be modified from the original without +first contacting FalsePattern. + + +Mod Code: +============================== +Any and all users are permitted to use the source for educational purposes, +or to create derivative works for private use only. GitHub forks and direct +downloads are considered derivative works. + +Unless given explicit written permission - verifiable electronic writing is +acceptable - no user may redistribute this source code nor any derivative +works. These pre-approved works must prominently contain this copyright notice. + +Derivative mods using any or all of the source code or assets are +EXPRESSLY FORBIDDEN. + +Additionally, no attempt may be made to achieve monetary gain from this code +by anyone except the original author. In the case of pre-approved derivative +works, any monetary gains made will be shared between the original author and +the other developer(s), proportional to the ratio of derived to original code. + +Finally, any and all displays, duplicates or derivatives of this code must be +prominently marked as such, and must contain attribution to the original +author, including a link to the original source. Any attempts to claim credit +for this code will be treated as intentional theft. + +Due to the Mojang and Minecraft Mod Terms of Service and Licensing +Restrictions, compiled versions of this code must be provided for free. +However, with the exception of pre-approved derivative works, only the original +author's modpacks may distribute compiled binary versions of this code. + +============================== + +Failure to comply with these restrictions is a violation of copyright law and +will be dealt with accordingly. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..da49aa0 --- /dev/null +++ b/build.gradle @@ -0,0 +1,1149 @@ +//version: 1656003793falsepattern63 +/* +DO NOT CHANGE THIS FILE! + +Also, you may replace this file at any time if there is an update available. +Please check https://github.com/FalsePattern/ExampleMod1.7.10/blob/main/build.gradle for updates. + */ + + +import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import com.matthewprenger.cursegradle.CurseArtifact +import com.matthewprenger.cursegradle.CurseRelation +import com.modrinth.minotaur.dependencies.ModDependency +import com.modrinth.minotaur.dependencies.VersionDependency +import org.gradle.internal.logging.text.StyledTextOutput.Style +import org.gradle.internal.logging.text.StyledTextOutputFactory + +import java.nio.file.Files +import java.nio.file.Paths +import java.util.concurrent.TimeUnit +import java.util.zip.ZipEntry +import java.util.zip.ZipInputStream +import java.util.zip.ZipOutputStream + +buildscript { + repositories { + mavenLocal() + maven { + name = "forge" + url = "https://mvn.falsepattern.com/forge" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" + } + maven { + name = "Scala CI dependencies" + url = "https://repo1.maven.org/maven2/" + } + maven { + name = "jitpack" + url = "https://mvn.falsepattern.com/jitpack/" + } + maven { + name = "mavenpattern" + url = "https://mvn.falsepattern.com/releases/" + } + maven { + name = "usrv" + url = "https://mvn.falsepattern.com/usrv/" + } + } + dependencies { + classpath 'net.minecraftforge.gradle:ForgeGradle:1.2.11' + classpath 'com.falsepattern:jtweaker:0.2.1' + } +} + +plugins { + id 'java-library' + id 'idea' + id 'eclipse' + id 'scala' + id 'maven-publish' + id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false + id 'org.jetbrains.kotlin.kapt' version '1.5.30' apply false + id 'com.google.devtools.ksp' version '1.5.30-1.0.0' 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' + id 'de.undercouch.download' version '5.0.1' + id 'com.github.gmazzo.buildconfig' version '3.0.3' apply false + id 'com.modrinth.minotaur' version '2.+' apply false + id 'com.matthewprenger.cursegradle' version '1.4.0' apply false +} +apply plugin: 'com.falsepattern.jtweaker' + +def out = services.get(StyledTextOutputFactory).create('an-output') + +apply plugin: 'forge' + +def projectJavaVersion = JavaLanguageVersion.of(8) + +java { + toolchain { + languageVersion.set(projectJavaVersion) + } +} + +idea { + module { + inheritOutputDirs = true + downloadJavadoc = true + downloadSources = true + } +} + +if(JavaVersion.current() != JavaVersion.VERSION_1_8) { + throw new GradleException("This project requires Java 8, but it's running on " + JavaVersion.current()) +} + +checkPropertyExists("modName") +checkPropertyExists("modId") +checkPropertyExists("modGroup") +checkPropertyExists("autoUpdateBuildScript") +checkPropertyExists("minecraftVersion") +checkPropertyExists("forgeVersion") +checkPropertyExists("replaceGradleTokenInFile") +checkPropertyExists("gradleTokenModId") +checkPropertyExists("gradleTokenModName") +checkPropertyExists("gradleTokenVersion") +checkPropertyExists("gradleTokenGroupName") +checkPropertyExists("apiPackage") +checkPropertyExists("accessTransformersFile") +checkPropertyExists("usesMixins") +checkPropertyExists("mixinPlugin") +checkPropertyExists("mixinsPackage") +checkPropertyExists("coreModClass") +checkPropertyExists("containsMixinsAndOrCoreModOnly") +checkPropertyExists("usesShadowedDependencies") +checkPropertyExists("developmentEnvironmentUserName") + +//Properties added in fork +propertyDefaultIfUnset("skipBuildScriptUpdateCheck", false) +propertyDefaultIfUnset("repositoryURL", "") +propertyDefaultIfUnset("repositoryName", "") +propertyDefaultIfUnset("mavenGroupId", "") +propertyDefaultIfUnset("mavenArtifactId", "") +propertyDefaultIfUnset("hasMixinDeps", false) +propertyDefaultIfUnset("mixinConfigs", "") +propertyDefaultIfUnset("mixinPluginPreInit", "") +propertyDefaultIfUnset("mixinPluginMinimumVersion", "0.8.5") +propertyDefaultIfUnset("remapStubs", false) + +propertyDefaultIfUnset("modrinthProjectId", "") +propertyDefaultIfUnset("modrinthDependencies", "") +propertyDefaultIfUnset("curseForgeProjectId", "") +propertyDefaultIfUnset("curseForgeRelations", "") +propertyDefaultIfUnset("changelog", "") + +propertyDefaultIfUnset("remoteMappings", "https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/") +propertyDefaultIfUnset("mappingsChannel", "stable") +propertyDefaultIfUnset("mappingsVersion", "12") + +String javaSourceDir = "src/main/java/" +String scalaSourceDir = "src/main/scala/" +String kotlinSourceDir = "src/main/kotlin/" + +String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") +String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") +String targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") +if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) { + throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin) +} + +if(apiPackage) { + targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) { + throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin) + } +} + +if(accessTransformersFile) { + String targetFile = "src/main/resources/META-INF/" + accessTransformersFile + if(!getFile(targetFile).exists()) { + throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile) + } +} + +if(usesMixins.toBoolean()) { + if(mixinsPackage.isEmpty()) { + throw new GradleException("\"usesMixins\" requires \"mixinsPackage\" to be set!") + } + + targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/") + targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/") + targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/") + if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) { + throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin) + } + + if (!mixinPlugin.isEmpty()) { + String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java" + String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".scala" + String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java" + String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".kt" + if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) { + throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin) + } + } +} + +if(coreModClass) { + String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java" + String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".scala" + String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java" + String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".kt" + if(!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) { + throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin) + } +} + +configurations.all { + resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS) + + // Make sure GregTech build won't time out + System.setProperty("org.gradle.internal.http.connectionTimeout", 120000 as String) + System.setProperty("org.gradle.internal.http.socketTimeout", 120000 as String) +} + +// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version +try { + 'git config core.fileMode false'.execute() +} +catch (Exception ignored) { + out.style(Style.Failure).println("git isn't installed at all") +} + +// Pulls version first from the VERSION env and then git tag +String identifiedVersion +String versionOverride = System.getenv("VERSION") ?: null +try { + identifiedVersion = versionOverride == null ? gitVersion() : versionOverride +} +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' + + '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 = identifiedVersion +ext { + modVersion = identifiedVersion +} + +if(identifiedVersion == versionOverride) { + out.style(Style.Failure).text('Override version to ').style(Style.Identifier).text(modVersion).style(Style.Failure).println('!\7') +} + +group = modGroup +if(project.hasProperty("customArchiveBaseName") && customArchiveBaseName) { + archivesBaseName = customArchiveBaseName +} +else { + archivesBaseName = modId +} +archivesBaseName += "-mc" + minecraftVersion + +minecraft { + version = minecraftVersion + "-" + forgeVersion + "-" + minecraftVersion + runDir = "run" + + if (replaceGradleTokenInFile) { + for (file in replaceGradleTokenInFile.split(',')) { + replaceIn file + } + if(gradleTokenModId) { + replace gradleTokenModId, modId + } + if(gradleTokenModName) { + replace gradleTokenModName, modName + } + if(gradleTokenVersion) { + replace gradleTokenVersion, modVersion + } + if(gradleTokenGroupName) { + replace gradleTokenGroupName, modGroup + } + } +} + +if(file("addon.gradle").exists()) { + apply from: "addon.gradle" +} + +apply from: 'repositories.gradle' + +configurations { + for (config in [shadowImplementation, shadowCompile, shadeCompile]) { + implementation.extendsFrom(shadeCompile) + compileClasspath.extendsFrom(config) + runtimeClasspath.extendsFrom(config) + testCompileClasspath.extendsFrom(config) + testRuntimeClasspath.extendsFrom(config) + } +} + +repositories { + maven { + name = "Overmind forge repo mirror" + url = "https://gregtech.overminddl1.com/" + } + if(usesMixins.toBoolean() || hasMixinDeps.toBoolean()) { + maven { + name = "sponge" + url = "https://mvn.falsepattern.com/releases" + } + maven { + name = "sponge2" + url = "https://mvn.falsepattern.com/sponge" + } + } +} + +dependencies { + if(usesMixins.toBoolean()) { + annotationProcessor("org.ow2.asm:asm-debug-all:5.0.3") + annotationProcessor("com.google.guava:guava:24.1.1-jre") + annotationProcessor("com.google.code.gson:gson:2.8.6") + annotationProcessor("com.llamalad7:MixinExtras:0.1.1-gasstation") + annotationProcessor("org.spongepowered:mixin:0.8.5-gasstation_7") + compile("org.spongepowered:mixin:0.8.5-gasstation_7") + compile("com.llamalad7:MixinExtras:0.1.1-gasstation") + compile("com.falsepattern:00gasstation-mc1.7.10:0.5.1:dev") + runtimeClasspath('org.jetbrains:intellij-fernflower:1.2.1.16') + testRuntimeClasspath('org.jetbrains:intellij-fernflower:1.2.1.16') + } else if(hasMixinDeps.toBoolean()) { + runtime("com.llamalad7:MixinExtras:0.1.1-gasstation") + runtime("org.spongepowered:mixin:0.8.5-gasstation_7") + runtime("com.falsepattern:00gasstation-mc1.7.10:0.5.1:dev") + } + // Latest LWJGL + compile "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209" + compile "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209" + minecraftNatives "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209" + minecraftDeps "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209" + minecraftDeps "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209" +} + +apply from: 'dependencies.gradle' + +def mixinDir = new File(project.buildDir, 'mixins') +if (!mixinDir.exists()) { + mixinDir.mkdirs() +} +def mixingConfigRefMap = "mixins." + modId + ".refmap.json" +def srgFile = new File(project.buildDir, 'srgs/mcp-srg.srg') +def mixinSrg = new File(mixinDir, "${mixingConfigRefMap}.srg") +def mixinRefMap = new File(mixinDir, mixingConfigRefMap) + +task generateAssets { + if(usesMixins.toBoolean() && !mixinPlugin.isEmpty()) { + getFile("/src/main/resources/mixins." + modId + ".json").text = """{ + "required": true, + "minVersion": "${mixinPluginMinimumVersion}", + "package": "${modGroup}.${mixinsPackage}", + "plugin": "${modGroup}.${mixinPlugin}", + "refmap": "${mixingConfigRefMap}", + "target": "@env(${mixinPluginPreInit.toBoolean() ? "PREINIT": "DEFAULT"})", + "compatibilityLevel": "JAVA_8" +} + +""" + } +} + +task relocateShadowJar(type: ConfigureShadowRelocation) { + target = tasks.shadowJar + prefix = modGroup + ".shadow" +} + +shadowJar { + if (remapStubs.toBoolean()) { + dependsOn(removeStub) + } + project.configurations.shadeCompile.each { dep -> + from(project.zipTree(dep)) { + exclude 'META-INF', 'META-INF/**' + } + } + + manifest { + attributes(getManifestAttributes()) + } + + minimize() // This will only allow shading for actually used classes + configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile] + dependsOn(relocateShadowJar) +} + +jar { + if (remapStubs.toBoolean()) { + dependsOn(removeStub) + } + project.configurations.shadeCompile.each { dep -> + from(project.zipTree(dep)) { + exclude 'META-INF', 'META-INF/**' + } + } + + manifest { + attributes(getManifestAttributes()) + } + + if(usesShadowedDependencies.toBoolean()) { + dependsOn(shadowJar) + enabled = false + } +} + +reobf { + if(usesMixins.toBoolean()) { + addExtraSrgFile mixinSrg + } +} + +if(usesMixins.toBoolean()) { + tasks.compileJava { + options.compilerArgs += [ + '-Xlint:-processing', + "-AreobfSrgFile=${srgFile}", + "-AoutSrgFile=${mixinSrg}", + "-AoutRefMapFile=${mixinRefMap}" + ] + } +} + +runClient { + def arguments = [] + def jvmArguments = [] + + if (usesMixins.toBoolean()) { + arguments += [ + "--mods=" + Paths.get("$projectDir").resolve(minecraft.runDir).normalize().relativize(Paths.get("$projectDir/build/libs/$archivesBaseName-${version}.jar")) + ] + } + + if(usesMixins.toBoolean() || hasMixinDeps.toBoolean()) { + arguments += [ + "--tweakClass", "org.spongepowered.asm.launch.MixinTweaker" + ] + jvmArguments += [ + "-Dmixin.debug=true", "-Dmixin.debug.countInjections=true", "-Dmixin.debug.verbose=true", "-Dmixin.debug.export=true" + ] + } + + if(developmentEnvironmentUserName) { + arguments += [ + "--username", + developmentEnvironmentUserName + ] + } + + args(arguments) + jvmArgs(jvmArguments) +} + +runServer { + def arguments = [] + def jvmArguments = [] + + if (usesMixins.toBoolean()) { + arguments += [ + "--mods=" + Paths.get("$projectDir").resolve(minecraft.runDir).normalize().relativize(Paths.get("$projectDir/build/libs/$archivesBaseName-${version}.jar")) + ] + } + + if (usesMixins.toBoolean() || hasMixinDeps.toBoolean()) { + arguments += [ + "--tweakClass", "org.spongepowered.asm.launch.MixinTweaker" + ] + jvmArguments += [ + "-Dmixin.debug=true", "-Dmixin.debug.countInjections=true", "-Dmixin.debug.verbose=true", "-Dmixin.debug.export=true" + ] + } + + args(arguments) + jvmArgs(jvmArguments) +} + +tasks.withType(JavaExec).configureEach { + javaLauncher.set( + javaToolchains.launcherFor { + languageVersion = projectJavaVersion + } + ) +} + +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' + + // replace modVersion and minecraftVersion + expand "minecraftVersion": project.minecraft.version, + "modVersion": modVersion, + "modId": modId, + "modName": modName + } + + if(usesMixins.toBoolean()) { + from mixinRefMap + } + + // copy everything else that's not the mcmod.info + from(sourceSets.main.resources.srcDirs) { + exclude 'mcmod.info' + } +} + +def getManifestAttributes() { + def manifestAttributes = [:] + if(!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) { + manifestAttributes += ["FMLCorePluginContainsFMLMod": true] + } + + if(accessTransformersFile) { + manifestAttributes += ["FMLAT" : accessTransformersFile.toString()] + } + + if(coreModClass) { + manifestAttributes += ["FMLCorePlugin": modGroup + "." + coreModClass] + } + + if(usesMixins.toBoolean()) { + String[] configs = []; + if (!mixinPlugin.isEmpty()) { + configs += ["mixins.${modId}.json"]; + } + if (!mixinConfigs.isEmpty()) { + configs += [mixinConfigs]; + } + manifestAttributes += [ + "TweakClass" : "org.spongepowered.asm.launch.MixinTweaker", + "MixinConfigs" : String.join(",", configs), + "ForceLoadAsMod" : !containsMixinsAndOrCoreModOnly.toBoolean() + ] + } + return manifestAttributes +} + +task sourcesJar(type: Jar) { + from (sourceSets.main.allSource) + from (file("$projectDir/LICENSE")) + getArchiveClassifier().set('sources') +} + +task shadowDevJar(type: ShadowJar) { + if (remapStubs.toBoolean()) { + dependsOn(removeStub) + } + project.configurations.shadeCompile.each { dep -> + from(project.zipTree(dep)) { + exclude 'META-INF', 'META-INF/**' + } + } + + from sourceSets.main.output + getArchiveClassifier().set("dev") + + manifest { + attributes(getManifestAttributes()) + } + + minimize() // This will only allow shading for actually used classes + configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile] +} + +task relocateShadowDevJar(type: ConfigureShadowRelocation) { + target = tasks.shadowDevJar + prefix = modGroup + ".shadow" +} + +task circularResolverJar(type: Jar) { + dependsOn(relocateShadowDevJar) + dependsOn(shadowDevJar) + enabled = false +} + +task devJar(type: Jar) { + if (remapStubs.toBoolean()) { + dependsOn(removeStub) + } + project.configurations.shadeCompile.each { dep -> + from(project.zipTree(dep)) { + exclude 'META-INF', 'META-INF/**' + } + } + + from sourceSets.main.output + getArchiveClassifier().set("dev") + + manifest { + attributes(getManifestAttributes()) + } + + if(usesShadowedDependencies.toBoolean()) { + dependsOn(circularResolverJar) + enabled = false + } +} + +task apiJar(type: Jar) { + from (sourceSets.main.allSource) { + include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**' + } + + from (sourceSets.main.output) { + include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**' + } + + from (sourceSets.main.resources.srcDirs) { + include("LICENSE") + } + + getArchiveClassifier().set('api') +} + +task copySrgs(type: Copy, dependsOn: 'genSrgs') { + from plugins.getPlugin('forge').delayedFile('{SRG_DIR}') + include '**/*.srg' + into layout.buildDirectory.file('srgs') +} + +compileJava.dependsOn(copySrgs) + +artifacts { + archives sourcesJar + archives devJar + if(apiPackage) { + archives apiJar + } +} + +// 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 + +def getMavenSettingsCredentials = { + String userHome = System.getProperty( "user.home" ); + File mavenSettings = new File(userHome, ".m2/settings.xml") + def xmlSlurper = new XmlSlurper() + def output = xmlSlurper.parse(mavenSettings) + return output."servers"."server" +} + +def getCredentials = { + String username = System.getenv("MAVEN_DEPLOY_USER") + String password = System.getenv("MAVEN_DEPLOY_PASSWORD") + if (username == null) { + try { + def entries = getMavenSettingsCredentials() + for (entry in entries) { + if (entry."id".text() == repositoryName) { + return [username: entry.username.text(), password: entry.password.text()] + } + } + } catch (Exception ignored){} + return [username: "none", password: "none"] + } else { + return [username: username, password: password] + } +} + +//Publishing +publishing { + publications { + maven(MavenPublication) { + from components.java + if (usesShadowedDependencies.toBoolean()) { + artifact source: shadowJar, classifier: "" + } + if (!project.hasProperty("noPublishedSources") || !noPublishedSources) { + artifact source: sourcesJar, classifier: "sources" + } + artifact source: usesShadowedDependencies.toBoolean() ? shadowDevJar : devJar, classifier: "dev" + if (apiPackage) { + artifact source: apiJar, classifier: "api" + } + + groupId = mavenGroupId + artifactId = mavenArtifactId + "-mc" + minecraftVersion + version = modVersion + + // remove extra garbage from minecraft and minecraftDeps configuration + pom.withXml { + 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() { + badArtifacts[it.groupId.text()].contains(it.artifactId.text()) + }.each() { + it.parent().remove(it) + } + } + } + } + + repositories { + if (repositoryURL.trim() != "") { + maven { + name = repositoryName + url = repositoryURL + def creds = getCredentials() + credentials { + username = creds?.username ?: "none" + password = creds?.password ?: "none" + } + } + } + } +} + +tasks.withType(PublishToMavenRepository) { task -> + dependsOn("build") +} + +publishToMavenLocal.dependsOn("build") + +if (project.changelog == "") { + File changelogFile = new File(System.getenv("CHANGELOG_FILE") ?: "CHANGELOG.md") + if (changelogFile.exists()) { + project.changelog = changelogFile.getText("UTF-8") + } else { + project.changelog = "No changelog was provided." + } +} +project.changelog = project.changelog.replace("{version}", modVersion) + +if (curseForgeProjectId != "" && System.getenv("CURSEFORGE_TOKEN") != null) { + apply plugin: 'com.matthewprenger.cursegradle' + curseforge { + apiKey = System.getenv("CURSEFORGE_TOKEN") + project { + id = curseForgeProjectId + changelogType = "markdown" + changelog = project.changelog + releaseType = modVersion.contains("-a") ? "alpha" : modVersion.contains("-b") ? "beta" : "release" + addGameVersion project.minecraft.version + addGameVersion "Forge" + mainArtifact(jar) { + displayName = "$modName version: $modVersion" + } + } + options { + javaIntegration = false + forgeGradleIntegration = false + } + } + if (curseForgeRelations.size() != 0) { + String[] deps = curseForgeRelations.split(";") + deps.each { dep -> + if (dep.size() == 0) { + return + } + String[] parts = dep.split(":") + String type = parts[0] + String name = parts[1] + addCurseForgeRelation(type, name) + } + } + + if (usesMixins.toBoolean()) { + addCurseForgeRelation("requiredDependency", "gasstation") + } + tasks.curseforge.dependsOn(build) + tasks.publish.dependsOn(tasks.curseforge) +} + +if (modrinthProjectId != "" && System.getenv("MODRINTH_TOKEN") != null) { + apply plugin: 'com.modrinth.minotaur' + modrinth { + token = System.getenv("MODRINTH_TOKEN") + projectId = modrinthProjectId + versionNumber = modVersion + versionType = modVersion.contains("-a") ? "alpha" : modVersion.contains("-b") ? "beta" : "release" + changelog = project.changelog + uploadFile = jar + gameVersions = [project.minecraft.version] + loaders = ["forge"] + } + if (modrinthDependencies.size() != 0) { + String[] deps = modrinthDependencies.split(";") + deps.each { dep -> + if (dep.size() == 0) { + return + } + String[] parts = dep.split(":") + String[] qual = parts[0].split("-") + String scope = qual[0] + String type = qual[1] + String name = parts[1] + addModrinthDep(scope, type, name) + } + } + if (usesMixins.toBoolean()) { + addModrinthDep("required", "project", "cdeAhgfp") + } + tasks.modrinth.dependsOn(build) + tasks.publish.dependsOn(tasks.modrinth) +} + +def addModrinthDep(scope, type, name) { + com.modrinth.minotaur.dependencies.Dependency dep; + if (!(scope in ["required", "optional", "incompatible", "embedded"])) { + throw new Exception("Invalid modrinth dependency scope: " + scope) + } + switch (type) { + case "project": + dep = new ModDependency(name, scope) + break + case "version": + dep = new VersionDependency(name, scope) + break + default: + throw new Exception("Invalid modrinth dependency type: " + type) + } + project.modrinth.dependencies.add(dep) +} + +def addCurseForgeRelation(type, name) { + if (!(type in ["requiredDependency", "embeddedLibrary", "optionalDependency", "tool", "incompatible"])) { + throw new Exception("Invalid CurseForge relation type: " + type) + } + CurseArtifact artifact = project.curseforge.curseProjects[0].mainArtifact + CurseRelation rel = (artifact.curseRelations ?: (artifact.curseRelations = new CurseRelation())) + rel."$type"(name) +} + +// Updating +task updateBuildScript { + doLast { + if (performBuildScriptUpdate(projectDir.toString())) return + + print("Build script already up-to-date!") + } +} + +if (!project.getGradle().startParameter.isOffline() && !skipBuildScriptUpdateCheck.toBoolean() && isNewBuildScriptVersionAvailable(projectDir.toString())) { + if (autoUpdateBuildScript.toBoolean()) { + performBuildScriptUpdate(projectDir.toString()) + } else { + out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'") + } +} + +static URL availableBuildScriptUrl() { + new URL("https://raw.githubusercontent.com/FalsePattern/ExampleMod1.7.10/main/build.gradle") +} + +boolean performBuildScriptUpdate(String projectDir) { + if (isNewBuildScriptVersionAvailable(projectDir)) { + def buildscriptFile = getFile("build.gradle") + availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } } + out.println("Build script updated. Please REIMPORT the project or RESTART your IDE!") + return true + } + return false +} + +boolean isNewBuildScriptVersionAvailable(String projectDir) { + Map parameters = ["connectTimeout": 2000, "readTimeout": 2000] + + String currentBuildScript = getFile("build.gradle").getText() + String currentBuildScriptHash = getVersionHash(currentBuildScript) + String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText() + String availableBuildScriptHash = getVersionHash(availableBuildScript) + + boolean isUpToDate = currentBuildScriptHash.empty || availableBuildScriptHash.empty || currentBuildScriptHash == availableBuildScriptHash + return !isUpToDate +} + +static String getVersionHash(String buildScriptContent) { + String versionLine = buildScriptContent.find("^//version: [a-z0-9]*") + if(versionLine != null) { + return versionLine.split(": ").last() + } + return "" +} + +configure(updateBuildScript) { + group = 'forgegradle' + description = 'Updates the build script to the latest version' +} + +// Parameter Deobfuscation + +task deobfParams { + doLast { + + String mcpDir = "$project.gradle.gradleUserHomeDir/caches/minecraft/de/oceanlabs/mcp/mcp_$mappingsChannel/$mappingsVersion" + String mcpZIP = "$mcpDir/mcp_$mappingsChannel-$mappingsVersion-${minecraftVersion}.zip" + String paramsCSV = "$mcpDir/params.csv" + + download.run { + src "https://maven.minecraftforge.net/de/oceanlabs/mcp/mcp_$mappingsChannel/$mappingsVersion-$minecraftVersion/mcp_$mappingsChannel-$mappingsVersion-${minecraftVersion}.zip" + dest mcpZIP + overwrite false + } + + if(!file(paramsCSV).exists()) { + println("Extracting MCP archive ...") + unzip(mcpZIP, mcpDir) + } + + println("Parsing params.csv ...") + Map params = new HashMap<>() + Files.lines(Paths.get(paramsCSV)).forEach{line -> + String[] cells = line.split(",") + if(cells.length > 2 && cells[0].matches("p_i?\\d+_\\d+_")) { + params.put(cells[0], cells[1]) + } + } + + out.style(Style.Success).println("Modified ${replaceParams(file("$projectDir/src/main/java"), params)} files!") + out.style(Style.Failure).println("Don't forget to verify that the code still works as before!\n It could be broken due to duplicate variables existing now\n or parameters taking priority over other variables.") + } +} + +static int replaceParams(File file, Map params) { + int fileCount = 0 + + if(file.isDirectory()) { + for(File f : file.listFiles()) { + fileCount += replaceParams(f, params) + } + return fileCount + } + println("Visiting ${file.getName()} ...") + try { + String content = new String(Files.readAllBytes(file.toPath())) + int hash = content.hashCode() + params.forEach{key, value -> + content = content.replaceAll(key, value) + } + if(hash != content.hashCode()) { + Files.write(file.toPath(), content.getBytes("UTF-8")) + return 1 + } + } catch(Exception e) { + e.printStackTrace() + } + return 0 +} + +// Credit: bitsnaps (https://gist.github.com/bitsnaps/00947f2dce66f4bbdabc67d7e7b33681) +static unzip(String zipFileName, String outputDir) { + byte[] buffer = new byte[16384] + ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName)) + ZipEntry zipEntry = zis.getNextEntry() + while (zipEntry != null) { + File newFile = new File(outputDir + File.separator, zipEntry.name) + if (zipEntry.isDirectory()) { + if (!newFile.isDirectory() && !newFile.mkdirs()) { + throw new IOException("Failed to create directory $newFile") + } + } else { + // fix for Windows-created archives + File parent = newFile.parentFile + if (!parent.isDirectory() && !parent.mkdirs()) { + throw new IOException("Failed to create directory $parent") + } + // write file content + FileOutputStream fos = new FileOutputStream(newFile) + int len = 0 + while ((len = zis.read(buffer)) > 0) { + fos.write(buffer, 0, len) + } + fos.close() + } + zipEntry = zis.getNextEntry() + } + zis.closeEntry() + zis.close() +} + +configure(deobfParams) { + group = 'forgegradle' + description = 'Rename all obfuscated parameter names inherited from Minecraft classes' +} + +// Dependency Deobfuscation + +def deobfMaven(mavenDep) { + throw new GradleException("deobfMaven(mavenDep) is deprecated. " + + "You must use the new deobfMaven(repoURL, mavenDep) method instead." + + "The old method broke the buildscript when used.") +} + +def deobfMaven(String repoURL, String mavenDep) { + if (!repoURL.endsWith("/")) { + repoURL += "/" + } + String[] parts = mavenDep.split(":") + parts[0] = parts[0].replace('.', '/') + def jarURL = repoURL + parts[0] + "/" + parts[1] + "/" + parts[2] + "/" + parts[1] + "-" + parts[2] + ".jar" + return deobf(jarURL) +} + +def deobf(String sourceURL) { + try { + URL url = new URL(sourceURL) + String fileName = url.getFile() + + //get rid of directories: + int lastSlash = fileName.lastIndexOf("/") + if(lastSlash > 0) { + fileName = fileName.substring(lastSlash + 1) + } + //get rid of extension: + if(fileName.endsWith(".jar") || fileName.endsWith(".litemod")) { + fileName = fileName.substring(0, fileName.lastIndexOf(".")) + } + + String hostName = url.getHost() + if(hostName.startsWith("www.")) { + hostName = hostName.substring(4) + } + List parts = Arrays.asList(hostName.split("\\.")) + Collections.reverse(parts) + hostName = String.join(".", parts) + + return deobf(sourceURL, "$hostName/$fileName") + } catch(Exception e) { + return deobf(sourceURL, "deobf/${sourceURL.hashCode()}") + } +} + +// The method above is to be preferred. Use this method if the filename is not at the end of the URL. +def deobf(String sourceURL, String rawFileName) { + String bon2Version = "2.5.1" + String fileName = URLDecoder.decode(rawFileName, "UTF-8") + String cacheDir = "$project.gradle.gradleUserHomeDir/caches" + String bon2Dir = "$cacheDir/forge_gradle/deobf" + String bon2File = "$bon2Dir/BON2-${bon2Version}.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) + } + + String mappingsVer + if(remoteMappings) { + String id = "${forgeVersion.split("\\.")[3]}-$minecraftVersion" + String mappingsZIP = "$cacheDir/forge_gradle/maven_downloader/de/oceanlabs/mcp/mcp_snapshot_nodoc/$id/mcp_snapshot_nodoc-${id}.zip" + + zipMappings(mappingsZIP, remoteMappings, bon2Dir) + + mappingsVer = "snapshot_$id" + } else { + mappingsVer = "${mappingsChannel}_$mappingsVersion" + } + + download.run { + src "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases/com/github/parker8283/BON2/$bon2Version-CUSTOM/BON2-$bon2Version-CUSTOM-all.jar" + dest bon2File + quiet true + overwrite false + } + + download.run { + src sourceURL + dest obfFile + quiet true + overwrite false + } + + exec { + commandLine Paths.get(System.getProperty("java.home"), "bin", "java").toAbsolutePath().toString(), '-jar', bon2File, '--inputJar', obfFile, '--outputJar', deobfFile, '--mcVer', minecraftVersion, '--mappingsVer', mappingsVer, '--notch' + workingDir bon2Dir + standardOutput = new FileOutputStream("${deobfFile}.log") + } + + return files(deobfFile) +} + +def zipMappings(String zipPath, String url, String bon2Dir) { + File zipFile = new File(zipPath) + if(zipFile.exists()) { + return + } + + String fieldsCache = "$bon2Dir/data/fields.csv" + String methodsCache = "$bon2Dir/data/methods.csv" + + download.run { + src "${url}fields.csv" + dest fieldsCache + quiet true + } + download.run { + src "${url}methods.csv" + dest methodsCache + quiet true + } + + zipFile.getParentFile().mkdirs() + ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile)) + + zos.putNextEntry(new ZipEntry("fields.csv")) + Files.copy(Paths.get(fieldsCache), zos) + zos.closeEntry() + + zos.putNextEntry(new ZipEntry("methods.csv")) + Files.copy(Paths.get(methodsCache), zos) + zos.closeEntry() + + zos.close() +} + +// Helper methods + +def checkPropertyExists(String propertyName) { + 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/FalsePattern/ExampleMod1.7.10/blob/main/gradle.properties") + } +} + +def propertyDefaultIfUnset(String propertyName, defaultValue) { + if (!project.hasProperty(propertyName)) { + System.err.println("Your gradle.properties is missing the $propertyName entry. It has been automatically set to \"$defaultValue\" as fallback. You can find all properties and their description here: https://github.com/FalsePattern/ExampleMod1.7.10/blob/main/gradle.properties") + } + if (!project.hasProperty(propertyName) || project.property(propertyName) == "") { + project.ext.setProperty(propertyName, defaultValue) + } +} + +def getFile(String relativePath) { + return new File(projectDir, relativePath) +} + +if(file("addon_final.gradle").exists()) { + apply from: "addon_final.gradle" +} \ No newline at end of file diff --git a/dependencies.gradle b/dependencies.gradle new file mode 100644 index 0000000..2c40c12 --- /dev/null +++ b/dependencies.gradle @@ -0,0 +1,9 @@ +dependencies { + compileOnly("org.projectlombok:lombok:[1.18.24,1.19)") { + transitive = false + } + annotationProcessor("org.projectlombok:lombok:[1.18.24,1.19)") + + implementation("com.falsepattern:falsepatternlib-mc1.7.10:[0.10.15,0.11):dev") + +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..518680d --- /dev/null +++ b/gradle.properties @@ -0,0 +1,214 @@ +# Mod settings +#region mod + +modName = ChunkAPI + +# This is a case-sensitive string to identify your mod. Convention is to use lower case. +modId = fplib_chunkapi + +# The "root package" of your mod. All of your mod classes *should* be placed under this package for simplicity. +modGroup = com.falsepattern.chunk + +# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can +# leave this property empty. +# Example value: apiPackage = api + modGroup = com.falsepattern.chunk -> com.falsepattern.chunk.api +apiPackage = api + +# WHY is there no version field? +# The build script relies on git to provide a version via tags. It is super easy and will enable you to always know the +# code base or your binary. Check out this tutorial: https://blog.mattclemente.com/2017/10/13/versioning-with-git-tags/ +# However, if you really want to, you can use the VERSION environment variable to override this. + +minecraftVersion = 1.7.10 +forgeVersion = 10.13.4.1614 + +# Select a username for testing your mod with breakpoints. You may leave this empty for a random username each time you +# restart Minecraft in development. Choose this dependent on your mod: +# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name +# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty +developmentEnvironmentUserName = Developer + +#endregion mod + +# Publishing settings +#region publishing + +# Note: Both the modrinth and the curseforge publications are invoked by the "publish" gradle task +# (when the respective publication's project ID is set up correctly, of course). You don't need to individually run +# each of them. + +# Maven publishing +#region maven + +# The maven server to upload the artifacts to +repositoryURL = https://mvn.falsepattern.com/releases/ + +# What name is the login information inside ~/.m2/settings.xml stored under +# (see https://gist.github.com/FalsePattern/82d93e3cfab01f671cc5f4a95931cfe3 for an example) +# You can also use the MAVEN_DEPLOY_USER and MAVEN_DEPLOY_PASSWORD environment variables to set this information! +repositoryName = mavenpattern + +# What the artifact should be called. These will be the "name" of the published package, suffixed with the minecraft +# version with a -mc prefix (groupid:artifactid-mcminecraftVersion:version:qualifier). +# For instance, the default values this example ships with would turn into com.falsepattern:mymodid-mc1.7.10:version +# The version is determined automatically from the git version. +mavenGroupId = com.falsepattern +mavenArtifactId = chunkapi + +#endregion maven + +# Modrinth publishing +#region modrinth + +# Publishing to modrinth requires you to set the MODRINTH_TOKEN environment variable to your current modrinth API token. + +# The project's ID on Modrinth. Can be either the slug or the ID. +# Leave this empty if you don't want to publish on Modrinth. +modrinthProjectId = + +# The project's dependencies on Modrinth. You can use this to refer to other projects on Modrinth. +# Syntax: scope1-type1:name1;scope2-type2:name2;... +# Where scope can be one of [required, optional, incompatible, embedded], +# type can be one of [project, version], +# and the name is the Modrinth project or version slug/id of the other mod. +# Example: required-project:fplib;incompatible-project:gregtech +# Note: GasStation is automatically set as a required dependency if usesMixins = true +modrinthDependencies = + +#endregion modrinth + +# CurseForge publishing +#region curseforge + +# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens. + +# The project's numeric ID on CurseForge. You can find this in the About Project box. +# Leave this empty if you don't want to publish on CurseForge. +curseForgeProjectId = + +# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge. +# Syntax: type1:name1;type2:name2;... +# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible], +# and the name is the CurseForge project id of the other mod. +# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft +# Note: GasStation is automatically set as a required dependency if usesMixins = true +curseForgeRelations = + +#endregion curseforge + +# This will be inserted as the changelog text in the Modrinth/CurseForge publications. +# If the text contains "{version}", it will be replaced with the current mod version. This is useful when the changelog +# is just a URL pointing to a GitHub release tag. +# If left empty, the changelog will be attempted to be read from the file at the CHANGELOG_FILE environment variable, +# or the CHANGELOG.md file in the project root if the variable is not set. +# If neither this property, nor the file, nor the environment variable (or the file it points to) exist, the changelog +# will be set to "No changelog was provided.". +# Example: https://github.com/myname/mymod/releases/tag/{version} +changelog = + +# endregion publishing + +# Buildscript automatic update checker settings +#region autoupdates + +# Will update your build.gradle automatically whenever an update is available +autoUpdateBuildScript = false +# Disable checking of buildscript updates. +skipBuildScriptUpdateCheck = false + +#endregion autoupdates + +# Gradle token strings +#region gradletokens + +# Define a source file of your project with: +# public static final String VERSION = "GRADLETOKEN_VERSION"; +# The string's content will be replaced with your mods version when compiled. You should use this to specify your mod's +# version in @Mod([...], version = VERSION, [...]) +# Leave these properties empty to skip individual token replacements +# Multiple source files can be defined here by providing a comma-seperated list: Class1.java,Class2.java,Class3.java +replaceGradleTokenInFile = Tags.java +gradleTokenModId = GRADLETOKEN_MODID +gradleTokenModName = GRADLETOKEN_MODNAME +gradleTokenVersion = GRADLETOKEN_VERSION +gradleTokenGroupName = GRADLETOKEN_GROUPNAME + +#endregion gradletokens + +# Mixins +#region mixins + +# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled! +# When this is enabled, the mixinPlugin, mixinPluginPreInit, mixinsPackage, and mixinConfigs properties become active. +usesMixins = true +# Enable this if one of the dependencies uses mixins. Note: if usesMixins is true, this property is ignored. Only use this +# if a dependency requires mixins BUT this mod doesn't. +hasMixinDeps = false +# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise. +mixinPlugin = mixin.plugin.MixinPlugin +# Whether you want the plugin to be configured as a PREINIT mixin +mixinPluginPreInit = false +# The minimum SpongePowered Mixins version required by the plugin. Internal default is 0.8.5 (GasStation) +mixinPluginMinimumVersion = +# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail! +mixinsPackage = mixin.mixins +# Specify any custom mixin .json configs here. If you have multiple, comma-separate them. If you don't want to load +# any jsons manually, leave this empty. You can use custom configs even if you already have a plugin added. +# note: mixins..json is used by the mixinPlugin's autogenerated config. Additionally, the refmap from the mixinsPackage +# is always put into mixins..refmap.json. +# example: mixins.foo.json,mixins.bar.json +mixinConfigs = + +#endregion mixins + +# Coremod and access transformers +#region core + +# Specify the configuration file for Forge's access transformers here. I must be placed into /src/main/resources/META-INF/ +# Example value: mymodid_at.cfg +accessTransformersFile = + +# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin! +# This parameter is for legacy compatibility only +# Example value: coreModClass = asm.FMLPlugin + modGroup = com.falsepattern.chunk -> com.falsepattern.chunk.asm.FMLPlugin +coreModClass = + +#endregion core + +# Dependency deobfuscation settings (advanced) +#region ddeobf + +# These 3 entries specify the location where the SRG mappings should be fetched from. Only set these if you know +# what you're doing. The defaults inside the buildscript should just work without any extra configuration. +remoteMappings = +mappingsChannel = +mappingsVersion = + +#endregion ddeobf + +# Miscellaneous settings +#region misc + +# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class +# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false! +containsMixinsAndOrCoreModOnly = false + +# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your +# responsibility check the licence and request permission for distribution, if required. +usesShadowedDependencies = false + +# If enabled, class stubbing will be enabled. In this mode, all classes with a package named "stubpackage" in their +# path will be removed, and all classes that refer to said classes will be modified so that the "stubpackage" will map +# to the root package instead. This is useful for referring to compile-time inaccessible classes, such as classes in the +# default package +remapStubs = false + +# Set this to true if you want to publish a proprietary mod without visible source code. +#noPublishedSources = + +# Optional parameter to customize the produced artifacts. Use this to preserver artifact naming when migrating older +# projects. New projects should not use this parameter. +#customArchiveBaseName = + +#endregion misc + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..5c2d1cf Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..3ab0b72 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..83f2acf --- /dev/null +++ b/gradlew @@ -0,0 +1,188 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..9618d8d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/repositories.gradle b/repositories.gradle new file mode 100644 index 0000000..b79651c --- /dev/null +++ b/repositories.gradle @@ -0,0 +1,6 @@ +repositories { + maven { + name = "mvnpattern" + url = "https://mvn.falsepattern.com/releases" + } +} diff --git a/src/main/java/com/falsepattern/chunk/ChunkAPI.java b/src/main/java/com/falsepattern/chunk/ChunkAPI.java new file mode 100644 index 0000000..17ee8f6 --- /dev/null +++ b/src/main/java/com/falsepattern/chunk/ChunkAPI.java @@ -0,0 +1,11 @@ +package com.falsepattern.chunk; + +import cpw.mods.fml.common.Mod; + +@Mod(modid = Tags.MODID, + version = Tags.VERSION, + name = Tags.MODNAME, + acceptedMinecraftVersions = "[1.7.10]", + dependencies = "required-after:falsepatternlib@[0.10.15,);") +public class ChunkAPI { +} \ No newline at end of file diff --git a/src/main/java/com/falsepattern/chunk/Common.java b/src/main/java/com/falsepattern/chunk/Common.java new file mode 100644 index 0000000..f2152f3 --- /dev/null +++ b/src/main/java/com/falsepattern/chunk/Common.java @@ -0,0 +1,11 @@ +package com.falsepattern.chunk; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * Non-minecraft stuff to avoid accidental classloading in spaghetti code + */ +public class Common { + public static final Logger LOG = LogManager.getLogger(Tags.MODID); +} diff --git a/src/main/java/com/falsepattern/chunk/Tags.java b/src/main/java/com/falsepattern/chunk/Tags.java new file mode 100644 index 0000000..46e1f2b --- /dev/null +++ b/src/main/java/com/falsepattern/chunk/Tags.java @@ -0,0 +1,8 @@ +package com.falsepattern.chunk; + +public class Tags { + public static final String MODID = "GRADLETOKEN_MODID"; + public static final String MODNAME = "GRADLETOKEN_MODNAME"; + public static final String VERSION = "GRADLETOKEN_VERSION"; + public static final String GROUPNAME = "GRADLETOKEN_GROUPNAME"; +} \ No newline at end of file diff --git a/src/main/java/com/falsepattern/chunk/mixin/plugin/Mixin.java b/src/main/java/com/falsepattern/chunk/mixin/plugin/Mixin.java new file mode 100644 index 0000000..b376a4b --- /dev/null +++ b/src/main/java/com/falsepattern/chunk/mixin/plugin/Mixin.java @@ -0,0 +1,47 @@ +/* + * FalseTweaks + * + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + * + * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.falsepattern.chunk.mixin.plugin; + +import com.falsepattern.lib.mixin.IMixin; +import com.falsepattern.lib.mixin.ITargetedMod; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.function.Predicate; + +@RequiredArgsConstructor +public enum Mixin implements IMixin { + // @formatter:off + ; + // @formatter:on + + @Getter + private final Side side; + @Getter + private final Predicate> filter; + @Getter + private final String mixin; +} + diff --git a/src/main/java/com/falsepattern/chunk/mixin/plugin/MixinPlugin.java b/src/main/java/com/falsepattern/chunk/mixin/plugin/MixinPlugin.java new file mode 100644 index 0000000..32edb43 --- /dev/null +++ b/src/main/java/com/falsepattern/chunk/mixin/plugin/MixinPlugin.java @@ -0,0 +1,46 @@ +/* + * FalseTweaks + * + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + * + * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.falsepattern.chunk.mixin.plugin; + +import com.falsepattern.chunk.Tags; +import com.falsepattern.lib.mixin.IMixin; +import com.falsepattern.lib.mixin.IMixinPlugin; +import com.falsepattern.lib.mixin.ITargetedMod; +import lombok.Getter; +import org.apache.logging.log4j.Logger; + +public class MixinPlugin implements IMixinPlugin { + @Getter + private final Logger logger = IMixinPlugin.createLogger(Tags.MODNAME); + + @Override + public ITargetedMod[] getTargetedModEnumValues() { + return TargetedMod.values(); + } + + @Override + public IMixin[] getMixinEnumValues() { + return Mixin.values(); + } +} diff --git a/src/main/java/com/falsepattern/chunk/mixin/plugin/TargetedMod.java b/src/main/java/com/falsepattern/chunk/mixin/plugin/TargetedMod.java new file mode 100644 index 0000000..2ba3f0a --- /dev/null +++ b/src/main/java/com/falsepattern/chunk/mixin/plugin/TargetedMod.java @@ -0,0 +1,42 @@ +/* + * FalseTweaks + * + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + * + * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.falsepattern.chunk.mixin.plugin; + +import com.falsepattern.lib.mixin.ITargetedMod; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.function.Predicate; + +@RequiredArgsConstructor +public enum TargetedMod implements ITargetedMod { + ; + + @Getter + private final String modName; + @Getter + private final boolean loadInDevelopment; + @Getter + private final Predicate condition; +} diff --git a/src/main/resources/LICENSE b/src/main/resources/LICENSE new file mode 100644 index 0000000..cf3b250 --- /dev/null +++ b/src/main/resources/LICENSE @@ -0,0 +1,63 @@ +#------------------------------------------------------------------------------- +# @author FalsePattern +# +# Copyright 2023 +# +# All rights reserved. +# Distribution of the software in any form is only allowed with +# explicit, prior permission from the owner. +#------------------------------------------------------------------------------- +@author FalsePattern + + +This code is the property of and owned and copyrighted by FalsePattern. +This code is provided under a modified visible-source license +that is as follows: + + +API Code: +============================== +API code is identifiable as being in an "API" package in the respective +repository or mod, and is intended to allow some level of inter-mod +interactions without creating hard dependencies on the mod proper. This code +is exempt from the below restrictions for "Mod Code", as it by nature will +require some level of copying and redistribution. + +The only restrictions imposed on API code are that it remain clearly marked +with its original authorship and source, that it be used for the purpose +described previously, and that it not be modified from the original without +first contacting FalsePattern. + + +Mod Code: +============================== +Any and all users are permitted to use the source for educational purposes, +or to create derivative works for private use only. GitHub forks and direct +downloads are considered derivative works. + +Unless given explicit written permission - verifiable electronic writing is +acceptable - no user may redistribute this source code nor any derivative +works. These pre-approved works must prominently contain this copyright notice. + +Derivative mods using any or all of the source code or assets are +EXPRESSLY FORBIDDEN. + +Additionally, no attempt may be made to achieve monetary gain from this code +by anyone except the original author. In the case of pre-approved derivative +works, any monetary gains made will be shared between the original author and +the other developer(s), proportional to the ratio of derived to original code. + +Finally, any and all displays, duplicates or derivatives of this code must be +prominently marked as such, and must contain attribution to the original +author, including a link to the original source. Any attempts to claim credit +for this code will be treated as intentional theft. + +Due to the Mojang and Minecraft Mod Terms of Service and Licensing +Restrictions, compiled versions of this code must be provided for free. +However, with the exception of pre-approved derivative works, only the original +author's modpacks may distribute compiled binary versions of this code. + +============================== + +Failure to comply with these restrictions is a violation of copyright law and +will be dealt with accordingly. \ No newline at end of file diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info new file mode 100644 index 0000000..96fab70 --- /dev/null +++ b/src/main/resources/mcmod.info @@ -0,0 +1,16 @@ +[ + { + "modid": "${modId}", + "name": "${modName}", + "description": "A chunk data hooking library.", + "version": "${modVersion}", + "mcversion": "${minecraftVersion}", + "url": "https://github.com/FalsePattern/ChunkAPI", + "updateUrl": "", + "authorList": ["FalsePattern"], + "credits": "", + "logoFile": "", + "screenshots": [], + "dependencies": [] + } +] diff --git a/src/main/resources/mixins.fplib_chunkapi.json b/src/main/resources/mixins.fplib_chunkapi.json new file mode 100644 index 0000000..f05b1b9 --- /dev/null +++ b/src/main/resources/mixins.fplib_chunkapi.json @@ -0,0 +1,10 @@ +{ + "required": true, + "minVersion": "0.8.5", + "package": "com.falsepattern.chunk.mixin.mixins", + "plugin": "com.falsepattern.chunk.mixin.plugin.MixinPlugin", + "refmap": "mixins.fplib_chunkapi.refmap.json", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8" +} +