mc-forge/build.gradle

1012 lines
40 KiB
Groovy

buildscript {
repositories {
mavenLocal()
maven { url = 'https://files.minecraftforge.net/maven' }
jcenter()
mavenCentral()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.197'
classpath 'net.minecraftforge.gradleutils:GradleUtils:1.0.24'
classpath 'org.ow2.asm:asm:7.1'
classpath 'org.ow2.asm:asm-tree:7.1'
classpath 'com.github.jponge:lzma-java:1.3' //Needed to compress deobf data
}
}
import groovy.json.JsonSlurper
import groovy.json.JsonBuilder
import java.nio.file.Files
import java.text.SimpleDateFormat
import java.util.Date
import java.util.LinkedHashMap
import java.util.TreeSet
import java.util.stream.Collectors
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
import java.security.MessageDigest
import java.net.URL
import net.minecraftforge.gradle.common.task.ArchiveChecksum
import net.minecraftforge.gradle.common.task.DownloadMavenArtifact
import net.minecraftforge.gradle.common.task.ExtractInheritance
import net.minecraftforge.gradle.common.task.SignJar
import net.minecraftforge.gradle.common.util.HashStore
import net.minecraftforge.gradle.mcp.function.MCPFunction
import net.minecraftforge.gradle.mcp.util.MCPEnvironment
import net.minecraftforge.gradle.patcher.task.ApplyBinPatches
import net.minecraftforge.gradle.patcher.task.GenerateBinPatches
import net.minecraftforge.gradle.patcher.task.TaskReobfuscateJar
import net.minecraftforge.gradle.userdev.tasks.RenameJar
import net.minecraftforge.gradleutils.ChangelogUtils
import org.apache.tools.ant.filters.ReplaceTokens
import de.undercouch.gradle.tasks.download.Download
import org.gradle.plugins.ide.eclipse.model.SourceFolder
import org.objectweb.asm.ClassReader
plugins {
id 'net.minecrell.licenser' version '0.4'
id 'org.ajoberstar.grgit' version '4.1.1'
id 'de.undercouch.download' version '3.3.0'
id 'com.github.ben-manes.versions' version '0.22.0'
}
apply plugin: 'eclipse'
ext {
JAR_SIGNER = null
if (project.hasProperty('keystore')) {
JAR_SIGNER = [
storepass: project.properties.keystoreStorePass,
keypass: project.properties.keystoreKeyPass,
keystore: project.properties.keystore
]
}
MAPPING_CHANNEL = 'snapshot'
MAPPING_VERSION = '20171003-1.12'
MC_VERSION = '1.12.2'
MCP_VERSION = '20200226.224830'
POST_PROCESSOR = [
tool: 'net.minecraftforge:mcpcleanup:2.3.2:fatjar',
repo: 'https://maven.minecraftforge.net/',
args: ['--input', '{input}', '--output', '{output}']
]
}
project(':mcp') {
apply plugin: 'net.minecraftforge.gradle.mcp'
mcp {
config = MC_VERSION + '-' + MCP_VERSION
pipeline = 'joined'
}
}
task createChangelog(type: net.minecraftforge.gradleutils.tasks.GenerateChangelogTask) {
startingCommit = '45da4f6910abe824aa487056276f6bf2fadb7f24'
}
project(':clean') {
evaluationDependsOn(':mcp')
apply plugin: 'eclipse'
apply plugin: 'net.minecraftforge.gradle.patcher'
compileJava.sourceCompatibility = compileJava.targetCompatibility = sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
repositories {
mavenCentral()
}
dependencies {
implementation 'net.minecraftforge:mergetool:0.2.3.3:forge'
}
patcher {
parent = project(':mcp')
mcVersion = MC_VERSION
patchedSrc = file('src/main/java')
mappings channel: MAPPING_CHANNEL, version: MAPPING_VERSION
processor = POST_PROCESSOR
runs {
clean_client {
taskName 'clean_client'
main 'net.minecraft.client.main.Main'
workingDirectory project.file('run')
args '--gameDir', '.'
args '--version', MC_VERSION
args '--assetsDir', downloadAssets.output
args '--assetIndex', '{asset_index}'
args '--accessToken', '0'
}
clean_server {
taskName 'clean_server'
main 'net.minecraft.server.MinecraftServer'
workingDirectory project.file('run')
}
}
}
}
project(':forge') {
evaluationDependsOn(':clean')
apply plugin: 'java-library'
apply plugin: 'maven-publish'
apply plugin: 'eclipse'
apply plugin: 'net.minecraftforge.gradle.patcher'
apply plugin: 'net.minecrell.licenser'
apply plugin: 'de.undercouch.download'
compileJava.sourceCompatibility = compileJava.targetCompatibility = sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
group = 'net.minecraftforge'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
sourceSets {
main {
java {
srcDirs = ["$rootDir/src/main/java"]
}
resources {
srcDirs = ["$rootDir/src/main/resources"]
}
}
test {
compileClasspath += sourceSets.main.runtimeClasspath
runtimeClasspath += sourceSets.main.runtimeClasspath
java {
srcDirs = ["$rootDir/src/test/java"]
}
resources {
srcDirs = ["$rootDir/src/test/resources"]
}
}
userdev {
compileClasspath += sourceSets.main.runtimeClasspath
runtimeClasspath += sourceSets.main.runtimeClasspath
java {
srcDirs = ["$rootDir/src/userdev/java"]
}
resources {
srcDirs = ["$rootDir/src/userdev/resources"]
}
}
}
//Eclipse adds the sourcesets twice, once where we tell it to, once in the projects folder. No idea why. So delete them
eclipse.classpath.file.whenMerged { cls -> cls.entries.removeIf { e -> e instanceof SourceFolder && e.path.startsWith('src/') && !e.path.startsWith('src/main/') } }
repositories {
mavenLocal()
mavenCentral()
}
ext {
LEGACY_MAJOR = 14 //Legacy versions have a API change prefix
LEGACY_BUILD = 2848 //Base build number to not conflict with existing build numbers
BUILD_NUMBER = 0 // LEGACY_BUILD + commit offset, used to mimic unique build from old versions
SPEC_VERSION = '23.5' // This is overwritten by git tag, but here so dev time doesnt explode
MCP_ARTIFACT = project(':mcp').mcp.config
SPECIAL_SOURCE = 'net.md-5:SpecialSource:1.8.5'
VERSION_JSON = project(':mcp').file('build/mcp/downloadJson/version.json')
BINPATCH_TOOL = 'net.minecraftforge:binarypatcher:1.1.1:fatjar'
}
def getVersion = {
//TAG-offset-hash
def raw = grgit.describe(longDescr: true, tags:true)
def desc = (raw == null ? '0.0-0-unknown' : grgit.describe(longDescr: true, tags:true)).split('-') as List
def hash = desc.remove(desc.size() - 1)
def offset = desc.remove(desc.size() - 1)
def tag = desc.join('-')
def branch = grgit.branch.current().name
if (branch in ['master', 'HEAD', MC_VERSION, MC_VERSION + '.0'])
branch = null
if (branch != null && branch.endsWith('.x') && MC_VERSION.startsWith(branch.substring(0, branch.length() - 2))) //1.13.x
branch = null
SPEC_VERSION = tag
BUILD_NUMBER = LEGACY_BUILD + offset.toInteger()
return "${MC_VERSION}-${LEGACY_MAJOR}.${tag}.${BUILD_NUMBER}${t -> if (branch != null) t << '-' + branch}".toString() //Bake the response instead of making it dynamic
}
version = getVersion()
logger.lifecycle "Version: $version"
patcher {
exc = file("$rootDir/src/main/resources/forge.exc")
parent = project(':clean')
patches = file("$rootDir/patches/minecraft")
patchedSrc = file('src/main/java')
srgPatches = true
notchObf = true
accessTransformer = file("$rootDir/src/main/resources/forge_at.cfg")
//sideAnnotationStripper = file("$rootDir/src/main/resources/forge.sas")
processor = POST_PROCESSOR
runs {
forge_client {
taskName 'forge_client'
main 'net.minecraftforge.legacydev.MainClient'
environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLTweaker'
environment 'mainClass', 'net.minecraft.launchwrapper.Launch'
environment 'assetIndex', '{asset_index}'
environment 'assetDirectory', '{assets_root}'
environment 'nativesDirectory', '{natives}'
environment 'MC_VERSION', MC_VERSION
environment 'MCP_MAPPINGS', '{mcp_mappings}'
environment 'MCP_TO_SRG', '{mcp_to_srg}'
environment 'FORGE_GROUP', "${project.group}"
environment 'FORGE_VERSION', "${project.version.substring(MC_VERSION.length() + 1)}"
}
forge_server {
taskName 'forge_server'
main 'net.minecraftforge.legacydev.MainServer'
environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLServerTweaker'
environment 'mainClass', 'net.minecraft.launchwrapper.Launch'
environment 'MC_VERSION', MC_VERSION
environment 'MCP_MAPPINGS', '{mcp_mappings}'
environment 'MCP_TO_SRG', '{mcp_to_srg}'
environment 'FORGE_GROUP', "${project.group}"
environment 'FORGE_VERSION', "${project.version.substring(MC_VERSION.length() + 1)}"
}
}
}
ext {
MANIFESTS = [
'/': [
'Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
'GitCommit': grgit.head().abbreviatedId,
'Git-Branch': grgit.branch.current().getName()
] as LinkedHashMap,
'net/minecraftforge/common/': [
'Specification-Title': 'Forge',
'Specification-Vendor': 'Forge Development LLC',
'Specification-Version': SPEC_VERSION,
'Implementation-Title': project.group,
'Implementation-Version': project.version.substring(MC_VERSION.length() + 1),
'Implementation-Vendor': 'Forge Development LLC'
] as LinkedHashMap
]
}
applyPatches {
canonicalizeAccess true
canonicalizeWhitespace true
maxFuzz 3
originalPrefix = '../src-base/minecraft/'
modifiedPrefix = '../src-work/minecraft/'
}
genPatches {
originalPrefix = '../src-base/minecraft/'
modifiedPrefix = '../src-work/minecraft/'
}
configurations {
installer {
transitive = false //Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it.
}
api.extendsFrom(installer)
fmllauncherImplementation.extendsFrom(installer)
}
dependencies {
installer 'org.ow2.asm:asm-debug-all:5.2'
installer 'net.minecraft:launchwrapper:1.12'
installer 'org.jline:jline:3.5.1'
installer 'com.typesafe.akka:akka-actor_2.11:2.3.3'
installer 'com.typesafe:config:1.2.1'
installer 'org.scala-lang:scala-actors-migration_2.11:1.1.0'
installer 'org.scala-lang:scala-compiler:2.11.1'
installer 'org.scala-lang.plugins:scala-continuations-library_2.11:1.0.2_mc' //We change the version so old installs don't break, as our clone of the jar is different the maven central
installer 'org.scala-lang.plugins:scala-continuations-plugin_2.11.1:1.0.2_mc' // --^
installer 'org.scala-lang:scala-library:2.11.1'
installer 'org.scala-lang:scala-parser-combinators_2.11:1.0.1'
installer 'org.scala-lang:scala-reflect:2.11.1'
installer 'org.scala-lang:scala-swing_2.11:1.0.1'
installer 'org.scala-lang:scala-xml_2.11:1.0.2'
installer 'lzma:lzma:0.0.1'
installer 'java3d:vecmath:1.5.2'
installer 'net.sf.trove4j:trove4j:3.0.3'
installer 'org.apache.maven:maven-artifact:3.5.3'
installer 'net.sf.jopt-simple:jopt-simple:5.0.3'
installer 'org.apache.logging.log4j:log4j-api:2.15.0' //TODO: Unpin in 1.18.1 or when Mojang bumps the Log4J version
installer 'org.apache.logging.log4j:log4j-core:2.15.0' //TODO: Unpin in 1.18.1 or when Mojang bumps the Log4J version
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.0.0'
testImplementation 'org.junit.vintage:junit-vintage-engine:5.+'
testImplementation 'org.opentest4j:opentest4j:1.0.0' // needed for junit 5
testImplementation 'org.hamcrest:hamcrest-all:1.3' // needs advanced matching for list order
}
def extraTxts = [
rootProject.file('CREDITS.txt'),
rootProject.file('LICENSE.txt'),
rootProject.file('LICENSE-Paulscode IBXM Library.txt'),
rootProject.file('LICENSE-Paulscode SoundSystem CodecIBXM.txt'),
rootProject.file('build/changelog.txt')
]
// We apply the bin patches we just created to make a jar that is JUST our changes
genClientBinPatches.tool = BINPATCH_TOOL
task applyClientBinPatches(type: ApplyBinPatches, dependsOn: genClientBinPatches) {
clean = { genClientBinPatches.cleanJar }
input = genClientBinPatches.output
tool = BINPATCH_TOOL
}
genServerBinPatches.tool = BINPATCH_TOOL
genJoinedBinPatches.tool = BINPATCH_TOOL
task genRuntimeBinPatches(type: GenerateBinPatches, dependsOn: [genClientBinPatches, genServerBinPatches]) {
tool = BINPATCH_TOOL
}
afterEvaluate { p ->
genRuntimeBinPatches {
cleanJar = genClientBinPatches.cleanJar
dirtyJar = genClientBinPatches.dirtyJar
srg = genClientBinPatches.srg
patchSets = genClientBinPatches.patchSets
args = [
'--output', '{output}',
'--patches', '{patches}',
'--srg', '{srg}',
'--legacy',
'--clean', '{clean}',
'--dirty', '{dirty}',
'--prefix', 'binpatch/client',
'--clean', '{server}',
'--dirty', '{dirty}',
'--prefix', 'binpatch/server'
]
addExtra('server', genServerBinPatches.cleanJar)
}
}
task downloadLibraries(dependsOn: ':mcp:setupMCP') {
inputs.file VERSION_JSON
doLast {
def json = new JsonSlurper().parseText(VERSION_JSON.text)
json.libraries.each {lib ->
def artifacts = [lib.downloads.artifact] + lib.downloads.get('classifiers', [:]).values()
artifacts.each{ art ->
def target = file('build/libraries/' + art.path)
if (!target.exists()) {
download {
src art.url
dest target
}
}
}
}
}
}
task extractInheritance(type: ExtractInheritance, dependsOn: [genJoinedBinPatches, downloadLibraries]) {
input { genJoinedBinPatches.cleanJar }
doFirst {
def json = new JsonSlurper().parseText(VERSION_JSON.text)
json.libraries.each {lib ->
def artifacts = [lib.downloads.artifact] + lib.downloads.get('classifiers', [:]).values()
artifacts.each{ art ->
def target = file('build/libraries/' + art.path)
if (target.exists())
addLibrary(target)
}
}
}
}
task checkATs(dependsOn: genJoinedBinPatches) {
inputs.file { genJoinedBinPatches.cleanJar }
inputs.files patcher.accessTransformers
doLast {
def vanilla = [:]
def zip = new java.util.zip.ZipFile(genJoinedBinPatches.cleanJar)
zip.entries().findAll { !it.directory && it.name.endsWith('.class') }.each { entry ->
new ClassReader(zip.getInputStream(entry)).accept(new org.objectweb.asm.ClassVisitor(org.objectweb.asm.Opcodes.ASM7) {
String name
void visit(int version, int access, String name, String sig, String superName, String[] interfaces) {
this.name = name
vanilla[name] = access
}
org.objectweb.asm.FieldVisitor visitField(int access, String name, String desc, String sig, Object value) {
vanilla[this.name + ' ' + name] = access
return null
}
org.objectweb.asm.MethodVisitor visitMethod(int access, String name, String desc, String sig, String[] excs) {
vanilla[this.name + ' ' + name + desc] = access
return null
}
}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES)
}
patcher.accessTransformers.each { f ->
TreeMap lines = [:]
f.eachLine { line ->
def idx = line.indexOf('#')
if (idx == 0 || line.isEmpty()) return
def comment = idx == -1 ? null : line.substring(idx)
if (idx != -1) line = line.substring(0, idx - 1)
def (modifier, cls, desc) = (line.trim() + ' ').split(' ', -1)
def key = cls + (desc.isEmpty() ? '' : ' ' + desc)
def access = vanilla[key.replace('.', '/')]
if (access == null) {
if ((desc.equals('*') || desc.equals('*()')) && vanilla[cls.replace('.', '/')] != null)
println('Warning: ' + line)
else {
println('Invalid: ' + line)
return
}
}
//TODO: Check access actually changes, and expand inheretence?
lines[key] = [modifier: modifier, comment: comment]
}
f.text = lines.collect{ it.value.modifier + ' ' + it.key + (it.value.comment == null ? '' : ' ' + it.value.comment) }.join('\n')
}
}
}
task checkSAS(dependsOn: extractInheritance) {
inputs.file { extractInheritance.output }
inputs.files patcher.sideAnnotationStrippers
doLast {
def json = new JsonSlurper().parseText(extractInheritance.output.text)
patcher.sideAnnotationStrippers.each { f ->
def lines = []
f.eachLine { line ->
if (line[0] == '\t') return //Skip any tabed lines, those are ones we add
def idx = line.indexOf('#')
if (idx == 0 || line.isEmpty()) {
lines.add(line)
return
}
def comment = idx == -1 ? null : line.substring(idx)
if (idx != -1) line = line.substring(0, idx - 1)
def (cls, desc) = (line.trim() + ' ').split(' ', -1)
cls = cls.replaceAll('\\.', '/')
desc = desc.replace('(', ' (')
if (desc.isEmpty() || json[cls] == null || json[cls]['methods'] == null || json[cls]['methods'][desc] == null) {
println('Invalid: ' + line)
return
}
def mtd = json[cls]['methods'][desc]
lines.add(cls + ' ' + desc.replace(' ', '') + (comment == null ? '' : ' ' + comment))
def children = json.values().findAll{ it.methods != null && it.methods[desc] != null && it.methods[desc].override == cls}
.collect { it.name + ' ' + desc.replace(' ', '') } as TreeSet
children.each { lines.add('\t' + it) }
}
f.text = lines.join('\n')
}
}
}
task launcherJson(dependsOn: ['signUniversalJar']) {
inputs.file { universalJar.archivePath }
ext {
output = file('build/version.json')
vanilla = project(':mcp').file('build/mcp/downloadJson/version.json')
timestamp = dateToIso8601(new Date())
comment = [
"Please do not automate the download and installation of Forge.",
"Our efforts are supported by ads from the download page.",
"If you MUST automate this, please consider supporting the project through https://www.patreon.com/LexManos/"
]
def idx = project.version.indexOf('-')
id = project.version.substring(0, idx) + "-${project.name}" + project.version.substring(idx)
}
inputs.file vanilla
outputs.file output
doLast {
def json_vanilla = new JsonSlurper().parseText(vanilla.text)
def json = [
_comment_: comment,
id: id,
time: timestamp,
releaseTime: timestamp,
type: 'release',
mainClass: 'net.minecraft.launchwrapper.Launch',
inheritsFrom: MC_VERSION,
logging: {},
minecraftArguments: [
'--username', '${auth_player_name}',
'--version', '${version_name}',
'--gameDir', '${game_directory}',
'--assetsDir', '${assets_root}',
'--assetIndex', '${assets_index_name}',
'--uuid', '${auth_uuid}',
'--accessToken', '${auth_access_token}',
'--userType', '${user_type}',
'--tweakClass', 'net.minecraftforge.fml.common.launcher.FMLTweaker',
'--versionType', 'Forge'
].join(' '),
libraries: [
[
//Package our universal jar as the 'main' jar Mojang's launcher loads. It will in turn load Forge's regular jars itself.
name: "${project.group}:${project.name}:${project.version}",
downloads: [
artifact: [
path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}.jar",
url: "", //Do not include the URL so that the installer/launcher won't grab it. This is also why we don't have the universal classifier
sha1: sha1(universalJar.archivePath),
size: universalJar.archivePath.length()
]
]
]
]
]
def artifacts = getArtifacts(project, project.configurations.installer, false)
artifacts.each { key, lib ->
json.libraries.add(lib)
}
output.text = new JsonBuilder(json).toPrettyString()
}
}
task installerJson(dependsOn: [launcherJson, genClientBinPatches/*, createClientSRG, createServerSRG*/]) {
ext {
output = file('build/install_profile.json')
INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.1.4'
}
inputs.file universalJar.archivePath
inputs.file genClientBinPatches.toolJar
inputs.file launcherJson.output
outputs.file output
doLast {
def libs = [
"${project.group}:${project.name}:${project.version}": [
name: "${project.group}:${project.name}:${project.version}",
downloads: [
artifact: [
path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}.jar",
url: "", //Do not include the URL so that the installer/launcher won't grab it. This is also why we don't have the universal classifier
sha1: sha1(universalJar.archivePath),
size: universalJar.archivePath.length()
]
]
]
]
def json = [
_comment_: launcherJson.comment,
spec: 0,
profile: project.name,
version: launcherJson.id,
icon: "data:image/png;base64," + new String(Base64.getEncoder().encode(Files.readAllBytes(rootProject.file("icon.ico").toPath()))),
json: '/version.json',
path: "${project.group}:${project.name}:${project.version}",
logo: '/big_logo.png',
minecraft: MC_VERSION,
welcome: "Welcome to the simple ${project.name.capitalize()} installer.",
data: [
] as Map,
processors: [
]
]
getClasspath(project, libs, MCP_ARTIFACT.descriptor) //Tell it to download mcp_config
json.libraries = libs.values().sort{a,b -> a.name.compareTo(b.name)}
output.text = new JsonBuilder(json).toPrettyString()
}
}
task extractObf2Srg(type:net.minecraftforge.gradle.common.task.ExtractMCPData, dependsOn: [':mcp:downloadConfig']) {
config = project(':mcp').downloadConfig.output
}
task deobfDataLzma(dependsOn: [extractObf2Srg]) {
ext {
output_srg = file('build/deobfDataLzma/data.srg')
output = file('build/deobfDataLzma/data.lzma')
}
inputs.file extractObf2Srg.output
outputs.file output
doLast {
net.minecraftforge.gradle.common.util.MappingFile.load(extractObf2Srg.output)
.write(net.minecraftforge.gradle.common.util.MappingFile.Format.SRG, output_srg)
output_srg.withInputStream { ins ->
output.withOutputStream { outs ->
def lz = new lzma.streams.LzmaOutputStream.Builder(outs).useEndMarkerMode(true).build()
def i = -1
def buf = new byte[0x100]
while ((i = ins.read(buf)) != -1)
lz.write(buf, 0, i)
lz.close()
}
}
}
}
universalJar {
from(extraTxts)
dependsOn(deobfDataLzma)
dependsOn(rootProject.createChangelog)
from(deobfDataLzma.output){
rename{"deobfuscation_data-${MC_VERSION}.lzma"}
}
dependsOn(genRuntimeBinPatches)
from(genRuntimeBinPatches.output) {
rename{'binpatches.pack.lzma'}
}
doFirst {
def classpath = new StringBuilder()
def artifacts = getArtifacts(project, project.configurations.installer, false)
artifacts.each { key, lib ->
classpath.append("libraries/${lib.downloads.artifact.path} ")
}
classpath += "minecraft_server.${MC_VERSION}.jar"
MANIFESTS.each{ pkg, values ->
if (pkg == '/') {
manifest.attributes(values += [
'Main-Class': 'net.minecraftforge.fml.relauncher.ServerLaunchWrapper',
'Class-Path': classpath.toString(),
'Tweak-Class': 'net.minecraftforge.fml.common.launcher.FMLTweaker'
])
} else {
manifest.attributes(values, pkg)
}
}
}
}
task downloadInstaller(type: DownloadMavenArtifact) {
artifact = 'net.minecraftforge:installer:2.2.7:fatjar'
changing = true
}
task installerJar(type: Zip, dependsOn: [downloadInstaller, installerJson, launcherJson, genClientBinPatches, genServerBinPatches, 'signUniversalJar', rootProject.createChangelog]) {
classifier = 'installer'
extension = 'jar' //Needs to be Zip task to not override Manifest, so set extension
destinationDir = file('build/libs')
from(extraTxts)
from(rootProject.file('/src/main/resources/forge_logo.png')) {
rename{'big_logo.png'}
}
from(rootProject.file('/src/main/resources/url.png'))
from(universalJar) {
into("/maven/${project.group.replace('.', '/')}/${project.name}/${project.version}/")
rename{"${project.name}-${project.version}.jar"}
}
from(installerJson.output)
from(launcherJson.output)
from(zipTree(downloadInstaller.output)) {
duplicatesStrategy = 'exclude'
}
}
[universalJar, installerJar].each { t ->
task "sign${t.name.capitalize()}"(type: SignJar, dependsOn: t) {
onlyIf {
JAR_SIGNER != null && t.state.failure == null
}
def jarsigner = JAR_SIGNER == null ? [:] : JAR_SIGNER
alias = 'forge'
storePass = jarsigner.storepass
keyPass = jarsigner.keypass
keyStore = jarsigner.keystore
inputFile = t.archivePath
outputFile = t.archivePath
doFirst {
project.logger.lifecycle('Signing: ' + inputFile)
}
}
t.finalizedBy(tasks.getByName("sign${t.name.capitalize()}"))
}
task makeMdk(type: Zip, dependsOn: [rootProject.createChangelog]) {
baseName = project.name
classifier = 'mdk'
version = project.version
destinationDir = file('build/libs')
from rootProject.file('gradlew')
from rootProject.file('gradlew.bat')
from extraTxts
from(rootProject.file('gradle/')){
into('gradle/')
}
from(rootProject.file('mdk/')){
rootProject.file('mdk/gitignore.txt').eachLine{
if (!it.trim().isEmpty() && !it.trim().startsWith('#'))
exclude it
}
filter(ReplaceTokens, tokens: [
FORGE_VERSION: project.version,
FORGE_GROUP: project.group,
FORGE_NAME: project.name,
MC_VERSION: MC_VERSION,
MAPPING_CHANNEL: MAPPING_CHANNEL,
MAPPING_VERSION: MAPPING_VERSION
])
rename 'gitignore\\.txt', '.gitignore'
}
}
userdevConfig {
def artifacts = getArtifacts(project, project.configurations.installer, true)
artifacts.each { key, lib ->
addLibrary(lib.name)
}
addLibrary('net.minecraftforge:legacydev:0.2.3.+:fatjar')
addUniversalFilter('^(?!binpatches\\.pack\\.lzma$).*$')
runs {
client {
main 'net.minecraftforge.legacydev.MainClient'
environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLTweaker'
environment 'mainClass', 'net.minecraft.launchwrapper.Launch'
environment 'assetIndex', '{asset_index}'
environment 'assetDirectory', '{assets_root}'
environment 'nativesDirectory', '{natives}'
environment 'MC_VERSION', MC_VERSION
environment 'MCP_MAPPINGS', '{mcp_mappings}'
environment 'MCP_TO_SRG', '{mcp_to_srg}'
environment 'FORGE_GROUP', "${project.group}"
environment 'FORGE_VERSION', "${project.version.substring(MC_VERSION.length() + 1)}"
}
server {
main 'net.minecraftforge.legacydev.MainServer'
environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLServerTweaker'
environment 'mainClass', 'net.minecraft.launchwrapper.Launch'
environment 'MC_VERSION', MC_VERSION
environment 'MCP_MAPPINGS', '{mcp_mappings}'
environment 'MCP_TO_SRG', '{mcp_to_srg}'
environment 'FORGE_GROUP', "${project.group}"
environment 'FORGE_VERSION', "${project.version.substring(MC_VERSION.length() + 1)}"
}
}
}
license {
header = file("$rootDir/LICENSE-header.txt")
include 'net/minecraftforge/'
/*
exclude 'net/minecraftforge/server/terminalconsole/'
exclude 'net/minecraftforge/api/' // exclude API here because it's validated in the SPI build
exclude 'net/minecraftforge/fml/common/versioning/ComparableVersion.java'
exclude 'net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java'
exclude 'net/minecraftforge/fml/common/versioning/Restriction.java'
exclude 'net/minecraftforge/fml/common/versioning/VersionRange.java'
*/
tasks {
main {
files = files("$rootDir/src/main/java")
}
test {
files = files("$rootDir/src/test/java")
}
}
}
task userdevExtras(type:Jar) {
dependsOn classes
from sourceSets.userdev.output
classifier 'userdev-temp'
}
task userdevExtrasReobf(type:TaskReobfuscateJar) {
dependsOn userdevExtras, createMcp2Srg
input = tasks.userdevExtras.archivePath
classpath = project.configurations.compile
srg = tasks.createMcp2Srg.output
}
userdevJar {
dependsOn userdevExtrasReobf
from (zipTree(tasks.userdevExtrasReobf.output)) {
into '/inject/'
}
from (sourceSets.userdev.output.resourcesDir) {
into '/inject/'
}
classifier 'userdev3'
}
/*
extractRangeMap {
addDependencies jar.archivePath
addSources sourceSets.userdev.java.srcDirs
}
applyRangeMap {
setSources sourceSets.userdev.java.srcDirs
}
*/
tasks.eclipse.dependsOn('genEclipseRuns')
if (project.hasProperty('UPDATE_MAPPINGS')) {
extractRangeMap {
sources sourceSets.test.java.srcDirs
}
applyRangeMap {
sources sourceSets.test.java.srcDirs
}
sourceSets.test.java.srcDirs.each { extractMappedNew.addTarget it }
}
publishing {
publications {
mavenJava(MavenPublication) {
artifact universalJar
artifact(rootProject.createChangelog.outputFile) {
builtBy rootProject.createChangelog
classifier = 'changelog'
extension = 'txt'
}
artifact installerJar
//TODO: installer-win
artifact makeMdk
artifact userdevJar
artifact sourcesJar
pom {
name = 'forge'
description = 'Modifactions to Minecraft to enable mod developers.'
url = 'https://github.com/MinecraftForge/MinecraftForge'
scm {
url = 'https://github.com/MinecraftForge/MinecraftForge'
connection = 'scm:git:git://github.com/MinecraftForge/MinecraftForge.git'
developerConnection = 'scm:git:git@github.com:MinecraftForge/MinecraftForge.git'
}
issueManagement {
system = 'github'
url = 'https://github.com/MinecraftForge/MinecraftForge/issues'
}
licenses {
license {
name = 'LGPL 2.1'
url = 'https://github.com/MinecraftForge/MinecraftForge/blob/1.12.x/LICENSE.txt'
distribution = 'repo'
}
}
}
}
}
repositories {
maven {
if (System.env.MAVEN_USER) {
url "https://maven.minecraftforge.net/releases/"
authentication {
basic(BasicAuthentication)
}
credentials {
username = System.env.MAVEN_USER ?: 'not'
password = System.env.MAVEN_PASSWORD ?: 'set'
}
} else {
url 'file://' + rootProject.file('repo').getAbsolutePath()
}
}
}
}
}
def dateToIso8601(date) {
def format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
def result = format.format(date)
return result[0..21] + ':' + result[22..-1]
}
def sha1(file) {
MessageDigest md = MessageDigest.getInstance('SHA-1')
file.eachByte 4096, {bytes, size ->
md.update(bytes, 0, size)
}
return md.digest().collect {String.format "%02x", it}.join()
}
def artifactTree(project, artifact) {
if (!project.ext.has('tree_resolver'))
project.ext.tree_resolver = 1
def cfg = project.configurations.create('tree_resolver_' + project.ext.tree_resolver++)
def dep = project.dependencies.create(artifact)
cfg.dependencies.add(dep)
def files = cfg.resolve()
return getArtifacts(project, cfg, true)
}
def getArtifacts(project, config, classifiers) {
def ret = [:]
config.resolvedConfiguration.resolvedArtifacts.each {
def art = [
group: it.moduleVersion.id.group,
name: it.moduleVersion.id.name,
version: it.moduleVersion.id.version,
classifier: it.classifier,
extension: it.extension,
file: it.file
]
def key = art.group + ':' + art.name
def folder = "${art.group.replace('.', '/')}/${art.name}/${art.version}/"
def filename = "${art.name}-${art.version}"
if (art.classifier != null)
filename += "-${art.classifier}"
filename += ".${art.extension}"
def path = "${folder}${filename}"
def url = "https://libraries.minecraft.net/${path}"
if (!checkExists(url)) {
url = "https://maven.minecraftforge.net/${path}"
}
//TODO remove when Mojang launcher is updated
if (!classifiers && art.classifier != null) { //Mojang launcher doesn't currently support classifiers, so... move it to part of the version, and force the extension to 'jar'
art.version = "${art.version}-${art.classifier}"
art.classifier = null
art.extension = 'jar'
path = "${art.group.replace('.', '/')}/${art.name}/${art.version}/${art.name}-${art.version}.jar"
}
ret[key] = [
name: "${art.group}:${art.name}:${art.version}" + (art.classifier == null ? '' : ":${art.classifier}") + (art.extension == 'jar' ? '' : "@${art.extension}"),
downloads: [
artifact: [
path: path,
url: url,
sha1: sha1(art.file),
size: art.file.length()
]
]
]
}
return ret
}
def checkExists(url) {
def code = new URL(url).openConnection().with {
requestMethod = 'HEAD'
connect()
responseCode
}
return code == 200
}
def getClasspath(project, libs, artifact) {
def ret = []
artifactTree(project, artifact).each { key, lib ->
libs[lib.name] = lib
if (lib.name != artifact)
ret.add(lib.name)
}
return ret
}
task ciWriteBuildNumber {
doFirst {
def file = file('src/main/java/net/minecraftforge/common/ForgeVersion.java');
def outfile = '';
def ln = '\n'; //Linux line endings because we're on git!
file.eachLine{ String s ->
if (s.matches('^ public static final int buildVersion = [\\d]+;\$'))
s = " public static final int buildVersion = ${project(':forge').BUILD_NUMBER};"
if (s.matches('^ public static final String mcVersion = "[^\\"]+";'))
s = " public static final String mcVersion = \"${MC_VERSION}\";"
outfile += (s+ln);
}
file.write(outfile);
}
}
//evaluationDependsOnChildren()
task setup() {
dependsOn ':clean:extractMapped'
dependsOn ':forge:extractMapped' //These must be strings so that we can do lazy resolution. Else we need evaluationDependsOnChildren above
}