buildscript { repositories { mavenCentral() maven { name = "forge" url = "http://files.minecraftforge.net/maven" } maven { name = "sonatype" url = "https://oss.sonatype.org/content/repositories/snapshots/" } maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' classpath "gradle.plugin.net.minecrell:licenser:0.2.1" } } apply plugin: 'net.minecraftforge.gradle.forge' apply plugin: 'maven' apply plugin: 'maven-publish' apply plugin: net.minecrell.gradle.licenser.Licenser sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { maven { name = "Modmuss50" url = "http://maven.modmuss50.me/" } maven { // JEI, TiC name "TiC" url "http://dvs1.progwml6.com/files/maven" } maven { name = "Amadornes" url "http://maven.amadornes.com/" } maven { // CraftTweaker2 name "Jared" url "http://maven.blamejared.com/" } maven { // TheOneProbe url "http://maven.tterrag.com/" } maven { // IC2 name = "ic2" url = "http://maven.ic2.player.to/" } maven { // HWYLA name "TehNut" url "http://tehnut.info/maven/" } maven { name 'CB Repo' url "http://chickenbones.net/maven/" } maven { // CoFH name 'Covers' url "http://maven.covers1624.net/" } ivy { name "BuildCraft" artifactPattern "http://www.mod-buildcraft.com/releases/BuildCraft/[revision]/[module]-[revision].[ext]" } maven { name "OpenComputer" url "http://maven.cil.li/" } } configurations { shade compile.extendsFrom shade } version = "2.17.1" def ENV = System.getenv() if (ENV.BUILD_NUMBER) { version = version + "." + "${System.getenv().BUILD_NUMBER}" } minecraft { version = "1.12.2-14.23.4.2705" mappings = "snapshot_20171003" replace "@MODVERSION@", project.version useDepAts = true runDir = "run" } license { header file('HEADER') include '**/*.java' ignoreFailures = true //Stops the build from failing if a file does not have a license header } group = 'TechReborn' dependencies { //Some dep we use wants the older jei, so this ingores it. We grab the latest anyway, so it shoudnt cause any issues. def withoutOldJEI = { exclude module: 'jei_1.12.2' } deobfCompile('RebornCore:RebornCore-1.12.2:+:universal') { transitive = false } compile "mcp.mobius.waila:Hwyla:+" compile "CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.0.12.323" compile name: 'buildcraft', version: '7.99.17', ext: 'jar' deobfCompile "mezz.jei:jei_1.12.2:+" deobfCompile "mcjty.theoneprobe:TheOneProbe-1.12:1.12-1.4.19-11" deobfCompile 'net.industrial-craft:industrialcraft-2:2.8.+' deobfCompile 'cofh:ThermalDynamics:1.12.2-2.5+:universal' deobfCompile 'cofh:ThermalExpansion:1.12.2-5.5+:universal' deobfCompile 'MCMultiPart2:MCMultiPart:2.4.1' deobfCompile "li.cil.oc:OpenComputers:MC1.12.2-1.7.2+" deobfCompile "blusunrize:ImmersiveEngineering:0.12-+:deobf" } 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 version and mcversion expand 'version': project.version, 'mcversion': project.minecraft.version } // copy everything else, thats not the mcmod.info from(sourceSets.main.resources.srcDirs) { exclude 'mcmod.info' } // Move access transformers to META-INF rename '(.+_at.cfg)', 'META-INF/$1' } task deobfJar(type: Jar) { from sourceSets.main.output exclude "**/*.psd" classifier = 'dev' manifest { attributes 'FMLAT': 'techreborn_at.cfg' } } jar { exclude "**/*.psd" classifier = 'universal' // configurations.shade.each { dep -> // from(project.zipTree(dep)){ // include 'ic2/api/' // include 'forestry/api/fuels/' // exclude 'META-INF', 'META-INF/**', '**/*.java' // } // } manifest { attributes 'FMLAT': 'techreborn_at.cfg' } from { crowdin.getDidWork() ? fileTree('build/translations').matching{exclude "**/en_US.lang"} : null} dependsOn 'renameCrowdin' } task apiJar(type: Jar) { from sourceSets.main.allSource from sourceSets.main.output include 'techreborn/api/**/*' classifier = "api" } apiJar.mustRunAfter deobfJar build.dependsOn deobfJar, apiJar //Taken from forge build script task crowdin(type: CrowdinDownload){ output = "build/translations.crowdin" projectId = 'techreborn' extract = true if (project.hasProperty('crowdinKey')) apiKey = project.crowdinKey } //Renames the translation files to be all lower case task renameCrowdin(type: Copy, dependsOn: 'crowdin'){ mustRunAfter 'crowdin' from crowdin.output into 'build/translations' rename { String filename -> return filename.toLowerCase() } } publishing { publications { maven(MavenPublication) { groupId 'TechReborn' artifactId project.archivesBaseName version project.version from components.java artifact apiJar { classifier "api" } artifact deobfJar { classifier "dev" } artifact sourceJar { classifier "sources" } //Removes all of the dependencies from the maven pom, fixes issues when other projects try to depend on tr pom.withXml { asNode().remove(asNode().get('dependencies')) } } } repositories { maven { url "http://mavenupload.modmuss50.me/" if (project.hasProperty('mavenPass')) { credentials { username 'buildslave' password project.getProperty('mavenPass') } } } } } //Thanks Matthew from #ForgeGradle https://gist.github.com/matthewprenger/108265e3efc83181bd2cc2d2fc31a853 task updateMappings(dependsOn: sourceJar) { def remapped = file('src_remapped/main/java') def methods = file('methods.csv') def fields = file('fields.csv') doLast { Map map = new HashMap<>() methods.eachLine {line -> String[] pts = line.split(",") map.put(pts[0], pts[1]) } fields.eachLine {line -> String[] pts = line.split(",") map.put(pts[0], pts[1]) } copy { from zipTree(sourceJar.archivePath) into remapped include '**/*.java' filter {javaLine -> map.entrySet().each {entry -> javaLine = javaLine.replace(entry.getKey(), entry.getValue()) } return javaLine } includeEmptyDirs = false eachFile {println "Processing: $it.name"} } } } task signJar(type: SignJar, dependsOn: reobfJar) { onlyIf { project.hasProperty('keyStore') } if (project.hasProperty('keyStore')) { keyStore = project.keyStore alias = project.keyStoreAlias storePass = project.keyStorePass keyPass = project.keyStoreKeyPass inputFile = jar.archivePath outputFile = jar.archivePath } } build.dependsOn signJar apply from: 'https://github.com/FabricMC/fabric-docs/raw/master/gradle/ideconfig.gradle' import com.google.gson.JsonArray import groovy.util.XmlSlurper import org.apache.commons.io.FileUtils task curseTools { doLast { def cacheFiles = new File(".gradle/curseTools") if (!cacheFiles.exists()) { cacheFiles.mkdirs() } def mavenMetadata = new File(cacheFiles, "maven-metadata.xml") logger.lifecycle(":downloading curseTools metadata") FileUtils.copyURLToFile(new URL("http://maven.modmuss50.me/CurseTools/CurseTools/maven-metadata.xml"), mavenMetadata) def metadata = new XmlSlurper().parseText(FileUtils.readFileToString(mavenMetadata)) def curseToolsVersion = metadata.versioning.release def curseTools = new File(cacheFiles, "${curseToolsVersion}.jar") logger.lifecycle(":downloading CurseTools") FileUtils.copyURLToFile(new URL("http://maven.modmuss50.me/CurseTools/CurseTools/${curseToolsVersion}/CurseTools-${curseToolsVersion}.jar"), curseTools) logger.lifecycle(":launching CurseTools") ant.java(jar: curseTools.getAbsolutePath(), fork: true, spawn: false) { arg(value: jar.archivePath.getAbsolutePath()) arg(value: deobfJar.archivePath.getAbsolutePath()) arg(value: apiJar.archivePath.getAbsolutePath()) } } } import com.google.gson.GsonBuilder import com.google.gson.JsonObject import org.apache.commons.io.IOUtils import java.util.zip.ZipFile //Reads the new fml_cache_annotation file built into the jar file, to find all crafttweaker methods, and saves the data to a file task mtDocGen { doLast{ def inputFile = new File(jar.archivePath.getAbsolutePath()) println("Reading " + inputFile.getName() + " for crafttweaker documentation") def jarFile = new ZipFile(inputFile) def annotation_cache = jarFile.getEntry("META-INF/fml_cache_annotation.json") def cache_json = IOUtils.toString(jarFile.getInputStream(annotation_cache), "UTF-8") def jsonObject = new GsonBuilder().create().fromJson(cache_json, JsonObject.class) def builder = new StringBuilder() for(entry in jsonObject.entrySet()){ def clzz = entry.value.asJsonObject if(!clzz.has("annotations")){ continue } def annoations = clzz.get("annotations").asJsonArray for(annotation in annoations.toList()){ if(annotation.asJsonObject.get("type").asString.equals("METHOD") && annotation.asJsonObject.get("name").asString.equals("Lstanhebben/zenscript/annotations/ZenMethod;")){ def method = sanitsiseMethodName(annotation.asJsonObject.get("target").asString) if(hasZenDoc(annotation, annoations)){ method = getZenDoc(annotation, annoations) } def zen_name = getZenMetName(clzz) builder.append(zen_name + "." + method) builder.append("\n") } } } def outputFile = new File(jar.archivePath.getAbsolutePath().replace(".jar", "-crafttweaker.txt")) outputFile.write builder.toString() println("Crafttweaker documentation saved to " + outputFile.name) } } boolean hasZenDoc(JsonObject currentAnnotation, JsonArray annoations){ for(annotation in annoations.toList()){ if(annotation.asJsonObject.get("target").asString.equals(currentAnnotation.get("target").asString) && annotation.asJsonObject.get("name").asString.equals("Ltechreborn/compat/crafttweaker/ZenDocumentation;")){ return true } } return false } String getZenDoc(JsonObject currentAnnotation, JsonArray annoations){ for(annotation in annoations.toList()){ if(annotation.asJsonObject.get("target").asString.equals(currentAnnotation.get("target").asString) && annotation.asJsonObject.get("name").asString.equals("Ltechreborn/compat/crafttweaker/ZenDocumentation;")){ def methodName = annotation.asJsonObject.get("target").asString.split("\\(")[0] def methodParams = annotation.asJsonObject.get("value").asJsonObject.get("value").asString if(!methodParams.startsWith("(")){ methodParams = "(" + methodParams } if(!methodParams.endsWith(")")){ methodParams = methodParams + ")" } return methodName + methodParams } } return "" } //Gets the zenMethod class name from the class json object String getZenMetName(JsonObject jsonObject){ def annoations = jsonObject.get("annotations").asJsonArray for(annotation in annoations.toList()){ if(annotation.asJsonObject.get("type").asString.equals("CLASS") && annotation.asJsonObject.get("name").asString.equals("Lstanhebben/zenscript/annotations/ZenClass;")){ return annotation.asJsonObject.get("value").asJsonObject.get("value").asString } } } String sanitsiseMethodName(String methodSig){ def builder = new StringBuilder() def name = methodSig.split("\\(")[0] builder.append(name) builder.append("(") def methodArgs = methodSig.split("\\(")[1].split("\\)")[0].split(";") for(arg in methodArgs){ def argSlit = arg.split("/") def argStr = argSlit[argSlit.length -1] //If a class is not in a package I assume its a primitive //TODO any suggestions for a better way to do this? if(!arg.contains("/") && !arg.isEmpty()){ argStr = humanizeArg(argStr) } builder.append(argStr) //Dont add the comma to the last arg if(arg != methodArgs[methodArgs.length - 1]){ builder.append(",") } } builder.append(")") return builder.toString() } //Argumets that are java primitives do not use a freindly name, this method replaces them with something most people will understand String humanizeArg(String arg){ def primitiveMap = [ Z: "Boolean", B: "Byte", C: "Char", D: "Double", F: "Float", I: "Integer", J: "Long", L: "Object", S: "Short" ] def builder = new StringBuilder() for(cha in arg.toCharArray()){ builder.append(primitiveMap.get(cha.toString().toUpperCase())) builder.append(",") } //Removes the last , return builder.toString().substring(0, builder.toString().length() - 1) } task copyToLib(type: Copy) { into "$buildDir/output/lib" from configurations.runtime }