buildscript { repositories { mavenCentral() jcenter() 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/" } maven { name = "CB Repo" url = "http://chickenbones.net/maven" } } dependencies { classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' classpath "gradle.plugin.net.minecrell:licenser:0.2.1" classpath 'de.undercouch:gradle-download-task:3.4.3' classpath 'net.covers1624:GradleStuff:1.0-SNAPSHOT' } } apply plugin: 'net.minecraftforge.gradle.forge' apply plugin: 'maven' apply plugin: 'maven-publish' apply plugin: net.minecrell.gradle.licenser.Licenser apply plugin: 'de.undercouch.download' apply plugin: 'net.covers1624.contained-deps' sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { maven { name = "Modmuss50" url = "http://maven.modmuss50.me/" } maven { // JEI name "JEI" url "http://dvs1.progwml6.com/files/maven" } } configurations { shade compile.extendsFrom shade } version = "2.21.2" def ENV = System.getenv() if (ENV.BUILD_NUMBER) { version = version + "." + "${System.getenv().BUILD_NUMBER}" } minecraft { version = "1.12.2-14.23.5.2796" 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 { deobfCompile('RebornCore:RebornCore-1.12.2:+:universal') { transitive = false } shade ('TechReborn:TechReborn-ModCompatibility-1.12.2:+:universal') { transitive = false } deobfCompile "mezz.jei:jei_1.12.2:+" } 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' } } containedDeps { configuration = "shade" tasks = "jar" } jar { exclude "**/*.psd" classifier = 'universal' 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 //Triggers crowdin to export the latest translations task crowdinExport() { onlyIf { project.hasProperty('crowdinKey') } doLast{ def apiKey = project.crowdinKey def projectId = 'techreborn' def response = new URL(sprintf('https://api.crowdin.com/api/project/%1$s/export?key=%2$s', [projectId, apiKey])).text def metadata = new XmlParser().parseText(response) project.logger.lifecycle("crowdin export status: " + metadata.@status) } } task crowdin(type: Download, dependsOn: 'crowdinExport'){ src 'https://crowdin.com/backend/download/project/techreborn.zip' dest file("build/translations.zip") overwrite true } task cleanCrowdin(type: Delete){ delete 'build/translations' } //Renames the translation files to be all lower case task renameCrowdin(type: Copy, dependsOn: ['crowdin', 'cleanCrowdin']){ mustRunAfter 'crowdin' from zipTree(file("build/translations.zip")) into file('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" } } } 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 }