560 lines
20 KiB
Groovy
560 lines
20 KiB
Groovy
buildscript {
|
|
def mcVersion
|
|
if (project.name != 'core') {
|
|
def (major, minor, patch) = project.name.tokenize('.')
|
|
mcVersion = "${major}${minor.padLeft(2, '0')}${(patch ?: '').padLeft(2, '0')}" as int
|
|
} else {
|
|
def f = file('mcVersion')
|
|
mcVersion = f.exists() ? f.readLines().first() as int : 11300
|
|
}
|
|
project.ext.mcVersion = mcVersion
|
|
|
|
repositories {
|
|
mavenLocal()
|
|
jcenter()
|
|
mavenCentral()
|
|
maven {
|
|
name = "forge"
|
|
url = "https://files.minecraftforge.net/maven"
|
|
}
|
|
maven {
|
|
name = "sonatype"
|
|
url = "https://oss.sonatype.org/content/repositories/snapshots/"
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
classpath 'org.ow2.asm:asm:6.0'
|
|
classpath('com.github.SpongePowered:MixinGradle:dcfaf61'){ // 0.6
|
|
// Because forgegradle requires 6.0 (not -debug-all) while mixingradle depends on 5.0
|
|
// and putting mixin right here will place it before forge in the class loader
|
|
exclude group: 'org.ow2.asm', module: 'asm-debug-all'
|
|
}
|
|
classpath 'net.minecraftforge.gradle:ForgeGradle:' + (
|
|
mcVersion >= 11300 ? '3.+' :
|
|
mcVersion >= 11200 ? '2.3-SNAPSHOT' :
|
|
mcVersion >= 10904 ? '2.2-SNAPSHOT' :
|
|
mcVersion >= 10809 ? '2.1-SNAPSHOT' :
|
|
mcVersion >= 10800 ? '2.0-SNAPSHOT' :
|
|
mcVersion >= 10710 ? '1.2-SNAPSHOT' :
|
|
'invalid'
|
|
)
|
|
}
|
|
}
|
|
|
|
def mcVersionStr = "${(int)(mcVersion/10000)}.${(int)(mcVersion/100)%100}" + (mcVersion%100==0 ? '' : ".${mcVersion%100}")
|
|
|
|
def FG3 = mcVersion >= 11300
|
|
|
|
if (mcVersion >= 10800) {
|
|
if (FG3) {
|
|
apply plugin: 'net.minecraftforge.gradle'
|
|
// FIXME use mixin plugin once updated
|
|
compileJava {
|
|
options.compilerArgs += ['-AreobfSrgFile=' + new File(project.buildDir, 'mcp-srg.srg').getCanonicalPath()]
|
|
}
|
|
} else {
|
|
apply plugin: 'net.minecraftforge.gradle.forge'
|
|
apply plugin: 'org.spongepowered.mixin'
|
|
}
|
|
} else {
|
|
apply plugin: 'forge'
|
|
|
|
ext {
|
|
mixinSrg = new File(project.buildDir, 'tmp/mixins/mixins.srg')
|
|
mixinRefMap = new File(project.buildDir, 'tmp/mixins/mixins.replaymod.refmap.json')
|
|
}
|
|
}
|
|
|
|
sourceCompatibility = 1.8
|
|
targetCompatibility = 1.8
|
|
|
|
afterEvaluate {
|
|
version = mcVersionStr + '-' + rootProject.version
|
|
}
|
|
group= "com.replaymod"
|
|
archivesBaseName = "replaymod"
|
|
|
|
minecraft {
|
|
if (FG3) {
|
|
runConfig {
|
|
name = 'Minecraft Client'
|
|
main = 'net.minecraftforge.userdev.UserdevLauncher'
|
|
ideaModuleName = '${project.name}_main'
|
|
workingDirectory = project.file('eclipse').canonicalPath
|
|
environment 'target', 'fmldevclient'
|
|
environment 'assetDirectory', downloadAssets.output.absolutePath
|
|
}
|
|
} else {
|
|
if (mcVersion >= 10800) {
|
|
coreMod = 'com.replaymod.core.LoadingPlugin'
|
|
}
|
|
runDir = "../../eclipse"
|
|
}
|
|
|
|
version = [
|
|
11202: '1.12.2-14.23.0.2486',
|
|
11201: '1.12.1-14.22.0.2444',
|
|
11200: '1.12-14.21.1.2387',
|
|
11102: '1.11.2-13.20.0.2216',
|
|
11100: '1.11-13.19.1.2188',
|
|
11002: '1.10.2-12.18.2.2099',
|
|
10904: '1.9.4-12.17.0.1976',
|
|
10809: '1.8.9-11.15.1.1722',
|
|
10800: '1.8-11.14.4.1563',
|
|
10710: '1.7.10-10.13.4.1558-1.7.10',
|
|
][mcVersion]
|
|
mappings = [
|
|
11300: "snapshot_20180921-1.13",
|
|
11202: "snapshot_20170615",
|
|
11201: "snapshot_20170615",
|
|
11200: "snapshot_20170615",
|
|
11102: "snapshot_20161220",
|
|
11100: "snapshot_20161111",
|
|
11002: "snapshot_20160518",
|
|
10904: "snapshot_20160518",
|
|
10809: "stable_22",
|
|
10800: "snapshot_nodoc_20141130",
|
|
10710: "stable_12",
|
|
][mcVersion]
|
|
}
|
|
|
|
afterEvaluate {
|
|
if (mcVersion >= 11300) {
|
|
} else {
|
|
// Note cannot use minecraft.replace because that has already been forwarded to the task by FG by now
|
|
tasks.sourceMainJava.replace '@MOD_VERSION@', project.version
|
|
// Includes intentional whitespace to stop Forge from declaring the mod to be compatible with
|
|
// a newer srg-compatible MC version (that may be using a different protocol version)
|
|
tasks.sourceMainJava.replace '@MC_VERSION@', "[ $mcVersionStr ]"
|
|
}
|
|
}
|
|
|
|
repositories {
|
|
mavenLocal()
|
|
maven {
|
|
name = "SpongePowered Repo"
|
|
url = "http://repo.spongepowered.org/maven/"
|
|
}
|
|
maven { url 'https://jitpack.io' }
|
|
}
|
|
|
|
configurations {
|
|
shade
|
|
compile.extendsFrom shade
|
|
|
|
shade.exclude group: 'com.google.code.gson', module: 'gson' // provided by MC
|
|
}
|
|
|
|
dependencies {
|
|
if (FG3) {
|
|
minecraft 'net.minecraftforge.test:forge:' + [
|
|
11300: '1.13-24.0.33-1.13-pre',
|
|
][mcVersion]
|
|
}
|
|
|
|
annotationProcessor group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
|
compileOnly group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
|
|
|
// compile 'com.github.SpongePowered:Mixin:404f5da' // 0.7.5-SNAPSHOT
|
|
// ^ mixin doesn't compile on jitpack, so we'll have to depend on the SNAPSHOT and build it manually for reprod
|
|
annotationProcessor 'org.spongepowered:mixin:0.7.8-SNAPSHOT'
|
|
compileOnly 'org.spongepowered:mixin:0.7.8-SNAPSHOT'
|
|
compile 'org.spongepowered:mixin:0.7.8-SNAPSHOT'
|
|
shade 'com.googlecode.mp4parser:isoparser:1.1.7'
|
|
shade 'org.apache.commons:commons-exec:1.3'
|
|
def withoutGuava = { exclude group: 'com.google.guava', module: 'guava-jdk5' }
|
|
shade 'com.google.apis:google-api-services-youtube:v3-rev178-1.22.0', withoutGuava
|
|
shade 'com.google.api-client:google-api-client-gson:1.20.0', withoutGuava
|
|
shade 'com.google.api-client:google-api-client-java6:1.20.0', withoutGuava
|
|
shade 'com.google.oauth-client:google-oauth-client-jetty:1.20.0'
|
|
|
|
shade 'org.aspectj:aspectjrt:1.8.2'
|
|
|
|
def studioVersion = mcVersionStr
|
|
if (studioVersion == '1.8.9') studioVersion = '1.8'
|
|
shade("com.replaymod.replaystudio:$studioVersion:2d8d41d"){ // FIXME
|
|
exclude group: 'com.google.guava', module: 'guava' // provided by MC
|
|
exclude group: 'org.projectlombok', module: 'lombok' // runtime only for @SneakyThrows which isn't used
|
|
}
|
|
|
|
def jGuiVersion = project.name
|
|
if (['1.10.2', '1.11', '1.11.2'].contains(jGuiVersion)) jGuiVersion = '1.9.4'
|
|
if (['1.12.1', '1.12.2'].contains(jGuiVersion)) jGuiVersion = '1.12'
|
|
shade(project(":jGui:$jGuiVersion")){
|
|
transitive = false // FG 1.2 puts all MC deps into the compile configuration and we don't want to shade those
|
|
exclude group: 'org.projectlombok', module: 'lombok' // runtime only for @SneakyThrows which isn't used
|
|
}
|
|
|
|
annotationProcessor 'org.projectlombok:lombok:1.16.6'
|
|
compile 'org.projectlombok:lombok:1.16.6' // runtime only for @SneakyThrows which isn't used
|
|
|
|
testCompile 'junit:junit:4.11'
|
|
}
|
|
|
|
if (mcVersion <= 10710) {
|
|
// FG 1.2 adds all MC deps to the compile configuration which we don't want
|
|
afterEvaluate {
|
|
// Remove them from the compile and runtime configurations
|
|
configurations.compile.extendsFrom -= [configurations.minecraft, configurations.minecraftDeps]
|
|
configurations.runtime.extendsFrom -= [configurations.forgeGradleStartClass]
|
|
// And add them to the source sets instead
|
|
sourceSets.main.with {
|
|
compileClasspath += configurations.minecraft + configurations.minecraftDeps
|
|
runtimeClasspath += configurations.minecraft + configurations.minecraftDeps + configurations.forgeGradleStartClass
|
|
}
|
|
// Also need to reconfigure the reobf task, so it can properly re-obfuscates inherited members
|
|
tasks.reobf.obfOutput.all { artifact ->
|
|
artifact.getFile() // force resolve
|
|
artifact.classpath += configurations.minecraft + configurations.minecraftDeps
|
|
}
|
|
}
|
|
}
|
|
|
|
if (project.name != 'core') {
|
|
apply from: '../preprocessor.gradle'
|
|
|
|
def preprocessedSrc = 'build/preprocessed/src'
|
|
def preprocessedRes = 'build/preprocessed/res'
|
|
def preprocessedAT = 'build/preprocessed/at.cfg'
|
|
def originalSrc = '../../src/main/java'
|
|
def originalRes = '../../src/main/resources'
|
|
def originalAT = originalRes + '/META-INF/replaymod_at.cfg'
|
|
def vars = [MC: mcVersion as int]
|
|
|
|
sourceSets {
|
|
main.java.srcDir preprocessedSrc
|
|
main.resources.srcDir preprocessedRes
|
|
}
|
|
|
|
task preprocessJava {
|
|
inputs.dir(originalSrc)
|
|
outputs.dir(preprocessedSrc)
|
|
doLast {
|
|
project.convertTree(vars, originalSrc, preprocessedSrc)
|
|
}
|
|
}
|
|
|
|
task preprocessResources {
|
|
inputs.dir(originalRes)
|
|
outputs.dir(preprocessedRes)
|
|
doLast {
|
|
project.convertTree(vars, originalRes, preprocessedRes)
|
|
}
|
|
}
|
|
|
|
compileJava.dependsOn preprocessJava
|
|
processResources.dependsOn preprocessResources
|
|
if (FG3) {
|
|
// FG3 reads the AT file right after project evaluation, so we need to convert it right now
|
|
project.convertTree(vars, originalAT, preprocessedAT)
|
|
minecraft.accessTransformers << file(preprocessedAT)
|
|
} else {
|
|
(mcVersion >= 10800 ? [deobfMcMCP, deobfMcSRG] : [deobfuscateJar, deobfBinJar]).each { task ->
|
|
task.dependsOn preprocessResources
|
|
}
|
|
minecraft.accessTransformer preprocessedRes + '/META-INF/replaymod_at.cfg'
|
|
}
|
|
} else {
|
|
if (FG3) {
|
|
minecraft.accessTransformers << file('../../src/main/resources/META-INF/replaymod_at.cfg')
|
|
}
|
|
sourceSets {
|
|
main.java.srcDirs = ['../../src/main/java']
|
|
main.resources.srcDirs = ['../../src/main/resources']
|
|
}
|
|
}
|
|
sourceSets {
|
|
main {
|
|
java {
|
|
exclude 'com/replaymod/compat'
|
|
exclude 'com/replaymod/editor'
|
|
exclude 'com/replaymod/extras'
|
|
exclude 'com/replaymod/online'
|
|
exclude 'com/replaymod/pathing'
|
|
exclude 'com/replaymod/render'
|
|
exclude 'com/replaymod/replay'
|
|
exclude 'com/replaymod/restrictions'
|
|
exclude 'com/replaymod/simplepathing'
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!FG3) { // FIXME
|
|
def reobfTask = mcVersion >= 10800 ? tasks.reobfJar : tasks.reobf
|
|
task configureRelocation() {
|
|
dependsOn tasks.jar
|
|
dependsOn configurations.shade
|
|
doLast {
|
|
def extraSrg = mcVersion >= 10800 ? reobfTask.extraSrgLines : reobfTask.extraSrg
|
|
files(configurations.shade).filter { it.exists() }.collect {
|
|
def tree = it.isDirectory() ? fileTree(it) : zipTree(it)
|
|
def pkgs = [].toSet()
|
|
tree.visit { file ->
|
|
if (!file.directory && file.name.endsWith('.class') && file.path.contains('/')) {
|
|
def pkg = file.path.substring(0, file.path.lastIndexOf('/'))
|
|
if (!pkg.startsWith('com/replaymod') && !pkg.startsWith('javax/')) {
|
|
pkgs << pkg
|
|
}
|
|
}
|
|
}
|
|
pkgs
|
|
}.flatten().unique().each { pkg ->
|
|
extraSrg << "PK: $pkg com/replaymod/lib/$pkg".toString()
|
|
}
|
|
}
|
|
}
|
|
reobfTask.dependsOn configureRelocation
|
|
}
|
|
|
|
if (mcVersion <= 10710) {
|
|
// Dummy task so "./gradlew reobfJar" also builds 1.7.10
|
|
task reobfJar() {
|
|
dependsOn reobf
|
|
}
|
|
}
|
|
|
|
jar {
|
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
|
|
dependsOn configurations.compile
|
|
dependsOn configurations.shade
|
|
|
|
if (mcVersion <= 10710) {
|
|
from project.mixinRefMap
|
|
}
|
|
|
|
def shade = {files(
|
|
configurations.compile.findAll {it.name.startsWith 'mixin-'}
|
|
+ configurations.shade
|
|
)}
|
|
|
|
def noticeDir = file("$buildDir/NOTICE")
|
|
doFirst {
|
|
noticeDir.deleteDir()
|
|
noticeDir.mkdirs()
|
|
shade().collect { it.isDirectory() ? fileTree(it) : zipTree(it) }.each {
|
|
it.matching { include '**/NOTICE*' }.each {
|
|
new File(noticeDir, 'NOTICE.txt') << it.getText('UTF-8') + '\n'
|
|
}
|
|
}
|
|
}
|
|
from noticeDir
|
|
|
|
from ({shade().collect { it.isDirectory() ? it : zipTree(it) }}) {
|
|
exclude '**/NOTICE*'
|
|
eachFile {
|
|
if (getName() == 'LICENSE.txt') {
|
|
setName(getFile().getParentFile().getName().split('.jar_')[0].tokenize('-')[0] + '-LICENSE.txt')
|
|
}
|
|
}
|
|
}
|
|
|
|
manifest {
|
|
attributes 'TweakClass': 'org.spongepowered.asm.launch.MixinTweaker',
|
|
'TweakOrder': '0',
|
|
'FMLCorePluginContainsFMLMod': 'true',
|
|
'FMLCorePlugin': 'com.replaymod.core.LoadingPlugin',
|
|
'FMLAT': 'replaymod_at.cfg'
|
|
}
|
|
}
|
|
|
|
processResources
|
|
{
|
|
// this will ensure that this task is redone when the versions change.
|
|
inputs.property 'version', { project.version }
|
|
inputs.property 'mcversion', { mcVersionStr }
|
|
|
|
// replace stuff in mcmod.info (pre 1.13) and mods.toml (1.13+), nothing else
|
|
from(sourceSets.main.resources.srcDirs) { spec ->
|
|
include 'mcmod.info'
|
|
include 'mods.toml'
|
|
|
|
// replace version and mcversion
|
|
afterEvaluate {
|
|
spec.expand 'version': project.version, 'mcversion': mcVersionStr
|
|
}
|
|
}
|
|
|
|
// copy everything else, thats not the mcmod.info (or mods.toml)
|
|
from(sourceSets.main.resources.srcDirs) {
|
|
exclude 'mcmod.info'
|
|
exclude 'mods.toml'
|
|
}
|
|
}
|
|
|
|
sourceSets {
|
|
main {
|
|
ext.refMap = "mixins.replaymod.refmap.json"
|
|
}
|
|
integrationTest {
|
|
compileClasspath += main.runtimeClasspath + main.output
|
|
java {
|
|
srcDir file('src/integration-test/java')
|
|
}
|
|
resources.srcDir file('src/integration-test/resources')
|
|
}
|
|
}
|
|
|
|
if (FG3) {
|
|
task copySrg(dependsOn: 'createMcpToSrg') {
|
|
doLast {
|
|
def tsrg = file(project.tasks.createMcpToSrg.output).readLines()
|
|
def srg = []
|
|
def cls = ''
|
|
for (def line : tsrg) {
|
|
if (line[0] != '\t') {
|
|
srg.add('CL: ' + line)
|
|
cls = line.split(' ')[0]
|
|
} else {
|
|
def parts = line.substring(1).split(' ')
|
|
if (line.contains('(')) {
|
|
srg.add('MD: ' + cls + '/' + parts[0] + ' ' + parts[1] + ' ' + cls + '/' + parts[2] + ' ' + parts[1])
|
|
} else {
|
|
srg.add('FD: ' + cls + '/' + parts[0] + ' ' + cls + '/' + parts[1])
|
|
}
|
|
}
|
|
}
|
|
new File(project.buildDir, 'mcp-srg.srg').write(srg.join('\n'))
|
|
}
|
|
}
|
|
} else {
|
|
task copySrg(type: Copy, dependsOn: 'genSrgs') {
|
|
from {project.tasks.genSrgs.mcpToSrg}
|
|
into 'build'
|
|
}
|
|
}
|
|
|
|
if (FG3) {
|
|
// FIXME project.tasks.idea.dependsOn copySrg
|
|
compileJava.dependsOn copySrg // FIXME can probably remove this one once mixingradle is updated
|
|
} else {
|
|
setupDecompWorkspace.dependsOn copySrg
|
|
setupDevWorkspace.dependsOn copySrg
|
|
}
|
|
|
|
if (mcVersion <= 10710) {
|
|
reobf.doFirst {
|
|
if (project.mixinSrg.exists()) {
|
|
addExtraSrgFile project.mixinSrg
|
|
}
|
|
}
|
|
|
|
compileJava.dependsOn copySrg
|
|
compileJava {
|
|
options.compilerArgs += [
|
|
"-AoutSrgFile=${project.mixinSrg.canonicalPath}",
|
|
"-AoutRefMapFile=${project.mixinRefMap.canonicalPath}",
|
|
"-AreobfSrgFile=${project.file('build/mcp-srg.srg').canonicalPath}"
|
|
]
|
|
}
|
|
}
|
|
|
|
/* FIXME
|
|
// Mixin uses multiple HashMaps to generate the refmap.
|
|
// HashMaps are unordered collections and as such do not produce deterministic output.
|
|
// To fix that, we simply sort the refmap json file.
|
|
import groovy.json.JsonSlurper
|
|
import groovy.json.JsonOutput
|
|
compileJava.doLast {
|
|
File refmapFile = mcVersion >= 10800 ? compileJava.ext.refMapFile : project.mixinRefMap
|
|
if (refmapFile.exists()) {
|
|
def ordered
|
|
ordered = {
|
|
if (it instanceof Map) {
|
|
def sorted = new TreeMap(it)
|
|
sorted.replaceAll { k, v -> ordered(v) }
|
|
sorted
|
|
} else if (it instanceof List) {
|
|
it.replaceAll { v -> ordered(v) }
|
|
} else {
|
|
it
|
|
}
|
|
}
|
|
def json = JsonOutput.toJson(ordered(new JsonSlurper().parse(refmapFile)))
|
|
refmapFile.withWriter { it.write json }
|
|
}
|
|
}
|
|
*/
|
|
|
|
import java.util.zip.ZipEntry
|
|
import java.util.zip.ZipFile
|
|
import java.util.zip.ZipOutputStream
|
|
|
|
import org.objectweb.asm.*
|
|
|
|
import static org.objectweb.asm.Opcodes.ASM5
|
|
|
|
// MC binaries were complied with a java version that produces invalid class files under certain circumstances
|
|
// This causes setupCIWorkspace to be insufficient for compiling.
|
|
// Related JDK bug: https://bugs.openjdk.java.net/browse/JDK-8066725
|
|
// As a workaround, to use setupCIWorkspace on Drone, we modify the bin jar in-place and remove all parameter annotations.
|
|
// WARNING: This piece of code ignores any and all gradle conventions and will probably fail horribly when run outside
|
|
// of a single-use environment (e.g. Drone). Use setupDecompWorkspace for normal use.
|
|
def annotationWorkaround = {
|
|
println "Applying RuntimeInvisibleParameterAnnotations workaround..."
|
|
File jar = getOutJar()
|
|
File tmp = new File((File) getTemporaryDir(), "workaround.jar")
|
|
tmp.withOutputStream {
|
|
new ZipOutputStream(it).withStream { dst ->
|
|
new ZipFile(jar).withCloseable { src ->
|
|
src.entries().each {
|
|
if (it.name.startsWith("net/minecraft/") && it.name.endsWith(".class")) {
|
|
def cw = new ClassWriter(0)
|
|
def cv = new ClassVisitor(ASM5, cw) {
|
|
@Override
|
|
MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
|
return new MethodVisitor(ASM5, cv.visitMethod(access, name, desc, signature, exceptions)) {
|
|
@Override
|
|
AnnotationVisitor visitParameterAnnotation(int parameter, String pdesc, boolean visible) {
|
|
return null // Strip all parameter annotations
|
|
}
|
|
}
|
|
}
|
|
}
|
|
new ClassReader(src.getInputStream(it)).accept(cv, 0)
|
|
dst.putNextEntry(new ZipEntry(it.name))
|
|
dst.write(cw.toByteArray())
|
|
} else {
|
|
dst.putNextEntry(it)
|
|
dst.write(src.getInputStream(it).bytes)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
jar.delete()
|
|
tmp.renameTo(jar)
|
|
}
|
|
if (mcVersion >= 10809 && !FG3) {
|
|
tasks.deobfMcMCP.doLast annotationWorkaround
|
|
}
|
|
|
|
if (!FG3) { // FIXME
|
|
task runIntegrationTest(type: JavaExec, dependsOn: ["makeStart", "jar"]) {
|
|
main = 'GradleStart'
|
|
standardOutput = System.out
|
|
errorOutput = System.err
|
|
workingDir file(minecraft.runDir)
|
|
|
|
def testDir = new File(minecraft.runDir, "integration-test")
|
|
doFirst {
|
|
testDir.deleteDir()
|
|
testDir.mkdirs()
|
|
}
|
|
|
|
doLast {
|
|
testDir.deleteDir()
|
|
}
|
|
|
|
afterEvaluate {
|
|
def runClient = tasks.getByName("runClient")
|
|
runIntegrationTest.jvmArgs = runClient.jvmArgs + "-Dfml.noGrab=true"
|
|
runIntegrationTest.args = runClient.args + "--gameDir" + testDir.canonicalPath
|
|
runIntegrationTest.classpath runClient.classpath + sourceSets.integrationTest.output
|
|
}
|
|
}
|
|
}
|
|
|
|
defaultTasks 'build'
|