diff --git a/build.gradle b/build.gradle index 95e1f5243..67581433a 100644 --- a/build.gradle +++ b/build.gradle @@ -15,45 +15,32 @@ buildscript { classpath 'org.ow2.asm:asm-tree:7.2' } } -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.forge.tasks.* -import net.minecraftforge.gradle.common.task.ArchiveChecksum +import static net.minecraftforge.forge.tasks.Util.* 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.TaskReobfuscateJar import net.minecraftforge.gradle.userdev.tasks.RenameJar 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 -import org.objectweb.asm.Opcodes plugins { id 'net.minecrell.licenser' version '0.4' id 'org.ajoberstar.grgit' version '3.1.1' - id 'de.undercouch.download' version '3.3.0' id 'com.github.ben-manes.versions' version '0.22.0' } apply plugin: 'eclipse' +Util.init() //Init all our extension methods! + println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) ext { @@ -138,7 +125,6 @@ project(':forge') { 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' @@ -484,419 +470,59 @@ project(':forge') { if (changelog.exists()) extraTxts += changelog - task downloadCrowdin() { - ext { - output = file('build/crowdin_raw.zip') - update = file('build/crowdin.json') - id = 'minecraft-forge' - } - onlyIf { - project.hasProperty('crowdinKey') && !project.gradle.startParameter.isOffline() - } - doLast { - download { - src "https://api.crowdin.com/api/project/${id}/export?key=${project.crowdinKey}&json" - dest update - overwrite true - } - if (!update.text.contains('success')) { - throw new RuntimeException("Crowdin export failed, see ${update} for more info") - } - download { - src "https://api.crowdin.com/api/project/${id}/download/all.zip?key=${project.crowdinKey}" - dest output - overwrite true - } - } - } - - task crowdin(type: Zip) { - dependsOn downloadCrowdin - onlyIf { - !downloadCrowdin.state.skipped - } - baseName = project.name - version = project.version - classifier = 'crowdin' - destinationDir = file('build/distributions') - from(zipTree(downloadCrowdin.output)){ - eachFile { //Tired of waiting for crowdin API, rename things myself. Remove once crowdin stops being dumb - if (it.name.equals('en_us.json') && !it.path.startsWith('assets/')) { - it.name = it.path.split('/')[0] + '.json' - it.path = 'assets/forge/lang/' + it.name - } - } - exclude { it.isDirectory() } - rename { it.toLowerCase() }//Minecraft needs it lowercase. - exclude '**/*.lang' //Pre-1.13 format - } - } + task crowdin(type: CrowdinTask) { + key = project.hasProperty('crowdinKey') ? project.crowdinKey : null + //TODO: Merge our english.json? + } // 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 - task applyServerBinPatches(type: ApplyBinPatches, dependsOn: genServerBinPatches) { - clean = { genServerBinPatches.cleanJar } - input = genServerBinPatches.output - tool = BINPATCH_TOOL - } - genJoinedBinPatches.tool = BINPATCH_TOOL - task applyJoinedBinPatches(type: ApplyBinPatches, dependsOn: genJoinedBinPatches) { - clean = { genJoinedBinPatches.cleanJar } - input = genJoinedBinPatches.output - tool = BINPATCH_TOOL - } - // Create SRG named Vanilla jars, using the SpecialSource we have in the installer - task createClientSRG(type: RenameJar, dependsOn: genClientBinPatches) { - tool = SPECIAL_SOURCE + ':shaded' - args = ['--stable', '--in-jar', '{input}', '--out-jar', '{output}', '--srg-in', '{mappings}'] - mappings = { genClientBinPatches.srg } - input = { genClientBinPatches.cleanJar } - output = file('build/createClientSRG/output.jar') - } - task createServerSRG(type: RenameJar, dependsOn: genServerBinPatches) { - tool = SPECIAL_SOURCE + ':shaded' - args = ['--stable', '--in-jar', '{input}', '--out-jar', '{output}', '--srg-in', '{mappings}'] - mappings = { genServerBinPatches.srg } - input = { genServerBinPatches.cleanJar } - output = file('build/createServerSRG/output.jar') - } - // Checksum tasks so that we can know if the vanilla classes are what we expect them to do! - task clientBaseChecksum(type: ArchiveChecksum, dependsOn: genClientBinPatches) { - input = { genClientBinPatches.cleanJar} //Lazy because Patcher Plugin sets the value afterEvaluate - name = 'client' - } - task serverBaseChecksum(type: ArchiveChecksum, dependsOn: genServerBinPatches) { - input = { genServerBinPatches.cleanJar } - name = 'server' - } - task joinedBaseChecksum(type: ArchiveChecksum, dependsOn: genJoinedBinPatches) { - input = { genJoinedBinPatches.cleanJar } - name = 'joined' - } - task clientPatchedChecksum(type: ArchiveChecksum, dependsOn: applyClientBinPatches) { - input = applyClientBinPatches.output - name = 'client_patched' - } - task serverPatchedChecksum(type: ArchiveChecksum, dependsOn: applyServerBinPatches) { - input = applyServerBinPatches.output - name = 'server_patched' - } - task joinedPatchedChecksum(type: ArchiveChecksum, dependsOn: applyJoinedBinPatches) { - input = applyJoinedBinPatches.output - name = 'joined_patched' - } - // Utility methods for testing checksums - task cleanChecksums() { - ['client', 'server', 'joined'].each { side -> - ['Base', 'Patched'].each { type -> - def clean = "clean${side.capitalize()}${type}Checksum" - dependsOn(clean) - tasks.findByName("${side}${type}Checksum").mustRunAfter(clean) - } - } - } - task checksums() { - ['client', 'server', 'joined'].each { side -> - ['Base', 'Patched'].each { type -> - dependsOn("${side}${type}Checksum") - } - } - } + ['Client', 'Server', 'Joined'].each { side -> + def gen = tasks.getByName("gen${side}BinPatches") + gen.tool = BINPATCH_TOOL + task "apply${side}BinPatches"(type: ApplyBinPatches, dependsOn: gen) { + clean = { gen.cleanJar } + input = gen.output + tool = BINPATCH_TOOL + } + if (side != 'Joined') { + // Create SRG named Vanilla jars, using the SpecialSource we have in the installer + task "create${side}SRG"(type: RenameJar, dependsOn: gen) { + tool = SPECIAL_SOURCE + ':shaded' + args = ['--stable', '--in-jar', '{input}', '--out-jar', '{output}', '--srg-in', '{mappings}'] + mappings = { gen.srg } + input = { gen.cleanJar } + output = file("build/create${name}SRG/output.jar") + } + } + } - 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 downloadLibraries(type: DownloadLibrariesTask, dependsOn: ':mcp:setupMCP') { + input = VERSION_JSON + output = rootProject.file('build/libraries/') } task extractInheritance(type: ExtractInheritance, dependsOn: [genJoinedBinPatches, downloadLibraries]) { tool = INSTALLER_TOOLS + ':fatjar' 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) - } - } - } + doFirst { downloadLibraries.libraries.each{ addLibrary(it) } } } - task checkATs(dependsOn: extractInheritance) { - inputs.file { extractInheritance.output } - inputs.files patcher.accessTransformers - doLast { - def parse = { line -> - def idx = line.indexOf('#') - 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) - return [modifier, cls, desc, comment, key] - } - def accessLevel = { access -> - if ((access & Opcodes.ACC_PUBLIC) != 0) return 3 - if ((access & Opcodes.ACC_PROTECTED) != 0) return 2 - if ((access & Opcodes.ACC_PRIVATE) != 0) return 0 - return 1 - } - def accessStr = { access -> - if (access.endsWith('-f') || access.endsWith('+f')) - return 4 - switch (access.toLowerCase()) { - case 'public': return 3 - case 'protected': return 2 - case 'default': return 1 - case 'private': return 0 - default: return -1 - } - } - def json = new JsonSlurper().parseText(extractInheritance.output.text) - - patcher.accessTransformers.each { f -> - TreeMap lines = [:] - def group = null - for (def line : f.readLines()) { - if (line.isEmpty()) continue - if (line.startsWith('#group ')) { - def (modifier, cls, desc, comment, key) = parse.call(line.substring(7)) - - if (!desc.equals('*') && !desc.equals('*()') && !desc.equals('')) - throw new IllegalStateException('Invalid group: ' + line) - - group = [modifier: modifier, cls: cls, desc: desc, comment: comment, - 'existing': [] as Set, - 'children': [] as TreeSet, - group: true - ] - if (lines.containsKey(key)) - throw new IllegalStateException('Duplicate group: ' + line) - - lines[key] = group - } else if (group != null) { - if (line.startsWith('#endgroup')) { - group = null - } else { - def (modifier, cls, desc, comment, key) = parse.call(line) - group['existing'].add(key) - } - } else if (line.startsWith('#endgroup')) { - throw new IllegalStateException('Invalid group ending: ' + line) - } else if (line.startsWith('#')) { - //Nom - } else { - def (modifier, cls, desc, comment, key) = parse.call(line) - if (lines.containsKey(key)) { - println('Duplicate: ' + line) - continue - } - lines[key] = [modifier: modifier, cls: cls, desc: desc, comment: comment, group: false] - } - } - - // Process Groups, this will remove any entries outside the group that is covered by the group - for (def key : new ArrayList<>(lines.keySet())) { - def entry = lines.get(key) - if (entry != null && entry['group']) { - def cls = entry['cls'] - def jcls = json.get(cls.replaceAll('\\.', '/')) - if (jcls == null) { - lines.remove(key) - println('Invalid Group: ' + key) - } else if ('*'.equals(entry['desc'])) { - if (!jcls.containsKey('fields')) { - lines.remove(key) - println('Invalid Group, Class has no fields: ' + key) - } else { - jcls['fields'].each { field, value -> - def fkey = cls + ' ' + field - if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) { - if (lines.containsKey(fkey)) { - lines.remove(fkey) - } else if (!entry['existing'].contains(fkey)) { - println('Added: ' + fkey) - } - entry['children'].add(fkey) - } else if (lines.containsKey(fkey)) { - lines.remove(fkey) - println('Removed: ' + fkey) - } - } - entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } - } - } else if ('*()'.equals(entry['desc'])) { - if (!jcls.containsKey('methods')) { - lines.remove(key) - println('Invalid Group, Class has no methods: ' + key) - } else { - jcls['methods'].each{ mtd, value -> - if (mtd.startsWith('')) - return - key = cls + ' ' + mtd.replace(' ', '') - if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) { - if (lines.containsKey(key)) { - lines.remove(key) - } else if (!entry['existing'].contains(key)) { - println('Added: ' + key) - } - entry['children'].add(key) - } else if (lines.containsKey(key)) { - lines.remove(key) - println('Removed: ' + key) - } - } - entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } - } - } else if (''.equals(entry['desc'])) { //Make all public non-abstract subclasses - json.each{ tcls,value -> - if (!value.containsKey('methods') || ((value['access'] & Opcodes.ACC_ABSTRACT) != 0)) - return - def parents = [] as Set - def parent = tcls - while (parent != null && json.containsKey(parent)) { - parents.add(parent) - def p = json[parent] - parent = p == null ? null : p['superName'] - } - if (parents.contains(cls.replaceAll('\\.', '/'))) { - value['methods'].each{ mtd, v -> - if (mtd.startsWith('')) { - def child = tcls.replaceAll('/', '\\.') + ' ' + mtd.replace(' ', '') - if (accessLevel.call(v['access']) < 3) { - if (lines.containsKey(child)) { - lines.remove(child) - } else if (!entry['existing'].contains(child)) { - println('Added: ' + child) - } - entry['children'].add(child) - } else if (lines.containsKey(child)) { - lines.remove(child) - println('Removed: ' + child) - } - } - } - } - } - entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } - } - } - } - - // Process normal lines, remove invalid and remove narrowing - for (def key : new ArrayList<>(lines.keySet())) { - def entry = lines.get(key) - if (entry != null && !entry['group']) { - def cls = entry['cls'] - def jcls = json.get(cls.replaceAll('\\.', '/')) - if (jcls == null) { - lines.remove(key) - println('Invalid: ' + key) - } else if (entry['desc'] == '') { - if (accessLevel.call(jcls['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { - lines.remove(key) - println('Invalid Narrowing: ' + key) - } - } else if (!entry['desc'].contains('(')) { - if (!jcls.containsKey('fields') || !jcls['fields'].containsKey(entry['desc'])) { - lines.remove(key) - println('Invalid: ' + key) - } else { - def value = jcls['fields'][entry['desc']] - if (accessLevel.call(value['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { - lines.remove(key) - println('Invalid Narrowing: ' + key) - println(entry.comment) - } - } - } else { - def jdesc = entry['desc'].replace('(', ' (') - if (!jcls.containsKey('methods') || !jcls['methods'].containsKey(jdesc)) { - lines.remove(key) - println('Invalid: ' + key) - } else { - def value = jcls['methods'][jdesc] - if (accessLevel.call(value['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { - lines.remove(key) - println('Invalid Narrowing: ' + key) - } - } - } - } - } - - - def data = [] - lines.each { key,value -> - if (!value.group) { - data.add(value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment)) - } else { - data.add('#group ' + value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment)) - value.children.each{ data.add(value.modifier + ' ' + it) } - data.add('#endgroup') - } - } - f.text = data.join('\n') - } - } + + task checkATs(type: CheckATs, dependsOn: extractInheritance) { + inheritance = extractInheritance.output + ats = patcher.accessTransformers } - 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 checkSAS(type: CheckSAS, dependsOn: extractInheritance) { + inheritance = extractInheritance.output + sass = patcher.sideAnnotationStrippers } + + task checkExcs(type: CheckExcs, dependsOn: jar) { + binary = jar.archivePath + excs = patcher.excs + } + + task checkAll(dependsOn: [checkATs, checkSAS, checkExcs]){} task checkPatchesAndFix(type: CheckPatches) { patchDir = file("$rootDir/patches") @@ -915,7 +541,7 @@ project(':forge') { ext { output = file('build/version.json') vanilla = project(':mcp').file('build/mcp/downloadJson/version.json') - timestamp = dateToIso8601(new Date()) + timestamp = iso8601Now() comment = [ "Please do not automate the download and installation of Forge.", "Our efforts are supported by ads from the download page.", @@ -927,7 +553,7 @@ project(':forge') { inputs.file vanilla outputs.file output doLast { - def json_vanilla = new JsonSlurper().parseText(vanilla.text) + def json_vanilla = vanilla.json() def json = [ _comment_: comment, id: id, @@ -948,7 +574,7 @@ project(':forge') { 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(launcherJar.archivePath), + sha1: launcherJar.archivePath.sha1(), size: launcherJar.archivePath.length() ] ] @@ -990,7 +616,7 @@ project(':forge') { artifact: [ path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}-universal.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), + sha1: universalJar.archivePath.sha1(), size: universalJar.archivePath.length() ] ] @@ -1021,32 +647,32 @@ project(':forge') { server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:slim]" ], MC_SLIM_SHA: [ - client: "'${sha1(tasks.getByName('downloadClientSlim').output)}'", - server: "'${sha1(tasks.getByName('downloadServerSlim').output)}'" + client: "'${tasks.getByName('downloadClientSlim').output.sha1()}'", + server: "'${tasks.getByName('downloadServerSlim').output.sha1()}'" ], MC_EXTRA: [ client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:extra]", server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:extra]" ], MC_EXTRA_SHA: [ - client: "'${sha1(tasks.getByName('downloadClientExtra').output)}'", - server: "'${sha1(tasks.getByName('downloadServerExtra').output)}'" + client: "'${tasks.getByName('downloadClientExtra').output.sha1()}'", + server: "'${tasks.getByName('downloadServerExtra').output.sha1()}'" ], MC_SRG: [ client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:srg]", server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:srg]" ], /*MC_SRG_SHA: [ - client: "'${sha1(createClientSRG.output)}'", - server: "'${sha1(createServerSRG.output)}'" + client: "'${createClientSRG.output.sha1()}'", + server: "'${createServerSRG.output.sha1()}'" ],*/ PATCHED: [ client: "[${project.group}:${project.name}:${project.version}:client]", server: "[${project.group}:${project.name}:${project.version}:server]" ], PATCHED_SHA: [ - client: "'${sha1(applyClientBinPatches.output)}'", - server: "'${sha1(applyServerBinPatches.output)}'" + client: "'${applyClientBinPatches.output.sha1()}'", + server: "'${applyServerBinPatches.output.sha1()}'" ], MCP_VERSION: [ client: "'${MCP_VERSION}'", @@ -1124,28 +750,10 @@ project(':forge') { universalJar { from extraTxts - /* TODO: Annotation Cache? need to talk to cpw about his new design. - from(fixAnnotationsJson){ - into 'META-INF' - } - dependsOn fixAnnotationsJson - */ - - /* We do not actually check this anywhere, so it's 400KB of uselless data - // Add checksum files of clean and patched vanilla classes. - ['client', 'server'].each { side -> - ['Base', 'Patched'].each { type -> - from(tasks.getByName("${side}${type}Checksum").output) { - into 'checksums/' - } - } - } - dependsOn checksums - */ - // add crowdin locales - from { !crowdin.state.skipped ? zipTree(crowdin.archivePath) : null} + from { crowdin.output.exists() ? zipTree(crowdin.output) : null} dependsOn crowdin + duplicatesStrategy = 'exclude' doFirst { MANIFESTS.each{ pkg, values -> @@ -1446,99 +1054,6 @@ project(':forge') { } } -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://files.minecraftforge.net/maven/${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) { - try { - def code = new URL(url).openConnection().with { - requestMethod = 'HEAD' - connect() - responseCode - } - return code == 200 - } catch (Exception e) { - if (e.toString().contains('unable to find valid certification path to requested target')) - throw new RuntimeException('Failed to connect to ' + url + ': Missing certificate root authority, try updating java') - throw e - } -} - -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 -} - //evaluationDependsOnChildren() task setup() { dependsOn ':clean:extractMapped' diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 000000000..5daa4d157 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,10 @@ +repositories { + //mavenCentral() //TODO: Update Gradle to use HTTPS by default + maven { + name 'maven_central' + url 'https://repo.maven.apache.org/maven2/' + } +} +dependencies { + implementation 'org.ow2.asm:asm:7.2' +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckATs.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckATs.groovy new file mode 100644 index 000000000..741b5ece1 --- /dev/null +++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckATs.groovy @@ -0,0 +1,231 @@ +package net.minecraftforge.forge.tasks + +import java.util.ArrayList +import java.util.TreeMap + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.TaskAction +import org.objectweb.asm.Opcodes + +public class CheckATs extends DefaultTask { + @InputFile File inheritance + @InputFiles File[] ats + + @TaskAction + protected void exec() { + Util.init() + def parse = { line -> + def idx = line.indexOf('#') + 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) + return [modifier, cls, desc, comment, key] + } + def accessLevel = { access -> + if ((access & Opcodes.ACC_PUBLIC) != 0) return 3 + if ((access & Opcodes.ACC_PROTECTED) != 0) return 2 + if ((access & Opcodes.ACC_PRIVATE) != 0) return 0 + return 1 + } + def accessStr = { access -> + if (access.endsWith('-f') || access.endsWith('+f')) + return 4 + switch (access.toLowerCase()) { + case 'public': return 3 + case 'protected': return 2 + case 'default': return 1 + case 'private': return 0 + default: return -1 + } + } + def json = inheritance.json() + + ats.each { f -> + TreeMap lines = [:] + def group = null + for (def line : f.readLines()) { + if (line.isEmpty()) continue + if (line.startsWith('#group ')) { + def (modifier, cls, desc, comment, key) = parse.call(line.substring(7)) + + if (!desc.equals('*') && !desc.equals('*()') && !desc.equals('')) + throw new IllegalStateException('Invalid group: ' + line) + + group = [modifier: modifier, cls: cls, desc: desc, comment: comment, + 'existing': [] as Set, + 'children': [] as TreeSet, + group: true + ] + if (lines.containsKey(key)) + throw new IllegalStateException('Duplicate group: ' + line) + + lines[key] = group + } else if (group != null) { + if (line.startsWith('#endgroup')) { + group = null + } else { + def (modifier, cls, desc, comment, key) = parse.call(line) + group['existing'].add(key) + } + } else if (line.startsWith('#endgroup')) { + throw new IllegalStateException('Invalid group ending: ' + line) + } else if (line.startsWith('#')) { + //Nom + } else { + def (modifier, cls, desc, comment, key) = parse.call(line) + if (lines.containsKey(key)) { + println('Duplicate: ' + line) + continue + } + lines[key] = [modifier: modifier, cls: cls, desc: desc, comment: comment, group: false] + } + } + + // Process Groups, this will remove any entries outside the group that is covered by the group + for (def key : new ArrayList<>(lines.keySet())) { + def entry = lines.get(key) + if (entry != null && entry['group']) { + def cls = entry['cls'] + def jcls = json.get(cls.replaceAll('\\.', '/')) + if (jcls == null) { + lines.remove(key) + println('Invalid Group: ' + key) + } else if ('*'.equals(entry['desc'])) { + if (!jcls.containsKey('fields')) { + lines.remove(key) + println('Invalid Group, Class has no fields: ' + key) + } else { + jcls['fields'].each { field, value -> + def fkey = cls + ' ' + field + if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) { + if (lines.containsKey(fkey)) { + lines.remove(fkey) + } else if (!entry['existing'].contains(fkey)) { + println('Added: ' + fkey) + } + entry['children'].add(fkey) + } else if (lines.containsKey(fkey)) { + lines.remove(fkey) + println('Removed: ' + fkey) + } + } + entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } + } + } else if ('*()'.equals(entry['desc'])) { + if (!jcls.containsKey('methods')) { + lines.remove(key) + println('Invalid Group, Class has no methods: ' + key) + } else { + jcls['methods'].each{ mtd, value -> + if (mtd.startsWith('')) + return + key = cls + ' ' + mtd.replace(' ', '') + if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) { + if (lines.containsKey(key)) { + lines.remove(key) + } else if (!entry['existing'].contains(key)) { + println('Added: ' + key) + } + entry['children'].add(key) + } else if (lines.containsKey(key)) { + lines.remove(key) + println('Removed: ' + key) + } + } + entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } + } + } else if (''.equals(entry['desc'])) { //Make all public non-abstract subclasses + json.each{ tcls,value -> + if (!value.containsKey('methods') || ((value['access'] & Opcodes.ACC_ABSTRACT) != 0)) + return + def parents = [] as Set + def parent = tcls + while (parent != null && json.containsKey(parent)) { + parents.add(parent) + def p = json[parent] + parent = p == null ? null : p['superName'] + } + if (parents.contains(cls.replaceAll('\\.', '/'))) { + value['methods'].each{ mtd, v -> + if (mtd.startsWith('')) { + def child = tcls.replaceAll('/', '\\.') + ' ' + mtd.replace(' ', '') + if (accessLevel.call(v['access']) < 3) { + if (lines.containsKey(child)) { + lines.remove(child) + } else if (!entry['existing'].contains(child)) { + println('Added: ' + child) + } + entry['children'].add(child) + } else if (lines.containsKey(child)) { + lines.remove(child) + println('Removed: ' + child) + } + } + } + } + } + entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } + } + } + } + + // Process normal lines, remove invalid and remove narrowing + for (def key : new ArrayList<>(lines.keySet())) { + def entry = lines.get(key) + if (entry != null && !entry['group']) { + def cls = entry['cls'] + def jcls = json.get(cls.replaceAll('\\.', '/')) + if (jcls == null) { + lines.remove(key) + println('Invalid: ' + key) + } else if (entry['desc'] == '') { + if (accessLevel.call(jcls['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { + lines.remove(key) + println('Invalid Narrowing: ' + key) + } + } else if (!entry['desc'].contains('(')) { + if (!jcls.containsKey('fields') || !jcls['fields'].containsKey(entry['desc'])) { + lines.remove(key) + println('Invalid: ' + key) + } else { + def value = jcls['fields'][entry['desc']] + if (accessLevel.call(value['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { + lines.remove(key) + println('Invalid Narrowing: ' + key) + println(entry.comment) + } + } + } else { + def jdesc = entry['desc'].replace('(', ' (') + if (!jcls.containsKey('methods') || !jcls['methods'].containsKey(jdesc)) { + lines.remove(key) + println('Invalid: ' + key) + } else { + def value = jcls['methods'][jdesc] + if (accessLevel.call(value['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { + lines.remove(key) + println('Invalid Narrowing: ' + key) + } + } + } + } + } + + + def data = [] + lines.each { key,value -> + if (!value.group) { + data.add(value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment)) + } else { + data.add('#group ' + value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment)) + value.children.each{ data.add(value.modifier + ' ' + it) } + data.add('#endgroup') + } + } + f.text = data.join('\n') + } + } +} diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckExcs.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckExcs.groovy new file mode 100644 index 000000000..e5b148018 --- /dev/null +++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckExcs.groovy @@ -0,0 +1,95 @@ +package net.minecraftforge.forge.tasks + +import java.util.ArrayList +import java.util.TreeMap + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.TaskAction + +import org.objectweb.asm.ClassReader +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.Opcodes +import org.objectweb.asm.Type + +import java.util.zip.ZipEntry +import java.util.zip.ZipInputStream + +public class CheckExcs extends DefaultTask { + @InputFile File binary + @InputFiles File[] excs + + @TaskAction + protected void exec() { + Util.init() + def known = [] + binary.withInputStream { i -> + new ZipInputStream(i).withCloseable { zin -> + def visitor = new ClassVisitor(Opcodes.ASM7) { + private String cls + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + this.cls = name + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + known.add(this.cls + '.' + name + descriptor) + super.visitMethod(access, name, descriptor, signature, exceptions) + } + } + ZipEntry zein + while ((zein = zin.nextEntry) != null) { + if (zein.name.endsWith('.class')) { + ClassReader reader = new ClassReader(zin) + reader.accept(visitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES) + } + } + } + } + + excs.each { f -> + def 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) + + if (!line.contains('=')) { + println('Invalid: ' + line) + return + } + + def (key, value) = line.split('=', 2) + if (!known.contains(key)) { + println(key) + println('Invalid: ' + line) + return + } + + def (cls, desc) = key.split('\\.', 2) + if (!desc.contains('(')) { + println('Invalid: ' + line) + return + } + def name = desc.split('\\(', 2)[0] + desc = '(' + desc.split('\\(', 2)[1] + + def (exceptions, args) = value.contains('|') ? value.split('|', 2) : [value, ''] + + if (args.split(',').length != Type.getArgumentTypes(desc).length) { + println('Invalid: ' + line) + return + } + lines.add(line) + } + f.text = lines.sort().join('\n') + } + } +} diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckSAS.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckSAS.groovy new file mode 100644 index 000000000..b2fdad0bd --- /dev/null +++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CheckSAS.groovy @@ -0,0 +1,51 @@ +package net.minecraftforge.forge.tasks + +import java.util.ArrayList +import java.util.TreeMap + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.TaskAction +import org.objectweb.asm.Opcodes + +public class CheckSAS extends DefaultTask { + @InputFile File inheritance + @InputFiles File[] sass + + @TaskAction + protected void exec() { + Util.init() + def json = inheritance.json() + + sass.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') + } + } +} diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CrowdinTask.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CrowdinTask.groovy new file mode 100644 index 000000000..f5d7651f3 --- /dev/null +++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/CrowdinTask.groovy @@ -0,0 +1,65 @@ +package net.minecraftforge.forge.tasks + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.OutputFile + +import java.util.zip.ZipEntry +import java.util.zip.ZipInputStream +import java.util.zip.ZipOutputStream +import java.net.URL + +public class CrowdinTask extends DefaultTask { + @Input String id = 'minecraft-forge' + @Input @Optional String key + @Input boolean json = true + @OutputFile output = project.file("build/${name}/output.zip") + @OutputFile export = project.file("build/${name}/export.json") + + CrowdinTask() { + outputs.upToDateWhen{ false } + } + + @TaskAction + def run() { + if (output.exists()) + output.delete() + + if (key == null) + return + + // Force an export + new URL("https://api.crowdin.com/api/project/${id}/export?key=${key}").withInputStream { i -> + export.withOutputStream { it << i } + } + + if (!export.text.contains('success')) { + throw new RuntimeException("Crowdin export failed, see ${export} for more info") + } + + new URL("https://api.crowdin.com/api/project/${id}/download/all.zip?key=${key}").withInputStream { i -> + new ZipInputStream(i).withCloseable { zin -> + output.withOutputStream { out -> + new ZipOutputStream(out).withCloseable { zout -> + ZipEntry zein + while ((zein = zin.nextEntry) != null) { + if (zein.isDirectory()) { + zout.putNextEntry(new ZipEntry(zein.name)) + } else { + // 1.13+ uses json + if (zein.name.endsWith('.json') == json) { + ZipEntry zeout = new ZipEntry(json ? zein.name.toLowerCase() : zein.name) + zeout.time = 1 + zout.putNextEntry(zeout) + zout << zin + } + } + } + } + } + } + } + } +} diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/DownloadLibrariesTask.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/DownloadLibrariesTask.groovy new file mode 100644 index 000000000..e9c2d0af6 --- /dev/null +++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/DownloadLibrariesTask.groovy @@ -0,0 +1,43 @@ +package net.minecraftforge.forge.tasks + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.OutputDirectory + +import java.io.File +import java.util.HashSet +import java.util.Set +import java.net.URL + +public class DownloadLibrariesTask extends DefaultTask { + @InputFile File input + @OutputDirectory File output = project.file("build/${name}/") + Set libraries = new HashSet<>() + + @TaskAction + def run() { + Util.init() + + def json = input.json().libraries.each { lib -> + //TODO: Thread? + def artifacts = [lib.downloads.artifact] + lib.downloads.get('classifiers', [:]).values() + artifacts.each{ art -> + def target = new File(output, art.path) + libraries.add(target) + if (!target.exists() || !art.sha1.equals(target.sha1())) { + project.logger.lifecycle("Downloading ${art.url}") + if (!target.parentFile.exists()) { + target.parentFile.mkdirs() + } + new URL(art.url).withInputStream { i -> + target.withOutputStream { it << i } + } + if (!art.sha1.equals(target.sha1())) { + throw new IllegalStateException("Failed to download ${art.url} to ${target.canonicalPath} SHA Mismatch") + } + } + } + } + } +} diff --git a/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/Util.groovy b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/Util.groovy new file mode 100644 index 000000000..cefba9fff --- /dev/null +++ b/buildSrc/src/main/groovy/net/minecraftforge/forge/tasks/Util.groovy @@ -0,0 +1,117 @@ +package net.minecraftforge.forge.tasks + +import groovy.json.JsonSlurper + +import java.io.File +import java.security.MessageDigest +import java.text.SimpleDateFormat +import java.util.Date + +public class Util { + static void init() { + File.metaClass.sha1 = { -> + MessageDigest md = MessageDigest.getInstance('SHA-1') + delegate.eachByte 4096, {bytes, size -> + md.update(bytes, 0, size) + } + return md.digest().collect {String.format "%02x", it}.join() + } + + File.metaClass.json = { -> new JsonSlurper().parseText(delegate.text) } + + Date.metaClass.iso8601 = { -> + def format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") + def result = format.format(delegate) + return result[0..21] + ':' + result[22..-1] + } + } + + public static String[] 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 + } + + public static 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://files.minecraftforge.net/maven/${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 + } + + public static def iso8601Now() { new Date().iso8601() } + + public static 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() + } + + private static 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) + } + + private static boolean checkExists(url) { + try { + def code = new URL(url).openConnection().with { + requestMethod = 'HEAD' + connect() + responseCode + } + return code == 200 + } catch (Exception e) { + if (e.toString().contains('unable to find valid certification path to requested target')) + throw new RuntimeException('Failed to connect to ' + url + ': Missing certificate root authority, try updating java') + throw e + } + } +} \ No newline at end of file diff --git a/patches/minecraft/net/minecraft/client/gui/widget/Widget.java.patch b/patches/minecraft/net/minecraft/client/gui/widget/Widget.java.patch index aeb0a0456..511c7cee0 100644 --- a/patches/minecraft/net/minecraft/client/gui/widget/Widget.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/widget/Widget.java.patch @@ -9,14 +9,10 @@ func_238472_a_(p_230431_1_, fontrenderer, this.func_230458_i_(), this.field_230690_l_ + this.field_230688_j_ / 2, this.field_230691_m_ + (this.field_230689_k_ - 8) / 2, j | MathHelper.func_76123_f(this.field_230695_q_ * 255.0F) << 24); } -@@ -206,6 +206,14 @@ +@@ -206,6 +206,10 @@ this.field_230688_j_ = p_230991_1_; } -+ public int getHeight() { -+ return this.field_230689_k_; -+ } -+ + public void setHeight(int value) { + this.field_230689_k_ = value; + } @@ -24,7 +20,7 @@ public void func_230986_a_(float p_230986_1_) { this.field_230695_q_ = p_230986_1_; } -@@ -233,4 +241,17 @@ +@@ -233,4 +237,17 @@ protected void func_230996_d_(boolean p_230996_1_) { this.field_230686_c_ = p_230996_1_; } diff --git a/patches/minecraft/net/minecraft/client/world/ClientWorld.java.patch b/patches/minecraft/net/minecraft/client/world/ClientWorld.java.patch index 1ff4dd5d1..702265025 100644 --- a/patches/minecraft/net/minecraft/client/world/ClientWorld.java.patch +++ b/patches/minecraft/net/minecraft/client/world/ClientWorld.java.patch @@ -62,7 +62,7 @@ if (p_217384_1_ == this.field_73037_M.field_71439_g) { this.field_73037_M.func_147118_V().func_147682_a(new EntityTickableSound(p_217384_3_, p_217384_4_, p_217384_2_)); } -@@ -857,6 +874,7 @@ +@@ -876,6 +893,7 @@ } public void func_239156_a_(Difficulty p_239156_1_) { diff --git a/patches/minecraft/net/minecraft/entity/monster/PhantomEntity.java.patch b/patches/minecraft/net/minecraft/entity/monster/PhantomEntity.java.patch new file mode 100644 index 000000000..ed8d5ac20 --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/monster/PhantomEntity.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/entity/monster/PhantomEntity.java ++++ b/net/minecraft/entity/monster/PhantomEntity.java +@@ -214,7 +214,7 @@ + this.field_203142_b = 60; + List list = PhantomEntity.this.field_70170_p.func_217373_a(this.field_220842_b, PhantomEntity.this, PhantomEntity.this.func_174813_aQ().func_72314_b(16.0D, 64.0D, 16.0D)); + if (!list.isEmpty()) { +- list.sort(Comparator.comparing(Entity::func_226278_cu_).reversed()); ++ list.sort(Comparator.comparing(Entity::func_226278_cu_).reversed()); + + for(PlayerEntity playerentity : list) { + if (PhantomEntity.this.func_213344_a(playerentity, EntityPredicate.field_221016_a)) { diff --git a/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java b/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java index fb40a7c52..15b1960a2 100644 --- a/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java +++ b/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java @@ -78,7 +78,7 @@ public class NotificationModUpdateScreen extends Screen int x = modButton.field_230690_l_; int y = modButton.field_230691_m_; int w = modButton.func_230998_h_(); - int h = modButton.getHeight(); + int h = modButton.func_238483_d_(); func_238463_a_(mStack, x + w - (h / 2 + 4), y + (h / 2 - 4), showNotification.getSheetOffset() * 8, (showNotification.isAnimated() && ((System.currentTimeMillis() / 800 & 1) == 1)) ? 8 : 0, 8, 8, 64, 16); } diff --git a/src/main/resources/forge.exc b/src/main/resources/forge.exc index 3c2d7ab4d..758aa8c6e 100644 --- a/src/main/resources/forge.exc +++ b/src/main/resources/forge.exc @@ -1,127 +1,44 @@ net/minecraft/block/FireBlock.tryCatchFire(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;ILjava/util/Random;ILnet/minecraft/util/Direction;)V=|p_176536_1_,p_176536_2_,p_176536_3_,p_176536_4_,p_176536_5_,face -net/minecraft/block/FlowerPotBlock.(Lnet/minecraft/block/FlowerPotBlock;Lnet/minecraft/block/Block;Lnet/minecraft/block/Block$Properties;)V=|emptyPot,p_i48395_1_,p_i48395_2_ -net/minecraft/block/FlowerPotBlock.(Ljava/util/function/Supplier;Ljava/util/function/Supplier;Lnet/minecraft/block/Block$Properties;)V=|emptyPot,p_i48395_1_,p_i48395_2_ -net/minecraft/block/PoweredRailBlock.(Lnet/minecraft/block/Block$Properties;Z)=|p_i48349_1_,isActivator net/minecraft/block/RedstoneWireBlock.canConnectTo(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Z=|p_176343_0_,world,pos,p_176343_1_ - -net/minecraft/client/gui/screen/Screen.renderToolTip(Lcom/mojang/blaze3d/matrix/MatrixStack;Ljava/util/List;IILnet/minecraft/client/gui/FontRenderer;)V=|p_238654_1_,p_238654_2_,p_238654_3_,p_238654_4_,font net/minecraft/client/gui/ScreenManager.getScreenFactory(Lnet/minecraft/inventory/container/ContainerType;Lnet/minecraft/client/Minecraft;ILnet/minecraft/util/text/ITextComponent;)Ljava/util/Optional;=|p_216909_0_,p_216909_1_,p_216909_2_,p_216909_3_ - -net/minecraft/client/renderer/BlockModelRenderer.renderModel(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z=|p_228802_1_,p_228802_2_,p_228802_3_,p_228802_4_,p_228802_5_,p_228802_6_,p_228802_7_,p_228802_8_,p_228802_9_,p_228802_11_,modelData +net/minecraft/client/gui/screen/Screen.renderToolTip(Lcom/mojang/blaze3d/matrix/MatrixStack;Ljava/util/List;IILnet/minecraft/client/gui/FontRenderer;)V=|p_238654_1_,p_238654_2_,p_238654_3_,p_238654_4_,font net/minecraft/client/renderer/BlockModelRenderer.renderModel(Lcom/mojang/blaze3d/matrix/MatrixStack$Entry;Lcom/mojang/blaze3d/vertex/IVertexBuilder;Lnet/minecraft/block/BlockState;Lnet/minecraft/client/renderer/model/IBakedModel;FFFIILnet/minecraftforge/client/model/data/IModelData;)V=|p_228804_1_,p_228804_2_,p_228804_3_,p_228804_4_,p_228804_5_,p_228804_6_,p_228804_7_,p_228804_8_,p_228804_9_,modelData -net/minecraft/client/renderer/BlockModelRenderer.renderModelFlat(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z=|p_228806_1_,p_228806_2_,p_228806_3_,p_228806_4_,p_228806_5_,p_228806_6_,p_228806_7_,p_228806_8_,p_228806_9_,p_228806_11_,modelData -net/minecraft/client/renderer/BlockModelRenderer.renderModelSmooth(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z=|p_228805_1_,p_228805_2_,p_228805_3_,p_228805_4_,p_228805_5_,p_228805_6_,p_228805_7_,p_228805_8_,p_228805_9_,p_228805_11_,modelData net/minecraft/client/renderer/BlockRendererDispatcher.renderBlock(Lnet/minecraft/block/BlockState;Lcom/mojang/blaze3d/matrix/MatrixStack;Lnet/minecraft/client/renderer/IRenderTypeBuffer;IILnet/minecraftforge/client/model/data/IModelData;)V=|p_228791_1_,p_228791_2_,p_228791_3_,p_228791_4_,p_228791_5_,modelData -net/minecraft/client/renderer/BlockRendererDispatcher.renderModel(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/ILightReader;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;Lnet/minecraftforge/client/model/data/IModelData;)V=|p_228792_1_,p_228792_2_,p_228792_3_,p_228792_4_,p_228792_5_,modelData -net/minecraft/client/renderer/BlockRendererDispatcher.renderModel(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/ILightReader;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;Lnet/minecraftforge/client/model/data/IModelData;)Z=|p_228793_1_,p_228793_2_,p_228793_3_,p_228793_4_,p_228793_5_,p_228793_6_,p_228793_7_,modelData -net/minecraft/client/renderer/FluidBlockRenderer.vertex(Lcom/mojang/blaze3d/vertex/IVertexBuilder;DDDFFFFFFI)V=|p_228797_1_,p_228797_2_,p_228797_4_,p_228797_6_,p_228797_8_,p_228797_9_,p_228797_10_,alpha,p_228797_11_,p_228797_12_,p_228797_13_ net/minecraft/client/renderer/FogRenderer.setupFog(Lnet/minecraft/client/renderer/ActiveRenderInfo;Lnet/minecraft/client/renderer/FogRenderer$FogType;FZF)V=|p_228372_0_,p_228372_1_,p_228372_2_,p_228372_3_,partialTicks net/minecraft/client/renderer/OverlayRenderer.getOverlayBlock(Lnet/minecraft/entity/player/PlayerEntity;)Lorg/apache/commons/lang3/tuple/Pair;=|p_230018_0_ - -net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.(Lnet/minecraft/world/World;Lnet/minecraft/client/renderer/WorldRenderer;Ljava/util/concurrent/Executor;ZLnet/minecraft/client/renderer/RegionRenderCacheBuilder;I)V=|p_i226020_1_,p_i226020_2_,p_i226020_3_,p_i226020_4_,p_i226020_5_,countRenderBuilders -net/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender$ChunkRenderTask.(Lnet/minecraft/util/math/ChunkPos;D)V=|pos,p_i226023_2_ -net/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender$RebuildTask.(Lnet/minecraft/util/math/ChunkPos;DLnet/minecraft/client/renderer/chunk/ChunkRenderCache;)V=|pos,p_i226024_2_,p_i226024_4_ -net/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender$SortTransparencyTask.(Lnet/minecraft/util/math/ChunkPos;DLnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$CompiledChunk;)V=|pos,p_i226025_2_,p_i226025_4_ - -net/minecraft/client/renderer/entity/layers/ArmorLayer.renderArmor(Lcom/mojang/blaze3d/matrix/MatrixStack;Lnet/minecraft/client/renderer/IRenderTypeBuffer;IZLnet/minecraft/client/renderer/entity/model/BipedModel;FFFLnet/minecraft/util/ResourceLocation;)V=|p_229128_1_,p_229128_2_,p_229128_3_,p_229128_5_,p_229128_6_,p_229128_8_,p_229128_9_,p_229128_10_,armorResource - net/minecraft/client/renderer/WorldRenderer.playRecord(Lnet/minecraft/util/SoundEvent;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/item/MusicDiscItem;)V=|p_184377_1_,p_184377_2_,musicDiscItem - -net/minecraft/client/renderer/model/BlockModel.bake(Lnet/minecraft/client/renderer/model/ModelBakery;Lnet/minecraft/client/renderer/model/BlockModel;Ljava/util/function/Function;Lnet/minecraft/client/renderer/texture/IModelTransform;Lnet/minecraft/client/renderer/vertex/VertexFormat;)Lnet/minecraft/client/renderer/model/IBakedModel;=|p_217644_1_,p_217644_2_,p_217644_3_,p_217644_4_,format +net/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender$ChunkRenderTask.(Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender;Lnet/minecraft/util/math/ChunkPos;D)V=|p_i226023_1_,pos,p_i226023_2_ +net/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender$RebuildTask.(Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender;Lnet/minecraft/util/math/ChunkPos;DLnet/minecraft/client/renderer/chunk/ChunkRenderCache;)V=|p_i226024_1_,pos,p_i226024_2_,p_i226024_4_ +net/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender$SortTransparencyTask.(Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$ChunkRender;Lnet/minecraft/util/math/ChunkPos;DLnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$CompiledChunk;)V=|p_i226025_1_,pos,p_i226025_2_,p_i226025_4_ +net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.(Lnet/minecraft/world/World;Lnet/minecraft/client/renderer/WorldRenderer;Ljava/util/concurrent/Executor;ZLnet/minecraft/client/renderer/RegionRenderCacheBuilder;I)V=|p_i226020_1_,p_i226020_2_,p_i226020_3_,p_i226020_4_,p_i226020_5_,countRenderBuilders net/minecraft/client/renderer/model/BlockModel.bakeVanilla(Lnet/minecraft/client/renderer/model/ModelBakery;Lnet/minecraft/client/renderer/model/BlockModel;Ljava/util/function/Function;Lnet/minecraft/client/renderer/model/IModelTransform;Lnet/minecraft/util/ResourceLocation;Z)Lnet/minecraft/client/renderer/model/IBakedModel;=|p_228813_1_,p_228813_2_,p_228813_3_,p_228813_4_,p_228813_5_,p_228813_6_ net/minecraft/client/renderer/model/BlockModel.getOverrides(Lnet/minecraft/client/renderer/model/ModelBakery;Lnet/minecraft/client/renderer/model/BlockModel;Ljava/util/function/Function;)Lnet/minecraft/client/renderer/model/ItemOverrideList;=|p_217646_1_,p_217646_2_,textureGetter net/minecraft/client/renderer/model/BlockModel.makeBakedQuad(Lnet/minecraft/client/renderer/model/BlockPart;Lnet/minecraft/client/renderer/model/BlockPartFace;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;Lnet/minecraft/util/Direction;Lnet/minecraft/client/renderer/model/IModelTransform;Lnet/minecraft/util/ResourceLocation;)Lnet/minecraft/client/renderer/model/BakedQuad;=|p_228812_0_,p_228812_1_,p_228812_2_,p_228812_3_,p_228812_4_,p_228812_5_ -net/minecraft/client/renderer/model/FaceBakery.fillVertexData([IILnet/minecraft/util/Direction;Lnet/minecraft/client/renderer/model/BlockFaceUV;[FLnet/minecraft/client/renderer/texture/TextureAtlasSprite;Lnet/minecraftforge/common/model/ITransformation;Lnet/minecraft/client/renderer/model/BlockPartRotation;Z)V=|p_188015_1_,p_188015_2_,p_188015_3_,p_188015_4_,p_188015_5_,p_188015_6_,p_188015_7_,p_188015_8_,p_188015_9_ -net/minecraft/client/renderer/model/FaceBakery.makeBakedQuad(Lnet/minecraft/client/renderer/Vector3f;Lnet/minecraft/client/renderer/Vector3f;Lnet/minecraft/client/renderer/model/BlockPartFace;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;Lnet/minecraft/util/Direction;Lnet/minecraft/client/renderer/texture/IModelTransform;Lnet/minecraft/client/renderer/model/BlockPartRotation;Z)Lnet/minecraft/client/renderer/model/BakedQuad;=|p_217648_1_,p_217648_2_,p_217648_3_,p_217648_4_,p_217648_5_,p_217648_6_,p_217648_7_,p_217648_8_,p_217648_9_ -net/minecraft/client/renderer/model/FaceBakery.makeQuadVertexData(Lnet/minecraft/client/renderer/model/BlockFaceUV;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;Lnet/minecraft/util/Direction;[FLnet/minecraftforge/common/model/ITransformation;Lnet/minecraft/client/renderer/model/BlockPartRotation;Z)[I=|p_188012_1_,p_188012_2_,p_188012_3_,p_188012_4_,p_188012_5_,p_188012_6_,p_188012_7_ net/minecraft/client/renderer/model/ItemOverrideList.(Lnet/minecraft/client/renderer/model/ModelBakery;Lnet/minecraft/client/renderer/model/IUnbakedModel;Ljava/util/function/Function;Ljava/util/function/Function;Ljava/util/List;)V=|p_i50984_1_,p_i50984_2_,p_i50984_3_,textureGetter,p_i50984_4_ net/minecraft/client/renderer/model/ModelBakery.(Lnet/minecraft/resources/IResourceManager;Lnet/minecraft/client/renderer/color/BlockColors;Z)V=|p_i226056_1_,p_i226056_2_,vanillaBakery net/minecraft/client/renderer/model/ModelBakery.addModelToCache(Lnet/minecraft/util/ResourceLocation;)V=|p_217843_1_ net/minecraft/client/renderer/model/ModelBakery.getBakedModel(Lnet/minecraft/util/ResourceLocation;Lnet/minecraft/client/renderer/model/IModelTransform;Ljava/util/function/Function;)Lnet/minecraft/client/renderer/model/IBakedModel;=|p_217845_1_,p_217845_2_,textureGetter net/minecraft/client/renderer/model/ModelBakery.processLoading(Lnet/minecraft/profiler/IProfiler;I)V=|p_i226056_3_,p_i226056_4_ net/minecraft/client/renderer/model/MultipartBakedModel.getQuads(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/Direction;Ljava/util/Random;Lnet/minecraftforge/client/model/data/IModelData;)Ljava/util/List;=|p_200117_1_,p_200117_2_,p_200117_3_,modelData -net/minecraft/client/renderer/model/VariantList.bake(Lnet/minecraft/client/renderer/model/ModelBakery;Ljava/util/function/Function;Lnet/minecraft/client/renderer/texture/IModelTransform;Lnet/minecraft/client/renderer/vertex/VertexFormat;)Lnet/minecraft/client/renderer/model/IBakedModel;=|p_217641_1_,p_217641_2_,p_217641_3_,format net/minecraft/client/renderer/model/WeightedBakedModel.getQuads(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/Direction;Ljava/util/Random;Lnet/minecraftforge/client/model/data/IModelData;)Ljava/util/List;=|p_200117_1_,p_200117_2_,p_200117_3_,modelData - -net/minecraft/client/renderer/model/multipart/Multipart.bake(Lnet/minecraft/client/renderer/model/ModelBakery;Ljava/util/function/Function;Lnet/minecraft/client/renderer/texture/IModelTransform;Lnet/minecraft/client/renderer/vertex/VertexFormat;)Lnet/minecraft/client/renderer/model/IBakedModel;=|p_217641_1_,p_217641_2_,p_217641_3_,format - -net/minecraft/client/resources/ClientResourcePackInfo.(Ljava/lang/String;ZLjava/util/function/Supplier;Lnet/minecraft/resources/IResourcePack;Lnet/minecraft/resources/data/PackMetadataSection;Lnet/minecraft/resources/ResourcePackInfo$Priority;Z)V=|p_i48113_1_,p_i48113_2_,p_i48113_3_,p_i48113_4_,p_i48113_5_,p_i48113_6_,hidden -net/minecraft/client/resources/ClientResourcePackInfo.(Ljava/lang/String;ZLjava/util/function/Supplier;Lnet/minecraft/util/text/ITextComponent;Lnet/minecraft/util/text/ITextComponent;Lnet/minecraft/resources/PackCompatibility;Lnet/minecraft/resources/ResourcePackInfo$Priority;ZLnet/minecraft/client/renderer/texture/NativeImage;Z)V=|p_i48114_1_,p_i48114_2_,p_i48114_3_,p_i48114_4_,p_i48114_5_,p_i48114_6_,p_i48114_7_,p_i48114_8_,p_i48114_9_,hidden - net/minecraft/entity/Entity.changeDimension(Lnet/minecraft/world/server/ServerWorld;Lnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_241206_1_,teleporter -net/minecraft/entity/EntityClassification.create(Ljava/lang/String;Ljava/lang/String;IZZ)Lnet/minecraft/entity/EntityClassification;=|name,p_i50381_3_,p_i50381_4_,p_i50381_5_,p_i50381_6_ -net/minecraft/entity/EntityType.(Lnet/minecraft/entity/EntityType$IFactory;Lnet/minecraft/entity/EntityClassification;ZZZZLnet/minecraft/entity/EntitySize;Ljava/util/function/Predicate;Ljava/util/function/ToIntFunction;Ljava/util/function/ToIntFunction;Ljava/util/function/BiFunction;)V=|p_i51559_1_,p_i51559_2_,p_i51559_3_,p_i51559_4_,p_i51559_5_,p_i51559_6_,p_i51559_7_,velocityUpdateSupplier,trackingRangeSupplier,updateIntervalSupplier,customClientFactory - net/minecraft/entity/item/EnderPearlEntity.changeDimension(Lnet/minecraft/world/server/ServerWorld;Lnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_241206_1_,teleporter net/minecraft/entity/item/ItemEntity.changeDimension(Lnet/minecraft/world/server/ServerWorld;Lnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_241206_1_,teleporter net/minecraft/entity/item/minecart/ContainerMinecartEntity.changeDimension(Lnet/minecraft/world/server/ServerWorld;Lnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_241206_1_,teleporter - net/minecraft/entity/merchant/villager/AbstractVillagerEntity.changeDimension(Lnet/minecraft/world/server/ServerWorld;Lnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_241206_1_,teleporter - net/minecraft/entity/player/PlayerEntity.getDigSpeed(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)F=|p_184813_1_,pos net/minecraft/entity/player/ServerPlayerEntity.changeDimension(Lnet/minecraft/world/server/ServerWorld;Lnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;=|p_241206_1_,teleporter - net/minecraft/item/BoneMealItem.applyBonemeal(Lnet/minecraft/item/ItemStack;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/player/PlayerEntity;)Z=|p_195966_0_,p_195966_1_,p_195966_2_,player net/minecraft/item/FilledMapItem.getCustomMapData(Lnet/minecraft/item/ItemStack;Lnet/minecraft/world/World;)Lnet/minecraft/world/storage/MapData;=|p_195950_0_,p_195950_1_ net/minecraft/item/ItemStack.(Lnet/minecraft/util/IItemProvider;ILnet/minecraft/nbt/CompoundNBT;)V=|p_i48204_1_,p_i48204_2_,capNBT net/minecraft/item/ItemStack.onItemUse(Lnet/minecraft/item/ItemUseContext;)Lnet/minecraft/util/ActionResultType;=|p_196084_1_ net/minecraft/item/ItemStack.onItemUse(Lnet/minecraft/item/ItemUseContext;Ljava/util/function/Function;)Lnet/minecraft/util/ActionResultType;=|p_196084_1_,callback -net/minecraft/item/Rarity.create(Ljava/lang/String;Lnet/minecraft/util/text/TextFormatting;)Lnet/minecraft/item/EnumRarity;=|name,p_i48837_3_ - net/minecraft/network/PacketBuffer.writeItemStack(Lnet/minecraft/item/ItemStack;Z)Lnet/minecraft/network/PacketBuffer;=|p_150788_1_,limitedTag - net/minecraft/potion/PotionBrewing$MixPredicate.(Lnet/minecraftforge/registries/ForgeRegistryEntry;Lnet/minecraft/item/crafting/Ingredient;Lnet/minecraftforge/registries/ForgeRegistryEntry;)V=|p_i47570_1_,p_i47570_2_,p_i47570_3_ - -net/minecraft/resources/ResourcePackInfo.(Ljava/lang/String;ZLjava/util/function/Supplier;Lnet/minecraft/util/text/ITextComponent;Lnet/minecraft/util/text/ITextComponent;Lnet/minecraft/resources/PackCompatibility;Lnet/minecraft/resources/ResourcePackInfo$Priority;ZZ)V=|p_i47907_1_,p_i47907_2_,p_i47907_3_,p_i47907_4_,p_i47907_5_,p_i47907_6_,p_i47907_7_,p_i47907_8_,hidden -net/minecraft/resources/ResourcePackInfo.(Ljava/lang/String;ZLjava/util/function/Supplier;Lnet/minecraft/resources/IResourcePack;Lnet/minecraft/resources/data/PackMetadataSection;Lnet/minecraft/resources/ResourcePackInfo$Priority;Z)V=|p_i47908_1_,p_i47908_2_,p_i47908_3_,p_i47908_4_,p_i47908_5_,p_i47908_6_,hidden - net/minecraft/server/management/PlayerInteractionManager.removeBlock(Lnet/minecraft/util/math/BlockPos;Z)Z=|p_180235_1_,canHarvest - -net/minecraft/tags/Tag.(Lnet/minecraft/util/ResourceLocation;Ljava/util/Collection;ZZ)V=|p_i48224_1_,p_i48224_2_,p_i48224_3_,replace - -net/minecraft/tileentity/BannerPattern.create(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lnet/minecraft/item/ItemStack;)Lnet/minecraft/tileentity/BannerPattern;=|enumName,p_i47246_3_,p_i47246_4_,p_i47246_5_ -net/minecraft/tileentity/BannerPattern.create(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lnet/minecraft/tileentity/BannerPattern;=|enumName,p_i47247_3_,p_i47247_4_,p_i47247_5_,p_i47247_6_,p_i47247_7_ - -net/minecraft/util/math/shapes/EntitySelectionContext.(Lnet/minecraft/entity/Entity;ZDLnet/minecraft/item/Item;)V=|entityIn,p_i51181_1_,p_i51181_2_,p_i51181_4_ - -net/minecraft/world/World.getBiomeBody(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/world/biome/Biome;=|p_180494_1_ -net/minecraft/world/World.markAndNotifyBlock(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/chunk/Chunk;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V=|p_180501_1_,chunk,blockstate,p_180501_2_,p_180501_3_ -net/minecraft/world/World.getSunBrightnessBody(F)F=|p_72971_1_ -net/minecraft/world/World.getSkyColorBody(Lnet/minecraft/util/math/BlockPos;F)Lnet/minecraft/util/math/Vec3d;=|p_217382_1_,p_217382_2_ -net/minecraft/world/World.getCloudColorBody(F)Lnet/minecraft/util/math/Vec3d;=|p_72824_1_ - -net/minecraft/world/chunk/BlockStateContainer.setBits(IZ)V=|p_186012_1_,forceBits - -net/minecraft/world/dimension/DimensionType.(ILjava/lang/String;Ljava/lang/String;Ljava/util/function/BiFunction;ZLnet/minecraftforge/common/ModDimension;Lnet/minecraft/network/PacketBuffer;)V=|p_i49935_1_,p_i49935_2_,p_i49935_3_,p_i49935_4_,p_i49935_5_,modType,data - -net/minecraft/world/end/DragonFightManager.(Lnet/minecraft/world/server/ServerWorld;Lnet/minecraft/nbt/CompoundNBT;Lnet/minecraft/world/dimension/EndDimension;)V=|p_i46669_1_,p_i46669_2_,dim - -net/minecraft/world/gen/feature/HugeTreesFeature.validSoil(Lnet/minecraft/world/gen/IWorldGenerationReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraftforge/common/IPlantable;)Z=|p_202405_1_,p_202405_2_,sapling -net/minecraft/world/gen/feature/OreFeatureConfig$FillerBlockType.create(Ljava/lang/String;Ljava/lang/String;Ljava/util/function/Predicate;)Lnet/minecraft/world/gen/feature/OreFeatureConfig$FillerBlockType;=|enumName,p_i50618_3_,p_i50618_4_ - net/minecraft/world/gen/feature/jigsaw/JigsawPattern$PlacementBehaviour.create(Ljava/lang/String;Ljava/lang/String;Lcom/google/common/collect/ImmutableList;)Lnet/minecraft/world/gen/feature/jigsaw/JigsawPattern$PlacementBehaviour;=|enumName,p_i50487_3_,p_i50487_4_ - -net/minecraft/world/gen/feature/template/StructureProcessor.process(Lnet/minecraft/world/IWorldReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/gen/feature/template/Template$BlockInfo;Lnet/minecraft/world/gen/feature/template/Template$BlockInfo;Lnet/minecraft/world/gen/feature/template/PlacementSettings;Lnet/minecraft/world/gen/feature/template/Template;)Lnet/minecraft/world/gen/feature/template/Template$BlockInfo;=|p_215194_1_,p_215194_2_,p_215194_3_,p_215194_4_,p_215194_5_,template -net/minecraft/world/gen/feature/template/Template.transformedVec3d(Lnet/minecraft/world/gen/feature/template/PlacementSettings;Lnet/minecraft/util/math/Vec3d;)Lnet/minecraft/util/math/Vec3d;=|p_186266_0_,p_186266_1_ -net/minecraft/world/gen/feature/template/Template.processBlockInfos(Lnet/minecraft/world/gen/feature/template/Template;Lnet/minecraft/world/IWorld;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/gen/feature/template/PlacementSettings;Ljava/util/List;)Ljava/util/List;=|template,p_215387_0_,p_215387_1_,p_215387_2_,p_215387_3_ net/minecraft/world/gen/feature/template/Template.processEntityInfos(Lnet/minecraft/world/gen/feature/template/Template;Lnet/minecraft/world/IWorld;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/gen/feature/template/PlacementSettings;Ljava/util/List;)Ljava/util/List;=|template,p_215387_0_,p_215387_1_,p_215387_2_,p_215387_3_ -net/minecraft/world/gen/feature/template/Template.addEntitiesToWorld(Lnet/minecraft/world/IWorld;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/gen/feature/template/PlacementSettings;Lnet/minecraft/util/Mirror;Lnet/minecraft/util/Rotation;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/MutableBoundingBox;)V=|p_207668_1_,p_207668_2_,placementIn,p_207668_3_,p_207668_4_,p_207668_5_,p_207668_6_ - -net/minecraft/world/server/ServerWorld.canMineBlockBody(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/math/BlockPos;)Z=|p_175660_1_,p_175660_2_ -net/minecraft/world/server/ServerWorld.removeEntityComplete(Lnet/minecraft/entity/Entity;Z)V=|p_217484_1_,keepData net/minecraft/world/server/ServerWorld.removeEntity(Lnet/minecraft/entity/Entity;Z)V=|p_217467_1_,keepData +net/minecraft/world/server/ServerWorld.removeEntityComplete(Lnet/minecraft/entity/Entity;Z)V=|p_217484_1_,keepData net/minecraft/world/server/ServerWorld.removePlayer(Lnet/minecraft/entity/player/ServerPlayerEntity;Z)V=|p_217434_1_,keepData - -net/minecraft/world/spawner/WorldEntitySpawner.canSpawnAtBody(Lnet/minecraft/entity/EntitySpawnPlacementRegistry$PlacementType;Lnet/minecraft/world/IWorldReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/EntityType;)Z=|p_209382_0_,p_209382_1_,p_209382_2_,p_209382_3_ -net/minecraft/world/spawner/WorldEntitySpawner.getSpawnList(Lnet/minecraft/world/gen/ChunkGenerator;Lnet/minecraft/entity/EntityClassification;Ljava/util/Random;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/World;)Z|p_222264_0_,p_222264_1_,p_222264_2_,p_222264_3_,world -net/minecraft/world/spawner/WorldEntitySpawner.getSpawnList(Lnet/minecraft/world/gen/ChunkGenerator;Lnet/minecraft/entity/EntityClassification;Lnet/minecraft/world/biome/Biome$SpawnListEntry;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/World;)Z|p_222261_0_,p_222261_1_,p_222261_2_,p_222261_3_,world - -net/minecraft/world/storage/SaveFormat.getWorldData(Ljava/io/File;Lcom/mojang/datafixers/DataFixer;Lnet/minecraft/world/storage/SaveHandler;)Lnet/minecraft/world/storage/WorldInfo;=|p_215780_0_,p_215780_1_,saveHandler - -net/minecraft/world/storage/loot/LootEntry.(II[Lnet/minecraft/world/storage/loot/conditions/LootCondition;Ljava/lang/String;)V=|p_i46642_1_,p_i46642_2_,p_i46642_3_,entryName -net/minecraft/world/storage/loot/LootEntryEmpty.(II[Lnet/minecraft/world/storage/loot/conditions/LootCondition;Ljava/lang/String;)V=|p_i46645_1_,p_i46645_2_,p_i46645_3_,entryName -net/minecraft/world/storage/loot/LootEntryItem.(Lnet/minecraft/item/Item;II[Lnet/minecraft/world/storage/loot/functions/LootFunction;[Lnet/minecraft/world/storage/loot/conditions/LootCondition;Ljava/lang/String;)V=|p_i46644_1_,p_i46644_2_,p_i46644_3_,p_i46644_4_,p_i46644_5_,entryName -net/minecraft/world/storage/loot/LootEntryTable.(Lnet/minecraft/util/ResourceLocation;II[Lnet/minecraft/world/storage/loot/conditions/LootCondition;Ljava/lang/String;)V=|p_i46639_1_,p_i46639_2_,p_i46639_3_,p_i46639_4_,entryName -net/minecraft/world/storage/loot/LootPool.([Lnet/minecraft/world/storage/loot/LootEntry;[Lnet/minecraft/world/storage/loot/conditions/LootCondition;Lnet/minecraft/world/storage/loot/RandomValueRange;Lnet/minecraft/world/storage/loot/RandomValueRange;Ljava/lang/String;)V=|p_i46643_1_,p_i46643_2_,p_i46643_3_,p_i46643_4_ - -net/minecraft/tags/NetworkTagManager.read(Lnet/minecraft/network/PacketBuffer;Lnet/minecraft/tags/NetworkTagManager;)Lnet/minecraft/tags/NetworkTagManager;=|p_199714_0_,networktagmanager +net/minecraft/world/spawner/WorldEntitySpawner.canSpawnAtBody(Lnet/minecraft/entity/EntitySpawnPlacementRegistry$PlacementType;Lnet/minecraft/world/IWorldReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/EntityType;)Z=|p_209382_0_,p_209382_1_,p_209382_2_,p_209382_3_ \ No newline at end of file diff --git a/src/main/resources/forge.sas b/src/main/resources/forge.sas index 8de57315e..8e766fff2 100644 --- a/src/main/resources/forge.sas +++ b/src/main/resources/forge.sas @@ -86,7 +86,7 @@ net/minecraft/resources/IResourceManager func_219533_b(Lnet/minecraft/util/Resou net/minecraft/resources/FallbackResourceManager func_219533_b(Lnet/minecraft/util/ResourceLocation;)Z net/minecraft/resources/IResourceManager$Instance func_219533_b(Lnet/minecraft/util/ResourceLocation;)Z net/minecraft/resources/SimpleReloadableResourceManager func_219533_b(Lnet/minecraft/util/ResourceLocation;)Z -net/minecraft/tags/TagCollection func_199913_a(Ljava/lang/Object;)Ljava/util/Collection; # getOwningTags +net/minecraft/tags/ITagCollection func_199913_a(Ljava/lang/Object;)Ljava/util/Collection; # getOwningTags net/minecraft/util/Direction func_176739_a(Ljava/lang/String;)Lnet/minecraft/util/Direction; # byName net/minecraft/util/Direction$Axis func_176717_a(Ljava/lang/String;)Lnet/minecraft/util/Direction$Axis; # byName net/minecraft/util/math/vector/Vector3d func_216371_e()Lnet/minecraft/util/math/vector/Vector3d;