diff --git a/build.gradle b/build.gradle index 0e3befbe8..36749dfb1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,477 +1,116 @@ buildscript { repositories { mavenLocal() + maven { url = 'http://files.minecraftforge.net/maven' } + jcenter() mavenCentral() - maven { - name = "forge" - url = "http://files.minecraftforge.net/maven" - } - maven { - name = "sonatype" - url = "https://oss.sonatype.org/content/repositories/snapshots/" - } } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' + classpath 'net.minecraftforge.gradle:ForgeGradle:3.+' } } -plugins { - id 'net.minecrell.licenser' version '0.4' -} - -apply plugin: "maven" -def patcher_plugin = plugins.apply('net.minecraftforge.gradle.patcher') -apply plugin: "net.minecraftforge.gradle.launch4j" - -minecraft.version = "1.12.2" - -minecraft { - mappings = 'snapshot_nodoc_20171003' - workspaceDir = "projects" - versionJson = "jsons/${minecraft.version}-dev.json" - buildUserdev = true - buildInstaller = true - installerVersion = "1.5" - - def common = { - patchPrefixOriginal "../src-base/minecraft" - patchPrefixChanged "../src-work/minecraft" - mainClassClient "net.minecraft.launchwrapper.Launch" - tweakClassClient "net.minecraftforge.fml.common.launcher.FMLTweaker" - mainClassServer "net.minecraft.launchwrapper.Launch" - tweakClassServer "net.minecraftforge.fml.common.launcher.FMLServerTweaker" - } - - projects { - forge { - rootDir "." - patchDir "patches/minecraft" - patchAfter "clean" - genPatchesFrom "clean" - genMcpPatches = false - applyMcpPatches = false - s2sKeepImports = true - with common - } - } -} +apply plugin: 'eclipse' group = 'net.minecraftforge' -version = getVersionFromJava(file("src/main/java/net/minecraftforge/common/ForgeVersion.java")) +version = '1.0.0' -extractForgeSources { exclude "**/SideOnly.java", "**/Side.java" } -extractForgeResources { exclude "**/log4j2.xml" } - -genGradleProjects { - addTestCompileDep "junit:junit:4.12" // TODO update unit tests to junit 5 and remove this - addTestCompileDep "org.junit.jupiter:junit-jupiter-api:5.0.0" - addTestCompileDep "org.opentest4j:opentest4j:1.0.0" // needed for junit 5 - addTestCompileDep "org.hamcrest:hamcrest-core:1.3" - filter { dep -> !dep.contains("scala") } +project(':mcp') { + apply plugin: 'net.minecraftforge.gradle.forgedev.mcp' + mcp { + config = 'de.oceanlabs.mcp:mcp_config:1.13@zip' + pipeline = 'joined' + } } -processJson { - releaseJson = "jsons/${minecraft.version}-rel.json" - addReplacements([ - "@minecraft_version@": project.minecraft.version, - "@version@": project.version, - "@project@": "forge", - "@artifact@": "net.minecraftforge:forge:${project.version}", - "@universal_jar@": { outputJar.archiveName }, - "@timestamp@": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), - ]) +project(':clean') { + evaluationDependsOn(':mcp') + apply plugin: 'eclipse' + apply plugin: 'net.minecraftforge.gradle.forgedev.patcher' + repositories { + mavenCentral() + } + patcher { + parent = project(':mcp') + patchedSrc = file('src/main/java') + mappings channel: 'snapshot', version: '20180813-1.12' + mcVersion = '1.13' + } } - -license { - header = project.file('LICENSE-header.txt') - - include 'net/minecraftforge/' - exclude 'net/minecraftforge/fml/repackage/' - exclude 'net/minecraftforge/server/terminalconsole/' - exclude 'net/minecraftforge/fml/common/versioning/ComparableVersion.java' - exclude 'net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java' - exclude 'net/minecraftforge/fml/common/versioning/Restriction.java' - exclude 'net/minecraftforge/fml/common/versioning/VersionRange.java' - - tasks { +project(':forge') { + evaluationDependsOn(':clean') + apply plugin: 'eclipse' + apply plugin: 'net.minecraftforge.gradle.forgedev.patcher' + sourceSets { main { - files = project.files('src/main/java') - } - test { - files = project.files('src/test/java') - } - } -} - -task changelog(type: JenkinsChangelog) { - - // skip if there is no forge jenkins pass - onlyIf { - project.hasProperty('forgeJenkinsPass') - } - - outputs.upToDateWhen { false } // never up to date - serverRoot = "http://ci.jenkins.minecraftforge.net/" - jobName = "minecraftforge" - targetBuild = System.env['BUILD_NUMBER'] ?: project.ext.properties.buildNumber ?:0; - authName = "console_script" - authPassword = project.hasProperty('forgeJenkinsPass') ? project.getProperty('forgeJenkinsPass') : ""; - output = "build/distributions/${project.name}-${project.version}-changelog.txt" -} - -task crowdin(type: CrowdinDownload) { - output = "build/crowdin.zip" - projectId = 'minecraft-forge' - extract = false // we wanna keep it as a zip. not extract it to a folder named "crowdin.zip" - - // task auomatically skips if this is null - if (project.hasProperty('crowdinKey')) - apiKey = project.crowdinKey -} - -def extraTxts = [ - "CREDITS.txt", - "LICENSE.txt", - "LICENSE-Paulscode SoundSystem CodecIBXM.txt", - "LICENSE-Paulscode IBXM Library.txt" -] -if (project.hasProperty('forgeJenkinsPass')) - extraTxts += changelog - -import groovy.json.JsonSlurper; -import groovy.json.JsonBuilder; - -task extractAnnotationsVanilla(type: net.minecraftforge.gradle.tasks.TaskExtractAnnotationsText, dependsOn: deobfuscateJar) { - jar = deobfuscateJar.outJar - output = 'build/vanilla_annotations_raw.json' - doLast { //Re-dump it so it's in groovy's sorted order. Because I like being able to do diffs against things. - def json = new JsonSlurper().parseText(file(output).text) - file(output).write(new JsonBuilder(json).toPrettyString()) - } -} - -task reobfToSRG(type: net.minecraftforge.gradle.patcher.TaskReobfuscate, dependsOn: reobfuscate) { - srg = patcher_plugin.delayedFile('{CACHE_DIR}/de/oceanlabs/mcp/mcp_{MAPPING_CHANNEL}/{MAPPING_VERSION}/{MC_VERSION}/srgs/mcp-srg.srg') - exc = reobfuscate.exc - preFFJar = reobfuscate.preFFJar - methodsCsv = reobfuscate.methodsCsv - fieldsCsv = reobfuscate.fieldsCsv - addLibs reobfuscate.libs - inJar = patcher_plugin.delayedFile('{BUILD_DIR}/localCache/Forge/recompiled.jar') - outJar = 'build/forge_srg.jar' -} - -task extractAnnotationsForgeSRG(type: net.minecraftforge.gradle.tasks.TaskExtractAnnotationsText, dependsOn: reobfToSRG) { - jar = reobfToSRG.outJar - output = 'build/forge_annotations.json' - doLast { //Re-dump it so it's in groovy's sorted order. Because I like being able to do diffs against things. - def json = new JsonSlurper().parseText(file(output).text) - json.entrySet().removeIf{e -> (!e.key.startsWith('net/minecraft/') && !e.key.startsWith('net/minecraftforge/')) || e.key.endsWith('/package-info')} - file(output).write(new JsonBuilder(json).toPrettyString()) - } -} - -task fixAnnotationsJson(dependsOn: [extractAnnotationsVanilla, extractAnnotationsForgeSRG, genPatches]) { - inputs.file(extractAnnotationsVanilla.output) - inputs.file(extractAnnotationsForgeSRG.output) - outputs.file('build/vanilla_annotations.json') - doLast { - def json_vanilla = new JsonSlurper().parseText(file(extractAnnotationsVanilla.output).text) as TreeMap - def json_forge = new JsonSlurper().parseText(file(extractAnnotationsForgeSRG.output).text) as TreeMap - def start = minecraft.projects.forge.patchDir.absolutePath.length() - file(minecraft.projects.forge.patchDir).traverse(type: groovy.io.FileType.FILES, nameFilter: {nf -> nf.endsWith('.java.patch')}) { f -> - def cls = f.absolutePath.substring(start+1).replace('\\', '/').replace('.java.patch', '') - json_vanilla.entrySet().removeIf{e -> e.key == cls || e.key.startsWith(cls + '$')} - json_forge.entrySet().stream().filter{e -> e.key == cls || e.key.startsWith(cls + '$')}.forEach{e -> json_vanilla.put(e.key, e.value)} - } - json_forge.entrySet().stream().filter{e -> e.key.startsWith('net/minecraftforge/')}.forEach{e -> json_vanilla.put(e.key, e.value)} - outputs.files.singleFile.write(new JsonBuilder(json_vanilla).toPrettyString()) - } -} - - -outputJar { - classifier = 'universal' - from extraTxts - from(fixAnnotationsJson){ - into 'META-INF' - } - dependsOn fixAnnotationsJson - - // add crowdin locales - from { crowdin.getDidWork() ? zipTree(crowdin.output) : null} - dependsOn 'crowdin' - - manifest.attributes([ - "Main-Class": "net.minecraftforge.fml.relauncher.ServerLaunchWrapper", - "TweakClass": "net.minecraftforge.fml.common.launcher.FMLTweaker", - "Class-Path": getServerClasspath(file("jsons/${minecraft.version}-rel.json")) - ]) -} - -installer { - classifier = 'installer' - from extraTxts - from "src/main/resources/forge_logo.png" - from "src/main/resources/url.png" - rename "forge_logo\\.png", "big_logo.png" -} - -task signUniversal(type: SignJar, dependsOn: 'outputJar') { - onlyIf { - project.hasProperty('jarsigner') - } - - def jarsigner = [:]; - - if (project.hasProperty('jarsigner')) - jarsigner = project.jarsigner; - - alias = 'forge' - exclude "paulscode/**" - storePass = jarsigner.storepass - keyPass = jarsigner.keypass - keyStore = jarsigner.keystore - inputFile = outputJar.archivePath - outputFile = outputJar.archivePath -} -uploadArchives.dependsOn signUniversal -build.dependsOn signUniversal -installer.dependsOn signUniversal - -// MDK package - -import org.apache.tools.ant.filters.ReplaceTokens -task makeMdk(type: Zip) { - baseName = project.name - classifier = "mdk" - version = project.version - destinationDir = file('build/distributions') - - from 'gradlew' - from 'gradlew.bat' - from extraTxts - into ('gradle') { - from 'gradle' - } - into ('eclipse') { - from 'mdk/eclipse' - } - from ('mdk') { - filter(ReplaceTokens, tokens: [ - VERSION: project.version, - MAPPINGS: minecraft.mappings.replace('nodoc_', '') - ]) - exclude 'eclipse' - rename 'gitignore\\.txt', '.gitignore' - } -} -tasks.build.dependsOn makeMdk - -// launch4j - -launch4j { - jar = installer.archivePath.canonicalPath - outfile = file("build/distributions/${project.name}-${project.version}-installer-win.exe").canonicalPath - icon = file('icon.ico').canonicalPath - manifest = file('l4jManifest.xml').canonicalPath - jreMinVersion = '1.8.0' - initialHeapPercent = 5; - maxHeapPercent = 100; -} -tasks.generateXmlConfig.dependsOn installer -tasks.build.dependsOn 'launch4j' - -// MAVEN - -artifacts { - if (project.hasProperty('forgeJenkinsPass')) - archives changelog.output - archives file("build/distributions/${project.name}-${project.version}-installer-win.exe") - archives makeMdk -} - -task ciWriteBuildNumber << { - def file = file("src/main/java/net/minecraftforge/common/ForgeVersion.java"); - def bn = System.getenv("BUILD_NUMBER")?:project.ext.properties.buildNumber?:0; - def outfile = ""; - def ln = "\n"; //Linux line endings because we're on git! - - file.eachLine{ String s -> - if (s.matches("^ public static final int buildVersion = [\\d]+;\$")) - s = " public static final int buildVersion = ${bn};"; - if (s.matches('^ public static final String mcVersion = "[^\\"]+";')) - s = " public static final String mcVersion = \"${minecraft.version}\";"; - outfile += (s+ln); - } - file.write(outfile); -} - -uploadArchives { - repositories.mavenDeployer { - - dependsOn 'build' - - if (project.hasProperty('forgeMavenPass')) - { - repository(url: "http://files.minecraftforge.net/maven/manage/upload") { - authentication(userName: "forge", password: project.getProperty('forgeMavenPass')) // the elvis operator. look it up. + java { + srcDir "$rootDir/src/main/java" } - } - else - { - // local repo folder. Might wanna juset use gradle install if you wanans end it to maven-local - repository(url: 'file://localhost/' + project.file('repo').getAbsolutePath()) - } - - pom { - groupId = project.group - version = project.version - artifactId = project.archivesBaseName - project { - name project.archivesBaseName - packaging 'jar' - description 'Minecraft Forge API' - url 'https://github.com/MinecraftForge/MinecraftForge' - - scm { - url 'https://github.com/MinecraftForge/MinecraftForge' - connection 'scm:git:git://github.com/MinecraftForge/MinecraftForge.git' - developerConnection 'scm:git:git@github.com:MinecraftForge/MinecraftForge.git' - } - - issueManagement { - system 'github' - url 'https://github.com/MinecraftForge/MinecraftForge/issues' - } - - licenses { - license { - name 'Forge Public License' - url 'https://raw.github.com/MinecraftForge/MinecraftForge/master/MinecraftForge-License.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'cpw' - name 'cpw' - roles { role 'developer' } - } - developer { - id 'LexManos' - name 'Lex Manos' - roles { role 'developer' } - } - developer { - id 'AbrarSyed' - name 'Abrar Syed' - roles { role 'contributor' } - } - } + resources { + srcDir "$rootDir/src/main/resources" } } } -} + repositories { + mavenCentral() + } + patcher { + parent = project(':clean') + patches = file("$rootDir/patches/minecraft") + patchedSrc = file('src/main/java') + accessTransformer = file("$rootDir/src/main/resources/forge_at.cfg") + srgPatches = false + } + applyPatches { + canonicalizeAccess true + canonicalizeWhitespace true + maxFuzz 3 + } + dependencies { + implementation project(':clean') + implementation 'cpw.mods:modlauncher:0.1+' + implementation 'net.minecraftforge:accesstransformers:0.10+:shadowed' + implementation 'net.minecraftforge:eventbus:0.1+:service' + implementation 'net.minecraftforge:forgespi:0.1+' + implementation 'net.minecraftforge:coremods:0.1+' + implementation 'com.electronwill.night-config:core:3.4.0' + implementation 'com.electronwill.night-config:toml:3.4.0' + } -// HELPER METHODS + configurations { + ecj + } + dependencies { + ecj 'org.eclipse.jdt.core.compiler:ecj:4.6.1' + } -String getServerClasspath(File file) -{ - def node = new JsonSlurper().parse(file); - def out = new StringBuilder() - node.versionInfo.libraries.each { lib -> - if (lib.serverreq) - { - // group : artifact : version - def split = lib.name.split(':') - def group = split[0].replace('.', '/') - def artifact = split[1] - def version = split[2] - out += "libraries/$group/$artifact/$version/$artifact-${version}.jar " + compileJava { + options.fork = true + options.failOnError = false + options.forkOptions.with { + executable = 'java' + jvmArgs = ['-classpath', project.configurations.ecj.asPath, 'org.eclipse.jdt.internal.compiler.batch.Main', '-nowarn'] } } - out += "minecraft_server.${minecraft.version}.jar" - - return out.toString(); -} - -String getVersionFromJava(File file) -{ - String major = "0"; - String minor = "0"; - String revision = "0"; - String build = "0"; - - String prefix = "public static final int"; - file.eachLine{ String s -> - s = s.trim(); - if (s.startsWith(prefix)) - { - s = s.substring(prefix.length(), s.length() - 1); - s = s.replace('=', ' ').replace("Version", "").replaceAll(" +", " ").trim(); - String[] pts = s.split(" "); - - if (pts[0].equals("major")) major = pts[pts.length - 1]; - else if (pts[0] == "minor") minor = pts[pts.length - 1]; - else if (pts[0] == "revision") revision = pts[pts.length - 1]; - } + task runclient(type: JavaExec) { + classpath sourceSets.main.runtimeClasspath + main 'net.minecraftforge.fml.LaunchTesting' + systemProperties target:'fmldevclient' } - build = System.getenv("BUILD_NUMBER") ?: project.ext.properties.buildNumber ?: 0 - - - String branch = null; - if (!System.getenv().containsKey("GIT_BRANCH")) - { - // TODO: use grgit - Tried to switch 07/07/16 - jgit broken on windows? - branch = "git rev-parse --abbrev-ref HEAD".execute().text.trim() + task runserver(type: JavaExec) { + classpath sourceSets.main.runtimeClasspath + main 'net.minecraftforge.fml.LaunchTesting' + systemProperties target:'fmldevserver' } - else - { - branch = System.getenv("GIT_BRANCH"); - branch = branch.substring(branch.lastIndexOf('/') + 1); - } - - def out = "${minecraft.version.replace('-', '_')}-$major.$minor.$revision.$build" - - if (branch && branch != 'master' && branch != 'HEAD' && branch != minecraft.version && branch != minecraft.version + '.0') - { - if (!(branch.endsWith('.x') && minecraft.version.startsWith(branch.substring(0, branch.length() -2)))) - out += "-$branch" - } - - return out; } -reobfuscate { - extraSrg = [ - 'MD: net/minecraftforge/fml/common/registry/FMLControlledNamespacedRegistry/getKeys ()Ljava/util/Set; net/minecraftforge/fml/common/registry/FMLControlledNamespacedRegistry/getKeys ()Ljava/util/Set;' - ] +//evaluationDependsOnChildren() +task setup() { + dependsOn ':clean:extractMapped' + dependsOn ':forge:extractMapped' //These must be strings so that we can do lazy resolution. Else we need evaluationDependsOnChildren above } -task resetBuildNumber << { - project.ext.properties.buildNumber = 0; - ciWriteBuildNumber.execute() -} -// re-add old tasks for jenkins compat -// should be removed, and the jenkins fixed when no longer building with FG 1.2 -task setupForge { dependsOn 'setup', 'ciWriteBuildNumber' } -task buildPackages { dependsOn 'build' } -//Temporary hack to fix compile errors caused by mappings shading in Bootstrap -/* -task fixParams << { - logger.lifecycle('Fixing param names!') - def params = new File(extractMcpMappings.destinationDir, 'params.csv') - def text = params.text - text = text.replaceAll('p_180276_1_,biome,', 'p_180276_1_,biomeIn,') - params.write(text) -} -fixParams.dependsOn('extractMcpMappings') -extractMcpMappings.finalizedBy('fixParams') -*/ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d3b83982b..7a3265ee9 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bed6a43c4..949819d28 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Sat Mar 10 11:15:39 EST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip diff --git a/gradlew b/gradlew index 27309d923..cccdd3d51 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -154,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 832fdb607..f9553162f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -49,7 +49,6 @@ goto fail @rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/settings.gradle b/settings.gradle index 74046b5b8..cee62b896 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,9 @@ -rootProject.name = 'forge' \ No newline at end of file +rootProject.name = 'Forge' + +include ':mcp' +include ':clean' +include ':forge' + +project(":mcp").projectDir = file("projects/mcp") +project(":clean").projectDir = file("projects/clean") +project(":forge").projectDir = file("projects/forge") diff --git a/src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java b/src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java deleted file mode 100644 index d095c3077..000000000 --- a/src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.advancements.critereon; - - -import com.google.gson.JsonObject; -import net.minecraft.util.JsonUtils; -import org.apache.commons.lang3.ArrayUtils; - -import net.minecraft.advancements.critereon.ItemPredicate; -import net.minecraft.item.ItemStack; -import net.minecraftforge.oredict.OreDictionary; - -/** - * An {@link ItemPredicate} that matches oredicts. - */ -public class OredictItemPredicate extends ItemPredicate -{ - private final String ore; - - public OredictItemPredicate(String ore) - { - this.ore = ore; - } - - public OredictItemPredicate(JsonObject jsonObject) { this(JsonUtils.getString(jsonObject, "ore")); } - - @Override - public boolean test(ItemStack stack) - { - return !stack.isEmpty() && ArrayUtils.contains(OreDictionary.getOreIDs(stack), OreDictionary.getOreID(ore)); - } -} diff --git a/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java b/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java deleted file mode 100644 index 1fb035e1a..000000000 --- a/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.classloading; - -import java.io.File; -import java.util.Map; - -import javax.annotation.Nullable; - -public class FMLForgePlugin -{ - public static boolean RUNTIME_DEOBF = false; -} diff --git a/src/main/java/net/minecraftforge/client/ClientCommandHandler.java b/src/main/java/net/minecraftforge/client/ClientCommandHandler.java index 8f237bb7e..1b3f813fd 100644 --- a/src/main/java/net/minecraftforge/client/ClientCommandHandler.java +++ b/src/main/java/net/minecraftforge/client/ClientCommandHandler.java @@ -46,7 +46,7 @@ import static net.minecraft.util.text.TextFormatting.*; * client, the client takes precedence! * */ -public class ClientCommandHandler extends CommandHandler +public class ClientCommandHandler {} /*extends CommandHandler { public static final ClientCommandHandler instance = new ClientCommandHandler(); @@ -55,7 +55,7 @@ public class ClientCommandHandler extends CommandHandler /** * @return 1 if successfully executed, -1 if no permission or wrong usage, * 0 if it doesn't exist or it was canceled (it's sent to the server) - */ + * / @Override public int executeCommand(ICommandSender sender, String message) { @@ -165,3 +165,4 @@ public class ClientCommandHandler extends CommandHandler return Minecraft.getMinecraft().getIntegratedServer(); } } +*/ diff --git a/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java b/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java index 4a5b4b56f..1386f31e6 100644 --- a/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java +++ b/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java @@ -26,11 +26,9 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.InventoryEffectRenderer; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import org.lwjgl.input.Mouse; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.ScaledResolution; import net.minecraftforge.eventbus.api.Cancelable; import net.minecraftforge.eventbus.api.Event; @@ -178,6 +176,7 @@ public class GuiScreenEvent extends Event * This event fires at the end of {@link GuiScreen#drawDefaultBackground()} and before the rest of the Gui draws. * This allows drawing next to Guis, above the background but below any tooltips. */ +/* public static class BackgroundDrawnEvent extends GuiScreenEvent { private final int mouseX; @@ -193,22 +192,27 @@ public class GuiScreenEvent extends Event this.mouseY = scaledHeight - Mouse.getY() * scaledHeight / gui.mc.displayHeight - 1; } - /** + */ +/** * The x coordinate of the mouse pointer on the screen. - */ + *//* + public int getMouseX() { return mouseX; } - /** + */ +/** * The y coordinate of the mouse pointer on the screen. - */ + *//* + public int getMouseY() { return mouseY; } } +*/ /** * This event fires in {@link InventoryEffectRenderer#updateActivePotionEffects()} diff --git a/src/main/java/net/minecraftforge/client/event/MouseEvent.java b/src/main/java/net/minecraftforge/client/event/MouseEvent.java deleted file mode 100644 index ed23487b9..000000000 --- a/src/main/java/net/minecraftforge/client/event/MouseEvent.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.client.event; - -import org.lwjgl.input.Mouse; - -import net.minecraftforge.eventbus.api.Cancelable; -import net.minecraftforge.eventbus.api.Event; - -/** - * Author: MachineMuse (Claire Semple) - * Created: 2:46 PM, 9/4/13 - */ -@net.minecraftforge.eventbus.api.Cancelable -public class MouseEvent extends net.minecraftforge.eventbus.api.Event -{ - private final int x; - private final int y; - private final int dx; - private final int dy; - private final int dwheel; - private final int button; - private final boolean buttonstate; - private final long nanoseconds; - - public MouseEvent() - { - this.x = Mouse.getEventX(); - this.y = Mouse.getEventY(); - this.dx = Mouse.getEventDX(); - this.dy = Mouse.getEventDY(); - this.dwheel = Mouse.getEventDWheel(); - this.button = Mouse.getEventButton(); - this.buttonstate = Mouse.getEventButtonState(); - this.nanoseconds = Mouse.getEventNanoseconds(); - } - - public int getX() { return x; } - public int getY() { return y; } - public int getDx() { return dx; } - public int getDy() { return dy; } - public int getDwheel() { return dwheel; } - public int getButton() { return button; } - public boolean isButtonstate() { return buttonstate; } - public long getNanoseconds() { return nanoseconds; } -} diff --git a/src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java b/src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java index cfea6b78c..29070fa56 100644 --- a/src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java +++ b/src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java @@ -24,9 +24,8 @@ import java.util.ArrayList; import net.minecraftforge.eventbus.api.Cancelable; import net.minecraftforge.eventbus.api.Event; import net.minecraft.client.gui.BossInfoClient; -import net.minecraft.client.gui.ScaledResolution; -@net.minecraftforge.eventbus.api.Cancelable +@Cancelable public class RenderGameOverlayEvent extends Event { public float getPartialTicks() @@ -34,11 +33,6 @@ public class RenderGameOverlayEvent extends Event return partialTicks; } - public ScaledResolution getResolution() - { - return resolution; - } - public ElementType getType() { return type; @@ -71,20 +65,17 @@ public class RenderGameOverlayEvent extends Event } private final float partialTicks; - private final ScaledResolution resolution; private final ElementType type; - public RenderGameOverlayEvent(float partialTicks, ScaledResolution resolution) + public RenderGameOverlayEvent(float partialTicks, Void resolution) { this.partialTicks = partialTicks; - this.resolution = resolution; this.type = null; } private RenderGameOverlayEvent(RenderGameOverlayEvent parent, ElementType type) { this.partialTicks = parent.getPartialTicks(); - this.resolution = parent.getResolution(); this.type = type; } diff --git a/src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java b/src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java index 64da6ddbd..7239bd3df 100644 --- a/src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java +++ b/src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java @@ -38,7 +38,7 @@ public class PlaySoundEvent extends SoundEvent { super(manager); this.sound = sound; - this.name = sound.getSoundLocation().getResourcePath(); + this.name = sound.getSoundLocation().getPath(); this.setResultSound(sound); } diff --git a/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java b/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java index 85b928a9c..3ce1cc58b 100644 --- a/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java +++ b/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java @@ -45,7 +45,7 @@ public class SoundEvent extends net.minecraftforge.eventbus.api.Event public SoundSourceEvent(SoundManager manager, ISound sound, String uuid) { super(manager); - this.name = sound.getSoundLocation().getResourcePath(); + this.name = sound.getSoundLocation().getPath(); this.sound = sound; this.uuid = uuid; } diff --git a/src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java b/src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java index c1fb8b6d2..2d92fad56 100644 --- a/src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java +++ b/src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java @@ -223,12 +223,14 @@ public class ForgeGuiFactory implements IModGuiFactory Property global = ForgeMod.getConfig().get(VERSION_CHECK_CAT, "Global", true); List props = new ArrayList(); - +// TODO +/* for (ModContainer mod : ForgeVersion.gatherMods().keySet()) { values.remove(mod.getModId()); props.add(ForgeMod.getConfig().get(VERSION_CHECK_CAT, mod.getModId(), true)); //Get or make the value in the config } +*/ props.addAll(values.values()); // Add any left overs from the config props.sort(Comparator.comparing(Property::getName)); @@ -378,12 +380,15 @@ public class ForgeGuiFactory implements IModGuiFactory private static Map getSelectableValues() { Map selectableValues = new TreeMap(); + // TODO +/* for (ModContainer mod : Loader.instance().getActiveModList()) // only add mods to the list that have a non-immutable ModContainer if (!mod.isImmutable() && mod.getMod() != null) selectableValues.put(mod.getModId(), mod.getName()); +*/ return selectableValues; } diff --git a/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java b/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java index a3d53900f..d92a80abb 100644 --- a/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java +++ b/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java @@ -28,7 +28,6 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.ForgeMod; import net.minecraftforge.common.ForgeVersion; -import net.minecraftforge.common.ForgeVersion.Status; import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.client.ClientModLoader; import net.minecraftforge.api.distmarker.Dist; @@ -85,7 +84,7 @@ public class NotificationModUpdateScreen extends GuiScreen public static NotificationModUpdateScreen init(GuiMainMenu guiMainMenu, GuiButton modButton) { NotificationModUpdateScreen notificationModUpdateScreen = new NotificationModUpdateScreen(modButton); - notificationModUpdateScreen.setGuiSize(guiMainMenu.width, guiMainMenu.height); + notificationModUpdateScreen.setWorldAndResolution(guiMainMenu.mc, guiMainMenu.width, guiMainMenu.height); notificationModUpdateScreen.initGui(); return notificationModUpdateScreen; } diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoader.java b/src/main/java/net/minecraftforge/client/model/ModelLoader.java index 7ed46494e..449c9c731 100644 --- a/src/main/java/net/minecraftforge/client/model/ModelLoader.java +++ b/src/main/java/net/minecraftforge/client/model/ModelLoader.java @@ -108,15 +108,17 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimaps; import com.google.common.collect.Sets; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import javax.annotation.Nonnull; import javax.annotation.Nullable; import static net.minecraftforge.fml.Logging.MODELLOADING; -import static net.minecraftforge.fml.Logging.fmlLog; public final class ModelLoader extends ModelBakery { + private static final Logger LOGGER = LogManager.getLogger(); private final Map stateModels = Maps.newHashMap(); private final Map multipartDefinitions = Maps.newHashMap(); private final Map multipartModels = Maps.newHashMap(); @@ -939,7 +941,7 @@ public final class ModelLoader extends ModelBakery // ignoring pure ResourceLocation arguments, all things we care about pass ModelResourceLocation if(entry.getKey() instanceof ModelResourceLocation) { - fmlLog.debug(MODELLOADING, ()-> new ModelLoaderErrorMessage((ModelResourceLocation)entry.getKey(), entry.getValue(), modelRegistry, this.blockModelShapes, this::getVariantNames)); + LOGGER.debug(MODELLOADING, ()-> new ModelLoaderErrorMessage((ModelResourceLocation)entry.getKey(), entry.getValue(), modelRegistry, this.blockModelShapes, this::getVariantNames)); final ModelResourceLocation location = (ModelResourceLocation)entry.getKey(); final IBakedModel model = modelRegistry.getObject(location); if(model == null) @@ -953,7 +955,7 @@ public final class ModelLoader extends ModelBakery IBakedModel model = modelRegistry.getObject(missing); if(model == null || model == missingModel) { - fmlLog.debug(MODELLOADING, ()-> new ModelLoaderErrorMessage(missing, null, modelRegistry, this.blockModelShapes, this::getVariantNames)); + LOGGER.debug(MODELLOADING, ()-> new ModelLoaderErrorMessage(missing, null, modelRegistry, this.blockModelShapes, this::getVariantNames)); } if(model == null) { diff --git a/src/main/java/net/minecraftforge/common/DimensionManager.java b/src/main/java/net/minecraftforge/common/DimensionManager.java index 1894ed161..b2b772dda 100644 --- a/src/main/java/net/minecraftforge/common/DimensionManager.java +++ b/src/main/java/net/minecraftforge/common/DimensionManager.java @@ -66,7 +66,7 @@ import javax.annotation.Nullable; public class DimensionManager { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker DIMMGR = MarkerManager.getMarker("DIMS"); private static class Dimension { diff --git a/src/main/java/net/minecraftforge/common/ForgeChunkManager.java b/src/main/java/net/minecraftforge/common/ForgeChunkManager.java index 6d5f53d4a..ec2a70abc 100644 --- a/src/main/java/net/minecraftforge/common/ForgeChunkManager.java +++ b/src/main/java/net/minecraftforge/common/ForgeChunkManager.java @@ -49,7 +49,7 @@ import net.minecraftforge.common.config.ConfigCategory; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Property; import net.minecraftforge.common.util.Constants; -import net.minecraftforge.fml.ServerLifecycleHooks; +import net.minecraftforge.fml.server.ServerLifecycleHooks; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.Loader; diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index f3eeddc77..0b1c3980b 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -170,7 +170,7 @@ import org.apache.logging.log4j.MarkerManager; public class ForgeHooks { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker FORGEHOOKS = MarkerManager.getMarker("FORGEHOOKS"); //TODO: Loot tables? static class SeedEntry extends WeightedRandom.Item diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index 4e9abea7f..9f715cc48 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -25,22 +25,21 @@ import net.minecraft.world.biome.Biome; import static net.minecraftforge.common.config.Configuration.CATEGORY_CLIENT; import static net.minecraftforge.common.config.Configuration.CATEGORY_GENERAL; -import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Map; import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.SidedExecutor; +import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.WorldPersistenceHooks; -import net.minecraftforge.fml.javafmlmod.ModLoadingContext; +import net.minecraftforge.fml.javafmlmod.FMLModLoadingContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.minecraft.item.Item; import net.minecraft.item.crafting.Ingredient; -import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.INBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.stats.StatList; import net.minecraft.world.storage.SaveHandler; @@ -66,9 +65,7 @@ import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent; import net.minecraftforge.fml.common.event.FMLModIdMappingEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; @@ -76,7 +73,7 @@ import org.apache.logging.log4j.MarkerManager; public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook { public static final String VERSION_CHECK_CAT = "version_checking"; - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker FORGEMOD = MarkerManager.getMarker("FORGEMOD"); public static int clumpingThreshold = 64; public static boolean removeErroringEntities = false; @@ -113,9 +110,9 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook public ForgeMod() { INSTANCE = this; - ModLoadingContext.get().getModEventBus().addListener(this::preInit); - ModLoadingContext.get().getModEventBus().addListener(this::postInit); - ModLoadingContext.get().getModEventBus().addListener(this::onAvailable); + FMLModLoadingContext.get().getModEventBus().addListener(this::preInit); + FMLModLoadingContext.get().getModEventBus().addListener(this::postInit); + FMLModLoadingContext.get().getModEventBus().addListener(this::onAvailable); MinecraftForge.EVENT_BUS.addListener(this::serverStarting); MinecraftForge.EVENT_BUS.addListener(this::playerLogin); MinecraftForge.EVENT_BUS.addListener(this::serverStopping); @@ -336,10 +333,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook if (event.isWorldRunning() && tmpStairs != disableStairSlabCulling) { - SidedExecutor.runOn(Dist.CLIENT,()->{ - Minecraft.getMinecraft().renderGlobal.loadRenderers(); - return null; - }); + DistExecutor.runWhenOn(Dist.CLIENT,()->()-> Minecraft.getMinecraft().renderGlobal.loadRenderers()); } } @@ -438,7 +432,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook } @Override - public void readData(SaveHandler handler, WorldInfo info, Map propertyMap, NBTTagCompound tag) + public void readData(SaveHandler handler, WorldInfo info, Map propertyMap, NBTTagCompound tag) { DimensionManager.loadDimensionDataMap(tag.hasKey("DimensionData") ? tag.getCompoundTag("DimensionData") : null); FluidRegistry.loadFluidDefaults(tag); @@ -449,10 +443,9 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook OreDictionary.rebakeMap(); StatList.reinit(); Ingredient.invalidateAll(); - SidedExecutor.runOn(Dist.CLIENT, ()-> { + DistExecutor.runWhenOn(Dist.CLIENT, ()-> () -> { Minecraft.getMinecraft().populateSearchTreeManager(); Minecraft.getMinecraft().getSearchTreeManager().onResourceManagerReload(Minecraft.getMinecraft().getResourceManager()); - return null; }); } diff --git a/src/main/java/net/minecraftforge/common/MinecraftForge.java b/src/main/java/net/minecraftforge/common/MinecraftForge.java index 499885131..92ccfa9bf 100644 --- a/src/main/java/net/minecraftforge/common/MinecraftForge.java +++ b/src/main/java/net/minecraftforge/common/MinecraftForge.java @@ -58,7 +58,7 @@ public class MinecraftForge public static final IEventBus ORE_GEN_BUS = IEventBus.create(); static final ForgeInternalHandler INTERNAL_HANDLER = new ForgeInternalHandler(); - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker FORGE = MarkerManager.getMarker("FORGE"); /** diff --git a/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java b/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java index 92a4046ac..085b8a8cc 100644 --- a/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java +++ b/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java @@ -22,7 +22,7 @@ package net.minecraftforge.common.brewing; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.potion.PotionHelper; +import net.minecraft.potion.PotionBrewing; import javax.annotation.Nonnull; @@ -49,7 +49,7 @@ public class VanillaBrewingRecipe implements IBrewingRecipe { @Override public boolean isIngredient(@Nonnull ItemStack stack) { - return PotionHelper.isReagent(stack); + return PotionBrewing.isReagent(stack); } /** @@ -63,7 +63,7 @@ public class VanillaBrewingRecipe implements IBrewingRecipe { { if (!input.isEmpty() && !ingredient.isEmpty() && isIngredient(ingredient)) { - ItemStack result = PotionHelper.doReaction(ingredient, input); + ItemStack result = PotionBrewing.doReaction(ingredient, input); if (result != input) { return result; diff --git a/src/main/java/net/minecraftforge/common/capabilities/Capability.java b/src/main/java/net/minecraftforge/common/capabilities/Capability.java index 90484033d..8a5622183 100644 --- a/src/main/java/net/minecraftforge/common/capabilities/Capability.java +++ b/src/main/java/net/minecraftforge/common/capabilities/Capability.java @@ -23,7 +23,7 @@ import java.util.concurrent.Callable; import com.google.common.base.Throwables; -import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.INBTBase; import net.minecraft.util.EnumFacing; import javax.annotation.Nullable; @@ -58,7 +58,7 @@ public class Capability * @return a NBT holding the data. Null if no data needs to be stored. */ @Nullable - NBTBase writeNBT(Capability capability, T instance, EnumFacing side); + INBTBase writeNBT(Capability capability, T instance, EnumFacing side); /** * Read the capability instance from a NBT tag. @@ -79,7 +79,7 @@ public class Capability * @param side The side of the object the instance is associated with. * @param nbt A NBT holding the data. Must not be null, as doesn't make sense to call this function with nothing to read... */ - void readNBT(Capability capability, T instance, EnumFacing side, NBTBase nbt); + void readNBT(Capability capability, T instance, EnumFacing side, INBTBase nbt); } /** @@ -97,7 +97,7 @@ public class Capability * Quick access to the IStorage's readNBT. * See {@link IStorage#readNBT(Capability, Object, EnumFacing, NBTBase)} for documentation. */ - public void readNBT(T instance, EnumFacing side, NBTBase nbt) + public void readNBT(T instance, EnumFacing side, INBTBase nbt) { storage.readNBT(this, instance, side, nbt); } @@ -107,7 +107,7 @@ public class Capability * See {@link IStorage#writeNBT(Capability, Object, EnumFacing)} for documentation. */ @Nullable - public NBTBase writeNBT(T instance, EnumFacing side) + public INBTBase writeNBT(T instance, EnumFacing side) { return storage.writeNBT(this, instance, side); } diff --git a/src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java b/src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java index 606b1d67c..c597038d0 100644 --- a/src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java +++ b/src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java @@ -26,7 +26,7 @@ import java.util.Map; import com.google.common.collect.Lists; -import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.INBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; @@ -45,7 +45,7 @@ import net.minecraftforge.common.util.INBTSerializable; public final class CapabilityDispatcher implements INBTSerializable, ICapabilityProvider { private ICapabilityProvider[] caps; - private INBTSerializable[] writers; + private INBTSerializable[] writers; private String[] names; public CapabilityDispatcher(Map list) @@ -57,7 +57,7 @@ public final class CapabilityDispatcher implements INBTSerializable list, @Nullable ICapabilityProvider parent) { List lstCaps = Lists.newArrayList(); - List> lstWriters = Lists.newArrayList(); + List> lstWriters = Lists.newArrayList(); List lstNames = Lists.newArrayList(); if (parent != null) // Parents go first! @@ -65,7 +65,7 @@ public final class CapabilityDispatcher implements INBTSerializable)parent); + lstWriters.add((INBTSerializable)parent); lstNames.add("Parent"); } } @@ -76,7 +76,7 @@ public final class CapabilityDispatcher implements INBTSerializable)prov); + lstWriters.add((INBTSerializable)prov); lstNames.add(entry.getKey().toString()); } } diff --git a/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java b/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java index 441a2e883..a9402f168 100644 --- a/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java +++ b/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java @@ -45,7 +45,7 @@ import static net.minecraftforge.fml.Logging.CAPABILITIES; public enum CapabilityManager { INSTANCE; - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); /** * Registers a capability to be consumed by others. diff --git a/src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java b/src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java index 4da91b3ef..b88a0ca45 100644 --- a/src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java +++ b/src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java @@ -19,8 +19,8 @@ package net.minecraftforge.common.capabilities; -import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.INBTBase; import net.minecraftforge.common.util.INBTSerializable; //Just a mix of the two, useful in patches to lower the size. -public interface ICapabilitySerializable extends ICapabilityProvider, INBTSerializable{} +public interface ICapabilitySerializable extends ICapabilityProvider, INBTSerializable{} diff --git a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java index 869e3ea7e..d82108f51 100644 --- a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java +++ b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java @@ -37,7 +37,7 @@ import javax.annotation.Nonnull; import net.minecraft.client.util.RecipeBookClient; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.SidedExecutor; +import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.loading.moddiscovery.ModFile; import org.apache.commons.io.FilenameUtils; @@ -81,7 +81,7 @@ import org.apache.logging.log4j.MarkerManager; public class CraftingHelper { private static final boolean DEBUG_LOAD_MINECRAFT = false; - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker CRAFTHELPER = MarkerManager.getMarker("CRAFTHELPER"); private static Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); private static Map conditions = new HashMap<>(); @@ -619,10 +619,7 @@ public class CraftingHelper { GameData.fireRegistryEvents(rl -> rl.equals(GameData.RECIPES)); //reg.freeze(); - SidedExecutor.runOn(Dist.CLIENT, ()-> { - RecipeBookClient.rebuildTable(); - return null; - }); + DistExecutor.runWhenOn(Dist.CLIENT, ()-> RecipeBookClient::rebuildTable); } private static void loadFactories(final ModFile modFile) diff --git a/src/main/java/net/minecraftforge/common/util/INBTSerializable.java b/src/main/java/net/minecraftforge/common/util/INBTSerializable.java index 2dfb9dd99..1642d1505 100644 --- a/src/main/java/net/minecraftforge/common/util/INBTSerializable.java +++ b/src/main/java/net/minecraftforge/common/util/INBTSerializable.java @@ -19,13 +19,13 @@ package net.minecraftforge.common.util; -import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.INBTBase; /** * An interface designed to unify various things in the Minecraft * code base that can be serialized to and from a NBT tag. */ -public interface INBTSerializable +public interface INBTSerializable { T serializeNBT(); void deserializeNBT(T nbt); diff --git a/src/main/java/net/minecraftforge/fluids/FluidRegistry.java b/src/main/java/net/minecraftforge/fluids/FluidRegistry.java index 90a57e859..24e69695e 100644 --- a/src/main/java/net/minecraftforge/fluids/FluidRegistry.java +++ b/src/main/java/net/minecraftforge/fluids/FluidRegistry.java @@ -58,7 +58,7 @@ import javax.annotation.Nullable; */ public abstract class FluidRegistry { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker FLUIDS = MarkerManager.getMarker("FLUIDS"); static int maxID = 0; diff --git a/src/main/java/net/minecraftforge/fml/AutomaticEventSubscriber.java b/src/main/java/net/minecraftforge/fml/AutomaticEventSubscriber.java index 24b8a1fee..f781945cd 100644 --- a/src/main/java/net/minecraftforge/fml/AutomaticEventSubscriber.java +++ b/src/main/java/net/minecraftforge/fml/AutomaticEventSubscriber.java @@ -43,7 +43,7 @@ import static net.minecraftforge.fml.Logging.LOADING; */ public class AutomaticEventSubscriber { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); public static void inject(final ModContainer mod, final ModFileScanData scanData, final ClassLoader loader) { if (scanData == null) return; diff --git a/src/main/java/net/minecraftforge/fml/SidedExecutor.java b/src/main/java/net/minecraftforge/fml/DistExecutor.java similarity index 82% rename from src/main/java/net/minecraftforge/fml/SidedExecutor.java rename to src/main/java/net/minecraftforge/fml/DistExecutor.java index c2bbccb6f..0be64f95e 100644 --- a/src/main/java/net/minecraftforge/fml/SidedExecutor.java +++ b/src/main/java/net/minecraftforge/fml/DistExecutor.java @@ -25,9 +25,9 @@ import net.minecraftforge.fml.loading.FMLEnvironment; import java.util.concurrent.Callable; import java.util.function.Supplier; -public final class SidedExecutor +public final class DistExecutor { - private SidedExecutor() {} + private DistExecutor() {} /** * Run the callable in the supplier only on the specified {@link Side} @@ -37,7 +37,7 @@ public final class SidedExecutor * @param The return type from the callable * @return The callable's result */ - public static T runOn(Dist dist, Supplier> toRun) { + public static T callWhenOn(Dist dist, Supplier> toRun) { if (dist == FMLEnvironment.dist) { try { @@ -51,7 +51,12 @@ public final class SidedExecutor return null; } - public static T runSided(Supplier> clientTarget, Supplier> serverTarget) { + public static void runWhenOn(Dist dist, Supplier toRun) { + if (dist == FMLEnvironment.dist) { + toRun.get().run(); + } + } + public static T runForDist(Supplier> clientTarget, Supplier> serverTarget) { switch (FMLEnvironment.dist) { case CLIENT: diff --git a/src/main/java/net/minecraftforge/fml/ExtensionPoint.java b/src/main/java/net/minecraftforge/fml/ExtensionPoint.java index 8351446e2..b81ec78bf 100644 --- a/src/main/java/net/minecraftforge/fml/ExtensionPoint.java +++ b/src/main/java/net/minecraftforge/fml/ExtensionPoint.java @@ -21,7 +21,7 @@ package net.minecraftforge.fml; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.resources.IResourcePack; +import net.minecraft.resources.IResourcePack; import net.minecraftforge.fml.client.ModFileResourcePack; import java.util.function.BiFunction; diff --git a/src/main/java/net/minecraftforge/fml/FMLWorldPersistenceHook.java b/src/main/java/net/minecraftforge/fml/FMLWorldPersistenceHook.java index 09cb3c383..712e834ab 100644 --- a/src/main/java/net/minecraftforge/fml/FMLWorldPersistenceHook.java +++ b/src/main/java/net/minecraftforge/fml/FMLWorldPersistenceHook.java @@ -25,7 +25,7 @@ import java.util.Map.Entry; import java.util.Optional; import com.google.common.collect.Multimap; -import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.INBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.ResourceLocation; @@ -47,7 +47,7 @@ import org.apache.logging.log4j.MarkerManager; public final class FMLWorldPersistenceHook implements WorldPersistenceHooks.WorldPersistenceHook { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker WORLDPERSISTENCE = MarkerManager.getMarker("WP"); @Override @@ -66,7 +66,7 @@ public final class FMLWorldPersistenceHook implements WorldPersistenceHooks.Worl final NBTTagCompound mod = new NBTTagCompound(); mod.setString("ModId", mi.getModId()); mod.setString("ModVersion", mi.getVersion().getVersionString()); - modList.appendTag(mod); + modList.add(mod); }); fmlData.setTag("LoadingModList", modList); @@ -82,12 +82,12 @@ public final class FMLWorldPersistenceHook implements WorldPersistenceHooks.Worl } @Override - public void readData(SaveHandler handler, WorldInfo info, Map propertyMap, NBTTagCompound tag) + public void readData(SaveHandler handler, WorldInfo info, NBTTagCompound tag) { if (tag.hasKey("LoadingModList")) { NBTTagList modList = tag.getTagList("LoadingModList", (byte)10); - for (int i = 0; i < modList.tagCount(); i++) + for (int i = 0; i < modList.size(); i++) { NBTTagCompound mod = modList.getCompoundTagAt(i); String modId = mod.getString("ModId"); diff --git a/src/main/java/net/minecraftforge/fml/FileUtils.java b/src/main/java/net/minecraftforge/fml/FileUtils.java index b99b40b60..36a5e0526 100644 --- a/src/main/java/net/minecraftforge/fml/FileUtils.java +++ b/src/main/java/net/minecraftforge/fml/FileUtils.java @@ -19,33 +19,37 @@ package net.minecraftforge.fml; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import java.io.IOException; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; import java.nio.file.Path; import static net.minecraftforge.fml.Logging.CORE; -import static net.minecraftforge.fml.Logging.fmlLog; public class FileUtils { + private static final Logger LOGGER = LogManager.getLogger(); + public static Path getOrCreateDirectory(Path dirPath, String dirLabel) { if (!Files.isDirectory(dirPath)) { - fmlLog.debug(CORE,"Making {} directory : {}", dirLabel, dirPath); + LOGGER.debug(CORE,"Making {} directory : {}", dirLabel, dirPath); try { Files.createDirectory(dirPath); } catch (IOException e) { if (e instanceof FileAlreadyExistsException) { - fmlLog.error(CORE,"Failed to create {} directory - there is a file in the way", dirLabel); + LOGGER.error(CORE,"Failed to create {} directory - there is a file in the way", dirLabel); } else { - fmlLog.error(CORE,"Problem with creating {} directory (Permissions?)", dirLabel, e); + LOGGER.error(CORE,"Problem with creating {} directory (Permissions?)", dirLabel, e); } throw new RuntimeException("Problem creating directory", e); } - fmlLog.debug(CORE,"Created {} directory : {}", dirLabel, dirPath); + LOGGER.debug(CORE,"Created {} directory : {}", dirLabel, dirPath); } else { - fmlLog.debug(CORE,"Found existing {} directory : {}", dirLabel, dirPath); + LOGGER.debug(CORE,"Found existing {} directory : {}", dirLabel, dirPath); } return dirPath; } diff --git a/src/main/java/net/minecraftforge/fml/LaunchTesting.java b/src/main/java/net/minecraftforge/fml/LaunchTesting.java index c8f07a057..167de278b 100644 --- a/src/main/java/net/minecraftforge/fml/LaunchTesting.java +++ b/src/main/java/net/minecraftforge/fml/LaunchTesting.java @@ -21,29 +21,15 @@ package net.minecraftforge.fml; import com.google.common.base.Strings; import cpw.mods.modlauncher.Launcher; -import net.minecraft.block.Block; -import net.minecraft.block.properties.PropertyEnum; -import net.minecraft.block.state.BlockStateContainer; -import net.minecraft.item.EnumDyeColor; import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.MarkerManager; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.ConfigurationFactory; import org.apache.logging.log4j.core.config.Configurator; -import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; -import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory; -import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; -import org.apache.logging.log4j.core.config.composite.CompositeConfiguration; import org.apache.logging.log4j.core.filter.MarkerFilter; import java.io.File; import java.lang.reflect.Field; -import static cpw.mods.modlauncher.Logging.CLASSLOADING; -import static net.minecraftforge.fml.Logging.fmlLog; - public class LaunchTesting { public static void main(String... args) throws InterruptedException diff --git a/src/main/java/net/minecraftforge/fml/Logging.java b/src/main/java/net/minecraftforge/fml/Logging.java index c180face5..c4614f68b 100644 --- a/src/main/java/net/minecraftforge/fml/Logging.java +++ b/src/main/java/net/minecraftforge/fml/Logging.java @@ -28,8 +28,6 @@ import org.apache.logging.log4j.core.config.Configurator; public class Logging { - public static final Logger fmlLog = LogManager.getLogger("FML"); - // Lots of markers public static final Marker CORE = MarkerManager.getMarker("CORE"); public static final Marker LOADING = MarkerManager.getMarker("LOADING"); diff --git a/src/main/java/net/minecraftforge/fml/ModContainer.java b/src/main/java/net/minecraftforge/fml/ModContainer.java index 4e8816254..a9b0e438a 100644 --- a/src/main/java/net/minecraftforge/fml/ModContainer.java +++ b/src/main/java/net/minecraftforge/fml/ModContainer.java @@ -34,7 +34,7 @@ import java.util.function.Supplier; * The container that wraps around mods in the system. *

* The philosophy is that individual mod implementation technologies should not - * impact the actual loading and management of mod code. This interface provides + * impact the actual loading and management of mod code. This class provides * a mechanism by which we can wrap actual mod code so that the loader and other * facilities can treat mods at arms length. *

diff --git a/src/main/java/net/minecraftforge/fml/ModList.java b/src/main/java/net/minecraftforge/fml/ModList.java index 032857e06..a49441462 100644 --- a/src/main/java/net/minecraftforge/fml/ModList.java +++ b/src/main/java/net/minecraftforge/fml/ModList.java @@ -20,11 +20,9 @@ package net.minecraftforge.fml; import com.google.common.collect.Streams; -import net.minecraftforge.fml.javafmlmod.ModLoadingContext; import net.minecraftforge.fml.language.ModFileScanData; import net.minecraftforge.fml.loading.DefaultModInfos; import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler; import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; import net.minecraftforge.fml.loading.moddiscovery.ModInfo; @@ -51,7 +49,7 @@ import static net.minecraftforge.fml.Logging.LOADING; */ public class ModList { - private static Logger LOGGER = LogManager.getLogger("FML"); + private static Logger LOGGER = LogManager.getLogger(); private static ModList INSTANCE; private final List modFiles; private final List sortedList; diff --git a/src/main/java/net/minecraftforge/fml/ModLoader.java b/src/main/java/net/minecraftforge/fml/ModLoader.java index 6f98f5724..01a837e4b 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoader.java +++ b/src/main/java/net/minecraftforge/fml/ModLoader.java @@ -47,7 +47,7 @@ import static net.minecraftforge.fml.Logging.CORE; public class ModLoader { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static ModLoader INSTANCE; private final ClassLoader launchClassLoader; private final LoadingModList loadingModList; @@ -97,7 +97,7 @@ public class ModLoader CapabilityManager.INSTANCE.injectCapabilities(modList.getAllScanData()); LifecycleEventProvider.PREINIT.dispatch(); GameData.fireRegistryEvents(rl -> !Objects.equals(rl, GameData.RECIPES)); - SidedExecutor.runOn(Dist.CLIENT, ModLoader::fireClientEvents); + Boolean result = DistExecutor.callWhenOn(Dist.CLIENT, ModLoader::fireClientEvents); LifecycleEventProvider.SIDEDINIT.dispatch(); } diff --git a/src/main/java/net/minecraftforge/fml/ModLoadingClassLoader.java b/src/main/java/net/minecraftforge/fml/ModLoadingClassLoader.java index d16a43619..63b31d06b 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoadingClassLoader.java +++ b/src/main/java/net/minecraftforge/fml/ModLoadingClassLoader.java @@ -21,6 +21,7 @@ package net.minecraftforge.fml; import net.minecraftforge.fml.loading.FMLLoader; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.io.IOException; import java.net.URL; @@ -32,6 +33,9 @@ import static net.minecraftforge.fml.Logging.LOADING; public class ModLoadingClassLoader extends SecureClassLoader { + + private static final Logger LOGGER = LogManager.getLogger(); + static { ClassLoader.registerAsParallelCapable(); } @@ -49,7 +53,7 @@ public class ModLoadingClassLoader extends SecureClassLoader @Override protected Class findClass(String name) throws ClassNotFoundException { - LogManager.getLogger("FML").debug(LOADING, "Loading class {}", name); + LOGGER.debug(LOADING, "Loading class {}", name); final String className = name.replace('.','/').concat(".class"); final Path classResource = FMLLoader.getLoadingModList().findResource(className); if (classResource != null) { diff --git a/src/main/java/net/minecraftforge/fml/SidedProvider.java b/src/main/java/net/minecraftforge/fml/SidedProvider.java index 32d1a0329..41856f07a 100644 --- a/src/main/java/net/minecraftforge/fml/SidedProvider.java +++ b/src/main/java/net/minecraftforge/fml/SidedProvider.java @@ -23,7 +23,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.fml.client.SplashProgress; +import net.minecraftforge.fml.client.ClientHooks; import net.minecraftforge.fml.common.event.FMLClientInitEvent; import net.minecraftforge.fml.common.event.FMLServerInitEvent; import net.minecraftforge.fml.loading.FMLEnvironment; @@ -34,12 +34,12 @@ import java.util.function.Supplier; public enum SidedProvider { // All of these need to be careful not to directly dereference the client and server elements in their signatures - DATAFIXER(c->c.get().getDataFixer(), s->s.get().getDataFixer()), + DATAFIXER(c->c.get().getDataFixer(), s->s.get().func_195563_aC()), SIDEDINIT((Function, Function>)c-> mc->new FMLClientInitEvent(c, mc), (Function, Function>)s-> mc->new FMLServerInitEvent(s, mc)), - STRIPCHARS((Function, Function>)c-> SplashProgress::stripSpecialChars, + STRIPCHARS((Function, Function>)c-> ClientHooks::stripSpecialChars, (Function, Function>)s-> str->str), - @SuppressWarnings("Convert2MethodRef") // need to not be methodrefs to avoid classloading all of StartupQuery's data + @SuppressWarnings("Convert2MethodRef") // need to not be methodrefs to avoid classloading all of StartupQuery's data (supplier is coming from StartupQuery) STARTUPQUERY(c->StartupQuery.QueryWrapper.clientQuery(c), s->StartupQuery.QueryWrapper.dedicatedServerQuery(s)); private static Supplier client; diff --git a/src/main/java/net/minecraftforge/fml/StartupQuery.java b/src/main/java/net/minecraftforge/fml/StartupQuery.java index 644c71b6a..012aaf750 100644 --- a/src/main/java/net/minecraftforge/fml/StartupQuery.java +++ b/src/main/java/net/minecraftforge/fml/StartupQuery.java @@ -33,6 +33,7 @@ import net.minecraftforge.fml.client.gui.GuiConfirmation; import net.minecraftforge.fml.client.gui.GuiNotification; import net.minecraftforge.fml.common.thread.EffectiveSide; import net.minecraftforge.fml.loading.FMLEnvironment; +import net.minecraftforge.fml.server.ServerLifecycleHooks; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; @@ -42,7 +43,7 @@ import javax.annotation.Nullable; public class StartupQuery { // internal class/functionality, do not use - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker SQ = MarkerManager.getMarker("STARTUPQUERY"); public static boolean confirm(String text) @@ -236,8 +237,6 @@ public class StartupQuery { throw new RuntimeException(); } - client.loadingScreen.displayLoadingString(""); - try { Thread.sleep(50); @@ -247,8 +246,6 @@ public class StartupQuery { query.exception = ie; } } - - client.loadingScreen.displayLoadingString(""); // make sure the blank screen is being drawn at the end } }; } diff --git a/src/main/java/net/minecraftforge/fml/WorldPersistenceHooks.java b/src/main/java/net/minecraftforge/fml/WorldPersistenceHooks.java index 7fad4ad2d..0e40ebc90 100644 --- a/src/main/java/net/minecraftforge/fml/WorldPersistenceHooks.java +++ b/src/main/java/net/minecraftforge/fml/WorldPersistenceHooks.java @@ -19,16 +19,13 @@ package net.minecraftforge.fml; -import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.storage.SaveHandler; import net.minecraft.world.storage.WorldInfo; import net.minecraftforge.fml.common.thread.EffectiveSide; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class WorldPersistenceHooks { @@ -47,9 +44,7 @@ public class WorldPersistenceHooks { if (EffectiveSide.get() == LogicalSide.SERVER) { - Map additionalProperties = new HashMap<>(); - worldInfo.setAdditionalProperties(additionalProperties); - worldPersistenceHooks.forEach(wac->wac.readData(handler, worldInfo, additionalProperties, tagCompound.getCompoundTag(wac.getModId()))); + worldPersistenceHooks.forEach(wac->wac.readData(handler, worldInfo, tagCompound.getCompoundTag(wac.getModId()))); } } @@ -76,6 +71,6 @@ public class WorldPersistenceHooks { String getModId(); NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info); - void readData(SaveHandler handler, WorldInfo info, Map propertyMap, NBTTagCompound tag); + void readData(SaveHandler handler, WorldInfo info, NBTTagCompound tag); } } diff --git a/src/main/java/net/minecraftforge/fml/client/ClientHooks.java b/src/main/java/net/minecraftforge/fml/client/ClientHooks.java index dcfbda51e..a7c07ada9 100644 --- a/src/main/java/net/minecraftforge/fml/client/ClientHooks.java +++ b/src/main/java/net/minecraftforge/fml/client/ClientHooks.java @@ -19,6 +19,7 @@ package net.minecraftforge.fml.client; +import com.google.common.base.CharMatcher; import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.gson.JsonArray; @@ -26,10 +27,10 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiConnecting; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiWorldSelection; import net.minecraft.client.gui.ServerListEntryNormal; -import net.minecraft.client.multiplayer.GuiConnecting; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.network.NetworkManager; @@ -39,7 +40,6 @@ import net.minecraft.world.storage.WorldSummary; import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.StartupQuery; import net.minecraftforge.fml.client.gui.GuiAccessDenied; -import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; import net.minecraftforge.registries.GameData; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -55,8 +55,11 @@ import java.util.concurrent.CountDownLatch; public class ClientHooks { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker CLIENTHOOKS = MarkerManager.getMarker("CLIENTHOOKS"); + // From FontRenderer.renderCharAtPos + private static final String ALLOWED_CHARS = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000"; + private static final CharMatcher DISALLOWED_CHAR_MATCHER = CharMatcher.anyOf(ALLOWED_CHARS).negate(); private static Map extraServerListData; private static Map serverDataTag; @@ -77,6 +80,7 @@ public class ClientHooks } public static void bindServerListData(ServerData data, ServerStatusResponse originalResponse) { +/* if (extraServerListData.containsKey(originalResponse)) { JsonObject jsonData = extraServerListData.get(originalResponse); @@ -104,6 +108,7 @@ public class ClientHooks } serverDataTag.put(data, new ExtendedServerListData("VANILLA", false, ImmutableMap.of(), !moddedClientAllowed)); } +*/ startupConnectionData.countDown(); } @@ -167,7 +172,7 @@ public class ClientHooks static File getSavesDir() { - return new File(Minecraft.getMinecraft().mcDataDir, "saves"); + return new File(Minecraft.getMinecraft().gameDir, "saves"); } public static void tryLoadExistingWorld(GuiWorldSelection selectWorldGUI, WorldSummary comparator) @@ -210,4 +215,9 @@ public class ClientHooks } } + public static String stripSpecialChars(String message) + { + // We can't handle many unicode points in the splash renderer + return DISALLOWED_CHAR_MATCHER.removeFrom(net.minecraft.util.StringUtils.stripControlCodes(message)); + } } diff --git a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java index 9b0d32a20..81714f4a0 100644 --- a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java +++ b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java @@ -20,11 +20,10 @@ package net.minecraftforge.fml.client; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.IReloadableResourceManager; -import net.minecraft.client.resources.IResourcePack; -import net.minecraft.client.resources.data.MetadataSerializer; +import net.minecraft.resources.IReloadableResourceManager; +import net.minecraft.resources.IResourcePack; +import net.minecraft.resources.data.IMetadataSectionSerializer; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.LogicalSidedProvider; @@ -33,7 +32,6 @@ import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.ModLoader; import net.minecraftforge.fml.client.gui.GuiNotification; import net.minecraftforge.fml.client.registry.RenderingRegistry; -import org.lwjgl.input.Mouse; import java.io.IOException; import java.util.List; @@ -44,13 +42,12 @@ public class ClientModLoader private static boolean loading; private static Minecraft mc; - public static void begin(final Minecraft minecraft, final List defaultResourcePacks, final IReloadableResourceManager mcResourceManager, MetadataSerializer metadataSerializer_) + public static void begin(final Minecraft minecraft, final List defaultResourcePacks, final IReloadableResourceManager mcResourceManager, IMetadataSectionSerializer metadataSerializer) { loading = true; ClientModLoader.mc = minecraft; SidedProvider.setClient(()->minecraft); LogicalSidedProvider.setClient(()->minecraft); - SplashProgress.start(); ModLoader.get().loadMods(); ResourcePackLoader.loadResourcePacks(defaultResourcePacks); minecraft.refreshResources(); @@ -61,7 +58,6 @@ public class ClientModLoader ModLoader.get().finishMods(); loading = false; mc.gameSettings.loadOptions(); - SplashProgress.finish(); } public static VersionChecker.Status checkForUpdates() @@ -75,27 +71,6 @@ public class ClientModLoader GlStateManager.enableTexture2D(); } - // If the startup screen has a notification on it, render that instead of the loading screen - public static boolean drawNotificationOverProgressScreen(final Minecraft client, final ScaledResolution scaledResolution) throws IOException - { - if (client.currentScreen instanceof GuiNotification) - { - int width = scaledResolution.getScaledWidth(); - int height = scaledResolution.getScaledHeight(); - int mouseX = Mouse.getX() * width / client.displayWidth; - int mouseZ = height - Mouse.getY() * height / client.displayHeight - 1; - - client.currentScreen.drawScreen(mouseX, mouseZ, 0); - client.currentScreen.handleInput(); - - return true; - } - else - { - return false; - } - } - public static boolean isErrored() { return false; diff --git a/src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java b/src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java deleted file mode 100644 index f4b1d7b6f..000000000 --- a/src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.client; - -import java.util.Set; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiScreen; -import net.minecraftforge.fml.client.config.GuiConfig; -import net.minecraftforge.fml.ModContainer; - -public class DefaultGuiFactory implements IModGuiFactory -{ - - protected String modid, title; - protected Minecraft minecraft; - - protected DefaultGuiFactory(String modid, String title) - { - this.modid = modid; - this.title = title; - } - - @Override - public boolean hasConfigGui() - { - return true; - } - - @Override - public void initialize(Minecraft minecraftInstance) - { - this.minecraft = minecraftInstance; - } - - @Override - public GuiScreen createConfigGui(GuiScreen parentScreen) - { - return new GuiConfig(parentScreen, modid, title); - } - - @Override - public Set runtimeGuiCategories() - { - return null; - } - - public static IModGuiFactory forMod(ModContainer mod) - { - return new DefaultGuiFactory(mod.getModId(), mod.getName()); - } -} diff --git a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java deleted file mode 100644 index d9ecb3241..000000000 --- a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java +++ /dev/null @@ -1,1109 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.client; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityPlayerSP; -import net.minecraft.client.gui.Gui; -import net.minecraft.client.gui.GuiIngameMenu; -import net.minecraft.client.gui.GuiMainMenu; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.GuiWorldSelection; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.gui.ServerListEntryNormal; -import net.minecraft.client.multiplayer.GuiConnecting; -import net.minecraft.client.multiplayer.ServerData; -import net.minecraft.client.multiplayer.WorldClient; -import net.minecraft.client.network.NetHandlerPlayClient; -import net.minecraft.client.network.ServerPinger; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.IReloadableResourceManager; -import net.minecraft.client.resources.IResource; -import net.minecraft.client.resources.IResourcePack; -import net.minecraft.client.resources.LegacyV2Adapter; -import net.minecraft.client.resources.data.MetadataSerializer; -import net.minecraft.client.resources.data.PackMetadataSection; -import net.minecraft.client.util.RecipeBookClient; -import net.minecraft.crash.CrashReport; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.launchwrapper.Launch; -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.network.NetworkManager; -import net.minecraft.network.ServerStatusResponse; -import net.minecraft.network.handshake.INetHandlerHandshakeServer; -import net.minecraft.network.login.INetHandlerLoginClient; -import net.minecraft.network.login.INetHandlerLoginServer; -import net.minecraft.network.play.INetHandlerPlayClient; -import net.minecraft.network.play.INetHandlerPlayServer; -import net.minecraft.network.status.INetHandlerStatusClient; -import net.minecraft.network.status.INetHandlerStatusServer; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.IThreadListener; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.StringUtils; -import net.minecraft.world.WorldSettings; -import net.minecraft.world.storage.WorldSummary; -import net.minecraft.world.storage.SaveFormatOld; -import net.minecraftforge.client.CloudRenderer; -import net.minecraftforge.client.IRenderHandler; -import net.minecraftforge.client.event.ModelRegistryEvent; -import net.minecraftforge.client.resource.IResourceType; -import net.minecraftforge.client.resource.ReloadRequirements; -import net.minecraftforge.client.resource.SelectiveReloadStateHandler; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.config.ConfigManager; -import net.minecraftforge.common.util.CompoundDataFixer; -import net.minecraftforge.fml.client.gui.CustomModLoadingErrorDisplayException; -import net.minecraftforge.fml.client.gui.GuiAccessDenied; -import net.minecraftforge.fml.client.gui.GuiConfirmation; -import net.minecraftforge.fml.client.gui.GuiCustomModLoadingErrorScreen; -import net.minecraftforge.fml.client.gui.GuiDupesFound; -import net.minecraftforge.fml.client.gui.GuiModList; -import net.minecraftforge.fml.client.gui.GuiModsMissing; -import net.minecraftforge.fml.client.gui.GuiMultipleModsErrored; -import net.minecraftforge.fml.client.gui.GuiNotification; -import net.minecraftforge.fml.client.gui.GuiOldSaveLoadConfirm; -import net.minecraftforge.fml.client.gui.GuiSortingProblem; -import net.minecraftforge.fml.client.gui.GuiWrongMinecraft; -import net.minecraftforge.fml.client.registry.RenderingRegistry; -import net.minecraftforge.fml.common.DummyModContainer; -import net.minecraftforge.fml.common.DuplicateModsFoundException; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.IFMLSidedHandler; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.LoaderException; -import net.minecraftforge.fml.common.MetadataCollection; -import net.minecraftforge.fml.common.MissingModsException; -import net.minecraftforge.fml.common.MultipleModsErrored; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.StartupQuery; -import net.minecraftforge.fml.common.WrongMinecraftVersionException; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.common.network.FMLNetworkEvent; -import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; -import net.minecraftforge.fml.common.toposort.ModSortingException; -import net.minecraftforge.registries.GameData; - -import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.Display; - -import com.google.common.base.CharMatcher; -import com.google.common.base.Strings; -import com.google.common.base.Throwables; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMap.Builder; -import com.google.common.collect.Maps; -import com.google.common.collect.SetMultimap; -import com.google.common.collect.Sets; -import com.google.common.collect.Table; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import javax.annotation.Nullable; - - -/** - * Handles primary communication from hooked code into the system - * - * The FML entry point is {@link #beginMinecraftLoading(Minecraft, List, IReloadableResourceManager, MetadataSerializer)} called from - * {@link Minecraft} - * - * Obfuscated code should focus on this class and other members of the "server" - * (or "client") code - * - * The actual mod loading is handled at arms length by {@link Loader} - * - * It is expected that a similar class will exist for each target environment: - * Bukkit and Client side. - * - * It should not be directly modified. - * - * @author cpw - * - */ -public class FMLClientHandler implements IFMLSidedHandler -{ - /** - * The singleton - */ - private static final FMLClientHandler INSTANCE = new FMLClientHandler(); - - /** - * A reference to the server itself - */ - private Minecraft client; - - private boolean loading = true; - - @Nullable - private IDisplayableError errorToDisplay; - - private boolean serverShouldBeKilledQuietly; - - private List resourcePackList; - - private MetadataSerializer metaSerializer; - - private Map resourcePackMap; - - private BiMap guiFactories; - - private Map extraServerListData; - private Map serverDataTag; - - private WeakReference currentPlayClient; - - private CloudRenderer cloudRenderer; - - /** - * Called to start the whole game off - * - * @param minecraft The minecraft instance being launched - * @param resourcePackList The resource pack list we will populate with mods - * @param resourceManager The resource manager - */ - public void beginMinecraftLoading(Minecraft minecraft, List resourcePackList, IReloadableResourceManager resourceManager, MetadataSerializer metaSerializer) - { - detectOptifine(); - SplashProgress.start(); - client = minecraft; - this.resourcePackList = resourcePackList; - this.metaSerializer = metaSerializer; - this.resourcePackMap = Maps.newHashMap(); - if (minecraft.isDemo()) - { - FMLLog.log.fatal("DEMO MODE DETECTED, FML will not work. Finishing now."); - haltGame("FML will not run in demo mode", new RuntimeException()); - return; - } - - List injectedModContainers = FMLCommonHandler.instance().beginLoading(this); - try - { - Loader.instance().loadMods(injectedModContainers); - } - catch (WrongMinecraftVersionException | DuplicateModsFoundException | MissingModsException | ModSortingException | CustomModLoadingErrorDisplayException | MultipleModsErrored e) - { - FMLLog.log.error("An exception was thrown, the game will display an error screen and halt.", e); - errorToDisplay = e; - MinecraftForge.EVENT_BUS.shutdown(); - } - catch (LoaderException le) - { - haltGame("There was a severe problem during mod loading that has caused the game to fail", le); - return; - } - finally - { - client.refreshResources(); - } - - try - { - Loader.instance().preinitializeMods(); - } - catch (LoaderException le) - { - if (le.getCause() instanceof CustomModLoadingErrorDisplayException) - { - CustomModLoadingErrorDisplayException custom = (CustomModLoadingErrorDisplayException) le.getCause(); - FMLLog.log.error("A custom exception was thrown by a mod, the game will display an error screen and halt.", custom); - errorToDisplay = custom; - MinecraftForge.EVENT_BUS.shutdown(); - } - else - { - haltGame("There was a severe problem during mod loading that has caused the game to fail", le); - return; - } - } - - @SuppressWarnings("unchecked") - Map> sharedModList = (Map>) Launch.blackboard.get("modList"); - if (sharedModList == null) - { - sharedModList = Maps.newHashMap(); - Launch.blackboard.put("modList", sharedModList); - } - for (ModContainer mc : Loader.instance().getActiveModList()) - { - Map sharedModDescriptor = mc.getSharedModDescriptor(); - if (sharedModDescriptor != null) - { - String sharedModId = "fml:"+mc.getModId(); - sharedModList.put(sharedModId, sharedModDescriptor); - } - } - } - - private void detectOptifine() - { - try - { - Class optifineConfig = Class.forName("Config", false, Loader.instance().getModClassLoader()); - String optifineVersion = (String) optifineConfig.getField("VERSION").get(null); - Map dummyOptifineMeta = ImmutableMap.builder().put("name", "Optifine").put("version", optifineVersion).build(); - try (InputStream optifineModInfoInputStream = getClass().getResourceAsStream("optifinemod.info")) - { - ModMetadata optifineMetadata = MetadataCollection.from(optifineModInfoInputStream, "optifine").getMetadataForId("optifine", dummyOptifineMeta); - optifineContainer = new DummyModContainer(optifineMetadata); - FMLLog.log.info("Forge Mod Loader has detected optifine {}, enabling compatibility features", optifineContainer.getVersion()); - } - } - catch (Exception e) - { - optifineContainer = null; - } - } - - @Override - public void haltGame(String message, Throwable t) - { - SplashProgress.finish(); - client.displayCrashReport(new CrashReport(message, t)); - Throwables.throwIfUnchecked(t); - throw new RuntimeException(t); - } - - public boolean hasError() - { - return errorToDisplay != null; - } - - /** - * Called a bit later on during initialization to finish loading mods - * Also initializes key bindings - * - */ - public void finishMinecraftLoading() - { - if (hasError()) - { - SplashProgress.finish(); - return; - } - try - { - Loader.instance().initializeMods(); - } - catch (LoaderException le) - { - if (le.getCause() instanceof CustomModLoadingErrorDisplayException) - { - CustomModLoadingErrorDisplayException custom = (CustomModLoadingErrorDisplayException) le.getCause(); - FMLLog.log.error("A custom exception was thrown by a mod, the game will display an error screen and halt.", custom); - errorToDisplay = custom; - MinecraftForge.EVENT_BUS.shutdown(); - } - else - { - haltGame("There was a severe problem during mod loading that has caused the game to fail", le); - return; - } - } - - RenderingRegistry.loadEntityRenderers(Minecraft.getMinecraft().getRenderManager().entityRenderMap); - guiFactories = HashBiMap.create(); - for (ModContainer mc : Loader.instance().getActiveModList()) - { - String className = mc.getGuiClassName(); - if (Strings.isNullOrEmpty(className)) - { - if (ConfigManager.hasConfigForMod(mc.getModId())) - { - guiFactories.put(mc, DefaultGuiFactory.forMod(mc)); - } - continue; - } - try - { - Class clazz = Class.forName(className, true, Loader.instance().getModClassLoader()); - Class guiClassFactory = clazz.asSubclass(IModGuiFactory.class); - IModGuiFactory guiFactory = guiClassFactory.newInstance(); - guiFactory.initialize(client); - guiFactories.put(mc, guiFactory); - } catch (Exception e) - { - FMLLog.log.error("A critical error occurred instantiating the gui factory for mod {}", mc.getModId(), e); - } - } - loading = false; - client.gameSettings.loadOptions(); //Reload options to load any mod added keybindings. - if (!hasError()) - Loader.instance().loadingComplete(); - SplashProgress.finish(); - } - - public void extendModList() - { - @SuppressWarnings("unchecked") - Map> modList = (Map>) Launch.blackboard.get("modList"); - if (modList != null) - { - for (Entry> modEntry : modList.entrySet()) - { - String sharedModId = modEntry.getKey(); - String system = sharedModId.split(":")[0]; - if ("fml".equals(system)) - { - continue; - } - /* - Map mod = modEntry.getValue(); - String modSystem = mod.get("modsystem"); // the modsystem (FML uses FML or ModLoader) - String modId = mod.get("id"); // unique ID - String modVersion = mod.get("version"); // version - String modName = mod.get("name"); // a human readable name - String modURL = mod.get("url"); // a URL for the mod (can be empty string) - String modAuthors = mod.get("authors"); // a csv of authors (can be empty string) - String modDescription = mod.get("description"); // a (potentially) multiline description (can be empty string) - */ - } - } - - } - public void onInitializationComplete() - { - // re-sync TEXTURE_2D, splash screen disables it with a direct GL call - GlStateManager.disableTexture2D(); - GlStateManager.enableTexture2D(); - if (errorToDisplay != null) - { - GuiScreen errorScreen = errorToDisplay.createGui(); - showGuiScreen(errorScreen); - } - else - { - logMissingTextureErrors(); - } - } - /** - * Get the server instance - */ - public Minecraft getClient() - { - return client; - } - - /** - * @return the instance - */ - public static FMLClientHandler instance() - { - return INSTANCE; - } - - /** - * @param player - * @param gui - */ - public void displayGuiScreen(EntityPlayer player, GuiScreen gui) - { - if (client.player==player && gui != null) { - client.displayGuiScreen(gui); - } - } - - /** - * @param mods - */ - public void addSpecialModEntries(ArrayList mods) - { - if (optifineContainer!=null) { - mods.add(optifineContainer); - } - } - - @Override - public List getAdditionalBrandingInformation() - { - if (optifineContainer!=null) - { - return Arrays.asList(String.format("Optifine %s",optifineContainer.getVersion())); - } else { - return ImmutableList.of(); - } - } - - @Override - public Side getSide() - { - return Side.CLIENT; - } - - public boolean hasOptifine() - { - return optifineContainer!=null; - } - - @Override - public void showGuiScreen(@Nullable Object clientGuiElement) - { - GuiScreen gui = (GuiScreen) clientGuiElement; - client.displayGuiScreen(gui); - } - - @Override - public void queryUser(StartupQuery query) throws InterruptedException - { - if (query.getResult() == null) - { - client.displayGuiScreen(new GuiNotification(query)); - } - else - { - client.displayGuiScreen(new GuiConfirmation(query)); - } - - if (query.isSynchronous()) - { - while (client.currentScreen instanceof GuiNotification) - { - if (Thread.interrupted()) throw new InterruptedException(); - - client.loadingScreen.displayLoadingString(""); - - Thread.sleep(50); - } - - client.loadingScreen.displayLoadingString(""); // make sure the blank screen is being drawn at the end - } - } - - public boolean handleLoadingScreen(ScaledResolution scaledResolution) throws IOException - { - if (client.currentScreen instanceof GuiNotification) - { - int width = scaledResolution.getScaledWidth(); - int height = scaledResolution.getScaledHeight(); - int mouseX = Mouse.getX() * width / client.displayWidth; - int mouseZ = height - Mouse.getY() * height / client.displayHeight - 1; - - client.currentScreen.drawScreen(mouseX, mouseZ, 0); - client.currentScreen.handleInput(); - - return true; - } - else - { - return false; - } - } - - public WorldClient getWorldClient() - { - return client.world; - } - - public EntityPlayerSP getClientPlayerEntity() - { - return client.player; - } - - @Override - public void beginServerLoading(MinecraftServer server) - { - serverShouldBeKilledQuietly = false; - // NOOP - } - - @Override - public void finishServerLoading() - { - // NOOP - } - - @Override - public File getSavesDirectory() - { - return ((SaveFormatOld) client.getSaveLoader()).savesDirectory; - } - - @Override - public MinecraftServer getServer() - { - return client.getIntegratedServer(); - } - - /** - * If the client is in the midst of loading, we disable saving so that custom settings aren't wiped out - */ - public boolean isLoading() - { - return loading; - } - - @Override - public boolean isDisplayCloseRequested() - { - return Display.isCreated() && Display.isCloseRequested(); - } - - @Override - public boolean shouldServerShouldBeKilledQuietly() - { - return serverShouldBeKilledQuietly; - } - - /** - * Is this GUI type open? - * - * @param gui The type of GUI to test for - * @return if a GUI of this type is open - */ - public boolean isGUIOpen(Class gui) - { - return client.currentScreen != null && client.currentScreen.getClass().equals(gui); - } - - - @Override - public void addModAsResource(ModContainer container) - { - Class resourcePackType = container.getCustomResourcePackClass(); - if (resourcePackType != null) - { - try - { - IResourcePack pack = (IResourcePack) resourcePackType.getConstructor(ModContainer.class).newInstance(container); - - PackMetadataSection meta = (PackMetadataSection)pack.getPackMetadata(this.metaSerializer, "pack"); - - if (meta != null && meta.getPackFormat() == 2) - { - pack = new LegacyV2Adapter(pack); - } - - resourcePackList.add(pack); - resourcePackMap.put(container.getModId(), pack); - } - catch (NoSuchMethodException e) - { - FMLLog.log.error("The container {} (type {}) returned an invalid class for its resource pack.", container.getName(), container.getClass().getName()); - } - catch (Exception e) - { - FormattedMessage message = new FormattedMessage("An unexpected exception occurred constructing the custom resource pack for {} ({})", container.getName(), container.getModId()); - throw new RuntimeException(message.getFormattedMessage(), e); - } - } - } - - public IResourcePack getResourcePackFor(String modId) - { - return resourcePackMap.get(modId); - } - - @Override - public String getCurrentLanguage() - { - return client.getLanguageManager().getCurrentLanguage().getLanguageCode(); - } - - @Override - public void serverStopped() - { - GameData.revertToFrozen(); - } - - @Override - public INetHandler getClientPlayHandler() - { - return this.currentPlayClient == null ? null : this.currentPlayClient.get(); - } - @Override - public NetworkManager getClientToServerNetworkManager() - { - return this.client.getConnection()!=null ? this.client.getConnection().getNetworkManager() : null; - } - - public void handleClientWorldClosing(WorldClient world) - { - NetworkManager client = getClientToServerNetworkManager(); - // ONLY revert a non-local connection - if (client != null && !client.isLocalChannel()) - { - GameData.revertToFrozen(); - } - } - - public void startIntegratedServer(String id, String name, WorldSettings settings) - { - } - - public File getSavesDir() - { - return new File(client.mcDataDir, "saves"); - } - public void tryLoadExistingWorld(GuiWorldSelection selectWorldGUI, WorldSummary comparator) - { - File dir = new File(getSavesDir(), comparator.getFileName()); - NBTTagCompound leveldat; - try - { - leveldat = CompressedStreamTools.readCompressed(new FileInputStream(new File(dir, "level.dat"))); - } - catch (Exception e) - { - try - { - leveldat = CompressedStreamTools.readCompressed(new FileInputStream(new File(dir, "level.dat_old"))); - } - catch (Exception e1) - { - FMLLog.log.warn("There appears to be a problem loading the save {}, both level files are unreadable.", comparator.getFileName()); - return; - } - } - NBTTagCompound fmlData = leveldat.getCompoundTag("FML"); - if (fmlData.hasKey("ModItemData")) - { - showGuiScreen(new GuiOldSaveLoadConfirm(comparator.getFileName(), comparator.getDisplayName(), selectWorldGUI)); - } - else - { - try - { - client.launchIntegratedServer(comparator.getFileName(), comparator.getDisplayName(), null); - } - catch (StartupQuery.AbortedException e) - { - // ignore - } - } - } - - public void showInGameModOptions(GuiIngameMenu guiIngameMenu) - { - showGuiScreen(new GuiModList(guiIngameMenu)); - } - - public IModGuiFactory getGuiFactoryFor(ModContainer selectedMod) - { - return guiFactories.get(selectedMod); - } - - - public void setupServerList() - { - extraServerListData = Collections.synchronizedMap(Maps.newHashMap()); - serverDataTag = Collections.synchronizedMap(Maps.newHashMap()); - } - - public void captureAdditionalData(ServerStatusResponse serverstatusresponse, JsonObject jsonobject) - { - if (jsonobject.has("modinfo")) - { - JsonObject fmlData = jsonobject.get("modinfo").getAsJsonObject(); - extraServerListData.put(serverstatusresponse, fmlData); - } - } - public void bindServerListData(ServerData data, ServerStatusResponse originalResponse) - { - if (extraServerListData.containsKey(originalResponse)) - { - JsonObject jsonData = extraServerListData.get(originalResponse); - String type = jsonData.get("type").getAsString(); - JsonArray modDataArray = jsonData.get("modList").getAsJsonArray(); - boolean moddedClientAllowed = jsonData.has("clientModsAllowed") ? jsonData.get("clientModsAllowed").getAsBoolean() : true; - Builder modListBldr = ImmutableMap.builder(); - for (JsonElement obj : modDataArray) - { - JsonObject modObj = obj.getAsJsonObject(); - modListBldr.put(modObj.get("modid").getAsString(), modObj.get("version").getAsString()); - } - - Map modListMap = modListBldr.build(); - String modRejections = FMLNetworkHandler.checkModList(modListMap, Side.SERVER); - serverDataTag.put(data, new ExtendedServerListData(type, modRejections == null, modListMap, !moddedClientAllowed)); - } - else - { - String serverDescription = data.serverMOTD; - boolean moddedClientAllowed = true; - if (!Strings.isNullOrEmpty(serverDescription)) - { - moddedClientAllowed = !serverDescription.endsWith(":NOFML§r"); - } - serverDataTag.put(data, new ExtendedServerListData("VANILLA", false, ImmutableMap.of(), !moddedClientAllowed)); - } - startupConnectionData.countDown(); - } - - private static final ResourceLocation iconSheet = new ResourceLocation("fml:textures/gui/icons.png"); - private static final CountDownLatch startupConnectionData = new CountDownLatch(1); - - @Nullable - public String enhanceServerListEntry(ServerListEntryNormal serverListEntry, ServerData serverEntry, int x, int width, int y, int relativeMouseX, int relativeMouseY) - { - String tooltip; - int idx; - boolean blocked = false; - if (serverDataTag.containsKey(serverEntry)) - { - ExtendedServerListData extendedData = serverDataTag.get(serverEntry); - if ("FML".equals(extendedData.type) && extendedData.isCompatible) - { - idx = 0; - tooltip = String.format("Compatible FML modded server\n%d mods present", extendedData.modData.size()); - } - else if ("FML".equals(extendedData.type) && !extendedData.isCompatible) - { - idx = 16; - tooltip = String.format("Incompatible FML modded server\n%d mods present", extendedData.modData.size()); - } - else if ("BUKKIT".equals(extendedData.type)) - { - idx = 32; - tooltip = String.format("Bukkit modded server"); - } - else if ("VANILLA".equals(extendedData.type)) - { - idx = 48; - tooltip = String.format("Vanilla server"); - } - else - { - idx = 64; - tooltip = String.format("Unknown server data"); - } - blocked = extendedData.isBlocked; - } - else - { - return null; - } - this.client.getTextureManager().bindTexture(iconSheet); - Gui.drawModalRectWithCustomSizedTexture(x + width - 18, y + 10, 0, (float)idx, 16, 16, 256.0f, 256.0f); - if (blocked) - { - Gui.drawModalRectWithCustomSizedTexture(x + width - 18, y + 10, 0, 80, 16, 16, 256.0f, 256.0f); - } - - return relativeMouseX > width - 15 && relativeMouseX < width && relativeMouseY > 10 && relativeMouseY < 26 ? tooltip : null; - } - - public String fixDescription(String description) - { - return description.endsWith(":NOFML§r") ? description.substring(0, description.length() - 8)+"§r" : description; - } - - public void connectToServerAtStartup(String host, int port) - { - setupServerList(); - ServerPinger osp = new ServerPinger(); - ServerData serverData = new ServerData("Command Line", host+":"+port,false); - try - { - osp.ping(serverData); - startupConnectionData.await(30, TimeUnit.SECONDS); - } - catch (Exception e) - { - showGuiScreen(new GuiConnecting(new GuiMainMenu(), client, host, port)); - return; - } - connectToServer(new GuiMainMenu(), serverData); - } - - public void connectToServer(GuiScreen guiMultiplayer, ServerData serverEntry) - { - ExtendedServerListData extendedData = serverDataTag.get(serverEntry); - if (extendedData != null && extendedData.isBlocked) - { - showGuiScreen(new GuiAccessDenied(guiMultiplayer, serverEntry)); - } - else - { - showGuiScreen(new GuiConnecting(guiMultiplayer, client, serverEntry)); - } - } - - public void connectToRealmsServer(String host, int port){} - - public void setPlayClient(NetHandlerPlayClient netHandlerPlayClient) - { - this.currentPlayClient = new WeakReference(netHandlerPlayClient); - } - - @Override - public void fireNetRegistrationEvent(IEventBus bus, NetworkManager manager, Set channelSet, String channel, Side side) - { - if (side == Side.CLIENT) - { - bus.post(new FMLNetworkEvent.CustomPacketRegistrationEvent(manager, channelSet, channel, side, NetHandlerPlayClient.class)); - } - else - { - bus.post(new FMLNetworkEvent.CustomPacketRegistrationEvent(manager, channelSet, channel, side, NetHandlerPlayServer.class)); - } - } - - @Override - public boolean shouldAllowPlayerLogins() - { - return true; //Always true as the server has to be started before clicking 'Open to lan' - } - - @Override - public void allowLogins() { - // NOOP for integrated server - } - - @Override - public IThreadListener getWorldThread(INetHandler net) - { - if (net instanceof INetHandlerPlayClient || - net instanceof INetHandlerLoginClient || - net instanceof INetHandlerStatusClient) return getClient(); - if (net instanceof INetHandlerHandshakeServer || - net instanceof INetHandlerLoginServer || - net instanceof INetHandlerPlayServer || - net instanceof INetHandlerStatusServer) return getServer(); - throw new RuntimeException("Unknown INetHandler: " + net); - } - - private Set badTextureDomains = Sets.newHashSet(); - private Table> brokenTextures = HashBasedTable.create(); - - public void trackMissingTexture(ResourceLocation resourceLocation) - { - badTextureDomains.add(resourceLocation.getResourceDomain()); - missingTextures.put(resourceLocation.getResourceDomain(),resourceLocation); - } - - public void trackBrokenTexture(ResourceLocation resourceLocation, String error) - { - badTextureDomains.add(resourceLocation.getResourceDomain()); - Set badType = brokenTextures.get(resourceLocation.getResourceDomain(), error); - if (badType == null) - { - badType = Sets.newHashSet(); - brokenTextures.put(resourceLocation.getResourceDomain(), MoreObjects.firstNonNull(error, "Unknown error"), badType); - } - badType.add(resourceLocation); - } - - public void logMissingTextureErrors() - { - if (missingTextures.isEmpty() && brokenTextures.isEmpty()) - { - return; - } - Logger logger = LogManager.getLogger("FML.TEXTURE_ERRORS"); - logger.error(Strings.repeat("+=", 25)); - logger.error("The following texture errors were found."); - Map resManagers = ObfuscationReflectionHelper.getPrivateValue(SimpleReloadableResourceManager.class, (SimpleReloadableResourceManager)Minecraft.getMinecraft().getResourceManager(), "domainResourceManagers", "field_110548"+"_a"); - for (String resourceDomain : badTextureDomains) - { - Set missing = missingTextures.get(resourceDomain); - logger.error(Strings.repeat("=", 50)); - logger.error(" DOMAIN {}", resourceDomain); - logger.error(Strings.repeat("-", 50)); - logger.error(" domain {} is missing {} texture{}",resourceDomain, missing.size(),missing.size()!=1 ? "s" : ""); - FallbackResourceManager fallbackResourceManager = resManagers.get(resourceDomain); - if (fallbackResourceManager == null) - { - logger.error(" domain {} is missing a resource manager - it is probably a side-effect of automatic texture processing", resourceDomain); - } - else - { - List resPacks = ObfuscationReflectionHelper.getPrivateValue(FallbackResourceManager.class, fallbackResourceManager, "resourcePacks","field_110540"+"_a"); - logger.error(" domain {} has {} location{}:",resourceDomain, resPacks.size(), resPacks.size() != 1 ? "s" :""); - for (IResourcePack resPack : resPacks) - { - if (resPack instanceof FMLContainerHolder) { - FMLContainerHolder containerHolder = (FMLContainerHolder) resPack; - ModContainer fmlContainer = containerHolder.getFMLContainer(); - logger.error(" mod {} resources at {}", fmlContainer.getModId(), fmlContainer.getSource().getPath()); - } - else if (resPack instanceof AbstractResourcePack) - { - AbstractResourcePack resourcePack = (AbstractResourcePack) resPack; - File resPath = ObfuscationReflectionHelper.getPrivateValue(AbstractResourcePack.class, resourcePack, "resourcePackFile","field_110597"+"_b"); - logger.error(" resource pack at path {}",resPath.getPath()); - } - else - { - logger.error(" unknown resourcepack type {} : {}", resPack.getClass().getName(), resPack.getPackName()); - } - } - } - logger.error(Strings.repeat("-", 25)); - if (missingTextures.containsKey(resourceDomain)) { - logger.error(" The missing resources for domain {} are:", resourceDomain); - for (ResourceLocation rl : missing) { - logger.error(" {}", rl.getResourcePath()); - } - logger.error(Strings.repeat("-", 25)); - } - if (!brokenTextures.containsRow(resourceDomain)) - { - logger.error(" No other errors exist for domain {}", resourceDomain); - } - else - { - logger.error(" The following other errors were reported for domain {}:",resourceDomain); - Map> resourceErrs = brokenTextures.row(resourceDomain); - for (String error: resourceErrs.keySet()) - { - logger.error(Strings.repeat("-", 25)); - logger.error(" Problem: {}", error); - for (ResourceLocation rl : resourceErrs.get(error)) - { - logger.error(" {}",rl.getResourcePath()); - } - } - } - logger.error(Strings.repeat("=", 50)); - } - logger.error(Strings.repeat("+=", 25)); - } - - @Override - public void processWindowMessages() - { - } - // From FontRenderer.renderCharAtPos - private static final String ALLOWED_CHARS = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000"; - private static final CharMatcher DISALLOWED_CHAR_MATCHER = CharMatcher.anyOf(ALLOWED_CHARS).negate(); - - @Override - public String stripSpecialChars(String message) - { - // We can't handle many unicode points in the splash renderer - return DISALLOWED_CHAR_MATCHER.removeFrom(StringUtils.stripControlCodes(message)); - } - - public void logMissingTextureErrors() {} - @Override - public void reloadRenderers() - { - this.client.renderGlobal.loadRenderers(); - } - - @Override - public void fireSidedRegistryEvents() - { - MinecraftForge.EVENT_BUS.post(new ModelRegistryEvent()); - } - - @Override - public CompoundDataFixer getDataFixer() - { - return (CompoundDataFixer)this.client.getDataFixer(); - } - - @Override - public boolean isDisplayVSyncForced() - { - return SplashProgress.isDisplayVSyncForced; - } - - @Override - public void resetClientRecipeBook() - { - RecipeBookClient.rebuildTable(); - } - - @Override - public void reloadSearchTrees() - { - this.client.populateSearchTreeManager(); - this.client.getSearchTreeManager().onResourceManagerReload(this.client.getResourceManager()); - } - - @Override - public void reloadCreativeSettings() - { - this.client.creativeSettings.read(); - } - - private CloudRenderer getCloudRenderer() - { - if (cloudRenderer == null) - cloudRenderer = new CloudRenderer(); - return cloudRenderer; - } - - public void updateCloudSettings() - { - getCloudRenderer().checkSettings(); - } - - public boolean renderClouds(int cloudTicks, float partialTicks) - { - IRenderHandler renderer = this.client.world.provider.getCloudRenderer(); - if (renderer != null) - { - renderer.render(partialTicks, this.client.world, this.client); - return true; - } - return getCloudRenderer().render(cloudTicks, partialTicks); - } - - public void refreshResources(IResourceType... inclusion) - { - this.refreshResources(ReloadRequirements.include(inclusion)); - } - - // Wrapper around the existing refreshResources with given reload predicates - public void refreshResources(Predicate resourcePredicate) - { - SelectiveReloadStateHandler.INSTANCE.beginReload(resourcePredicate); - this.client.refreshResources(); - SelectiveReloadStateHandler.INSTANCE.endReload(); - } - - public ListenableFuture scheduleResourcesRefresh(IResourceType... inclusion) - { - return this.scheduleResourcesRefresh(ReloadRequirements.include(inclusion)); - } - - public ListenableFuture scheduleResourcesRefresh(Predicate resourcePredicate) - { - return this.client.addScheduledTask(() -> this.refreshResources(resourcePredicate)); - } -} diff --git a/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java b/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java deleted file mode 100644 index c0cfec8ec..000000000 --- a/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.client; - -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - -import net.minecraftforge.fml.common.FMLLog; -import org.apache.logging.log4j.LogManager; - -import javax.imageio.ImageIO; - -import net.minecraft.client.resources.FileResourcePack; -import net.minecraftforge.fml.common.FMLContainerHolder; -import net.minecraftforge.fml.ModContainer; - -public class FMLFileResourcePack extends FileResourcePack implements FMLContainerHolder { - - private ModContainer container; - - public FMLFileResourcePack(ModContainer container) - { - super(container.getSource()); - this.container = container; - } - - @Override - public String getPackName() - { - return "FMLFileResourcePack:"+container.getName(); - } - @Override - protected InputStream getInputStreamByName(String resourceName) throws IOException - { - try - { - return super.getInputStreamByName(resourceName); - } - catch (IOException ioe) - { - if ("pack.mcmeta".equals(resourceName)) - { - FMLLog.log.debug("Mod {} is missing a pack.mcmeta file, substituting a dummy one", container.getName()); - return new ByteArrayInputStream(("{\n" + - " \"pack\": {\n"+ - " \"description\": \"dummy FML pack for "+container.getName()+"\",\n"+ - " \"pack_format\": 2\n"+ - "}\n" + - "}").getBytes(StandardCharsets.UTF_8)); - } - else throw ioe; - } - } - - @Override - public BufferedImage getPackImage() throws IOException - { - return ImageIO.read(getInputStreamByName(container.getMetadata().logoFile)); - } - - @Override - public ModContainer getFMLContainer() - { - return container; - } -} diff --git a/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java b/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java deleted file mode 100644 index 389006815..000000000 --- a/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.client; - -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - -import net.minecraftforge.fml.common.FMLLog; -import org.apache.logging.log4j.LogManager; - -import javax.imageio.ImageIO; - -import net.minecraft.client.resources.FolderResourcePack; -import net.minecraftforge.fml.common.FMLContainerHolder; -import net.minecraftforge.fml.ModContainer; - -public class FMLFolderResourcePack extends FolderResourcePack implements FMLContainerHolder { - - private ModContainer container; - - public FMLFolderResourcePack(ModContainer container) - { - super(container.getSource()); - this.container = container; - } - - @Override - protected boolean hasResourceName(String p_110593_1_) - { - return super.hasResourceName(p_110593_1_); - } - @Override - public String getPackName() - { - return "FMLFileResourcePack:"+container.getName(); - } - @Override - protected InputStream getInputStreamByName(String resourceName) throws IOException - { - try - { - return super.getInputStreamByName(resourceName); - } - catch (IOException ioe) - { - if ("pack.mcmeta".equals(resourceName)) - { - FMLLog.log.debug("Mod {} is missing a pack.mcmeta file, substituting a dummy one", container.getName()); - return new ByteArrayInputStream(("{\n" + - " \"pack\": {\n"+ - " \"description\": \"dummy FML pack for "+container.getName()+"\",\n"+ - " \"pack_format\": 2\n"+ - "}\n" + - "}").getBytes(StandardCharsets.UTF_8)); - } - else throw ioe; - } - } - - @Override - public BufferedImage getPackImage() throws IOException - { - return ImageIO.read(getInputStreamByName(container.getMetadata().logoFile)); - } - - @Override - public ModContainer getFMLContainer() - { - return container; - } - -} diff --git a/src/main/java/net/minecraftforge/fml/client/ModFileResourcePack.java b/src/main/java/net/minecraftforge/fml/client/ModFileResourcePack.java index 8b7c98320..a48e34cf5 100644 --- a/src/main/java/net/minecraftforge/fml/client/ModFileResourcePack.java +++ b/src/main/java/net/minecraftforge/fml/client/ModFileResourcePack.java @@ -19,15 +19,19 @@ package net.minecraftforge.fml.client; -import net.minecraft.client.resources.AbstractResourcePack; +import net.minecraft.resources.AbstractResourcePack; +import net.minecraft.resources.ResourcePackType; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.loading.moddiscovery.ModFile; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; +import java.util.Collection; import java.util.Collections; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Collectors; public class ModFileResourcePack extends AbstractResourcePack @@ -45,32 +49,57 @@ public class ModFileResourcePack extends AbstractResourcePack } @Override - public String getPackName() + public String func_195762_a() { return modFile.getFileName(); } @Override - protected InputStream getInputStreamByName(String name) throws IOException + protected InputStream func_195766_a(String name) throws IOException { return Files.newInputStream(modFile.getLocator().findPath(modFile, name)); } @Override - protected boolean hasResourceName(String name) + protected boolean func_195768_c(String name) { return Files.exists(modFile.getLocator().findPath(modFile, name)); } @Override - public Set getResourceDomains() + public Collection func_195758_a(ResourcePackType p_195758_1_, String p_195758_2_, int p_195758_3_, Predicate p_195758_4_) + { + + try + { + return Files.walk(modFile.getLocator().findPath(modFile, p_195758_1_.func_198956_a())). + filter(path -> !path.toString().endsWith(".mcmeta")). + filter(path -> path.getNameCount() > 2 && p_195758_2_.equals(path.getName(2).toString())). + filter(path -> p_195758_4_.test(path.subpath(3, Math.min(p_195758_3_+3, path.getNameCount())).toString())). + map(path -> new ResourceLocation(path.getName(1).toString(),path.subpath(3,Math.min(p_195758_3_+3, path.getNameCount())).toString())). + collect(Collectors.toList()); + } + catch (IOException e) + { + return Collections.emptyList(); + } + } + + @Override + public Set func_195759_a(ResourcePackType p_195759_1_) { try { - return Files.walk(modFile.getLocator().findPath(modFile, "assets"),1).map(p->p.getFileName().toString()).collect(Collectors.toSet()); + return Files.walk(modFile.getLocator().findPath(modFile, p_195759_1_.func_198956_a()),1).map(p->p.getFileName().toString()).collect(Collectors.toSet()); } catch (IOException e) { return Collections.emptySet(); } } + + @Override + public void close() throws IOException + { + + } } diff --git a/src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java b/src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java index c4a1c4dea..be81bc848 100644 --- a/src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java +++ b/src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java @@ -19,10 +19,10 @@ package net.minecraftforge.fml.client; -import net.minecraft.client.resources.AbstractResourcePack; -import net.minecraft.client.resources.FileResourcePack; -import net.minecraft.client.resources.FolderResourcePack; -import net.minecraft.client.resources.IResourcePack; +import net.minecraft.resources.AbstractResourcePack; +import net.minecraft.resources.FilePack; +import net.minecraft.resources.FolderPack; +import net.minecraft.resources.IResourcePack; import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.moddiscovery.ModFile; @@ -48,8 +48,8 @@ public class ResourcePackLoader map(mf -> new ModFileResourcePack(mf.getFile())). collect(Collectors.toMap(ModFileResourcePack::getModFile, Function.identity())); forgePack = Files.isDirectory(FMLLoader.getForgePath()) ? - new FolderResourcePack(FMLLoader.getForgePath().toFile()) : - new FileResourcePack(FMLLoader.getForgePath().toFile()); + new FolderPack(FMLLoader.getForgePath().toFile()) : + new FilePack(FMLLoader.getForgePath().toFile()); resourcePacks.add(forgePack); resourcePacks.addAll(modResourcePacks.values()); } diff --git a/src/main/java/net/minecraftforge/fml/client/SplashProgress.java b/src/main/java/net/minecraftforge/fml/client/SplashProgress.java index 0ec64ff74..26fc0161f 100644 --- a/src/main/java/net/minecraftforge/fml/client/SplashProgress.java +++ b/src/main/java/net/minecraftforge/fml/client/SplashProgress.java @@ -18,7 +18,7 @@ */ package net.minecraftforge.fml.client; - +/* import static net.minecraftforge.fml.Logging.SPLASH; import static net.minecraftforge.fml.Logging.fmlLog; import static org.lwjgl.opengl.GL11.*; @@ -86,6 +86,7 @@ import org.lwjgl.util.glu.GLU; @SuppressWarnings("serial") public class SplashProgress { +/* private static Drawable d; private static volatile boolean pause = false; private static volatile boolean done = false; @@ -613,7 +614,7 @@ public class SplashProgress * Resource loading doesn't usually require this call. * Call {@link #resume()} when you're done. * @deprecated not a stable API, will break, don't use this yet - */ + * / @Deprecated public static void pause() { @@ -635,7 +636,7 @@ public class SplashProgress /** * @deprecated not a stable API, will break, don't use this yet - */ + * / @Deprecated public static void resume() { @@ -980,4 +981,5 @@ public class SplashProgress { return (int) (bytes / 1024L / 1024L); } + */ } \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/fml/client/TextureTracker.java b/src/main/java/net/minecraftforge/fml/client/TextureTracker.java index db8f72490..bdeba8a1e 100644 --- a/src/main/java/net/minecraftforge/fml/client/TextureTracker.java +++ b/src/main/java/net/minecraftforge/fml/client/TextureTracker.java @@ -20,27 +20,13 @@ package net.minecraftforge.fml.client; import com.google.common.base.MoreObjects; -import com.google.common.base.Strings; import com.google.common.collect.HashBasedTable; import com.google.common.collect.HashMultimap; import com.google.common.collect.SetMultimap; import com.google.common.collect.Sets; import com.google.common.collect.Table; -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.AbstractResourcePack; -import net.minecraft.client.resources.FallbackResourceManager; -import net.minecraft.client.resources.IResourcePack; -import net.minecraft.client.resources.SimpleReloadableResourceManager; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.FMLContainerHolder; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import java.io.File; -import java.util.List; -import java.util.Map; import java.util.Set; public class TextureTracker @@ -51,24 +37,25 @@ public class TextureTracker public static void trackMissingTexture(ResourceLocation resourceLocation) { - badTextureDomains.add(resourceLocation.getResourceDomain()); - missingTextures.put(resourceLocation.getResourceDomain(),resourceLocation); + badTextureDomains.add(resourceLocation.getNamespace()); + missingTextures.put(resourceLocation.getNamespace(),resourceLocation); } public static void trackBrokenTexture(ResourceLocation resourceLocation, String error) { - badTextureDomains.add(resourceLocation.getResourceDomain()); - Set badType = brokenTextures.get(resourceLocation.getResourceDomain(), error); + badTextureDomains.add(resourceLocation.getNamespace()); + Set badType = brokenTextures.get(resourceLocation.getNamespace(), error); if (badType == null) { badType = Sets.newHashSet(); - brokenTextures.put(resourceLocation.getResourceDomain(), MoreObjects.firstNonNull(error, "Unknown error"), badType); + brokenTextures.put(resourceLocation.getNamespace(), MoreObjects.firstNonNull(error, "Unknown error"), badType); } badType.add(resourceLocation); } public static void logMissingTextureErrors() { +/* if (missingTextures.isEmpty() && brokenTextures.isEmpty()) { return; @@ -141,6 +128,7 @@ public class TextureTracker logger.error(Strings.repeat("=", 50)); } logger.error(Strings.repeat("+=", 25)); +*/ } diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java b/src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java index b8243de7e..32a53c9e7 100644 --- a/src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java +++ b/src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java @@ -34,8 +34,6 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.resources.I18n; import net.minecraft.util.text.TextComponentString; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.config.ConfigElement; -import net.minecraftforge.common.config.ConfigManager; import net.minecraftforge.fml.client.config.GuiConfigEntries.IConfigEntry; import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent; @@ -85,51 +83,6 @@ public class GuiConfig extends GuiScreen protected HoverChecker resetHoverChecker; protected HoverChecker checkBoxHoverChecker; - /** - * This constructor handles the {@code @Config} configuration classes - * @param parentScreen the parent GuiScreen object - * @param mod the mod for which to create a screen - */ - public GuiConfig(GuiScreen parentScreen, String modid, String title) - { - this(parentScreen, modid, false, false, title, ConfigManager.getModConfigClasses(modid)); - } - - /** - * - * @param parentScreen the parrent GuiScreen object - * @param modID the mod ID for the mod whose config settings will be editted - * @param allRequireWorldRestart whether all config elements on this screen require a world restart - * @param allRequireMcRestart whether all config elements on this screen require a game restart - * @param title the desired title for this screen. For consistency it is recommended that you pass the path of the config file being - * edited. - * @param configClasses an array of classes annotated with {@code @Config} providing the configuration - */ - public GuiConfig(GuiScreen parentScreen, String modID, boolean allRequireWorldRestart, boolean allRequireMcRestart, String title, - Class... configClasses) - { - this(parentScreen, collectConfigElements(configClasses), modID, null, allRequireWorldRestart, allRequireMcRestart, title, null); - } - - private static List collectConfigElements(Class[] configClasses) - { - List toReturn; - if(configClasses.length == 1) - { - toReturn = ConfigElement.from(configClasses[0]).getChildElements(); - } - else - { - toReturn = new ArrayList(); - for(Class clazz : configClasses) - { - toReturn.add(ConfigElement.from(clazz)); - } - } - toReturn.sort(Comparator.comparing(e -> I18n.format(e.getLanguageKey()))); - return toReturn; - } - /** * GuiConfig constructor that will use ConfigChangedEvent when editing is concluded. If a non-null value is passed for configID, * the OnConfigChanged and PostConfigChanged events will be posted when the Done button is pressed if any configElements were changed @@ -214,7 +167,7 @@ public class GuiConfig extends GuiScreen this.parentScreen = parentScreen; this.configElements = configElements; this.entryList = new GuiConfigEntries(this, mc); - this.initEntries = new ArrayList(entryList.listEntries); + this.initEntries = new ArrayList<>(entryList.listEntries); this.allRequireWorldRestart = allRequireWorldRestart; IF:if (!allRequireWorldRestart) { diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java b/src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java index f6b3af12d..c2fa2d4a9 100644 --- a/src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java +++ b/src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java @@ -27,7 +27,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.TreeMap; +import java.util.stream.Collectors; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiListExtended; @@ -35,10 +35,10 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiTextField; import net.minecraft.client.resources.I18n; import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.ModContainer; +import net.minecraftforge.fml.loading.moddiscovery.ModInfo; import org.lwjgl.input.Keyboard; /** @@ -150,10 +150,7 @@ public class GuiConfigEntries extends GuiListExtended } else if (configElement.getType() == ConfigGuiType.MOD_ID) { - Map values = new TreeMap(); - for (ModContainer mod : Loader.instance().getActiveModList()) - values.put(mod.getModId(), mod.getName()); - values.put("minecraft", "Minecraft"); + Map values = ModList.get().getMods().stream().collect(Collectors.toMap(ModInfo::getModId, ModInfo::getDisplayName)); this.listEntries.add(new SelectValueEntry(this.owningScreen, this, configElement, values)); } else if (configElement.getType() == ConfigGuiType.STRING) diff --git a/src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java b/src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java index ebc4ddf7b..f696b9c9c 100644 --- a/src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java +++ b/src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java @@ -20,13 +20,13 @@ package net.minecraftforge.fml.client.registry; import com.google.common.collect.Maps; +import net.minecraft.client.renderer.tileentity.TileEntityRenderer; import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; import org.apache.commons.lang3.ArrayUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.client.settings.KeyBinding; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.fml.common.registry.GameRegistry; @@ -45,13 +45,13 @@ public class ClientRegistry * @param id * @param specialRenderer */ - public static void registerTileEntity(Class tileEntityClass, String id, TileEntitySpecialRenderer specialRenderer) + public static void registerTileEntity(Class tileEntityClass, String id, TileEntityRenderer specialRenderer) { GameRegistry.registerTileEntity(tileEntityClass, id); bindTileEntitySpecialRenderer(tileEntityClass, specialRenderer); } - public static void bindTileEntitySpecialRenderer(Class tileEntityClass, TileEntitySpecialRenderer specialRenderer) + public static void bindTileEntitySpecialRenderer(Class tileEntityClass, TileEntityRenderer specialRenderer) { TileEntityRendererDispatcher.instance.renderers.put(tileEntityClass, specialRenderer); specialRenderer.setRendererDispatcher(TileEntityRendererDispatcher.instance); diff --git a/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java b/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java deleted file mode 100644 index 5d6816a4b..000000000 --- a/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java +++ /dev/null @@ -1,677 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.io.File; -import java.lang.ref.WeakReference; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.FutureTask; -import java.util.concurrent.TimeUnit; - -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.IInventory; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.EnumConnectionState; -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetworkManager; -import net.minecraft.network.handshake.client.C00Handshake; -import net.minecraft.network.login.server.SPacketDisconnect; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.IThreadListener; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.world.World; -import net.minecraft.world.storage.SaveHandler; -import net.minecraft.world.storage.WorldInfo; -import net.minecraftforge.client.model.animation.Animation; -import net.minecraftforge.common.ForgeVersion; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.util.CompoundDataFixer; -import net.minecraftforge.fml.LogicalSide; -import net.minecraftforge.fml.StartupQuery; -import net.minecraftforge.fml.WorldPersistenceHooks; -import net.minecraftforge.fml.BrandingControl; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.common.gameevent.InputEvent; -import net.minecraftforge.fml.common.gameevent.PlayerEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; -import net.minecraftforge.fml.common.network.FMLNetworkEvent; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.thread.SidedThreadGroup; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.server.FMLServerHandler; - -import org.apache.logging.log4j.Logger; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.collect.MapMaker; -import com.google.common.collect.Maps; - -/** - * The main class for non-obfuscated hook handling code - * - * Anything that doesn't require obfuscated or client/server specific code should - * go in this handler - * - * It also contains a reference to the sided handler instance that is valid - * allowing for common code to access specific properties from the obfuscated world - * without a direct dependency - * - * @author cpw - * - */ -public class FMLCommonHandler -{ - /** - * The singleton - */ - private static final FMLCommonHandler INSTANCE = new FMLCommonHandler(); - /** - * The delegate for side specific data and functions - */ - private IFMLSidedHandler sidedDelegate; - - private boolean noForge; - private List brandings; - private List brandingsNoMC; - private Set handlerSet = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap()); - private WeakReference handlerToCheck; - private IEventBus eventBus = MinecraftForge.EVENT_BUS; - private volatile CountDownLatch exitLatch = null; - - private FMLCommonHandler() - { - } - /** - * The FML event bus. Subscribe here for FML related events - * - * @Deprecated Use {@link MinecraftForge#EVENT_BUS} they're the same thing now - * @return the event bus - */ - @Deprecated - public IEventBus bus() - { - return eventBus; - } - - public List beginLoading(IFMLSidedHandler handler) - { - sidedDelegate = handler; - MinecraftForge.initialize(); -// MinecraftForge.registerCrashCallable(); - return ImmutableList.of(); - } - - /** - * @return the instance - */ - public static FMLCommonHandler instance() - { - return INSTANCE; - } - /** - * Find the container that associates with the supplied mod object - * @param mod - */ - public ModContainer findContainerFor(Object mod) - { - if (mod instanceof String) - { - return Loader.instance().getIndexedModList().get(mod); - } - else - { - return Loader.instance().getReversedModObjectList().get(mod); - } - } - /** - * Get the forge mod loader logging instance (goes to the forgemodloader log file) - * @return The log instance for the FML log file - * - * @deprecated Not used in FML, Mods use your own logger, see {@link FMLPreInitializationEvent#getModLog()} - */ - @Deprecated - public Logger getFMLLogger() - { - return FMLLog.log; - } - - public Side getSide() - { - return sidedDelegate.getSide(); - } - - /** - * Return the effective side for the context in the game. This is dependent - * on thread analysis to try and determine whether the code is running in the - * server or not. Use at your own risk - */ - public Side getEffectiveSide() - { - final ThreadGroup group = Thread.currentThread().getThreadGroup(); - return group instanceof SidedThreadGroup ? ((SidedThreadGroup) group).getSide() : Side.CLIENT; - } - /** - * Raise an exception - */ - public void raiseException(Throwable exception, String message, boolean stopGame) - { - FMLLog.log.error("Something raised an exception. The message was '{}'. 'stopGame' is {}", stopGame, exception); - if (stopGame) - { - getSidedDelegate().haltGame(message,exception); - } - } - - - public List getBrandings(boolean includeMC) - { - if (brandings == null) - { - BrandingControl.computeBranding(); - } - return includeMC ? ImmutableList.copyOf(brandings) : ImmutableList.copyOf(brandingsNoMC); - } - - public IFMLSidedHandler getSidedDelegate() - { - return sidedDelegate; - } - - public void onPostServerTick() - { - bus().post(new TickEvent.ServerTickEvent(Phase.END)); - } - - /** - * Every tick just after world and other ticks occur - */ - public void onPostWorldTick(World world) - { - bus().post(new TickEvent.WorldTickEvent(Side.SERVER, Phase.END, world)); - } - - public void onPreServerTick() - { - bus().post(new TickEvent.ServerTickEvent(Phase.START)); - } - - /** - * Every tick just before world and other ticks occur - */ - public void onPreWorldTick(World world) - { - bus().post(new TickEvent.WorldTickEvent(Side.SERVER, Phase.START, world)); - } - - public boolean handleServerAboutToStart(MinecraftServer server) - { - return Loader.instance().serverAboutToStart(server); - } - - public boolean handleServerStarting(MinecraftServer server) - { - return Loader.instance().serverStarting(server); - } - - public void handleServerStarted() - { - Loader.instance().serverStarted(); - sidedDelegate.allowLogins(); - } - - public void handleServerStopping() - { - Loader.instance().serverStopping(); - } - - public File getSavesDirectory() { - return sidedDelegate.getSavesDirectory(); - } - - public MinecraftServer getMinecraftServerInstance() - { - return sidedDelegate.getServer(); - } - - public void showGuiScreen(Object clientGuiElement) - { - sidedDelegate.showGuiScreen(clientGuiElement); - } - - public void queryUser(StartupQuery query) throws InterruptedException - { - sidedDelegate.queryUser(query); - } - - public void onServerStart(MinecraftServer dedicatedServer) - { - FMLServerHandler.instance(); - sidedDelegate.beginServerLoading(dedicatedServer); - } - - public void onServerStarted() - { - sidedDelegate.finishServerLoading(); - } - - - public void onPreClientTick() - { - bus().post(new TickEvent.ClientTickEvent(Phase.START)); - } - - public void onPostClientTick() - { - bus().post(new TickEvent.ClientTickEvent(Phase.END)); - } - - public void onRenderTickStart(float timer) - { - Animation.setClientPartialTickTime(timer); - bus().post(new TickEvent.RenderTickEvent(Phase.START, timer)); - } - - public void onRenderTickEnd(float timer) - { - bus().post(new TickEvent.RenderTickEvent(Phase.END, timer)); - } - - public void onPlayerPreTick(EntityPlayer player) - { - bus().post(new TickEvent.PlayerTickEvent(Phase.START, player)); - } - - public void onPlayerPostTick(EntityPlayer player) - { - bus().post(new TickEvent.PlayerTickEvent(Phase.END, player)); - } - - public void handleWorldDataSave(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound) - { - for (ModContainer mc : Loader.instance().getModList()) - { - if (mc instanceof InjectedModContainer) - { - WorldPersistenceHooks.WorldPersistenceHook wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer(); - if (wac != null) - { - NBTTagCompound dataForWriting = wac.getDataForWriting(handler, worldInfo); - tagCompound.setTag(mc.getModId(), dataForWriting); - } - } - } - } - - public void handleWorldDataLoad(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound) - { - if (getEffectiveSide()!=LogicalSide.SERVER) - { - return; - } - if (handlerSet.contains(handler)) - { - return; - } - handlerSet.add(handler); - handlerToCheck = new WeakReference(handler); // for confirmBackupLevelDatUse - Map additionalProperties = Maps.newHashMap(); - worldInfo.setAdditionalProperties(additionalProperties); - for (ModContainer mc : Loader.instance().getModList()) - { - if (mc instanceof InjectedModContainer) - { - WorldPersistenceHooks.WorldPersistenceHook wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer(); - if (wac != null) - { - wac.readData(handler, worldInfo, additionalProperties, tagCompound.getCompoundTag(mc.getModId())); - } - } - } - } - - public void confirmBackupLevelDatUse(SaveHandler handler) - { - if (handlerToCheck == null || handlerToCheck.get() != handler) { - // only run if the save has been initially loaded - handlerToCheck = null; - return; - } - - String text = "Forge Mod Loader detected that the backup level.dat is being used.\n\n" + - "This may happen due to a bug or corruption, continuing can damage\n" + - "your world beyond repair or lose data / progress.\n\n" + - "It's recommended to create a world backup before continuing."; - - boolean confirmed = StartupQuery.confirm(text); - if (!confirmed) StartupQuery.abort(); - } - - public boolean isDisplayCloseRequested() - { - return sidedDelegate != null && sidedDelegate.isDisplayCloseRequested(); - } - - public boolean shouldServerBeKilledQuietly() - { - if (sidedDelegate == null) - { - return false; - } - return sidedDelegate.shouldServerShouldBeKilledQuietly(); - } - - /** - * Make handleExit() wait for handleServerStopped(). - * - * For internal use only! - */ - public void expectServerStopped() - { - exitLatch = new CountDownLatch(1); - } - - /** - * Delayed System.exit() until the server is actually stopped/done saving. - * - * For internal use only! - * - * @param retVal Exit code for System.exit() - */ - public void handleExit(int retVal) - { - CountDownLatch latch = exitLatch; - - if (latch != null) - { - try - { - FMLLog.log.info("Waiting for the server to terminate/save."); - if (!latch.await(10, TimeUnit.SECONDS)) - { - FMLLog.log.warn("The server didn't stop within 10 seconds, exiting anyway."); - } - else - { - FMLLog.log.info("Server terminated."); - } - } - catch (InterruptedException e) - { - FMLLog.log.warn("Interrupted wait, exiting."); - } - } - - System.exit(retVal); - } - - public void handleServerStopped() - { - sidedDelegate.serverStopped(); - MinecraftServer server = getMinecraftServerInstance(); - Loader.instance().serverStopped(); - // FORCE the internal server to stop: hello optifine workaround! - if (server!=null) ObfuscationReflectionHelper.setPrivateValue(MinecraftServer.class, server, false, "field_71316"+"_v", "u", "serverStopped"); - - // allow any pending exit to continue, clear exitLatch - CountDownLatch latch = exitLatch; - - if (latch != null) - { - latch.countDown(); - exitLatch = null; - } - } - - public String getModName() - { - List modNames = Lists.newArrayListWithExpectedSize(3); - modNames.add("fml"); - if (!noForge) - { - modNames.add(ForgeVersion.MOD_ID); - } - - if (Loader.instance().getFMLBrandingProperties().containsKey("snooperbranding")) - { - modNames.add(Loader.instance().getFMLBrandingProperties().get("snooperbranding")); - } - return Joiner.on(',').join(modNames); - } - - public void addModToResourcePack(ModContainer container) - { - sidedDelegate.addModAsResource(container); - } - - public String getCurrentLanguage() - { - - return sidedDelegate.getCurrentLanguage(); - } - - public void bootstrap() - { - } - - public NetworkManager getClientToServerNetworkManager() - { - return sidedDelegate.getClientToServerNetworkManager(); - } - - public void fireMouseInput() - { - bus().post(new InputEvent.MouseInputEvent()); - } - - public void fireKeyInput() - { - bus().post(new InputEvent.KeyInputEvent()); - } - - public void firePlayerChangedDimensionEvent(EntityPlayer player, int fromDim, int toDim) - { - bus().post(new PlayerEvent.PlayerChangedDimensionEvent(player, fromDim, toDim)); - } - - public void firePlayerLoggedIn(EntityPlayer player) - { - bus().post(new PlayerEvent.PlayerLoggedInEvent(player)); - } - - public void firePlayerLoggedOut(EntityPlayer player) - { - bus().post(new PlayerEvent.PlayerLoggedOutEvent(player)); - } - - public void firePlayerRespawnEvent(EntityPlayer player, boolean endConquered) - { - bus().post(new PlayerEvent.PlayerRespawnEvent(player, endConquered)); - } - - public void firePlayerItemPickupEvent(EntityPlayer player, EntityItem item, ItemStack clone) - { - bus().post(new PlayerEvent.ItemPickupEvent(player, item, clone)); - } - - public void firePlayerCraftingEvent(EntityPlayer player, ItemStack crafted, IInventory craftMatrix) - { - bus().post(new PlayerEvent.ItemCraftedEvent(player, crafted, craftMatrix)); - } - - public void firePlayerSmeltedEvent(EntityPlayer player, ItemStack smelted) - { - bus().post(new PlayerEvent.ItemSmeltedEvent(player, smelted)); - } - - public INetHandler getClientPlayHandler() - { - return sidedDelegate.getClientPlayHandler(); - } - - public void fireNetRegistrationEvent(NetworkManager manager, Set channelSet, String channel, Side side) - { - sidedDelegate.fireNetRegistrationEvent(bus(), manager, channelSet, channel, side); - } - - public boolean shouldAllowPlayerLogins() - { - return sidedDelegate.shouldAllowPlayerLogins(); - } - - public void fireServerConnectionEvent(NetworkManager manager) - { - bus().post(new FMLNetworkEvent.ServerConnectionFromClientEvent(manager)); - } - - /** - * Process initial Handshake packet, kicks players from the server if they are connecting while we are starting up. - * Also verifies the client has the FML marker. - * - * @param packet Handshake Packet - * @param manager NetworkDirection connection - * @return True to allow connection, otherwise False. - */ - public boolean handleServerHandshake(C00Handshake packet, NetworkManager manager) - { - if (!shouldAllowPlayerLogins()) - { - TextComponentString text = new TextComponentString("Server is still starting! Please wait before reconnecting."); - LOGGER.info("Disconnecting Player: {}", text.getUnformattedText()); - manager.sendPacket(new SPacketDisconnect(text)); - manager.closeChannel(text); - return false; - } - - if (packet.getRequestedState() == EnumConnectionState.LOGIN && (!NetworkRegistry.INSTANCE.isVanillaAccepted(Side.CLIENT) && !packet.hasFMLMarker())) - { - manager.setConnectionState(EnumConnectionState.LOGIN); - TextComponentString text = new TextComponentString("This server has mods that require FML/Forge to be installed on the client. Contact your server admin for more details."); - Collection modNames = NetworkRegistry.INSTANCE.getRequiredMods(Side.CLIENT); - FMLLog.log.info("Disconnecting Player: This server has mods that require FML/Forge to be installed on the client: {}", modNames); - manager.sendPacket(new SPacketDisconnect(text)); - manager.closeChannel(text); - return false; - } - - manager.channel().attr(net.minecraftforge.fml.network.NetworkRegistry.FML_MARKER).set(packet.hasFMLMarker()); - return true; - } - - public void processWindowMessages() - { - if (sidedDelegate == null) return; - sidedDelegate.processWindowMessages(); - } - - /** - * Used to exit from java, with system exit preventions in place. Will be tidy about it and just log a message, - * unless debugging is enabled - * - * @param exitCode The exit code - * @param hardExit Perform a halt instead of an exit (only use when the world is unsavable) - read the warnings at {@link Runtime#halt(int)} - */ - public void exitJava(int exitCode, boolean hardExit) - { - FMLLog.log.warn("Java has been asked to exit (code {})", exitCode); - if (hardExit) - { - FMLLog.log.warn("This is an abortive exit and could cause world corruption or other things"); - } - StackTraceElement[] stack = Thread.currentThread().getStackTrace(); - FMLLog.log.warn("Exit trace:"); - //The first 2 elements are Thread#getStackTrace and FMLCommonHandler#exitJava and aren't relevant - for (int i = 2; i < stack.length; i++) - { - FMLLog.log.warn("\t{}", stack[i]); - } - if (hardExit) - { - Runtime.getRuntime().halt(exitCode); - } - else - { - Runtime.getRuntime().exit(exitCode); - } - } - - public IThreadListener getWorldThread(INetHandler net) - { - return sidedDelegate.getWorldThread(net); - } - - public static void callFuture(FutureTask task) - { - try - { - task.run(); - task.get(); // Forces the exception to be thrown if any - } - catch (InterruptedException | ExecutionException e) - { - FMLLog.log.fatal("Exception caught executing FutureTask: {}", e.toString(), e); - } - } - - public String stripSpecialChars(String message) - { - return sidedDelegate != null ? sidedDelegate.stripSpecialChars(message) : message; - } - - public void reloadRenderers() { - sidedDelegate.reloadRenderers(); - } - - public void fireSidedRegistryEvents() - { - sidedDelegate.fireSidedRegistryEvents(); - } - - public CompoundDataFixer getDataFixer() - { - return (CompoundDataFixer)sidedDelegate.getDataFixer(); - } - - public boolean isDisplayVSyncForced() { return sidedDelegate.isDisplayVSyncForced(); } - public void resetClientRecipeBook() { - this.sidedDelegate.resetClientRecipeBook(); - } - - public void reloadSearchTrees() { - this.sidedDelegate.reloadSearchTrees(); - } - - public void reloadCreativeSettings() - { - this.sidedDelegate.reloadCreativeSettings(); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/FMLLog.java b/src/main/java/net/minecraftforge/fml/common/FMLLog.java deleted file mode 100644 index 22e2ac96f..000000000 --- a/src/main/java/net/minecraftforge/fml/common/FMLLog.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.util.Locale; - -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.api.distmarker.Dist; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.ThreadContext; - -/** - * FMLs logging class. Internal use only, NOT FOR MOD LOGGING! Mods use your own log, see {@link FMLPreInitializationEvent#getModLog()}. - * TODO 1.13 remove all the deprecated methods - */ -public class FMLLog -{ - - public static final Logger log = LogManager.getLogger("FML"); - - public static void bigWarning(String format, Object... data) - { - StackTraceElement[] trace = Thread.currentThread().getStackTrace(); - log.warn("****************************************"); - log.warn("* "+format, data); - for (int i = 2; i < 8 && i < trace.length; i++) - { - log.warn("* at {}{}", trace[i].toString(), i == 7 ? "..." : ""); - } - log.warn("****************************************"); - } - - @Deprecated - public static void log(String targetLog, Level level, String format, Object... data) - { - FMLRelaunchLog.log(targetLog, level, format, data); - } - - @Deprecated - public static void log(Level level, String format, Object... data) - { - FMLRelaunchLog.log(level, format, data); - } - - @Deprecated - public static void log(String targetLog, Level level, Throwable ex, String format, Object... data) - { - FMLRelaunchLog.log(targetLog, level, ex, format, data); - } - - @Deprecated - public static void log(Level level, Throwable ex, String format, Object... data) - { - FMLRelaunchLog.log(level, ex, format, data); - } - - @Deprecated - public static void severe(String format, Object... data) - { - log(Level.ERROR, format, data); - } - - @Deprecated - public static void warning(String format, Object... data) - { - log(Level.WARN, format, data); - } - - @Deprecated - public static void info(String format, Object... data) - { - log(Level.INFO, format, data); - } - - @Deprecated - public static void fine(String format, Object... data) - { - log(Level.DEBUG, format, data); - } - - @Deprecated - public static void finer(String format, Object... data) - { - log(Level.TRACE, format, data); - } - - @Deprecated - public static Logger getLogger() - { - return log; - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/FMLPaths.java b/src/main/java/net/minecraftforge/fml/common/FMLPaths.java index 0a570d752..fe4c2d44a 100644 --- a/src/main/java/net/minecraftforge/fml/common/FMLPaths.java +++ b/src/main/java/net/minecraftforge/fml/common/FMLPaths.java @@ -21,22 +21,23 @@ package net.minecraftforge.fml.common; import cpw.mods.modlauncher.api.IEnvironment; import net.minecraftforge.fml.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; -import java.util.Objects; import static net.minecraftforge.fml.Logging.CORE; -import static net.minecraftforge.fml.Logging.fmlLog; public enum FMLPaths { GAMEDIR(), MODSDIR("mods"), CONFIGDIR("config"), - FMLCONFIG(false, CONFIGDIR, "fml.cfg"); + FMLCONFIG(false, CONFIGDIR, "fml.toml"); + private static final Logger LOGGER = LogManager.getLogger(); private final Path relativePath; private final boolean isDirectory; private Path absolutePath; @@ -71,7 +72,7 @@ public enum FMLPaths for (FMLPaths path : FMLPaths.values()) { path.absolutePath = rootPath.resolve(path.relativePath).toAbsolutePath(); - fmlLog.debug(CORE,"Path {} is {}", ()-> path, ()-> path.absolutePath); + LOGGER.debug(CORE,"Path {} is {}", ()-> path, ()-> path.absolutePath); if (path.isDirectory) { FileUtils.getOrCreateDirectory(path.absolutePath, path.name()); diff --git a/src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java b/src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java deleted file mode 100644 index 158fcf1b2..000000000 --- a/src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import com.google.common.base.Predicate; -import net.minecraft.command.EntitySelector; -import net.minecraft.command.ICommandSender; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.Vec3d; - -import javax.annotation.Nonnull; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * Allows mods to create custom selectors in commands. - * Registered in {@link net.minecraftforge.fml.common.registry.GameRegistry#registerEntitySelector(IEntitySelectorFactory, String...)} - * For an example implementation, see CustomEntitySelectorTest - */ -public interface IEntitySelectorFactory -{ - /** - * Called every time a command that contains entity selectors is executed - * - * @param arguments A map with all arguments and their values - * @param mainSelector The main selector string (e.g. 'a' for all players or 'e' for all entities) - * @param sender The sender of the command - * @param position A position either specified in the selector arguments or by the players position. See {@link EntitySelector#getPosFromArguments(Map, Vec3d)} - * @return A list of new predicates, can be empty ({@link Collections#emptyList()} but not null. - */ - @Nonnull List> createPredicates(Map arguments, String mainSelector, ICommandSender sender, Vec3d position); -} diff --git a/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java b/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java deleted file mode 100644 index 56a46d8f1..000000000 --- a/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.io.File; -import java.util.List; -import java.util.Set; - -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetworkManager; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.IThreadListener; -import net.minecraftforge.common.util.CompoundDataFixer; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.StartupQuery; - -public interface IFMLSidedHandler -{ - List getAdditionalBrandingInformation(); - - Side getSide(); - - void haltGame(String message, Throwable exception); - - void showGuiScreen(Object clientGuiElement); - - void queryUser(StartupQuery query) throws InterruptedException; - - void beginServerLoading(MinecraftServer server); - - void finishServerLoading(); - - File getSavesDirectory(); - - MinecraftServer getServer(); - - boolean isDisplayCloseRequested(); - - boolean shouldServerShouldBeKilledQuietly(); - - void addModAsResource(ModContainer container); - - String getCurrentLanguage(); - - void serverStopped(); - - NetworkManager getClientToServerNetworkManager(); - - INetHandler getClientPlayHandler(); - - void fireNetRegistrationEvent(IEventBus bus, NetworkManager manager, Set channelSet, String channel, Side side); - - boolean shouldAllowPlayerLogins(); - - void allowLogins(); - - IThreadListener getWorldThread(INetHandler net); - - void processWindowMessages(); - - String stripSpecialChars(String message); - - void reloadRenderers(); - - void fireSidedRegistryEvents(); - - CompoundDataFixer getDataFixer(); - - boolean isDisplayVSyncForced(); - - default void resetClientRecipeBook(){} - - default void reloadSearchTrees(){} - - default void reloadCreativeSettings(){} -} diff --git a/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java b/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java deleted file mode 100644 index 7913b53a0..000000000 --- a/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; - -/** - * @deprecated set your item's {@link Item#getItemBurnTime(ItemStack)} or subscribe to {@link FurnaceFuelBurnTimeEvent} instead. - */ -@Deprecated -public interface IFuelHandler -{ - int getBurnTime(ItemStack fuel); -} diff --git a/src/main/java/net/minecraftforge/fml/common/LoadController.java b/src/main/java/net/minecraftforge/fml/common/LoadController.java deleted file mode 100644 index d7c060bd1..000000000 --- a/src/main/java/net/minecraftforge/fml/common/LoadController.java +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import net.minecraftforge.common.util.TextTable; -import net.minecraftforge.fml.common.ProgressManager.ProgressBar; -import net.minecraftforge.fml.common.event.ModLifecycleEvent; -import net.minecraftforge.fml.common.event.FMLLoadEvent; -import net.minecraftforge.fml.common.event.FMLModDisabledEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.versioning.ArtifactVersion; - -import net.minecraftforge.fml.ModContainer; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.ThreadContext; -import org.apache.logging.log4j.message.FormattedMessage; - -import com.google.common.base.Throwables; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.BiMap; -import com.google.common.collect.ImmutableBiMap; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMap.Builder; -import com.google.common.collect.Iterables; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.eventbus.EventBus; -import com.google.common.eventbus.Subscribe; - -import javax.annotation.Nullable; - -public class LoadController -{ - private Loader loader; - private EventBus masterChannel; - private ImmutableMap eventChannels; - private LoaderState state; - private Multimap modStates = ArrayListMultimap.create(); - private List activeModList = Lists.newArrayList(); - private ModContainer activeContainer; - private BiMap modObjectList; - private ListMultimap packageOwners; - - public LoadController(Loader loader) - { - this.loader = loader; - this.masterChannel = new FMLThrowingEventBus((exception, context) -> { - Throwables.throwIfUnchecked(exception); - // should not happen, but add some extra context for checked exceptions - Method method = context.getSubscriberMethod(); - String parameterNames = Stream.of(method.getParameterTypes()).map(Class::getName).collect(Collectors.joining(", ")); - String message = "Exception thrown during LoadController." + method.getName() + '(' + parameterNames + ')'; - throw new LoaderExceptionModCrash(message, exception); - }); - this.masterChannel.register(this); - - state = LoaderState.NOINIT; - packageOwners = ArrayListMultimap.create(); - - } - - void disableMod(ModContainer mod) - { - HashMap temporary = Maps.newHashMap(eventChannels); - String modId = mod.getModId(); - EventBus bus = temporary.remove(modId); - bus.post(new FMLModDisabledEvent()); - eventChannels = ImmutableMap.copyOf(temporary); - modStates.put(modId, ModState.DISABLED); - modObjectList.remove(mod); - activeModList.remove(mod); - } - - @Subscribe - public void buildModList(FMLLoadEvent event) - { - Builder eventBus = ImmutableMap.builder(); - - for (final ModContainer mod : loader.getModList()) - { - EventBus bus = new FMLThrowingEventBus((exception, context) -> this.errorOccurred(mod, exception)); - - boolean isActive = mod.registerBus(bus, this); - if (isActive) - { - activeModList.add(mod); - modStates.put(mod.getModId(), ModState.UNLOADED); - eventBus.put(mod.getModId(), bus); - FMLCommonHandler.instance().addModToResourcePack(mod); - } - else - { - FMLLog.log.warn("Mod {} has been disabled through configuration", mod.getModId()); - modStates.put(mod.getModId(), ModState.UNLOADED); - modStates.put(mod.getModId(), ModState.DISABLED); - } - } - - eventChannels = eventBus.build(); - } - - public void distributeStateMessage(LoaderState state, Object... eventData) - { - if (state.hasEvent()) - { - masterChannel.post(state.getEvent(eventData)); - } - } - - public void transition(LoaderState desiredState, boolean forceState) - { - if (FMLCommonHandler.instance().isDisplayCloseRequested()) - { - FMLLog.log.info("The game window is being closed by the player, exiting."); - FMLCommonHandler.instance().exitJava(0, false); - } - - LoaderState oldState = state; - state = state.transition(false); - if (state != desiredState) - { - if (!forceState) - { - FormattedMessage message = new FormattedMessage("A fatal error occurred during the state transition from {} to {}. State became {} instead. Loading cannot continue.", oldState, desiredState, state); - throw new LoaderException(message.getFormattedMessage()); - } - else - { - FMLLog.log.info("The state engine was in incorrect state {} and forced into state {}. Errors may have been discarded.", state, desiredState); - forceState(desiredState); - } - } - } - - @Nullable - public ModContainer activeContainer() - { - return activeContainer != null ? activeContainer : findActiveContainerFromStack(); - } - - void forceActiveContainer(@Nullable ModContainer container) - { - activeContainer = container; - } - - @Subscribe - public void propogateStateMessage(ModLifecycleEvent stateEvent) - { - if (stateEvent instanceof FMLPreInitializationEvent) - { - modObjectList = buildModObjectList(); - } - ProgressBar bar = ProgressManager.push(stateEvent.description(), activeModList.size(), true); - for (ModContainer mc : activeModList) - { - bar.step(mc.getName()); - sendEventToModContainer(stateEvent, mc); - } - ProgressManager.pop(bar); - } - - private void sendEventToModContainer(ModLifecycleEvent stateEvent, ModContainer mc) - { - String modId = mc.getModId(); - Collection requirements = mc.getRequirements().stream().map(ArtifactVersion::getLabel).collect(Collectors.toCollection(HashSet::new)); - for (ArtifactVersion av : mc.getDependencies()) - { - if (av.getLabel() != null && requirements.contains(av.getLabel()) && modStates.containsEntry(av.getLabel(), ModState.ERRORED)) - { - LogManager.getLogger(modId).error("Skipping event {} and marking errored mod {} since required dependency {} has errored", stateEvent.getEventType(), modId, av.getLabel()); - modStates.put(modId, ModState.ERRORED); - return; - } - } - activeContainer = mc; - stateEvent.applyModContainer(mc); - ThreadContext.put("mod", modId); - LogManager.getLogger(modId).trace("Sending event {} to mod {}", stateEvent.getEventType(), modId); - eventChannels.get(modId).post(stateEvent); - LogManager.getLogger(modId).trace("Sent event {} to mod {}", stateEvent.getEventType(), modId); - ThreadContext.remove("mod"); - activeContainer = null; - if (stateEvent instanceof FMLStateEvent) - { - if (!errors.containsKey(modId)) - { - modStates.put(modId, ((FMLStateEvent)stateEvent).getModState()); - } - else - { - modStates.put(modId, ModState.ERRORED); - } - } - } - - public ImmutableBiMap buildModObjectList() - { - ImmutableBiMap.Builder builder = ImmutableBiMap.builder(); - for (ModContainer mc : activeModList) - { - if (!mc.isImmutable() && mc.getMod() != null) - { - builder.put(mc, mc.getMod()); - List packages = mc.getOwnedPackages(); - for (String pkg : packages) - { - packageOwners.put(pkg, mc); - } - } - if (mc.getMod() == null && !mc.isImmutable() && state != LoaderState.CONSTRUCTING) - { - FormattedMessage message = new FormattedMessage("There is a severe problem with {} ({}) - it appears not to have constructed correctly", mc.getName(), mc.getModId()); - this.errorOccurred(mc, new RuntimeException(message.getFormattedMessage())); - } - } - return builder.build(); - } - - public void errorOccurred(ModContainer modContainer, Throwable exception) - { - String modId = modContainer.getModId(); - String modName = modContainer.getName(); - modStates.put(modId, ModState.ERRORED); - if (exception instanceof InvocationTargetException) - { - exception = exception.getCause(); - } - if (exception instanceof LoaderException) // avoid wrapping loader exceptions multiple times - { - throw (LoaderException) exception; - } - FormattedMessage message = new FormattedMessage("Caught exception from {} ({})", modName, modId); - throw new LoaderExceptionModCrash(message.getFormattedMessage(), exception); - } - - public void printModStates(StringBuilder ret) - { - ret.append("\n\tStates:"); - for (ModState state : ModState.values()) - ret.append(" '").append(state.getMarker()).append("' = ").append(state.toString()); - - TextTable table = new TextTable(Lists.newArrayList( - TextTable.column("State"), - TextTable.column("ID"), - TextTable.column("Version"), - TextTable.column("Source"), - TextTable.column("Signature")) - ); - for (ModContainer mc : loader.getModList()) - { - table.add( - modStates.get(mc.getModId()).stream().map(ModState::getMarker).reduce("", (a, b) -> a + b), - mc.getModId(), - mc.getVersion(), - mc.getSource().getName(), - mc.getSigningCertificate() != null ? CertificateHelper.getFingerprint(mc.getSigningCertificate()) : "None" - ); - } - - ret.append("\n"); - ret.append("\n\t"); - table.append(ret, "\n\t"); - ret.append("\n"); - } - - public List getActiveModList() - { - return activeModList; - } - - public ModState getModState(ModContainer selectedMod) - { - return Iterables.getLast(modStates.get(selectedMod.getModId()), ModState.AVAILABLE); - } - - public void distributeStateMessage(Class customEvent) - { - Object eventInstance; - try - { - eventInstance = customEvent.newInstance(); - } - catch (InstantiationException | IllegalAccessException e) - { - throw new LoaderException("Failed to create new event instance for " + customEvent.getName(), e); - } - masterChannel.post(eventInstance); - } - - public BiMap getModObjectList() - { - if (modObjectList == null) - { - FMLLog.log.fatal("Detected an attempt by a mod {} to perform game activity during mod construction. This is a serious programming error.", activeContainer); - return buildModObjectList(); - } - return ImmutableBiMap.copyOf(modObjectList); - } - - public boolean isInState(LoaderState state) - { - return this.state == state; - } - - boolean hasReachedState(LoaderState state) - { - return this.state.ordinal() >= state.ordinal() && this.state != LoaderState.ERRORED; - } - - void forceState(LoaderState newState) - { - this.state = newState; - } - - @Nullable - private ModContainer findActiveContainerFromStack() - { - for (Class c : getCallingStack()) - { - int idx = c.getName().lastIndexOf('.'); - if (idx == -1) - { - continue; - } - String pkg = c.getName().substring(0, idx); - if (packageOwners.containsKey(pkg)) - { - return packageOwners.get(pkg).get(0); - } - } - - return null; - } - - private FMLSecurityManager accessibleManager = new FMLSecurityManager(); - - class FMLSecurityManager extends SecurityManager - { - Class[] getStackClasses() - { - return getClassContext(); - } - } - - Class[] getCallingStack() - { - return accessibleManager.getStackClasses(); - } - - LoaderState getState() - { - return state; - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/Loader.java b/src/main/java/net/minecraftforge/fml/common/Loader.java deleted file mode 100644 index 079f865e8..000000000 --- a/src/main/java/net/minecraftforge/fml/common/Loader.java +++ /dev/null @@ -1,1010 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.net.MalformedURLException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.common.ForgeVersion; -import net.minecraftforge.common.capabilities.CapabilityManager; -import net.minecraftforge.common.config.ConfigManager; -import net.minecraftforge.common.crafting.CraftingHelper; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.ModContainer.Disableable; -import net.minecraftforge.fml.common.ProgressManager.ProgressBar; -import net.minecraftforge.fml.common.event.FMLLoadEvent; -import net.minecraftforge.fml.common.event.FMLModIdMappingEvent; -import net.minecraftforge.fml.common.registry.*; -import net.minecraftforge.fml.common.toposort.ModSorter; -import net.minecraftforge.fml.common.toposort.ModSortingException; -import net.minecraftforge.fml.common.toposort.TopologicalSort; -import net.minecraftforge.fml.common.toposort.ModSortingException.SortingExceptionData; -import net.minecraftforge.fml.common.versioning.ArtifactVersion; -import net.minecraftforge.fml.common.versioning.DependencyParser; -import net.minecraftforge.fml.common.versioning.VersionParser; -import net.minecraftforge.fml.relauncher.ModListHelper; -import net.minecraftforge.registries.GameData; -import net.minecraftforge.registries.ObjectHolderRegistry; - -import org.apache.commons.io.IOUtils; -import org.apache.logging.log4j.Level; - -import com.google.common.base.CharMatcher; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultiset; -import com.google.common.collect.Iterables; -import com.google.common.collect.LinkedHashMultimap; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimaps; -import com.google.common.collect.Multiset.Entry; -import com.google.common.collect.Multisets; -import com.google.common.collect.Ordering; -import com.google.common.collect.SetMultimap; -import com.google.common.collect.Sets; -import com.google.common.collect.TreeMultimap; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - -import javax.annotation.Nullable; - -/** - * The loader class performs the actual loading of the mod code from disk. - * - *

- * There are several {@link LoaderState}s to mod loading, triggered in two - * different stages from the FML handler code's hooks into the minecraft code. - *

- * - *
    - *
  1. LOADING. Scanning the filesystem for mod containers to load (zips, jars, - * directories), adding them to the {@link #modClassLoader} Scanning, the loaded - * containers for mod classes to load and registering them appropriately.
  2. - *
  3. PREINIT. The mod classes are configured, they are sorted into a load - * order, and instances of the mods are constructed.
  4. - *
  5. INIT. The mod instances are initialized. For BaseMod mods, this involves - * calling the load method.
  6. - *
  7. POSTINIT. The mod instances are post initialized. For BaseMod mods this - * involves calling the modsLoaded method.
  8. - *
  9. UP. The Loader is complete
  10. - *
  11. ERRORED. The loader encountered an error during the LOADING phase and - * dropped to this state instead. It will not complete loading from this state, - * but it attempts to continue loading before abandoning and giving a fatal - * error.
  12. - *
- * - * Phase 1 code triggers the LOADING and PREINIT states. Phase 2 code triggers - * the INIT and POSTINIT states. - * - * @author cpw - * - */ -@SuppressWarnings("unused") -public class Loader -{ - public static final String MC_VERSION = ForgeVersion.mcVersion; - /** - * The singleton instance - */ - private static Loader instance; - /** - * Build information for tracking purposes. - */ - private static String major; - private static String minor; - private static String rev; - private static String build; - private static String mccversion; - private static String mcpversion; - - /** - * The class loader we load the mods into. - */ - private ModClassLoader modClassLoader; - /** - * The sorted list of mods. - */ - private List mods; - /** - * A named list of mods - */ - private Map namedMods; - /** - * A reverse dependency graph for mods - */ - private ListMultimap reverseDependencies; - /** - * The canonical configuration directory - */ - private File canonicalConfigDir; - private File canonicalModsDir; - private LoadController modController; - private MinecraftDummyContainer minecraft; - private MCPDummyContainer mcp; - - private static File minecraftDir; - private static List injectedContainers; - private ImmutableMap fmlBrandingProperties; - private File forcedModFile; - private ModDiscoverer discoverer; - private ProgressBar progressBar; - - public static Loader instance() - { - if (instance == null) - { - instance = new Loader(); - } - - return instance; - } - - @SuppressWarnings("unchecked") - public static void injectData(Object... data) - { - major = (String) data[0]; - minor = (String) data[1]; - rev = (String) data[2]; - build = (String) data[3]; - mccversion = (String) data[4]; - mcpversion = (String) data[5]; - minecraftDir = (File) data[6]; - injectedContainers = (List)data[7]; - } - - private Loader() - { - modClassLoader = new ModClassLoader(getClass().getClassLoader()); - if (mccversion !=null && !mccversion.equals(MC_VERSION)) - { - FMLLog.log.fatal("This version of FML is built for Minecraft {}, we have detected Minecraft {} in your minecraft jar file", mccversion, MC_VERSION); - throw new LoaderException(String.format("This version of FML is built for Minecraft %s, we have detected Minecraft %s in your minecraft jar file", mccversion, MC_VERSION)); - } - - minecraft = new MinecraftDummyContainer(MC_VERSION); - InputStream mcpModInputStream = getClass().getResourceAsStream("/mcpmod.info"); - try - { - mcp = new MCPDummyContainer(MetadataCollection.from(mcpModInputStream, "MCP").getMetadataForId("mcp", null)); - } - finally - { - IOUtils.closeQuietly(mcpModInputStream); - } - } - - /** - * Sort the mods into a sorted list, using dependency information from the - * containers. The sorting is performed using a {@link TopologicalSort} - * based on the pre- and post- dependency information provided by the mods. - */ - private void sortModList() - { - FMLLog.log.trace("Verifying mod requirements are satisfied"); - List wrongMinecraftExceptions = new ArrayList<>(); - List missingModsExceptions = new ArrayList<>(); - try - { - BiMap modVersions = HashBiMap.create(); - for (ModContainer mod : Iterables.concat(getActiveModList(), ModAPIManager.INSTANCE.getAPIList())) - { - modVersions.put(mod.getModId(), mod.getProcessedVersion()); - } - - ArrayListMultimap reqList = ArrayListMultimap.create(); - for (ModContainer mod : getActiveModList()) - { - if (!mod.acceptableMinecraftVersionRange().containsVersion(minecraft.getProcessedVersion())) - { - FMLLog.log.fatal("The mod {} does not wish to run in Minecraft version {}. You will have to remove it to play.", mod.getModId(), getMCVersionString()); - WrongMinecraftVersionException ret = new WrongMinecraftVersionException(mod, getMCVersionString()); - FMLLog.log.fatal(ret.getMessage()); - wrongMinecraftExceptions.add(ret); - continue; - } - - reqList.putAll(mod.getModId(), Iterables.transform(mod.getRequirements(), ArtifactVersion::getLabel)); - - Set allDeps = Sets.newHashSet(); - - allDeps.addAll(mod.getDependants()); - allDeps.addAll(mod.getDependencies()); - allDeps.addAll(mod.getRequirements()); - - MissingModsException missingModsException = new MissingModsException(mod.getModId(), mod.getName()); - for (ArtifactVersion acceptedVersion : allDeps) - { - boolean required = mod.getRequirements().contains(acceptedVersion); - if (required || modVersions.containsKey(acceptedVersion.getLabel())) - { - ArtifactVersion currentVersion = modVersions.get(acceptedVersion.getLabel()); - if (currentVersion == null || !acceptedVersion.containsVersion(currentVersion)) - { - missingModsException.addMissingMod(acceptedVersion, currentVersion, required); - } - } - } - if (!missingModsException.getMissingModInfos().isEmpty()) - { - FMLLog.log.fatal(missingModsException.toString()); - missingModsExceptions.add(missingModsException); - } - } - - if (wrongMinecraftExceptions.isEmpty() && missingModsExceptions.isEmpty()) - { - FMLLog.log.trace("All mod requirements are satisfied"); - } - else if (missingModsExceptions.size()==1 && wrongMinecraftExceptions.isEmpty()) - { - throw missingModsExceptions.get(0); - } - else if (wrongMinecraftExceptions.size()==1 && missingModsExceptions.isEmpty()) - { - throw wrongMinecraftExceptions.get(0); - } - else - { - throw new MultipleModsErrored(wrongMinecraftExceptions, missingModsExceptions); - } - - reverseDependencies = Multimaps.invertFrom(reqList, ArrayListMultimap.create()); - ModSorter sorter = new ModSorter(getActiveModList(), namedMods); - - try - { - FMLLog.log.trace("Sorting mods into an ordered list"); - List sortedMods = sorter.sort(); - // Reset active list to the sorted list - modController.getActiveModList().clear(); - modController.getActiveModList().addAll(sortedMods); - // And inject the sorted list into the overall list - mods.removeAll(sortedMods); - sortedMods.addAll(mods); - mods = sortedMods; - FMLLog.log.trace("Mod sorting completed successfully"); - } - catch (ModSortingException sortException) - { - FMLLog.log.fatal("A dependency cycle was detected in the input mod set so an ordering cannot be determined"); - SortingExceptionData exceptionData = sortException.getExceptionData(); - FMLLog.log.fatal("The first mod in the cycle is {}", exceptionData.getFirstBadNode()); - FMLLog.log.fatal("The mod cycle involves"); - for (ModContainer mc : exceptionData.getVisitedNodes()) - { - FMLLog.log.fatal("{} : before: {}, after: {}", mc.toString(), mc.getDependants(), mc.getDependencies()); - } - FMLLog.log.error("The full error", sortException); - throw sortException; - } - } - finally - { - FMLLog.log.debug("Mod sorting data"); - int unprintedMods = mods.size(); - for (ModContainer mod : getActiveModList()) - { - if (!mod.isImmutable()) - { - FMLLog.log.debug("\t{}({}:{}): {} ({})", mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName(), mod.getSortingRules()); - unprintedMods--; - } - } - if (unprintedMods == mods.size()) - { - FMLLog.log.debug("No user mods found to sort"); - } - } - - } - - /** - * The primary loading code - * - * - * The found resources are first loaded into the {@link #modClassLoader} - * (always) then scanned for class resources matching the specification - * above. - * - * If they provide the {@link Mod} annotation, they will be loaded as - * "FML mods" - * - * Finally, if they are successfully loaded as classes, they are then added - * to the available mod list. - */ - private ModDiscoverer identifyMods(List additionalContainers) - { - injectedContainers.addAll(additionalContainers); - FMLLog.log.debug("Building injected Mod Containers {}", injectedContainers); - mods.add(minecraft); - // Add in the MCP mod container - mods.add(new InjectedModContainer(mcp,new File("minecraft.jar"))); - for (String cont : injectedContainers) - { - ModContainer mc; - try - { - mc = (ModContainer) Class.forName(cont,true,modClassLoader).newInstance(); - } - catch (Exception e) - { - FMLLog.log.error("A problem occurred instantiating the injected mod container {}", cont, e); - throw new LoaderException(e); - } - mods.add(new InjectedModContainer(mc,mc.getSource())); - } - ModDiscoverer discoverer = new ModDiscoverer(); - - //if (!FMLForgePlugin.RUNTIME_DEOBF) //Only descover mods in the classpath if we're in the dev env. - { //TODO: Move this to GradleStart? And add a specific mod canidate for Forge itself. - FMLLog.log.debug("Attempting to load mods contained in the minecraft jar file and associated classes"); - discoverer.findClasspathMods(modClassLoader); - FMLLog.log.debug("Minecraft jar mods loaded successfully"); - } - - List maven_canidates = LibraryManager.flattenLists(minecraftDir); - List file_canidates = LibraryManager.gatherLegacyCanidates(minecraftDir); - - for (Artifact artifact : maven_canidates) - { - artifact = Repository.resolveAll(artifact); - if (artifact != null) - { - File target = artifact.getFile(); - if (!file_canidates.contains(target)) - file_canidates.add(target); - } - } - //Do we want to sort the full list after resolving artifacts? - //TODO: Add dependency gathering? - - for (File mod : file_canidates) - { - // skip loaded coremods - if (CoreModManager.getIgnoredMods().contains(mod.getName())) - { - FMLLog.log.trace("Skipping already parsed coremod or tweaker {}", mod.getName()); - } - else - { - FMLLog.log.debug("Found a candidate zip or jar file {}", mod.getName()); - discoverer.addCandidate(new ModCandidate(mod, mod, ContainerType.JAR)); - } - } - - mods.addAll(discoverer.identifyMods()); - identifyDuplicates(mods); - namedMods = Maps.uniqueIndex(mods, ModContainer::getModId); - FMLLog.log.info("Forge Mod Loader has identified {} mod{} to load", mods.size(), mods.size() != 1 ? "s" : ""); - return discoverer; - } - - private class ModIdComparator implements Comparator - { - @Override - public int compare(ModContainer o1, ModContainer o2) - { - return o1.getModId().compareTo(o2.getModId()); - } - } - - private void identifyDuplicates(List mods) - { - TreeMultimap dupsearch = TreeMultimap.create(new ModIdComparator(), Ordering.arbitrary()); - for (ModContainer mc : mods) - { - if (mc.getSource() != null) - { - dupsearch.put(mc, mc.getSource()); - } - } - - ImmutableMultiset duplist = Multisets.copyHighestCountFirst(dupsearch.keys()); - SetMultimap dupes = LinkedHashMultimap.create(); - for (Entry e : duplist.entrySet()) - { - if (e.getCount() > 1) - { - FMLLog.log.fatal("Found a duplicate mod {} at {}", e.getElement().getModId(), dupsearch.get(e.getElement())); - dupes.putAll(e.getElement(),dupsearch.get(e.getElement())); - } - } - if (!dupes.isEmpty()) - { - throw new DuplicateModsFoundException(dupes); - } - } - - /** - * - */ - private void initializeLoader() - { - File modsDir = new File(minecraftDir, "mods"); - File configDir = new File(minecraftDir, "config"); - String canonicalModsPath; - String canonicalConfigPath; - - try - { - canonicalModsPath = modsDir.getCanonicalPath(); - canonicalConfigPath = configDir.getCanonicalPath(); - canonicalConfigDir = configDir.getCanonicalFile(); - canonicalModsDir = modsDir.getCanonicalFile(); - } - catch (IOException ioe) - { - FMLLog.log.error("Failed to resolve loader directories: mods : {} ; config {}", canonicalModsDir.getAbsolutePath(), - configDir.getAbsolutePath(), ioe); - throw new LoaderException(ioe); - } - - if (!canonicalModsDir.exists()) - { - FMLLog.log.info("No mod directory found, creating one: {}", canonicalModsPath); - boolean dirMade = canonicalModsDir.mkdir(); - if (!dirMade) - { - FMLLog.log.fatal("Unable to create the mod directory {}", canonicalModsPath); - throw new LoaderException(String.format("Unable to create the mod directory %s", canonicalModsPath)); - } - FMLLog.log.info("Mod directory created successfully"); - } - - if (!canonicalConfigDir.exists()) - { - FMLLog.log.debug("No config directory found, creating one: {}", canonicalConfigPath); - boolean dirMade = canonicalConfigDir.mkdir(); - if (!dirMade) - { - FMLLog.log.fatal("Unable to create the config directory {}", canonicalConfigPath); - throw new LoaderException(); - } - FMLLog.log.info("Config directory created successfully"); - } - - if (!canonicalModsDir.isDirectory()) - { - FMLLog.log.fatal("Attempting to load mods from {}, which is not a directory", canonicalModsPath); - throw new LoaderException(); - } - - if (!configDir.isDirectory()) - { - FMLLog.log.fatal("Attempting to load configuration from {}, which is not a directory", canonicalConfigPath); - throw new LoaderException(); - } - - readInjectedDependencies(); - } - - public List getModList() - { - return instance().mods != null ? ImmutableList.copyOf(instance().mods) : ImmutableList.of(); - } - - /** - * Used to setup a testharness with a single dummy mod instance for use with various testing hooks - * @param containers A list of dummy containers that will be returned as "active" for all queries - */ - public void setupTestHarness(ModContainer... containers) - { - modController = new LoadController(this); - mods = Lists.newArrayList(containers); - namedMods = Maps.uniqueIndex(mods, ModContainer::getModId); - modController.transition(LoaderState.LOADING, false); - modController.transition(LoaderState.CONSTRUCTING, false); - ObjectHolderRegistry.INSTANCE.findObjectHolders(new ASMDataTable()); - modController.forceActiveContainer(containers[0]); - } - - /** - * Called from the hook to start mod loading. We trigger the - * {@link #identifyMods(List)} and Constructing, Preinitalization, and Initalization phases here. Finally, - * the mod list is frozen completely and is consider immutable from then on. - * @param injectedModContainers containers to inject - */ - public void loadMods(List injectedModContainers) - { - progressBar = ProgressManager.push("Loading", 7); - progressBar.step("Constructing Mods"); - initializeLoader(); - mods = Lists.newArrayList(); - namedMods = Maps.newHashMap(); - modController = new LoadController(this); - modController.transition(LoaderState.LOADING, false); - discoverer = identifyMods(injectedModContainers); - ModAPIManager.INSTANCE.manageAPI(modClassLoader, discoverer); - disableRequestedMods(); - modController.distributeStateMessage(FMLLoadEvent.class); - sortModList(); - ModAPIManager.INSTANCE.cleanupAPIContainers(modController.getActiveModList()); - ModAPIManager.INSTANCE.cleanupAPIContainers(mods); - mods = ImmutableList.copyOf(mods); - for (File nonMod : discoverer.getNonModLibs()) - { - if (nonMod.isFile()) - { - FMLLog.log.info("FML has found a non-mod file {} in your mods directory. It will now be injected into your classpath. This could severe stability issues, it should be removed if possible.", nonMod.getName()); - try - { - modClassLoader.addFile(nonMod); - } - catch (MalformedURLException e) - { - FMLLog.log.error("Encountered a weird problem with non-mod file injection : {}", nonMod.getName(), e); - } - } - } - - ConfigManager.loadData(discoverer.getASMTable()); - - modController.transition(LoaderState.CONSTRUCTING, false); - modController.distributeStateMessage(LoaderState.CONSTRUCTING, modClassLoader, discoverer.getASMTable(), reverseDependencies); - - FMLLog.log.debug("Mod signature data"); - FMLLog.log.debug(" \tValid Signatures:"); - for (ModContainer mod : getActiveModList()) - { - if (mod.getSigningCertificate() != null) - FMLLog.log.debug("\t\t({}) {}\t({}\t{})\t{}", CertificateHelper.getFingerprint(mod.getSigningCertificate()), mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName()); - } - FMLLog.log.debug(" \tMissing Signatures:"); - for (ModContainer mod : getActiveModList()) - { - if (mod.getSigningCertificate() == null) - FMLLog.log.debug("\t\t{}\t({}\t{})\t{}", mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName()); - } - if (getActiveModList().isEmpty()) - { - FMLLog.log.debug("No user mod signature data found"); - } - progressBar.step("Initializing mods Phase 1"); - modController.transition(LoaderState.PREINITIALIZATION, false); - } - - public void preinitializeMods() - { - if (!modController.isInState(LoaderState.PREINITIALIZATION)) - { - FMLLog.log.warn("There were errors previously. Not beginning mod initialization phase"); - return; - } - GameData.fireCreateRegistryEvents(); - ObjectHolderRegistry.INSTANCE.findObjectHolders(discoverer.getASMTable()); - ItemStackHolderInjector.INSTANCE.findHolders(discoverer.getASMTable()); - CapabilityManager.INSTANCE.injectCapabilities(discoverer.getASMTable()); - modController.distributeStateMessage(LoaderState.PREINITIALIZATION, discoverer.getASMTable(), canonicalConfigDir); - GameData.fireRegistryEvents(rl -> !rl.equals(GameData.RECIPES)); - FMLCommonHandler.instance().fireSidedRegistryEvents(); - ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - ItemStackHolderInjector.INSTANCE.inject(); - modController.transition(LoaderState.INITIALIZATION, false); - progressBar.step("Initializing Minecraft Engine"); - } - - private void disableRequestedMods() - { - String forcedModList = System.getProperty("fml.modStates", ""); - FMLLog.log.trace("Received a system property request \'{}\'",forcedModList); - Map sysPropertyStateList = Splitter.on(CharMatcher.anyOf(";:")) - .omitEmptyStrings().trimResults().withKeyValueSeparator("=") - .split(forcedModList); - FMLLog.log.trace("System property request managing the state of {} mods", sysPropertyStateList.size()); - Map modStates = Maps.newHashMap(); - - forcedModFile = new File(canonicalConfigDir, "fmlModState.properties"); - Properties forcedModListProperties = new Properties(); - if (forcedModFile.exists() && forcedModFile.isFile()) - { - FMLLog.log.trace("Found a mod state file {}", forcedModFile.getName()); - try - { - forcedModListProperties.load(new InputStreamReader(new FileInputStream(forcedModFile), StandardCharsets.UTF_8)); - FMLLog.log.trace("Loaded states for {} mods from file", forcedModListProperties.size()); - } - catch (Exception e) - { - FMLLog.log.info("An error occurred reading the fmlModState.properties file", e); - } - } - modStates.putAll(Maps.fromProperties(forcedModListProperties)); - modStates.putAll(sysPropertyStateList); - FMLLog.log.debug("After merging, found state information for {} mods", modStates.size()); - - Map isEnabled = Maps.transformValues(modStates, Boolean::parseBoolean); - - for (Map.Entry entry : isEnabled.entrySet()) - { - if (namedMods.containsKey(entry.getKey())) - { - FMLLog.log.info("Setting mod {} to enabled state {}", entry.getKey(), entry.getValue()); - namedMods.get(entry.getKey()).setEnabledState(entry.getValue()); - } - } - } - - /** - * Query if we know of a mod named modname - * - * @param modname - * @return If the mod is loaded - */ - public static boolean isModLoaded(String modname) - { - return instance().namedMods.containsKey(modname) && instance().modController.getModState(instance.namedMods.get(modname))!=ModState.DISABLED; - } - - public File getConfigDir() - { - return canonicalConfigDir; - } - - public String getCrashInformation() - { - // Handle being called before we've begun setup - if (modController == null) - { - return ""; - } - StringBuilder ret = new StringBuilder(); - List branding = FMLCommonHandler.instance().getBrandings(false); - - Joiner.on(' ').skipNulls().appendTo(ret, branding); - if (modController != null) - { - modController.printModStates(ret); - } - return ret.toString(); - } - - public String getFMLVersionString() - { - return "8.0.99.99"; - } - - public ModClassLoader getModClassLoader() - { - return modClassLoader; - } - - /** - * @deprecated use {@link DependencyParser#parseDependencies(String)} - */ - @Deprecated // TODO: remove in 1.13 - public void computeDependencies(String dependencyString, Set requirements, List dependencies, List dependants) - { - DependencyParser dependencyParser = new DependencyParser("unknown", FMLCommonHandler.instance().getSide()); - DependencyParser.DependencyInfo info = dependencyParser.parseDependencies(dependencyString); - requirements.addAll(info.requirements); - dependencies.addAll(info.dependencies); - dependants.addAll(info.dependants); - } - - public Map getIndexedModList() - { - return namedMods != null ? ImmutableMap.copyOf(namedMods) : ImmutableMap.of(); - } - - public void initializeMods() - { - progressBar.step("Initializing mods Phase 2"); - CraftingHelper.loadRecipes(false); - // Mod controller should be in the initialization state here - modController.distributeStateMessage(LoaderState.INITIALIZATION); - progressBar.step("Initializing mods Phase 3"); - modController.transition(LoaderState.POSTINITIALIZATION, false); - modController.distributeStateMessage(FMLInterModComms.IMCEvent.class); - ItemStackHolderInjector.INSTANCE.inject(); - modController.distributeStateMessage(LoaderState.POSTINITIALIZATION); - progressBar.step("Finishing up"); - modController.transition(LoaderState.AVAILABLE, false); - modController.distributeStateMessage(LoaderState.AVAILABLE); - GameData.freezeData(); - FMLLog.log.info("Forge Mod Loader has successfully loaded {} mod{}", mods.size(), mods.size() == 1 ? "" : "s"); - progressBar.step("Completing Minecraft initialization"); - } - - public ICrashCallable getCallableCrashInformation() - { - } - - public List getActiveModList() - { - return modController != null ? modController.getActiveModList() : ImmutableList.of(); - } - - public ModState getModState(ModContainer selectedMod) - { - return modController.getModState(selectedMod); - } - - public String getMCVersionString() - { - return "Minecraft " + mccversion; - } - - public boolean serverStarting(Object server) - { - try - { - modController.distributeStateMessage(LoaderState.SERVER_STARTING, server); - modController.transition(LoaderState.SERVER_STARTING, false); - } - catch (Throwable t) - { - FMLLog.log.error("A fatal exception occurred during the server starting event", t); - return false; - } - return true; - } - - public void serverStarted() - { - modController.distributeStateMessage(LoaderState.SERVER_STARTED); - modController.transition(LoaderState.SERVER_STARTED, false); - } - - public void serverStopping() - { - modController.distributeStateMessage(LoaderState.SERVER_STOPPING); - modController.transition(LoaderState.SERVER_STOPPING, false); - } - - public BiMap getModObjectList() - { - return modController.getModObjectList(); - } - - public BiMap getReversedModObjectList() - { - return getModObjectList().inverse(); - } - - @Nullable - public ModContainer activeModContainer() - { - return modController != null ? modController.activeContainer() : null; - } - - public boolean isInState(LoaderState state) - { - return modController.isInState(state); - } - - public MinecraftDummyContainer getMinecraftModContainer() - { - return minecraft; - } - - public boolean hasReachedState(LoaderState state) - { - return modController != null ? modController.hasReachedState(state) : false; - } - - public String getMCPVersionString() - { - return String.format("MCP %s", mcpversion); - } - - public void serverStopped() - { - modController.distributeStateMessage(LoaderState.SERVER_STOPPED); - modController.transition(LoaderState.SERVER_STOPPED, true); - modController.transition(LoaderState.AVAILABLE, true); - } - - public boolean serverAboutToStart(Object server) - { - try - { - modController.distributeStateMessage(LoaderState.SERVER_ABOUT_TO_START, server); - modController.transition(LoaderState.SERVER_ABOUT_TO_START, false); - } - catch (Throwable t) - { - FMLLog.log.error("A fatal exception occurred during the server about to start event", t); - return false; - } - return true; - } - - public Map getFMLBrandingProperties() - { - if (fmlBrandingProperties == null) - { - Properties loaded = new Properties(); - try - { - loaded.load(getClass().getClassLoader().getResourceAsStream("fmlbranding.properties")); - } - catch (Exception e) - { - // File not found - ignore - } - fmlBrandingProperties = Maps.fromProperties(loaded); - } - return fmlBrandingProperties; - } - - - public Map getCustomModProperties(String modId) - { - return getIndexedModList().get(modId).getCustomModProperties(); - } - - boolean checkRemoteModList(Map modList, Side side) - { - Set remoteModIds = modList.keySet(); - Set localModIds = namedMods.keySet(); - - Set difference = Sets.newLinkedHashSet(Sets.difference(localModIds, remoteModIds)); - for (Iterator iterator = difference.iterator(); iterator.hasNext();) - { - String missingRemotely = iterator.next(); - ModState modState = modController.getModState(namedMods.get(missingRemotely)); - if (modState == ModState.DISABLED) - { - iterator.remove(); - } - } - - if (difference.size() > 0) - FMLLog.log.info("Attempting connection with missing mods {} at {}", difference, side); - return true; - } - - public void fireRemapEvent(Map> remaps, boolean isFreezing) - { - if (modController!=null) - { - modController.propogateStateMessage(new FMLModIdMappingEvent(remaps, isFreezing)); - } - } - - public void runtimeDisableMod(String modId) - { - ModContainer mc = namedMods.get(modId); - Disableable disableable = mc.canBeDisabled(); - if (disableable == Disableable.NEVER) - { - FMLLog.log.info("Cannot disable mod {} - it is never allowed to be disabled", modId); - return; - } - if (disableable == Disableable.DEPENDENCIES) - { - FMLLog.log.info("Cannot disable mod {} - there are dependent mods that require its presence", modId); - return; - } - if (disableable == Disableable.YES) - { - FMLLog.log.info("Runtime disabling mod {}", modId); - modController.disableMod(mc); - List localmods = Lists.newArrayList(mods); - localmods.remove(mc); - mods = ImmutableList.copyOf(localmods); - } - - try - { - Properties props = new Properties(); - props.load(new InputStreamReader(new FileInputStream(forcedModFile), StandardCharsets.UTF_8)); - props.put(modId, "false"); - props.store(new OutputStreamWriter(new FileOutputStream(forcedModFile), StandardCharsets.UTF_8), null); - } - catch (Exception e) - { - FMLLog.log.info("An error occurred writing the fml mod states file, your disabled change won't persist", e); - } - } - - public void loadingComplete() - { - ProgressManager.pop(progressBar); - progressBar = null; - } - - private ListMultimap injectedBefore = ArrayListMultimap.create(); - private ListMultimap injectedAfter = ArrayListMultimap.create(); - - private void readInjectedDependencies() - { - File injectedDepFile = new File(getConfigDir(),"injectedDependencies.json"); - if (!injectedDepFile.exists()) - { - FMLLog.log.debug("File {} not found. No dependencies injected", injectedDepFile.getAbsolutePath()); - return; - } - JsonParser parser = new JsonParser(); - JsonElement injectedDeps; - try - { - injectedDeps = parser.parse(new InputStreamReader(new FileInputStream(injectedDepFile), StandardCharsets.UTF_8)); - for (JsonElement el : injectedDeps.getAsJsonArray()) - { - JsonObject jo = el.getAsJsonObject(); - String modId = jo.get("modId").getAsString(); - JsonArray deps = jo.get("deps").getAsJsonArray(); - for (JsonElement dep : deps) - { - JsonObject depObj = dep.getAsJsonObject(); - String type = depObj.get("type").getAsString(); - if (type.equals("before")) { - injectedBefore.put(modId, VersionParser.parseVersionReference(depObj.get("target").getAsString())); - } else if (type.equals("after")) { - injectedAfter.put(modId, VersionParser.parseVersionReference(depObj.get("target").getAsString())); - } else { - FMLLog.log.error("Invalid dependency type {}", type); - throw new RuntimeException("Unable to parse type"); - } - } - } - } catch (Exception e) - { - FMLLog.log.error("Unable to parse {} - skipping", injectedDepFile); - FMLLog.log.throwing(Level.ERROR, e); - return; - } - FMLLog.log.debug("Loaded {} injected dependencies on modIds: {}", injectedBefore.size(), injectedBefore.keySet()); - } - - List getInjectedBefore(String modId) - { - return injectedBefore.get(modId); - } - List getInjectedAfter(String modId) - { - return injectedAfter.get(modId); - } - - public final LoaderState getLoaderState() - { - return modController != null ? modController.getState() : LoaderState.NOINIT; - } - - public void setActiveModContainer(@Nullable ModContainer container) - { - this.modController.forceActiveContainer(container); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/MetadataCollection.java b/src/main/java/net/minecraftforge/fml/common/MetadataCollection.java deleted file mode 100644 index e398f893a..000000000 --- a/src/main/java/net/minecraftforge/fml/common/MetadataCollection.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.Map; - -import net.minecraftforge.fml.common.versioning.ArtifactVersion; -import net.minecraftforge.fml.common.versioning.VersionParser; - -import com.google.common.collect.Maps; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.google.gson.JsonParser; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; - -import javax.annotation.Nullable; - -public class MetadataCollection -{ - private String modListVersion; - private ModMetadata[] modList; - private Map metadatas = Maps.newHashMap(); - - public static MetadataCollection from(@Nullable InputStream inputStream, String sourceName) - { - if (inputStream == null) - { - return new MetadataCollection(); - } - - InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); - try - { - MetadataCollection collection; - Gson gson = new GsonBuilder().registerTypeAdapter(ArtifactVersion.class, new ArtifactVersionAdapter()).create(); - JsonParser parser = new JsonParser(); - JsonElement rootElement = parser.parse(reader); - if (rootElement.isJsonArray()) - { - collection = new MetadataCollection(); - JsonArray jsonList = rootElement.getAsJsonArray(); - collection.modList = new ModMetadata[jsonList.size()]; - int i = 0; - for (JsonElement mod : jsonList) - { - collection.modList[i++]=gson.fromJson(mod, ModMetadata.class); - } - } - else - { - collection = gson.fromJson(rootElement, MetadataCollection.class); - } - collection.parseModMetadataList(); - return collection; - } - catch (JsonParseException e) - { - FMLLog.log.error("The mcmod.info file in {} cannot be parsed as valid JSON. It will be ignored", sourceName, e); - return new MetadataCollection(); - } - } - - private void parseModMetadataList() - { - for (ModMetadata modMetadata : modList) - { - metadatas.put(modMetadata.modId, modMetadata); - } - } - - public ModMetadata getMetadataForId(String modId, Map extraData) - { - if (!metadatas.containsKey(modId)) - { - ModMetadata dummy = new ModMetadata(); - dummy.modId = modId; - dummy.name = (String) extraData.get("name"); - dummy.version = (String) extraData.get("version"); - dummy.autogenerated = true; - metadatas.put(modId, dummy); - } - return metadatas.get(modId); - } - - public static class ArtifactVersionAdapter extends TypeAdapter - { - - @Override - public void write(JsonWriter out, ArtifactVersion value) throws IOException - { - // no op - we never write these out - } - - @Override - public ArtifactVersion read(JsonReader in) throws IOException - { - return VersionParser.parseVersionReference(in.nextString()); - } - - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/MissingModsException.java b/src/main/java/net/minecraftforge/fml/common/MissingModsException.java deleted file mode 100644 index 7e64f4adb..000000000 --- a/src/main/java/net/minecraftforge/fml/common/MissingModsException.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import com.google.common.base.Preconditions; - -import net.minecraft.client.gui.GuiScreen; -import net.minecraftforge.fml.client.GuiModsMissing; -import net.minecraftforge.fml.client.IDisplayableError; -import net.minecraftforge.fml.common.versioning.ArtifactVersion; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public class MissingModsException extends EnhancedRuntimeException implements IDisplayableError -{ - private static final long serialVersionUID = 1L; - private final String id; - private final String name; - /** @deprecated use {@link #getMissingModInfos()} */ - @Deprecated // TODO remove in 1.13 - public final Set missingMods; - private final List missingModsInfos; - private final String modName; - - public MissingModsException(String id, String name) - { - this(new HashSet<>(), id, name); - } - - /** - * @deprecated use {@link #MissingModsException(String, String)} - */ - @Deprecated // TODO remove in 1.13 - public MissingModsException(Set missingMods, String id, String name) - { - this.id = id; - this.name = name; - this.missingMods = missingMods; - this.missingModsInfos = new ArrayList<>(); - for (ArtifactVersion artifactVersion : missingMods) - { - missingModsInfos.add(new MissingModInfo(artifactVersion, null, true)); - } - this.modName = name; - } - - @Override - public String getMessage() - { - Set missingMods = missingModsInfos.stream().map(MissingModInfo::getAcceptedVersion).collect(Collectors.toSet()); - return String.format("Mod %s (%s) requires %s", id, name, missingMods); - } - - public void addMissingMod(ArtifactVersion acceptedVersion, @Nullable ArtifactVersion currentVersion, boolean required) - { - MissingModInfo missingModInfo = new MissingModInfo(acceptedVersion, currentVersion, required); - this.missingModsInfos.add(missingModInfo); - this.missingMods.add(acceptedVersion); - } - - public String getModName() - { - return modName; - } - - public List getMissingModInfos() - { - return Collections.unmodifiableList(this.missingModsInfos); - } - - @Override - protected void printStackTrace(WrappedPrintStream stream) - { - stream.println("Missing Mods:"); - for (MissingModInfo info : this.missingModsInfos) - { - ArtifactVersion acceptedVersion = info.getAcceptedVersion(); - ArtifactVersion currentVersion = info.getCurrentVersion(); - String currentString = currentVersion != null ? currentVersion.getVersionString() : "missing"; - stream.println(String.format("\t%s : need %s: have %s", acceptedVersion.getVersionString(), acceptedVersion.getRangeString(), currentString)); - } - stream.println(""); - } - - @Override - @SideOnly(Side.CLIENT) - public GuiScreen createGui() - { - return new GuiModsMissing(this); - } - - public static class MissingModInfo - { - private final ArtifactVersion acceptedVersion; - @Nullable - private final ArtifactVersion currentVersion; - private final boolean required; - - private MissingModInfo(ArtifactVersion acceptedVersion, @Nullable ArtifactVersion currentVersion, boolean required) - { - Preconditions.checkNotNull(acceptedVersion, "acceptedVersion"); - this.acceptedVersion = acceptedVersion; - this.currentVersion = currentVersion; - this.required = required; - } - - @Nullable - public ArtifactVersion getCurrentVersion() - { - return currentVersion; - } - - public ArtifactVersion getAcceptedVersion() - { - return acceptedVersion; - } - - public boolean isRequired() - { - return required; - } - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/ModClassLoader.java b/src/main/java/net/minecraftforge/fml/common/ModClassLoader.java deleted file mode 100644 index 133cfbd19..000000000 --- a/src/main/java/net/minecraftforge/fml/common/ModClassLoader.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -import net.minecraft.launchwrapper.IClassTransformer; -import net.minecraft.launchwrapper.LaunchClassLoader; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; - -/** - * A simple delegating class loader used to load mods into the system - * - * - * @author cpw - * - */ -public class ModClassLoader extends URLClassLoader -{ - private static final List STANDARD_LIBRARIES = ImmutableList.of("jinput.jar", "lwjgl.jar", "lwjgl_util.jar", "rt.jar"); - private LaunchClassLoader mainClassLoader; - private List sources; - - public ModClassLoader(ClassLoader parent) { - super(new URL[0], null); - if (parent instanceof LaunchClassLoader) - { - this.mainClassLoader = (LaunchClassLoader)parent; - } - this.sources = Lists.newArrayList(); - } - - public void addFile(File modFile) throws MalformedURLException - { - URL url = modFile.toURI().toURL(); - mainClassLoader.addURL(url); - this.sources.add(modFile); - } - - @Override - public Class loadClass(String name) throws ClassNotFoundException - { - return mainClassLoader.loadClass(name); - } - - public File[] getParentSources() { - try - { - List files=new ArrayList(); - for(URL url : mainClassLoader.getSources()) - { - URI uri = url.toURI(); - if(uri.getScheme().equals("file")) - { - files.add(new File(uri)); - } - } - return files.toArray(new File[]{}); - } - catch (URISyntaxException e) - { - FMLLog.log.error("Unable to process our input to locate the minecraft code", e); - throw new LoaderException(e); - } - } - - public List getDefaultLibraries() - { - return STANDARD_LIBRARIES; - } - - public boolean isDefaultLibrary(File file) - { - String home = System.getProperty("java.home"); // Nullcheck just in case some JVM decides to be stupid - if (home != null && file.getAbsolutePath().startsWith(home)) return true; - // Should really pull this from the json somehow, but we dont have that at runtime. - String name = file.getName(); - if (!name.endsWith(".jar")) return false; - String[] prefixes = - { - "launchwrapper-", - "asm-all-", - "akka-actor_2.11-", - "config-", - "scala-", - "jopt-simple-", - "lzma-", - "realms-", - "httpclient-", - "httpcore-", - "vecmath-", - "trove4j-", - "icu4j-core-mojang-", - "codecjorbis-", - "codecwav-", - "libraryjavawound-", - "librarylwjglopenal-", - "soundsystem-", - "netty-all-", - "guava-", - "commons-lang3-", - "commons-compress-", - "commons-logging-", - "commons-io-", - "commons-codec-", - "jinput-", - "jutils-", - "gson-", - "authlib-", - "log4j-api-", - "log4j-core-", - "lwjgl-", - "lwjgl_util-", - "twitch-", - "jline-", - "jna-", - "platform-", - "oshi-core-", - "netty-", - "libraryjavasound-", - "fastutil-" - }; - for (String s : prefixes) - { - if (name.startsWith(s)) return true; - } - return false; - } - - public void clearNegativeCacheFor(Set classList) - { - mainClassLoader.clearNegativeEntries(classList); - } - - public ModAPITransformer addModAPITransformer(ASMDataTable dataTable) - { - mainClassLoader.registerTransformer("net.minecraftforge.fml.common.asm.transformers.ModAPITransformer"); - List transformers = mainClassLoader.getTransformers(); - ModAPITransformer modAPI = (ModAPITransformer) transformers.get(transformers.size()-1); - modAPI.initTable(dataTable); - return modAPI; - } - - List parentURLs = null; - public boolean containsSource(File source) - { - if (parentURLs == null) { - parentURLs = Arrays.asList(mainClassLoader.getURLs()); - } - try - { - return parentURLs.contains(source.toURI().toURL()); - } catch (MalformedURLException e) - { - // shouldn't happen - return false; - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/Optional.java b/src/main/java/net/minecraftforge/fml/common/Optional.java deleted file mode 100644 index 2a257f062..000000000 --- a/src/main/java/net/minecraftforge/fml/common/Optional.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Classes annotated with this will have the named interface or method removed from the runtime definition of the class - * if the modid specified is missing. - * - * @author cpw - * - */ -public final class Optional { - /** - * Not constructable - */ - private Optional() {} - - /** - * Mark a list of interfaces as removable - * @author cpw - * - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - public @interface InterfaceList { - /** - * Mark a list of interfaces for optional removal. - * @return - */ - Interface[] value(); - } - /** - * Used to remove optional interfaces - * @author cpw - * - */ - @Repeatable(InterfaceList.class) - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - public @interface Interface { - /** - * The fully qualified name of the interface to be stripped - * @return the interface name - */ - String iface(); - - /** - * The modid that is required to be present for stripping NOT to occur - * @return the modid - */ - String modid(); - - /** - * Strip references to this interface in method declarations? (Useful to kill synthetic methods from scala f.e.) - * - * @return if references should be stripped - */ - boolean striprefs() default false; - } - /** - * Used to remove optional methods - * @author cpw - * - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - public @interface Method { - /** - * The modid that is required to be present for stripping NOT to occur - * @return the modid - */ - String modid(); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/ProgressManager.java b/src/main/java/net/minecraftforge/fml/common/ProgressManager.java index 2137a96b2..26f394f03 100644 --- a/src/main/java/net/minecraftforge/fml/common/ProgressManager.java +++ b/src/main/java/net/minecraftforge/fml/common/ProgressManager.java @@ -26,14 +26,12 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Function; import java.util.stream.Collectors; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.SidedExecutor; import net.minecraftforge.fml.SidedProvider; -import net.minecraftforge.fml.client.SplashProgress; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.message.MessageFormatMessage; import static net.minecraftforge.fml.Logging.SPLASH; -import static net.minecraftforge.fml.Logging.fmlLog; /** * Not a fully fleshed out API, may change in future MC versions. @@ -41,7 +39,9 @@ import static net.minecraftforge.fml.Logging.fmlLog; */ public class ProgressManager { + private static final Logger LOGGER = LogManager.getLogger(); private static final List bars = new CopyOnWriteArrayList(); + /** * Not a fully fleshed out API, may change in future MC versions. * However feel free to use and suggest additions. @@ -62,13 +62,10 @@ public class ProgressManager { bar.timeEachStep(); } - SidedExecutor.runOn(Dist.CLIENT, ()->SplashProgress::processMessages); +// DistExecutor.runWhenOn(Dist.CLIENT, ()->SplashProgress::processMessages); return bar; } - public static boolean isDisplayVSyncForced() { - return FMLCommonHandler.instance().isDisplayVSyncForced(); - } /** * Not a fully fleshed out API, may change in future MC versions. * However feel free to use and suggest additions. @@ -81,13 +78,13 @@ public class ProgressManager { long newTime = System.nanoTime(); if (bar.timeEachStep) - fmlLog.debug(SPLASH, () -> new MessageFormatMessage("Bar Step: {0} - {1} took {2,number,0.000}ms", bar.getTitle(), bar.getMessage(), (newTime - bar.lastTime) / 1.0e6)); + LOGGER.debug(SPLASH, () -> new MessageFormatMessage("Bar Step: {0} - {1} took {2,number,0.000}ms", bar.getTitle(), bar.getMessage(), (newTime - bar.lastTime) / 1.0e6)); if (bar.getSteps() == 1) - fmlLog.debug(SPLASH, () -> new MessageFormatMessage("Bar Finished: {0} - {1} took {2,number,0.000}ms", bar.getTitle(), bar.getMessage(), (newTime - bar.lastTime) / 1.0e6)); + LOGGER.debug(SPLASH, () -> new MessageFormatMessage("Bar Finished: {0} - {1} took {2,number,0.000}ms", bar.getTitle(), bar.getMessage(), (newTime - bar.lastTime) / 1.0e6)); else - fmlLog.debug(SPLASH, () -> new MessageFormatMessage("Bar Finished: {0} took {1,number,0.000}ms", bar.getTitle(), (newTime - bar.lastTime) / 1.0e6)); + LOGGER.debug(SPLASH, () -> new MessageFormatMessage("Bar Finished: {0} took {1,number,0.000}ms", bar.getTitle(), (newTime - bar.lastTime) / 1.0e6)); } - SidedExecutor.runOn(Dist.CLIENT, ()->SplashProgress::processMessages); +// DistExecutor.runWhenOn(Dist.CLIENT, ()->SplashProgress::processMessages); } /* @@ -121,7 +118,7 @@ public class ProgressManager public void step(Class classToName, String... extra) { - step(ClassNameUtils.shortName(classToName)+ Arrays.stream(extra).collect(Collectors.joining(" "))); + step(ClassNameUtils.shortName(classToName)+ String.join(" ", extra)); } public void step(String message) @@ -130,7 +127,7 @@ public class ProgressManager if (timeEachStep && step != 0) { long newTime = System.nanoTime(); - fmlLog.debug(SPLASH,new MessageFormatMessage("Bar Step: {0} - {1} took {2,number,0.000}ms", getTitle(), getMessage(), (newTime - lastTime) / 1.0e6)); + LOGGER.debug(SPLASH,new MessageFormatMessage("Bar Step: {0} - {1} took {2,number,0.000}ms", getTitle(), getMessage(), (newTime - lastTime) / 1.0e6)); lastTime = newTime; } step += 1; diff --git a/src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java b/src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java deleted file mode 100644 index 97f47fb46..000000000 --- a/src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A method annotated with this on the {@link Mod} will be called whenever a local save is listed in - * the save games list. - * - * @author cpw - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface SaveInspectionHandler -{ - -} diff --git a/src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java b/src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java deleted file mode 100644 index 7cc0d640a..000000000 --- a/src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.io.PrintStream; - -import org.apache.logging.log4j.Logger; - -/** - * PrintStream which redirects it's output to a given logger. - * - * @author Arkan - */ -public class TracingPrintStream extends PrintStream { - - private Logger logger; - private int BASE_DEPTH = 3; - - public TracingPrintStream(Logger logger, PrintStream original) { - super(original); - this.logger = logger; - } - - @Override - public void println(Object o) { - logger.info("{}{}", getPrefix(), o); - } - - @Override - public void println(String s) { - logger.info("{}{}", getPrefix(), s); - } - - private String getPrefix() { - StackTraceElement[] elems = Thread.currentThread().getStackTrace(); - StackTraceElement elem = elems[BASE_DEPTH]; // The caller is always at BASE_DEPTH, including this call. - if (elem.getClassName().startsWith("kotlin.io.")) { - elem = elems[BASE_DEPTH + 2]; // Kotlins IoPackage masks origins 2 deeper in the stack. - } else if (elem.getClassName().startsWith("java.lang.Throwable")) { - elem = elems[BASE_DEPTH + 4]; - } - return "[" + elem.getClassName() + ":" + elem.getMethodName() + ":" + elem.getLineNumber() + "]: "; - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java b/src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java deleted file mode 100644 index 0be678d93..000000000 --- a/src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import net.minecraft.client.gui.GuiScreen; -import net.minecraftforge.fml.client.GuiWrongMinecraft; -import net.minecraftforge.fml.client.IDisplayableError; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import net.minecraftforge.fml.ModContainer; - -public class WrongMinecraftVersionException extends EnhancedRuntimeException implements IDisplayableError -{ - private static final long serialVersionUID = 1L; - public ModContainer mod; - private String mcVersion; - - public WrongMinecraftVersionException(ModContainer mod, String mcver) - { - super(String.format("Wrong Minecraft version for %s", mod.getModId())); - this.mod = mod; - this.mcVersion = mcver; - } - - @Override - protected void printStackTrace(WrappedPrintStream stream) { - stream.println("Wrong Minecraft Versions!"); - stream.println("Mod: " + mod.getModId()); - stream.println("Location: " + mod.getSource().toString()); - stream.println("Expected: " + mod.acceptableMinecraftVersionRange().toString()); - stream.println("Current: " + mcVersion); - stream.println(""); - } - - @Override - @SideOnly(Side.CLIENT) - public GuiScreen createGui() - { - return new GuiWrongMinecraft(this); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/ZipperUtil.java b/src/main/java/net/minecraftforge/fml/common/ZipperUtil.java deleted file mode 100644 index 7f2d370b9..000000000 --- a/src/main/java/net/minecraftforge/fml/common/ZipperUtil.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common; - -import java.io.Closeable; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.URI; -import java.util.Deque; -import java.util.LinkedList; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import org.apache.logging.log4j.Level; - -import com.google.common.io.Files; - -/** - * Copied from http://stackoverflow.com/questions/1399126/java-util-zip-recreating-directory-structure - * because the code looked very tidy and neat. Thanks, McDowell! - * - * @author McDowell - * - */ -public class ZipperUtil { - public static void zip(File directory, File zipfile) throws IOException - { - URI base = directory.toURI(); - Deque queue = new LinkedList(); - queue.push(directory); - OutputStream out = new FileOutputStream(zipfile); - Closeable res = null; - try - { - ZipOutputStream zout = new ZipOutputStream(out); - res = zout; - while (!queue.isEmpty()) - { - directory = queue.pop(); - for (File kid : directory.listFiles()) - { - String name = base.relativize(kid.toURI()).getPath(); - if (kid.isDirectory()) - { - queue.push(kid); - name = name.endsWith("/") ? name : name + "/"; - zout.putNextEntry(new ZipEntry(name)); - } else - { - zout.putNextEntry(new ZipEntry(name)); - Files.copy(kid, zout); - zout.closeEntry(); - } - } - } - } finally - { - res.close(); - } - } - - public static void backupWorld() throws IOException - { - String dirName = FMLCommonHandler.instance().getMinecraftServerInstance().getFolderName(); - - backupWorld(dirName); - } - - @Deprecated - public static void backupWorld(String dirName, String saveName) throws IOException - { - backupWorld(dirName); - } - - public static void backupWorld(String dirName) throws IOException - { - File dstFolder = FMLCommonHandler.instance().getSavesDirectory(); - File zip = new File(dstFolder, String.format("%s-%2$tY%2$tm%2$td-%2$tH%2$tM%2$tS.zip", dirName, System.currentTimeMillis())); - - try - { - ZipperUtil.zip(new File(dstFolder, dirName), zip); - } - catch (IOException e) - { - FMLLog.log.warn("World backup failed.", e); - throw e; - } - - FMLLog.log.info("World backup created at {}.", zip.getCanonicalPath()); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java b/src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java deleted file mode 100644 index c14d0bad2..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.security.Permission; -import java.util.Map; - -import net.minecraft.launchwrapper.IClassTransformer; -import net.minecraft.launchwrapper.LaunchClassLoader; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.GeneratorAdapter; -import org.objectweb.asm.commons.Method; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.Maps; - -import javax.annotation.Nullable; - -public class ASMTransformerWrapper -{ - private static final Map wrapperModMap = Maps.newHashMap(); - private static final Map wrapperParentMap = Maps.newHashMap(); - - private static final LoadingCache wrapperCache = CacheBuilder.newBuilder() - .maximumSize(30) - .weakValues() - .build(new CacheLoader() - { - @Override - public byte[] load(String file) throws Exception - { - return makeWrapper(file); - } - }); - - private static final URL asmGenRoot; - private static boolean injected = false; - - static - { - try - { - asmGenRoot = new URL("asmgen", null, -1, "/", new ASMGenHandler()); - } - catch(MalformedURLException e) - { - throw new RuntimeException(e); - } - } - - private static class ASMGenHandler extends URLStreamHandler - { - @Override - @Nullable - protected URLConnection openConnection(URL url) throws IOException - { - String file = url.getFile(); - if(file.equals("/")) - { - return new URLConnection(url) - { - @Override - public void connect() throws IOException - { - throw new UnsupportedOperationException(); - } - }; - } - if(!file.startsWith("/")) throw new RuntimeException("Malformed URL: " + url); - file = file.substring(1); - if(wrapperModMap.containsKey(file)) - { - return new ASMGenConnection(url, file); - } - return null; - } - } - - private static class ASMGenConnection extends URLConnection - { - private final String file; - - protected ASMGenConnection(URL url, String file) - { - super(url); - this.file = file; - } - - @Override - public void connect() throws IOException - { - throw new UnsupportedOperationException(); - } - - @Override - public InputStream getInputStream() - { - return new ByteArrayInputStream(wrapperCache.getUnchecked(file)); - } - - @Override - @Nullable - public Permission getPermission() - { - return null; - } - } - - public static String getTransformerWrapper(LaunchClassLoader launchLoader, String parentClass, String coreMod) - { - if(!injected) - { - injected = true; - launchLoader.addURL(asmGenRoot); - } - - String name = getWrapperName(parentClass); - String fileName = name.replace('.', '/') + ".class"; - wrapperModMap.put(fileName, coreMod); - wrapperParentMap.put(fileName, parentClass); - return name; - } - - private static byte[] makeWrapper(String fileName) - { - if(!wrapperModMap.containsKey(fileName) || !wrapperParentMap.containsKey(fileName) || !fileName.endsWith(".class")) - { - throw new IllegalArgumentException("makeWrapper called with strange argument: " + fileName); - } - String name = fileName.substring(0, fileName.length() - ".class".length()); - - try - { - Type wrapper = Type.getType(TransformerWrapper.class); - - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - - writer.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, name, null, wrapper.getInternalName(), null); - - Method m = Method.getMethod("void ()"); - GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, writer); - mg.loadThis(); - mg.invokeConstructor(wrapper, m); - mg.returnValue(); - mg.endMethod(); - - m = Method.getMethod("java.lang.String getParentClass ()"); - mg = new GeneratorAdapter(Opcodes.ACC_PROTECTED, m, null, null, writer); - mg.push(wrapperParentMap.get(fileName)); - mg.returnValue(); - mg.endMethod(); - - m = Method.getMethod("java.lang.String getCoreMod ()"); - mg = new GeneratorAdapter(Opcodes.ACC_PROTECTED, m, null, null, writer); - mg.push(wrapperModMap.get(fileName)); - mg.returnValue(); - mg.endMethod(); - - writer.visitEnd(); - - return writer.toByteArray(); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - private static String getWrapperName(String parentClass) - { - return "$wrapper." + parentClass; - } - - @SuppressWarnings("unused") - private static class WrapperVisitor extends ClassVisitor - { - private final String name; - private final String parentClass; - - public WrapperVisitor(ClassVisitor cv, String name, String parentClass) - { - super(Opcodes.ASM5, cv); - this.name = name.replace('.', '/'); - this.parentClass = parentClass; - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) - { - super.visit(version, access, this.name, signature, superName, interfaces); - } - - @Override - public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) - { - if(name.equals("parentClass")) - { - return super.visitField(access, name, desc, signature, parentClass); - } - return super.visitField(access, name, desc, signature, value); - } - } - - public static abstract class TransformerWrapper implements IClassTransformer - { - private final IClassTransformer parent; - - public TransformerWrapper() - { - try - { - this.parent = (IClassTransformer)this.getClass().getClassLoader().loadClass(getParentClass()).newInstance(); - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } - - @Override - public byte[] transform(String name, String transformedName, byte[] basicClass) - { - try - { - return parent.transform(name, transformedName, basicClass); - } - catch(Throwable e) - { - throw new TransformerException("Exception in class transformer " + parent + " from coremod " + getCoreMod(), e); - } - } - - @Override - public String toString() - { - return "TransformerWrapper(" + getParentClass() + ", " + getCoreMod() + ")"; - } - - protected abstract String getParentClass(); - - protected abstract String getCoreMod(); - } - - static class TransformerException extends RuntimeException - { - private static final long serialVersionUID = -6616232415696157218L; - - public TransformerException(String message, Throwable cause) - { - super(message, cause); - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/DeobfuscationTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/DeobfuscationTransformer.java deleted file mode 100644 index 09f173423..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/DeobfuscationTransformer.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm; - -import net.minecraft.launchwrapper.IClassNameTransformer; -import net.minecraft.launchwrapper.IClassTransformer; -import net.minecraftforge.fml.common.asm.deobf.FMLDeobfuscatingRemapper; -import net.minecraftforge.fml.common.asm.deobf.FMLRemappingAdapter; - -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.commons.RemappingClassAdapter; - -public class DeobfuscationTransformer implements IClassTransformer, IClassNameTransformer { - - private static final boolean RECALC_FRAMES = Boolean.parseBoolean(System.getProperty("FORGE_FORCE_FRAME_RECALC", "false")); - private static final int WRITER_FLAGS = ClassWriter.COMPUTE_MAXS | (RECALC_FRAMES ? ClassWriter.COMPUTE_FRAMES : 0); - private static final int READER_FLAGS = RECALC_FRAMES ? ClassReader.SKIP_FRAMES : ClassReader.EXPAND_FRAMES; - // COMPUTE_FRAMES causes classes to be loaded, which could cause issues if the classes do not exist. - // However in testing this has not happened. {As we run post RuntimeDistCleaner} - // If reported we need to add a custom implementation of ClassWriter.getCommonSuperClass - // that does not cause class loading. - - @Override - public byte[] transform(String name, String transformedName, byte[] bytes) - { - if (bytes == null) - { - return null; - } - ClassReader classReader = new ClassReader(bytes); - ClassWriter classWriter = new ClassWriter(WRITER_FLAGS); - RemappingClassAdapter remapAdapter = new FMLRemappingAdapter(classWriter); - classReader.accept(remapAdapter, READER_FLAGS); - return classWriter.toByteArray(); - } - - @Override - public String remapClassName(String name) - { - return FMLDeobfuscatingRemapper.INSTANCE.map(name.replace('.','/')).replace('/', '.'); - } - - @Override - public String unmapClassName(String name) - { - return FMLDeobfuscatingRemapper.INSTANCE.unmap(name.replace('.', '/')).replace('/','.'); - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java b/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java deleted file mode 100644 index 7f4fd3afa..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm; - -import java.io.File; -import java.io.InputStream; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.security.CodeSource; -import java.security.cert.Certificate; -import java.util.Map; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import net.minecraftforge.fml.common.FMLLog; -import org.apache.commons.io.IOUtils; - -import net.minecraft.launchwrapper.LaunchClassLoader; -import net.minecraftforge.fml.common.CertificateHelper; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.asm.deobf.FMLDeobfuscatingRemapper; -import net.minecraftforge.fml.common.patcher.ClassPatchManager; -import net.minecraftforge.api.distmarker.Dist; - -import com.google.common.io.ByteStreams; - -public class FMLSanityChecker implements IFMLCallHook -{ - private static final String FMLFINGERPRINT = "51:0A:FB:4C:AF:A4:A0:F2:F5:CF:C5:0E:B4:CC:3C:30:24:4A:E3:8E".toLowerCase().replace(":", ""); - private static final String FORGEFINGERPRINT = "E3:C3:D5:0C:7C:98:6D:F7:4C:64:5C:0A:C5:46:39:74:1C:90:A5:57".toLowerCase().replace(":", ""); - private static final String MCFINGERPRINT = "CD:99:95:96:56:F7:53:DC:28:D8:63:B4:67:69:F7:F8:FB:AE:FC:FC".toLowerCase().replace(":", ""); - private LaunchClassLoader cl; - private boolean liveEnv; - public static File fmlLocation; - - @Override - public Void call() throws Exception - { - CodeSource codeSource = getClass().getProtectionDomain().getCodeSource(); - boolean goodFML = false; - boolean fmlIsJar = false; - if (codeSource.getLocation().getProtocol().equals("jar")) - { - fmlIsJar = true; - Certificate[] certificates = codeSource.getCertificates(); - if (certificates!=null) - { - - for (Certificate cert : certificates) - { - String fingerprint = CertificateHelper.getFingerprint(cert); - if (fingerprint.equals(FMLFINGERPRINT)) - { - FMLLog.log.info("Found valid fingerprint for FML. Certificate fingerprint {}", fingerprint); - goodFML = true; - } - else if (fingerprint.equals(FORGEFINGERPRINT)) - { - FMLLog.log.info("Found valid fingerprint for Minecraft Forge. Certificate fingerprint {}", fingerprint); - goodFML = true; - } - else - { - FMLLog.log.error("Found invalid fingerprint for FML: {}", fingerprint); - } - } - } - } - else - { - goodFML = true; - } - // Server is not signed, so assume it's good - a deobf env is dev time so it's good too - boolean goodMC = FMLLaunchHandler.side() == Side.SERVER || !liveEnv; - int certCount = 0; - try - { - Class cbr = Class.forName("net.minecraft.client.ClientBrandRetriever",false, cl); - codeSource = cbr.getProtectionDomain().getCodeSource(); - } - catch (Exception e) - { - // Probably a development environment, or the server (the server is not signed) - goodMC = true; - } - JarFile mcJarFile = null; - if (fmlIsJar && !goodMC && codeSource.getLocation().getProtocol().equals("jar")) - { - try - { - String mcPath = codeSource.getLocation().getPath().substring(5); - mcPath = mcPath.substring(0, mcPath.lastIndexOf('!')); - mcPath = URLDecoder.decode(mcPath, StandardCharsets.UTF_8.name()); - mcJarFile = new JarFile(mcPath,true); - mcJarFile.getManifest(); - JarEntry cbrEntry = mcJarFile.getJarEntry("net/minecraft/client/ClientBrandRetriever.class"); - InputStream mcJarFileInputStream = mcJarFile.getInputStream(cbrEntry); - try - { - ByteStreams.toByteArray(mcJarFileInputStream); - } - finally - { - IOUtils.closeQuietly(mcJarFileInputStream); - } - Certificate[] certificates = cbrEntry.getCertificates(); - certCount = certificates != null ? certificates.length : 0; - if (certificates!=null) - { - - for (Certificate cert : certificates) - { - String fingerprint = CertificateHelper.getFingerprint(cert); - if (fingerprint.equals(MCFINGERPRINT)) - { - FMLLog.log.info("Found valid fingerprint for Minecraft. Certificate fingerprint {}", fingerprint); - goodMC = true; - } - } - } - } - catch (Throwable e) - { - FMLLog.log.error("A critical error occurred trying to read the minecraft jar file", e); - } - finally - { - IOUtils.closeQuietly(mcJarFile); - } - } - else - { - goodMC = true; - } - if (!goodMC) - { - FMLLog.log.error("The minecraft jar {} appears to be corrupt! There has been CRITICAL TAMPERING WITH MINECRAFT, it is highly unlikely minecraft will work! STOP NOW, get a clean copy and try again!", codeSource.getLocation().getFile()); - if (!Boolean.parseBoolean(System.getProperty("fml.ignoreInvalidMinecraftCertificates","false"))) - { - FMLLog.log.error("For your safety, FML will not launch minecraft. You will need to fetch a clean version of the minecraft jar file"); - FMLLog.log.error("Technical information: The class net.minecraft.client.ClientBrandRetriever should have been associated with the minecraft jar file, " + - "and should have returned us a valid, intact minecraft jar location. This did not work. Either you have modified the minecraft jar file (if so " + - "run the forge installer again), or you are using a base editing jar that is changing this class (and likely others too). If you REALLY " + - "want to run minecraft in this configuration, add the flag -Dfml.ignoreInvalidMinecraftCertificates=true to the 'JVM settings' in your launcher profile."); - FMLCommonHandler.instance().exitJava(1, false); - } - else - { - FMLLog.log.error("FML has been ordered to ignore the invalid or missing minecraft certificate. This is very likely to cause a problem!"); - FMLLog.log.error("Technical information: ClientBrandRetriever was at {}, there were {} certificates for it", codeSource.getLocation(), certCount); - } - } - if (!goodFML) - { - FMLLog.log.error("FML appears to be missing any signature data. This is not a good thing"); - } - return null; - } - - @Override - public void injectData(Map data) - { - liveEnv = (Boolean)data.get("runtimeDeobfuscationEnabled"); - cl = (LaunchClassLoader) data.get("classLoader"); - File mcDir = (File)data.get("mcLocation"); - fmlLocation = (File)data.get("coremodLocation"); - ClassPatchManager.INSTANCE.setup(FMLLaunchHandler.side()); - FMLDeobfuscatingRemapper.INSTANCE.setup(mcDir, cl, (String) data.get("deobfuscationFileName")); - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/FieldRedirectTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/FieldRedirectTransformer.java deleted file mode 100644 index 93faedb75..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/FieldRedirectTransformer.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm; - -import java.util.ListIterator; - -import net.minecraft.launchwrapper.IClassTransformer; - -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.tree.AbstractInsnNode; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.FieldInsnNode; -import org.objectweb.asm.tree.FieldNode; -import org.objectweb.asm.tree.MethodInsnNode; -import org.objectweb.asm.tree.MethodNode; - -public class FieldRedirectTransformer implements IClassTransformer -{ - private final String clsName; - private final String TYPE; - private final String DESC; - private final String bypass; - - protected FieldRedirectTransformer(String cls, String type, String bypass) - { - this.clsName = cls; - this.TYPE = type; - this.DESC = "()" + type; - this.bypass = bypass; - } - - @Override - public byte[] transform(String name, String transformedName, byte[] basicClass) - { - if (!this.clsName.equals(transformedName)) - return basicClass; - - ClassNode classNode = new ClassNode(); - ClassReader classReader = new ClassReader(basicClass); - classReader.accept(classNode, 0); - - FieldNode fieldRef = null; - for (FieldNode f : classNode.fields) - { - if (this.TYPE.equals(f.desc) && fieldRef == null) - { - fieldRef = f; - } - else if (this.TYPE.equals(f.desc)) - { - throw new RuntimeException("Error processing " + clsName + " - found a duplicate holder field"); - } - } - if (fieldRef == null) - { - throw new RuntimeException("Error processing " + clsName + " - no holder field declared (is the code somehow obfuscated?)"); - } - - MethodNode getMethod = null; - for (MethodNode m: classNode.methods) - { - if (m.name.equals(this.bypass)) continue; - if (this.DESC.equals(m.desc) && getMethod == null) - { - getMethod = m; - } - else if (this.DESC.equals(m.desc)) - { - throw new RuntimeException("Error processing " + clsName + " - duplicate get method found"); - } - } - if (getMethod == null) - { - throw new RuntimeException("Error processing " + clsName + " - no get method found (is the code somehow obfuscated?)"); - } - - for (MethodNode m: classNode.methods) - { - if (m.name.equals(this.bypass)) continue; - for (ListIterator it = m.instructions.iterator(); it.hasNext(); ) - { - AbstractInsnNode insnNode = it.next(); - if (insnNode.getType() == AbstractInsnNode.FIELD_INSN) - { - FieldInsnNode fi = (FieldInsnNode)insnNode; - if (fieldRef.name.equals(fi.name) && fi.getOpcode() == Opcodes.GETFIELD) - { - it.remove(); - MethodInsnNode replace = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classNode.name, getMethod.name, getMethod.desc, false); - it.add(replace); - } - } - } - } - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); - classNode.accept(writer); - return writer.toByteArray(); - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/ItemBlockSpecialTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/ItemBlockSpecialTransformer.java deleted file mode 100644 index de9e64a2f..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/ItemBlockSpecialTransformer.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm; - -public class ItemBlockSpecialTransformer extends FieldRedirectTransformer -{ - public ItemBlockSpecialTransformer() - { - super("net.minecraft.item.ItemBlockSpecial", "Lnet/minecraft/block/Block;", "getBlockRaw"); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/ItemBlockTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/ItemBlockTransformer.java deleted file mode 100644 index 2581c99d9..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/ItemBlockTransformer.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm; - -public class ItemBlockTransformer extends FieldRedirectTransformer -{ - public ItemBlockTransformer() - { - super("net.minecraft.item.ItemBlock", "Lnet/minecraft/block/Block;", "getBlockRaw"); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/ItemStackTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/ItemStackTransformer.java deleted file mode 100644 index 13b384922..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/ItemStackTransformer.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm; - -public class ItemStackTransformer extends FieldRedirectTransformer -{ - public ItemStackTransformer() - { - super("net.minecraft.item.ItemStack", "Lnet/minecraft/item/Item;", "getItemRaw"); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java b/src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java deleted file mode 100644 index 7f9d5d9de..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Used to force certain classes to reobfuscate - * @author cpw - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -public @interface ReobfuscationMarker { - -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/TerminalTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/TerminalTransformer.java deleted file mode 100644 index 54e3df4dc..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/TerminalTransformer.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm; - -import org.objectweb.asm.*; - -import net.minecraft.launchwrapper.IClassTransformer; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.relauncher.FMLSecurityManager.ExitTrappedException; - -public class TerminalTransformer implements IClassTransformer -{ - @Override - public byte[] transform(String name, String transformedName, byte[] basicClass) - { - if (basicClass == null) return null; - ClassReader reader = new ClassReader(basicClass); - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); - - ClassVisitor visitor = writer; - visitor = new ExitVisitor(visitor); - - reader.accept(visitor, 0); - return writer.toByteArray(); - } - - public static class ExitVisitor extends ClassVisitor - { - private String clsName = null; - private static final String callbackOwner = org.objectweb.asm.Type.getInternalName(ExitVisitor.class); - - private ExitVisitor(ClassVisitor cv) - { - super(Opcodes.ASM5, cv); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) - { - super.visit(version, access, name, signature, superName, interfaces); - this.clsName = name; - } - - @Override - public MethodVisitor visitMethod(int mAccess, final String mName, final String mDesc, String mSignature, String[] mExceptions) - { - final boolean warn = !(clsName.equals("net/minecraft/client/Minecraft") || - clsName.equals("net/minecraft/server/dedicated/DedicatedServer") || - clsName.equals("net/minecraft/server/dedicated/ServerHangWatchdog") || - clsName.equals("net/minecraft/server/dedicated/ServerHangWatchdog$1") || - clsName.equals("net/minecraftforge/fml/common/FMLCommonHandler") || - clsName.startsWith("com/jcraft/jogg/") || - clsName.startsWith("scala/sys/") || - clsName.startsWith("net/minecraft/server/gui/MinecraftServerGui") || - clsName.startsWith("com/sun/jna/") - ); - - return new MethodVisitor(Opcodes.ASM5, super.visitMethod(mAccess, mName, mDesc, mSignature, mExceptions)) - { - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isIntf) - { - if (opcode == Opcodes.INVOKESTATIC && owner.equals("java/lang/System") && name.equals("exit") && desc.equals("(I)V")) - { - if (warn) - { - FMLLog.log.warn("============================================================="); - FMLLog.log.warn("MOD HAS DIRECT REFERENCE System.exit() THIS IS NOT ALLOWED REROUTING TO FML!"); - FMLLog.log.warn("Offender: {}.{}{}", ExitVisitor.this.clsName, mName, mDesc); - FMLLog.log.warn("Use FMLCommonHandler.exitJava instead"); - FMLLog.log.warn("============================================================="); - } - owner = ExitVisitor.callbackOwner; - name = "systemExitCalled"; - } - else if (opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/lang/Runtime") && name.equals("exit") && desc.equals("(I)V")) - { - if (warn) - { - FMLLog.log.warn("============================================================="); - FMLLog.log.warn("MOD HAS DIRECT REFERENCE Runtime.exit() THIS IS NOT ALLOWED REROUTING TO FML!"); - FMLLog.log.warn("Offender: {}.{}{}", ExitVisitor.this.clsName, mName, mDesc); - FMLLog.log.warn("Use FMLCommonHandler.exitJava instead"); - FMLLog.log.warn("============================================================="); - } - opcode = Opcodes.INVOKESTATIC; - owner = ExitVisitor.callbackOwner; - name = "runtimeExitCalled"; - desc = "(Ljava/lang/Runtime;I)V"; - } - else if (opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/lang/Runtime") && name.equals("halt") && desc.equals("(I)V")) - { - if (warn) - { - FMLLog.log.warn("============================================================="); - FMLLog.log.warn("MOD HAS DIRECT REFERENCE Runtime.halt() THIS IS NOT ALLOWED REROUTING TO FML!"); - FMLLog.log.warn("Offendor: {}.{}{}", ExitVisitor.this.clsName, mName, mDesc); - FMLLog.log.warn("Use FMLCommonHandler.exitJava instead"); - FMLLog.log.warn("============================================================="); - } - opcode = Opcodes.INVOKESTATIC; - owner = ExitVisitor.callbackOwner; - name = "runtimeHaltCalled"; - desc = "(Ljava/lang/Runtime;I)V"; - } - - super.visitMethodInsn(opcode, owner, name, desc, isIntf); - } - }; - } - - // Intercept System.exit, and check if the caller is allowed to use it, if not wrap it in a ExitTrappedException - public static void systemExitCalled(int status) - { - ExitVisitor.checkAccess(); - System.exit(status); - } - // Intercept Runtime.getRuntime().exit, and check if the caller is allowed to use it, if not wrap it in a ExitTrappedException - public static void runtimeExitCalled(Runtime runtime, int status) - { - ExitVisitor.checkAccess(); - runtime.exit(status); - } - - // Intercept Runtime.getRuntime().halt, and check if the caller is allowed to use it, if not wrap it in a ExitTrappedException - public static void runtimeHaltCalled(Runtime runtime, int status) - { - ExitVisitor.checkAccess(); - runtime.halt(status); - } - - private static void checkAccess() - { - StackTraceElement[] cause = Thread.currentThread().getStackTrace(); - - String callingClass = cause.length > 2 ? cause[3].getClassName() : "none"; - String callingParent = cause.length > 3 ? cause[4].getClassName() : "none"; - // FML is allowed to call system exit and the Minecraft applet (from the quit button), and the dedicated server (from itself) - boolean allowed = false; - allowed |= callingClass.startsWith("net.minecraftforge.fml."); - allowed |= callingClass.equals("net.minecraft.client.Minecraft") && callingParent.equals("net.minecraft.client.Minecraft"); - allowed |= callingClass.equals("net.minecraft.server.gui.MinecraftServerGui$1") && callingParent.equals("java.awt.AWTEventMulticaster"); - allowed |= callingClass.equals("net.minecraft.server.dedicated.DedicatedServer") && callingParent.equals("net.minecraft.server.MinecraftServer"); - allowed |= callingClass.equals("net.minecraft.server.dedicated.ServerHangWatchdog"); - allowed |= callingClass.equals("net.minecraft.server.dedicated.ServerHangWatchdog$1"); - - if (!allowed) - { - throw new ExitTrappedException(); - } - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/deobf/FMLDeobfuscatingRemapper.java b/src/main/java/net/minecraftforge/fml/common/asm/deobf/FMLDeobfuscatingRemapper.java deleted file mode 100644 index c6dfab834..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/deobf/FMLDeobfuscatingRemapper.java +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm.deobf; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import net.minecraft.launchwrapper.LaunchClassLoader; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.patcher.ClassPatchManager; - -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.commons.Remapper; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.FieldNode; - -import com.google.common.base.CharMatcher; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.BiMap; -import com.google.common.collect.ImmutableBiMap; -import com.google.common.collect.ImmutableBiMap.Builder; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.io.CharSource; -import com.google.common.io.Files; - -import javax.annotation.Nullable; - -public class FMLDeobfuscatingRemapper extends Remapper { - public static final FMLDeobfuscatingRemapper INSTANCE = new FMLDeobfuscatingRemapper(); - - private BiMap classNameBiMap; - - private Map> rawFieldMaps; - private Map> rawMethodMaps; - - private Map> fieldNameMaps; - private Map> methodNameMaps; - - private LaunchClassLoader classLoader; - - - private static final boolean DEBUG_REMAPPING = Boolean.parseBoolean(System.getProperty("fml.remappingDebug", "false")); - private static final boolean DUMP_FIELD_MAPS = Boolean.parseBoolean(System.getProperty("fml.remappingDebug.dumpFieldMaps", "false")) && DEBUG_REMAPPING; - private static final boolean DUMP_METHOD_MAPS = Boolean.parseBoolean(System.getProperty("fml.remappingDebug.dumpMethodMaps", "false")) && DEBUG_REMAPPING; - - private FMLDeobfuscatingRemapper() - { - classNameBiMap=ImmutableBiMap.of(); - } - - public void setupLoadOnly(String deobfFileName, boolean loadAll) - { - try - { - File mapData = new File(deobfFileName); - LZMAInputSupplier zis = new LZMAInputSupplier(new FileInputStream(mapData)); - CharSource srgSource = zis.asCharSource(StandardCharsets.UTF_8); - List srgList = srgSource.readLines(); - rawMethodMaps = Maps.newHashMap(); - rawFieldMaps = Maps.newHashMap(); - Builder builder = ImmutableBiMap.builder(); - Splitter splitter = Splitter.on(CharMatcher.anyOf(": ")).omitEmptyStrings().trimResults(); - for (String line : srgList) - { - String[] parts = Iterables.toArray(splitter.split(line),String.class); - String typ = parts[0]; - if ("CL".equals(typ)) - { - parseClass(builder, parts); - } - else if ("MD".equals(typ) && loadAll) - { - parseMethod(parts); - } - else if ("FD".equals(typ) && loadAll) - { - parseField(parts); - } - } - classNameBiMap = builder.build(); - } - catch (IOException ioe) - { - FMLLog.log.error("An error occurred loading the deobfuscation map data", ioe); - } - methodNameMaps = Maps.newHashMapWithExpectedSize(rawMethodMaps.size()); - fieldNameMaps = Maps.newHashMapWithExpectedSize(rawFieldMaps.size()); - - } - public void setup(File mcDir, LaunchClassLoader classLoader, String deobfFileName) - { - this.classLoader = classLoader; - try - { - List srgList; - final String gradleStartProp = System.getProperty("net.minecraftforge.gradle.GradleStart.srg.srg-mcp"); - - if (Strings.isNullOrEmpty(gradleStartProp)) - { - // get as a resource - InputStream classData = getClass().getResourceAsStream(deobfFileName); - LZMAInputSupplier zis = new LZMAInputSupplier(classData); - CharSource srgSource = zis.asCharSource(StandardCharsets.UTF_8); - srgList = srgSource.readLines(); - FMLLog.log.debug("Loading deobfuscation resource {} with {} records", deobfFileName, srgList.size()); - } - else - { - srgList = Files.readLines(new File(gradleStartProp), StandardCharsets.UTF_8); - FMLLog.log.debug("Loading deobfuscation resource {} with {} records", gradleStartProp, srgList.size()); - } - - rawMethodMaps = Maps.newHashMap(); - rawFieldMaps = Maps.newHashMap(); - Builder builder = ImmutableBiMap.builder(); - Splitter splitter = Splitter.on(CharMatcher.anyOf(": ")).omitEmptyStrings().trimResults(); - for (String line : srgList) - { - String[] parts = Iterables.toArray(splitter.split(line),String.class); - String typ = parts[0]; - if ("CL".equals(typ)) - { - parseClass(builder, parts); - } - else if ("MD".equals(typ)) - { - parseMethod(parts); - } - else if ("FD".equals(typ)) - { - parseField(parts); - } - } - classNameBiMap = builder.build(); - } - catch (IOException ioe) - { - FMLLog.log.error("An error occurred loading the deobfuscation map data", ioe); - } - methodNameMaps = Maps.newHashMapWithExpectedSize(rawMethodMaps.size()); - fieldNameMaps = Maps.newHashMapWithExpectedSize(rawFieldMaps.size()); - } - - public boolean isRemappedClass(String className) - { - return !map(className).equals(className); - } - - private void parseField(String[] parts) - { - String oldSrg = parts[1]; - int lastOld = oldSrg.lastIndexOf('/'); - String cl = oldSrg.substring(0,lastOld); - String oldName = oldSrg.substring(lastOld+1); - String newSrg = parts[2]; - int lastNew = newSrg.lastIndexOf('/'); - String newName = newSrg.substring(lastNew+1); - if (!rawFieldMaps.containsKey(cl)) - { - rawFieldMaps.put(cl, Maps.newHashMap()); - } - String fieldType = getFieldType(cl, oldName); - // We might be in mcp named land, where in fact the name is "new" - if (fieldType == null) fieldType = getFieldType(cl, newName); - rawFieldMaps.get(cl).put(oldName + ":" + fieldType, newName); - rawFieldMaps.get(cl).put(oldName + ":null", newName); - } - - /* - * Cache the field descriptions for classes so we don't repeatedly reload the same data again and again - */ - private final Map> fieldDescriptions = Maps.newHashMap(); - - // Cache null values so we don't waste time trying to recompute classes with no field or method maps - private Set negativeCacheMethods = Sets.newHashSet(); - private Set negativeCacheFields = Sets.newHashSet(); - - @Nullable - private String getFieldType(String owner, String name) - { - if (fieldDescriptions.containsKey(owner)) - { - return fieldDescriptions.get(owner).get(name); - } - synchronized (fieldDescriptions) - { - try - { - byte[] classBytes = ClassPatchManager.INSTANCE.getPatchedResource(owner, map(owner).replace('/', '.'), classLoader); - if (classBytes == null) - { - return null; - } - ClassReader cr = new ClassReader(classBytes); - ClassNode classNode = new ClassNode(); - cr.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); - Map resMap = Maps.newHashMap(); - for (FieldNode fieldNode : classNode.fields) { - resMap.put(fieldNode.name, fieldNode.desc); - } - fieldDescriptions.put(owner, resMap); - return resMap.get(name); - } - catch (IOException e) - { - FMLLog.log.error("A critical exception occurred reading a class file {}", owner, e); - } - return null; - } - } - - private void parseClass(Builder builder, String[] parts) - { - builder.put(parts[1],parts[2]); - } - - private void parseMethod(String[] parts) - { - String oldSrg = parts[1]; - int lastOld = oldSrg.lastIndexOf('/'); - String cl = oldSrg.substring(0,lastOld); - String oldName = oldSrg.substring(lastOld+1); - String sig = parts[2]; - String newSrg = parts[3]; - int lastNew = newSrg.lastIndexOf('/'); - String newName = newSrg.substring(lastNew+1); - if (!rawMethodMaps.containsKey(cl)) - { - rawMethodMaps.put(cl, Maps.newHashMap()); - } - rawMethodMaps.get(cl).put(oldName+sig, newName); - } - - String mapMemberFieldName(String owner, String name, String desc) - { - String remappedName = mapFieldName(owner, name, desc, true); - storeMemberFieldMapping(owner, name, desc, remappedName); - return remappedName; - } - - private void storeMemberFieldMapping(String owner, String name, String desc, String remappedName) { - Map fieldMap = getRawFieldMap(owner); - - String key = name + ":" + desc; - String altKey = name + ":null"; - - if (!fieldMap.containsKey(key)) { - fieldMap.put(key, remappedName); - fieldMap.put(altKey, remappedName); - - // Alternatively, maps could be made mutable and we could just set the relevant entry, saving - // the need to regenerate the super map each time - fieldNameMaps.remove(owner); - } - } - - @Override - public String mapFieldName(String owner, String name, @Nullable String desc) - { - return mapFieldName(owner, name, desc, false); - } - - String mapFieldName(String owner, String name, @Nullable String desc, boolean raw) - { - if (classNameBiMap == null || classNameBiMap.isEmpty()) - { - return name; - } - Map fieldMap = getFieldMap(owner, raw); - return fieldMap!=null && fieldMap.containsKey(name+":"+desc) ? fieldMap.get(name+":"+desc) : fieldMap!=null && fieldMap.containsKey(name+":null") ? fieldMap.get(name+":null") :name; - } - - @Override - public String map(String typeName) - { - if (classNameBiMap == null || classNameBiMap.isEmpty()) - { - return typeName; - } - if (classNameBiMap.containsKey(typeName)) - { - return classNameBiMap.get(typeName); - } - int dollarIdx = typeName.lastIndexOf('$'); - if (dollarIdx > -1) - { - return map(typeName.substring(0, dollarIdx)) + "$" + typeName.substring(dollarIdx + 1); - } - return typeName; - } - - public String unmap(String typeName) - { - if (classNameBiMap == null || classNameBiMap.isEmpty()) - { - return typeName; - } - - if (classNameBiMap.containsValue(typeName)) - { - return classNameBiMap.inverse().get(typeName); - } - int dollarIdx = typeName.lastIndexOf('$'); - if (dollarIdx > -1) - { - return unmap(typeName.substring(0, dollarIdx)) + "$" + typeName.substring(dollarIdx + 1); - } - return typeName; - } - - - @Override - public String mapMethodName(String owner, String name, String desc) - { - if (classNameBiMap==null || classNameBiMap.isEmpty()) - { - return name; - } - Map methodMap = getMethodMap(owner); - String methodDescriptor = name+desc; - return methodMap!=null && methodMap.containsKey(methodDescriptor) ? methodMap.get(methodDescriptor) : name; - } - - @Override - @Nullable - public String mapSignature(String signature, boolean typeSignature) - { - // JDT decorates some lambdas with this and SignatureReader chokes on it - if (signature != null && signature.contains("!*")) - { - return null; - } - return super.mapSignature(signature, typeSignature); - } - - private Map getRawFieldMap(String className) - { - if (!rawFieldMaps.containsKey(className)) - { - rawFieldMaps.put(className, Maps.newHashMap()); - } - return rawFieldMaps.get(className); - } - - private Map getFieldMap(String className, boolean raw) - { - if (raw) - { - return getRawFieldMap(className); - } - - if (!fieldNameMaps.containsKey(className) && !negativeCacheFields.contains(className)) - { - findAndMergeSuperMaps(className); - if (!fieldNameMaps.containsKey(className)) - { - negativeCacheFields.add(className); - } - - if (DUMP_FIELD_MAPS) - { - FMLLog.log.trace("Field map for {} : {}", className, fieldNameMaps.get(className)); - } - } - return fieldNameMaps.get(className); - } - - private Map getMethodMap(String className) - { - if (!methodNameMaps.containsKey(className) && !negativeCacheMethods.contains(className)) - { - findAndMergeSuperMaps(className); - if (!methodNameMaps.containsKey(className)) - { - negativeCacheMethods.add(className); - } - if (DUMP_METHOD_MAPS) - { - FMLLog.log.trace("Method map for {} : {}", className, methodNameMaps.get(className)); - } - - } - return methodNameMaps.get(className); - } - - private void findAndMergeSuperMaps(String name) - { - try - { - String superName = null; - String[] interfaces = new String[0]; - byte[] classBytes = ClassPatchManager.INSTANCE.getPatchedResource(name, map(name), classLoader); - if (classBytes != null) - { - ClassReader cr = new ClassReader(classBytes); - superName = cr.getSuperName(); - interfaces = cr.getInterfaces(); - } - mergeSuperMaps(name, superName, interfaces); - } - catch (IOException e) - { - FMLLog.log.error("Error getting patched resource:", e); - } - } - public void mergeSuperMaps(String name, @Nullable String superName, String[] interfaces) - { -// System.out.printf("Computing super maps for %s: %s %s\n", name, superName, Arrays.asList(interfaces)); - if (classNameBiMap == null || classNameBiMap.isEmpty()) - { - return; - } - // Skip Object - if (Strings.isNullOrEmpty(superName)) - { - return; - } - - List allParents = ImmutableList.builder().add(superName).addAll(Arrays.asList(interfaces)).build(); - // generate maps for all parent objects - for (String parentThing : allParents) - { - if (!fieldNameMaps.containsKey(parentThing)) - { - findAndMergeSuperMaps(parentThing); - } - } - Map methodMap = Maps.newHashMap(); - Map fieldMap = Maps.newHashMap(); - for (String parentThing : allParents) - { - if (methodNameMaps.containsKey(parentThing)) - { - methodMap.putAll(methodNameMaps.get(parentThing)); - } - if (fieldNameMaps.containsKey(parentThing)) - { - fieldMap.putAll(fieldNameMaps.get(parentThing)); - } - } - if (rawMethodMaps.containsKey(name)) - { - methodMap.putAll(rawMethodMaps.get(name)); - } - if (rawFieldMaps.containsKey(name)) - { - fieldMap.putAll(rawFieldMaps.get(name)); - } - methodNameMaps.put(name, ImmutableMap.copyOf(methodMap)); - fieldNameMaps.put(name, ImmutableMap.copyOf(fieldMap)); -// System.out.printf("Maps: %s %s\n", name, methodMap); - } - - public Set getObfedClasses() - { - return ImmutableSet.copyOf(classNameBiMap.keySet()); - } - - @Nullable - public String getStaticFieldType(String oldType, String oldName, String newType, String newName) - { - String fType = getFieldType(newType, newName); - if (oldType.equals(newType)) - { - return fType; - } - Map newClassMap = fieldDescriptions.computeIfAbsent(newType, k -> Maps.newHashMap()); - newClassMap.put(newName, fType); - return fType; - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/deobf/FMLRemappingAdapter.java b/src/main/java/net/minecraftforge/fml/common/asm/deobf/FMLRemappingAdapter.java deleted file mode 100644 index 700bc9ebf..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/deobf/FMLRemappingAdapter.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm.deobf; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.Handle; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.Remapper; -import org.objectweb.asm.commons.RemappingClassAdapter; -import org.objectweb.asm.commons.RemappingMethodAdapter; - -import java.util.Arrays; -import java.util.List; - -public class FMLRemappingAdapter extends RemappingClassAdapter { - public FMLRemappingAdapter(ClassVisitor cv) - { - super(cv, FMLDeobfuscatingRemapper.INSTANCE); - } - - private static final List META_FACTORIES = Arrays.asList( - new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", - "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;", - false), - new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "altMetafactory", - "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;", - false) - ); - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) - { - if (interfaces == null) - { - interfaces = new String[0]; - } - FMLDeobfuscatingRemapper.INSTANCE.mergeSuperMaps(name, superName, interfaces); - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { - FMLDeobfuscatingRemapper remapper = FMLDeobfuscatingRemapper.INSTANCE; - FieldVisitor fv = cv.visitField(access, - remapper.mapMemberFieldName(className, name, desc), - remapper.mapDesc(desc), remapper.mapSignature(signature, true), - remapper.mapValue(value)); - return createRemappingFieldAdapter(fv); - } - - @Override - protected MethodVisitor createRemappingMethodAdapter(int access, String newDesc, MethodVisitor mv) - { - return new StaticFixingMethodVisitor(access, newDesc, mv, remapper); - } - - private static class StaticFixingMethodVisitor extends RemappingMethodAdapter - { - - public StaticFixingMethodVisitor(int access, String desc, MethodVisitor mv, Remapper remapper) - { - super(access, desc, mv, remapper); - } - - @Override - public void visitFieldInsn(int opcode, String originalType, String originalName, String desc) - { - // This method solves the problem of a static field reference changing type. In all probability it is a - // compatible change, however we need to fix up the desc to point at the new type - String type = remapper.mapType(originalType); - String fieldName = remapper.mapFieldName(originalType, originalName, desc); - String newDesc = remapper.mapDesc(desc); - if (opcode == Opcodes.GETSTATIC && type.startsWith("net/minecraft/") && newDesc.startsWith("Lnet/minecraft/")) - { - String replDesc = FMLDeobfuscatingRemapper.INSTANCE.getStaticFieldType(originalType, originalName, type, fieldName); - if (replDesc != null) - { - newDesc = remapper.mapDesc(replDesc); - } - } - // super.super - if (mv != null) { - mv.visitFieldInsn(opcode, type, fieldName, newDesc); - } - } - - @Override - public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) - { - // Special case lambda metaFactory to get new name - if (META_FACTORIES.contains(bsm)) - { - String owner = Type.getReturnType(desc).getInternalName(); - String odesc = ((Type) bsmArgs[0]).getDescriptor(); // First constant argument is "samMethodType - Signature and return type of method to be implemented by the function object." - name = remapper.mapMethodName(owner, name, odesc); - } - - super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/deobf/LZMAInputSupplier.java b/src/main/java/net/minecraftforge/fml/common/asm/deobf/LZMAInputSupplier.java deleted file mode 100644 index 25603f474..000000000 --- a/src/main/java/net/minecraftforge/fml/common/asm/deobf/LZMAInputSupplier.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.asm.deobf; - -import java.io.IOException; -import java.io.InputStream; - -import LZMA.LzmaInputStream; - -import com.google.common.io.ByteSource; - -public class LZMAInputSupplier extends ByteSource { - private InputStream compressedData; - - public LZMAInputSupplier(InputStream compressedData) - { - this.compressedData = compressedData; - } - - @Override - public InputStream openStream() throws IOException - { - return new LzmaInputStream(this.compressedData); - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java b/src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java deleted file mode 100644 index 5a740d00a..000000000 --- a/src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.discovery.json; - -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -import org.objectweb.asm.Type; - -import com.google.common.base.MoreObjects; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation.EnumHolder; - -//Package private, modders shouldn't access this. Do it through ASMDataTable. -class ASMInfo -{ - String name; - String[] interfaces; - List annotations; - private Map byID; - - public Annotation getSubAnnotation(int id) - { - if (byID == null) - { - byID = Maps.newHashMap(); - annotations.forEach(a -> { if (a.id != null) byID.put(a.id, a); }); - } - return byID.get(id); - } - - @Override - public String toString() - { - return MoreObjects.toStringHelper("") - .add("name", name) - .add("itf", interfaces) - .add("ann", annotations) - .toString(); - } - - public enum TargetType { CLASS, FIELD, METHOD, SUBTYPE }; - public enum ValueType - { - BOOL(Boolean::valueOf, v -> {boolean[] ret = new boolean[v.length]; for (int x = 0; x < v.length; x++) ret[x] = Boolean.parseBoolean(v[x]); return ret; }), - BYTE(Byte::valueOf, v -> {byte[] ret = new byte[v.length]; for (int x = 0; x < v.length; x++) ret[x] = Byte.parseByte(v[x]); return ret; }), - CHAR(x -> x.charAt(0), v -> {char[] ret = new char[v.length]; for (int x = 0; x < v.length; x++) ret[x] = v[x].charAt(0); return ret; }), - SHORT(Short::valueOf, v -> {short[] ret = new short[v.length]; for (int x = 0; x < v.length; x++) ret[x] = Short.parseShort(v[x]); return ret; }), - INT(Integer::valueOf, v -> {int[] ret = new int[v.length]; for (int x = 0; x < v.length; x++) ret[x] = Integer.parseInt(v[x]); return ret; }), - LONG(Long::valueOf, v -> {long[] ret = new long[v.length]; for (int x = 0; x < v.length; x++) ret[x] = Long.parseLong(v[x]); return ret; }), - FLOAT(Float::valueOf, v -> {float[] ret = new float[v.length]; for (int x = 0; x < v.length; x++) ret[x] = Float.parseFloat(v[x]); return ret; }), - DOUBLE(Double::valueOf, v -> {double[] ret = new double[v.length]; for (int x = 0; x < v.length; x++) ret[x] = Double.parseDouble(v[x]); return ret; }), - STRING(x -> x, x -> x), - CLASS(Type::getType, v -> {Type[] ret = new Type[v.length]; for (int x = 0; x < v.length; x++) ret[x] = Type.getType(v[x]); return ret; }), - ENUM(ValueType::getEnumHolder, v -> {List ret = Lists.newArrayList(); for (int x = 0; x < v.length; x++) ret.add(ValueType.getEnumHolder(v[x])); return ret; }), - ANNOTATION(null, null), - NULL(x -> null, x -> null); - - public final Function single; - public final Function array; - - private ValueType(Function single, Function array) - { - this.single = single; - this.array = array; - } - - private static EnumHolder getEnumHolder(String value) - { - int idx = value.lastIndexOf('/'); - if (idx <= 1) - throw new IllegalArgumentException("Can not create a EnumHolder for value: " + value); - String field = value.substring(idx + 1); - value = value.substring(0, idx); - idx = value.indexOf(';'); //Legacy internal name. - value = value.substring(1, idx); - return new EnumHolder(value, field); - } - }; - - static class Annotation - { - TargetType type; - String name; - String target; - Integer id; - ValueHolder value; - Map values; - private Map _values; - - public Map getValues(ASMInfo pool) - { - if (_values == null) - { - _values = Maps.newHashMap(); - if (values != null) - values.forEach((k, v) -> _values.put(k, v.get(pool))); - else - _values.put("value", value == null ? null : value.get(pool)); - } - - return _values; - } - - @Override - public String toString() - { - return MoreObjects.toStringHelper("") - .add("type", type) - .add("name", name) - .add("target", target) - .add("id", id) - .add("value", value) - .toString(); - } - } - - static class ValueHolder - { - ValueType type; - String value; - String[] values; - - private Object _value; - - private ValueType getType() - { - return type == null ? ValueType.STRING : type; - } - - public Object get(ASMInfo pool) - { - if (_value == null) - { - if (values != null) - { - if (type == ValueType.ANNOTATION) - { - List> list = Lists.newArrayList(); - _value = list; - - for (String s : values) - { - Annotation sub = pool.getSubAnnotation(Integer.parseInt(s)); - if (sub == null) - FMLLog.log.error("Invalid Sub-Annotation in Annotation JSON: " + s); - else - list.add(sub.getValues(pool)); - } - } - else - _value = getType().array.apply(values); - } - else - { - if (type == ValueType.ANNOTATION) - { - Annotation sub = pool.getSubAnnotation(Integer.parseInt(value)); - if (sub == null) - FMLLog.log.error("Invalid Sub-Annotation in Annotation JSON: " + value); - else - _value = sub.getValues(pool); - } - else - _value = getType().single.apply(value); - } - } - return _value; - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java b/src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java deleted file mode 100644 index da3c1ce0e..000000000 --- a/src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.discovery.json; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.Map; -import java.util.Map.Entry; - -import org.objectweb.asm.Type; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; - -import net.minecraftforge.fml.common.discovery.json.ASMInfo.Annotation; -import net.minecraftforge.fml.common.discovery.json.ASMInfo.TargetType; - -public class JsonAnnotationLoader -{ - public static final String ANNOTATION_JSON = "META-INF/fml_cache_annotation.json"; - private static final Gson GSON = new GsonBuilder().create(); - private static final java.lang.reflect.Type INFO_TABLE = new TypeToken>(){}.getType(); - - public static Multimap loadJson(InputStream data, ModCandidate candidate, ASMDataTable table) - { - Map map = GSON.fromJson(new InputStreamReader(data, StandardCharsets.UTF_8), INFO_TABLE); - Multimap ret = HashMultimap.create(); - - for (Entry entry : map.entrySet()) - { - //TODO: Java9 Multi-Release Jars, picking the correct class for the current platform. For now we just ignore them. - if (entry.getKey().startsWith("META-INF/")) - continue; - //TODO: Remove in 1.13, some older mods have these in the entries due to FG issue. Basically filter out scala synthetic class. - if (entry.getKey().endsWith("$")) - continue; - - ASMInfo asm_info = entry.getValue(); - if (asm_info.interfaces != null) - { - for (String type : asm_info.interfaces) - { - //Interfaces use internal name, but annotations use source names. See ASMModParser.sendToTable - table.addASMData(candidate, type, asm_info.name, null, null); - ret.put(type, new ASMData(candidate, type, asm_info.name, null, null)); - } - } - - - String owner_name = asm_info.name.replace('/', '.'); - if (asm_info.annotations != null) - { - for (Annotation anno : asm_info.annotations) - { - String name = anno.name.indexOf(';') > 0 ? Type.getType(anno.name).getClassName() : anno.name; - String target = anno.target != null && (anno.type == TargetType.CLASS || anno.type == TargetType.SUBTYPE) ? anno.target.replace('/', '.') : anno.target; - - table.addASMData(candidate, name, owner_name, target, anno.getValues(asm_info)); - ret.put(name, new ASMData(candidate, name, owner_name, target, anno.getValues(asm_info))); - } - } - } - - return ret; - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java b/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java index d94f1c3a1..559fa196c 100644 --- a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java +++ b/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java @@ -19,8 +19,6 @@ package net.minecraftforge.fml.common.event; -import net.minecraft.command.CommandHandler; -import net.minecraft.command.ICommand; import net.minecraft.server.MinecraftServer; /** @@ -36,10 +34,4 @@ public class FMLServerStartingEvent extends ServerLifecycleEvent { super(server); } - - public void registerServerCommand(ICommand command) - { - CommandHandler ch = (CommandHandler) getServer().getCommandManager(); - ch.registerCommand(command); - } } diff --git a/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java b/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java index cd7b7f263..0ad8a305d 100644 --- a/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java +++ b/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java @@ -50,289 +50,6 @@ import com.google.common.collect.ImmutableList; * */ public class ByteBufUtils { - /** - * The number of bytes to write the supplied int using the 7 bit varint encoding. - * - * @param toCount The number to analyse - * @return The number of bytes it will take to write it (maximum of 5) - */ - public static int varIntByteCount(int toCount) - { - return (toCount & 0xFFFFFF80) == 0 ? 1 : ((toCount & 0xFFFFC000) == 0 ? 2 : ((toCount & 0xFFE00000) == 0 ? 3 : ((toCount & 0xF0000000) == 0 ? 4 : 5))); - } - /** - * Read a varint from the supplied buffer. - * - * @param buf The buffer to read from - * @param maxSize The maximum length of bytes to read - * @return The integer - */ - public static int readVarInt(ByteBuf buf, int maxSize) - { - Validate.isTrue(maxSize < 6 && maxSize > 0, "Varint length is between 1 and 5, not %d", maxSize); - int i = 0; - int j = 0; - byte b0; - - do - { - b0 = buf.readByte(); - i |= (b0 & 127) << j++ * 7; - - if (j > maxSize) - { - throw new RuntimeException("VarInt too big"); - } - } - while ((b0 & 128) == 128); - - return i; - } - /** - * An extended length short. Used by custom payload packets to extend size. - * - * @param buf - * @return - */ - public static int readVarShort(ByteBuf buf) - { - int low = buf.readUnsignedShort(); - int high = 0; - if ((low & 0x8000) != 0) - { - low = low & 0x7FFF; - high = buf.readUnsignedByte(); - } - return ((high & 0xFF) << 15) | low; - } - - public static void writeVarShort(ByteBuf buf, int toWrite) - { - int low = toWrite & 0x7FFF; - int high = ( toWrite & 0x7F8000 ) >> 15; - if (high != 0) - { - low = low | 0x8000; - } - buf.writeShort(low); - if (high != 0) - { - buf.writeByte(high); - } - } - /** - * Write an integer to the buffer using variable length encoding. The maxSize constrains - * how many bytes (and therefore the maximum number) that will be written. - * - * @param to The buffer to write to - * @param toWrite The integer to write - * @param maxSize The maximum number of bytes to use - */ - public static void writeVarInt(ByteBuf to, int toWrite, int maxSize) - { - Validate.isTrue(varIntByteCount(toWrite) <= maxSize, "Integer is too big for %d bytes", maxSize); - while ((toWrite & -128) != 0) - { - to.writeByte(toWrite & 127 | 128); - toWrite >>>= 7; - } - - to.writeByte(toWrite); - } - /** - * Read a UTF8 string from the byte buffer. - * It is encoded as [] - * - * @param from The buffer to read from - * @return The string - */ - public static String readUTF8String(ByteBuf from) - { - int len = readVarInt(from,2); - String str = from.toString(from.readerIndex(), len, StandardCharsets.UTF_8); - from.readerIndex(from.readerIndex() + len); - return str; - } - - /** - * Write a String with UTF8 byte encoding to the buffer. - * It is encoded as [] - * @param to the buffer to write to - * @param string The string to write - */ - public static void writeUTF8String(ByteBuf to, String string) - { - byte[] utf8Bytes = string.getBytes(StandardCharsets.UTF_8); - Validate.isTrue(varIntByteCount(utf8Bytes.length) < 3, "The string is too long for this encoding."); - writeVarInt(to, utf8Bytes.length, 2); - to.writeBytes(utf8Bytes); - } - - /** - * Write an {@link ItemStack} using minecraft compatible encoding. - * - * @param to The buffer to write to - * @param stack The itemstack to write - */ - public static void writeItemStack(ByteBuf to, ItemStack stack) - { - PacketBuffer pb = new PacketBuffer(to); - pb.writeItemStack(stack); - } - - /** - * Read an {@link ItemStack} from the byte buffer provided. It uses the minecraft encoding. - * - * @param from The buffer to read from - * @return The itemstack read - */ - public static ItemStack readItemStack(ByteBuf from) - { - PacketBuffer pb = new PacketBuffer(from); - try - { - return pb.readItemStack(); - } - catch (IOException e) - { - // Unpossible? - throw new RuntimeException(e); - } - } - - /** - * Write an {@link NBTTagCompound} to the byte buffer. It uses the minecraft encoding. - * - * @param to The buffer to write to - * @param tag The tag to write - */ - public static void writeTag(ByteBuf to, NBTTagCompound tag) - { - PacketBuffer pb = new PacketBuffer(to); - pb.writeCompoundTag(tag); - } - - /** - * Read an {@link NBTTagCompound} from the byte buffer. It uses the minecraft encoding. - * - * @param from The buffer to read from - * @return The read tag - */ - @Nullable - public static NBTTagCompound readTag(ByteBuf from) - { - PacketBuffer pb = new PacketBuffer(from); - try - { - return pb.readCompoundTag(); - } catch (IOException e) - { - // Unpossible? - throw new RuntimeException(e); - } - } - - /** - * Write a registry entry to the stream. The serialized format is not specified and must not be relied upon. - * Do not use this to write to a file, it is used for client-server communication only. - * @param out the buffer to write to - * @param entry the registry entry - */ - public static > void writeRegistryEntry(@Nonnull ByteBuf out, @Nonnull T entry) - { - ForgeRegistry registry = (ForgeRegistry)GameRegistry.findRegistry(entry.getRegistryType()); - writeUTF8String(out, RegistryManager.ACTIVE.getName(registry).toString()); - writeVarInt(out, registry.getID(entry), 5); - } - - /** - * Read a registry entry from the stream. The same format as in {@link #writeRegistryEntry(ByteBuf, IForgeRegistryEntry)} is used. - * @param in the buffer to read from - * @param registry the registry the entry belongs to - * @return the read registry entry - */ - @Nonnull - public static > T readRegistryEntry(@Nonnull ByteBuf in, @Nonnull IForgeRegistry registry) - { - String registryName = readUTF8String(in); - int id = readVarInt(in, 5); - ResourceLocation expectedRegistryName = RegistryManager.ACTIVE.getName(registry); - - if (!expectedRegistryName.toString().equals(registryName)) - throw new IllegalArgumentException("Registry mismatch: " + registryName + " != " + expectedRegistryName); - - T thing = ((ForgeRegistry)registry).getRaw(id); - if (thing == null) - throw new IllegalArgumentException("Unknown ID " + id + " for registry " + expectedRegistryName + " received."); - - return thing; - } - - /** - * Write multiple registry entries from the same registry to the stream. The serialized format may be more compact than using - * {@link #writeRegistryEntry(ByteBuf, IForgeRegistryEntry)} multiple times. - * @param out the buffer to write to - * @param entries the entries to write - */ - public static > void writeRegistryEntries(@Nonnull ByteBuf out, @Nonnull Collection entries) - { - writeVarInt(out, entries.size(), 5); - - Iterator it = entries.iterator(); - if (it.hasNext()) - { - T first = it.next(); - ForgeRegistry registry = (ForgeRegistry)GameRegistry.findRegistry(first.getRegistryType()); - writeUTF8String(out, RegistryManager.ACTIVE.getName(registry).toString()); - writeVarInt(out, registry.getID(first), 5); - - while (it.hasNext()) - { - int id = registry.getID(it.next()); - if (id == -1) - throw new IllegalArgumentException("Unregistered IForgeRegistryEntry in collection " + entries + "."); - writeVarInt(out, id, 5); - } - } - } - - /** - * Read multiple registry entries from the same registries from the stream. The list of entries must have been written by - * {@link #writeRegistryEntries(ByteBuf, Collection)}. - * @param in the buffer to read from - * @param registry the registry the entries belong to - * @return the immutable list of entries - */ - @Nonnull - public static > List readRegistryEntries(@Nonnull ByteBuf in, @Nonnull IForgeRegistry registry) - { - int size = readVarInt(in, 5); - if (size == 0) - { - return ImmutableList.of(); - } - else - { - String registryName = readUTF8String(in); - ResourceLocation expectedRegistryName = RegistryManager.ACTIVE.getName(registry); - if (!expectedRegistryName.toString().equals(registryName)) - { - throw new IllegalArgumentException("Registry mismatch: " + registryName + " != " + expectedRegistryName); - } - - ImmutableList.Builder b = ImmutableList.builder(); - for (int i = 0; i < size; i++) - { - int id = readVarInt(in, 5); - T thing = ((ForgeRegistry)registry).getRaw(id); - if (thing == null) - throw new IllegalArgumentException("Unknown ID " + id + " for registry " + expectedRegistryName + " received."); - - b.add(thing); - } - return b.build(); - } - } public static String getContentDump(ByteBuf buffer) { diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java b/src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java deleted file mode 100644 index f10ae0dfb..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.embedded.EmbeddedChannel; - -import java.util.Map.Entry; - -import net.minecraft.network.Packet; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.LogicalSide; -import net.minecraftforge.fml.ModThreadContext; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.common.network.FMLOutboundHandler.OutboundTarget; -import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; - -import javax.annotation.Nullable; - -/** - * Utility wrapper around {@link EmbeddedChannel}. Provides some convenience methods - * associated with the specific needs of FML network handling. - * - * @author cpw - * - */ -public class FMLEmbeddedChannel extends EmbeddedChannel { - public FMLEmbeddedChannel(String channelName, LogicalSide source, ChannelHandler... handlers) - { - this(ModThreadContext.get().getActiveContainer(), channelName, source, handlers); - } - public FMLEmbeddedChannel(ModContainer container, String channelName, LogicalSide source, ChannelHandler... handlers) - { - super(handlers); - this.attr(NetworkRegistry.FML_CHANNEL).set(channelName); - this.attr(NetworkRegistry.CHANNEL_SOURCE).set(source); - this.attr(NetworkRegistry.MOD_CONTAINER).setIfAbsent(container); - this.pipeline().addFirst("fml:outbound",new FMLOutboundHandler()); - } - - - /** - * Utility method to generate a regular packet from a custom packet. Basically, it writes the packet through the - * outbound side which should have a message to message codec present (such as {@link FMLIndexedMessageToMessageCodec}, - * transforming from mod packets to standard {@link FMLProxyPacket}s. - * - * This is mostly useful in cases where vanilla expects a packet, such as the TileEntity getDescriptionPacket. - * - * @param object The inbound packet - * @return A Packet suitable for passing to vanilla network code. - */ - public Packet generatePacketFrom(Object object) - { - OutboundTarget outboundTarget = attr(FMLOutboundHandler.FML_MESSAGETARGET).getAndSet(OutboundTarget.NOWHERE); - writeOutbound(object); - Packet pkt = (Packet) outboundMessages().poll(); - attr(FMLOutboundHandler.FML_MESSAGETARGET).set(outboundTarget); - return pkt; - } - - @Nullable - public String findChannelHandlerNameForType(Class type) - { - String targetName = null; - for (Entry entry : pipeline()) - { - if (type.isInstance(entry.getValue())) - { - targetName = entry.getKey(); - break; - } - } - return targetName; - } - - public void cleanAttributes() - { - this.attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(null); - this.attr(NetworkRegistry.NET_HANDLER).set(null); - this.attr(NetworkDispatcher.FML_DISPATCHER).set(null); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java b/src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java deleted file mode 100644 index fad03205f..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network; - -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; - -import java.util.EnumMap; - -import net.minecraft.client.network.NetHandlerPlayClient; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; -import net.minecraftforge.api.distmarker.Dist; - -import javax.annotation.Nullable; - -/** - * An event driven network channel, using {@link FMLNetworkEvent.CustomPacketEvent} and {@link FMLNetworkEvent.CustomNetworkEvent} - * to deliver messages to an event listener. There is one "bus" for each channel, due to the - * impossibility of filtering a bus for specific events. - * - * This event driven system completely wraps the netty code. Mod code deals with FMLProxyPackets directly. It is not - * possible to enhance the netty pipeline, and I would expect highly unexpected results if it were modified reflectively. - * Use a real ChannelHandler if you want to use netty. - * - * @author cpw - * - */ -public class FMLEventChannel { - private EnumMap channels; - private IEventBus eventBus; - - /* - * This is done this way so that the CLIENT specific code in the factory only loads on the client - */ - private enum EventFactory - { - SERVER() - { - @Override - @Nullable - FMLNetworkEvent.CustomPacketEvent make(FMLProxyPacket msg) - { - FMLNetworkEvent.CustomPacketEvent event = null; - if (msg.handler() instanceof NetHandlerPlayServer) - { - NetHandlerPlayServer server = (NetHandlerPlayServer) msg.handler(); - event = new FMLNetworkEvent.ServerCustomPacketEvent(server.getNetworkManager(), msg); - } - return event; - } - }, - CLIENT() - { - @Override - @Nullable - FMLNetworkEvent.CustomPacketEvent make(FMLProxyPacket msg) - { - FMLNetworkEvent.CustomPacketEvent event = null; - if (msg.handler() instanceof NetHandlerPlayClient) - { - NetHandlerPlayClient client = (NetHandlerPlayClient) msg.handler(); - event = new FMLNetworkEvent.ClientCustomPacketEvent(client.getNetworkManager(), msg); - } - else if (msg.handler() instanceof NetHandlerPlayServer) - { - NetHandlerPlayServer server = (NetHandlerPlayServer) msg.handler(); - event = new FMLNetworkEvent.ServerCustomPacketEvent(server.getNetworkManager(), msg); - } - return event; - } - }; - @Nullable - abstract FMLNetworkEvent.CustomPacketEvent make(FMLProxyPacket msg); - } - - private static EventFactory factory = FMLCommonHandler.instance().getSide() == Side.CLIENT ? EventFactory.CLIENT : EventFactory.SERVER; - FMLEventChannel(String name) - { - this.channels = NetworkRegistry.INSTANCE.newChannel(name, new NetworkEventFiringHandler(this)); - this.eventBus = IEventBus.create(); - } - - /** - * Register an event listener with this channel and bus. See {@link SubscribeEvent} - * - * @param object - */ - public void register(Object object) - { - this.eventBus.register(object); - } - - /** - * Unregister an event listener from the bus. - * @param object - */ - public void unregister(Object object) - { - this.eventBus.unregister(object); - } - - void fireRead(FMLProxyPacket msg, ChannelHandlerContext ctx) - { - FMLNetworkEvent.CustomPacketEvent event = factory.make(msg); - if (event != null) - { - this.eventBus.post(event); - if (event.getReply() != null) - { - ctx.channel().attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.REPLY); - ctx.writeAndFlush(event.getReply()).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - } - } - - public void fireUserEvent(Object evt, ChannelHandlerContext ctx) - { - FMLNetworkEvent.CustomNetworkEvent event = new FMLNetworkEvent.CustomNetworkEvent(evt); - this.eventBus.post(event); - } - - /** - * Send a packet to all on the server - * - * @param pkt - */ - public void sendToAll(FMLProxyPacket pkt) - { - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL); - channels.get(Side.SERVER).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Send to a specific player - * - * @param pkt - * @param player - */ - public void sendTo(FMLProxyPacket pkt, EntityPlayerMP player) - { - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER); - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player); - channels.get(Side.SERVER).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Send to all around a point - * @param pkt - * @param point - */ - public void sendToAllAround(FMLProxyPacket pkt, NetworkRegistry.TargetPoint point) - { - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT); - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point); - channels.get(Side.SERVER).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Send to all tracking the point - * The {@code range} field of the {@link NetworkRegistry.TargetPoint} is ignored. - * @param pkt - * @param point - */ - public void sendToAllTracking(FMLProxyPacket pkt, NetworkRegistry.TargetPoint point) - { - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TRACKING_POINT); - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point); - channels.get(Side.SERVER).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Send to all tracking the entity - * This is not equivalent to {@link #sendToAllTracking(FMLProxyPacket, NetworkRegistry.TargetPoint)} - * because entities have different tracking distances based on their type. - * @param pkt - * @param entity - */ - public void sendToAllTracking(FMLProxyPacket pkt, Entity entity) - { - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TRACKING_ENTITY); - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(entity); - channels.get(Side.SERVER).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Send to all in a dimension - * @param pkt - * @param dimensionId - */ - public void sendToDimension(FMLProxyPacket pkt, int dimensionId) - { - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION); - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(dimensionId); - channels.get(Side.SERVER).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Send to the server - * @param pkt - */ - public void sendToServer(FMLProxyPacket pkt) - { - channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER); - channels.get(Side.CLIENT).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java b/src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java deleted file mode 100644 index 490b2d80e..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToMessageCodec; -import io.netty.util.AttributeKey; - -import java.lang.ref.WeakReference; -import java.util.List; - -import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap; -import it.unimi.dsi.fastutil.bytes.Byte2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.Object2ByteMap; -import it.unimi.dsi.fastutil.objects.Object2ByteOpenHashMap; - -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; - -@Sharable -public abstract class FMLIndexedMessageToMessageCodec extends MessageToMessageCodec -{ - private final Byte2ObjectMap> discriminators = new Byte2ObjectOpenHashMap<>(); - private final Object2ByteMap> types = new Object2ByteOpenHashMap<>(); - - /** - * Make this accessible to subclasses - */ - - public static final AttributeKey>> INBOUNDPACKETTRACKER = AttributeKey.valueOf("fml:inboundpacket"); - - @Override - public void handlerAdded(ChannelHandlerContext ctx) throws Exception - { - super.handlerAdded(ctx); - ctx.channel().attr(INBOUNDPACKETTRACKER).set(new ThreadLocal>()); - } - - public FMLIndexedMessageToMessageCodec addDiscriminator(int discriminator, Class type) - { - discriminators.put((byte)discriminator, type); - types.put(type, (byte)discriminator); - return this; - } - - public abstract void encodeInto(ChannelHandlerContext ctx, A msg, ByteBuf target) throws Exception; - - @Override - protected final void encode(ChannelHandlerContext ctx, A msg, List out) throws Exception - { - String channel = ctx.channel().attr(NetworkRegistry.FML_CHANNEL).get(); - Class clazz = msg.getClass(); - if (!types.containsKey(clazz)) - { - throw new RuntimeException("Undefined discriminator for message type " + clazz.getName() + " in channel " + channel); - } - byte discriminator = types.getByte(clazz); - PacketBuffer buffer = new PacketBuffer(Unpooled.buffer()); - buffer.writeByte(discriminator); - encodeInto(ctx, msg, buffer); - FMLProxyPacket proxy = new FMLProxyPacket(buffer, channel); - WeakReference ref = ctx.channel().attr(INBOUNDPACKETTRACKER).get().get(); - FMLProxyPacket old = ref == null ? null : ref.get(); - if (old != null) - { - proxy.setDispatcher(old.getDispatcher()); - } - out.add(proxy); - } - - public abstract void decodeInto(ChannelHandlerContext ctx, ByteBuf source, A msg); - - @Override - protected final void decode(ChannelHandlerContext ctx, FMLProxyPacket msg, List out) throws Exception - { - testMessageValidity(msg); - ByteBuf payload = msg.payload().duplicate(); - if (payload.readableBytes() < 1) - { - FMLLog.log.error("The FMLIndexedCodec has received an empty buffer on channel {}, likely a result of a LAN server issue. Pipeline parts : {}", ctx.channel().attr(NetworkRegistry.FML_CHANNEL), ctx.pipeline().toString()); - } - byte discriminator = payload.readByte(); - Class clazz = discriminators.get(discriminator); - if(clazz == null) - { - throw new NullPointerException("Undefined message for discriminator " + discriminator + " in channel " + msg.channel()); - } - A newMsg = clazz.newInstance(); - ctx.channel().attr(INBOUNDPACKETTRACKER).get().set(new WeakReference(msg)); - decodeInto(ctx, payload.slice(), newMsg); - out.add(newMsg); - payload.release(); - } - - /** - * Called to verify the message received. This can be used to hard disconnect in case of an unexpected packet, - * say due to a weird protocol mismatch. Use with caution. - * @param msg - */ - protected void testMessageValidity(FMLProxyPacket msg) - { - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception - { - FMLLog.log.error("FMLIndexedMessageCodec exception caught", cause); - super.exceptionCaught(ctx, cause); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java b/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java deleted file mode 100644 index 68b530eb5..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network; - -import java.util.Set; - -import com.google.common.collect.ImmutableSet; - -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetworkManager; -import net.minecraft.network.play.INetHandlerPlayClient; -import net.minecraft.network.play.INetHandlerPlayServer; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; -import net.minecraftforge.api.distmarker.Dist; - -public class FMLNetworkEvent extends Event { - private final T handler; - private final NetworkManager manager; - private final Class type; - - FMLNetworkEvent(T thing, Class type, NetworkManager manager) - { - this.handler = thing; - this.type = type; - this.manager = manager; - } - - public Class getHandlerType() - { - return getType(); - } - - public T getHandler() - { - return handler; - } - - public NetworkManager getManager() - { - return manager; - } - - public Class getType() - { - return type; - } - - /** - * Fired at the client when a client connects to a server - */ - public static class ClientConnectedToServerEvent extends FMLNetworkEvent { - private final boolean isLocal; - private final String connectionType; - public ClientConnectedToServerEvent(NetworkManager manager, String connectionType) - { - super((INetHandlerPlayClient) manager.getNetHandler(), INetHandlerPlayClient.class, manager); - this.isLocal = manager.isLocalChannel(); - this.connectionType = connectionType; - } - - public boolean isLocal() - { - return isLocal; - } - - public String getConnectionType() - { - return connectionType; - } - } - - /** - * Fired at the server when a client connects to the server. - * - * @author cpw - * - */ - public static class ServerConnectionFromClientEvent extends FMLNetworkEvent { - private final boolean isLocal; - public ServerConnectionFromClientEvent(NetworkManager manager) - { - super((INetHandlerPlayServer) manager.getNetHandler(), INetHandlerPlayServer.class, manager); - this.isLocal = manager.isLocalChannel(); - } - - public boolean isLocal() - { - return isLocal; - } - } - /** - * Fired at the server when a client disconnects. - * - * @author cpw - * - */ - public static class ServerDisconnectionFromClientEvent extends FMLNetworkEvent { - public ServerDisconnectionFromClientEvent(NetworkManager manager) - { - super((INetHandlerPlayServer) manager.getNetHandler(), INetHandlerPlayServer.class, manager); - } - } - /** - * Fired at the client when the client is disconnected from the server. - * - * @author cpw - * - */ - public static class ClientDisconnectionFromServerEvent extends FMLNetworkEvent { - public ClientDisconnectionFromServerEvent(NetworkManager manager) - { - super((INetHandlerPlayClient) manager.getNetHandler(), INetHandlerPlayClient.class, manager); - } - } - - /** - * Fired when the REGISTER/UNREGISTER for custom channels is received. - * - * @author cpw - * - * @param The side - */ - public static class CustomPacketRegistrationEvent extends FMLNetworkEvent { - private final ImmutableSet registrations; - private final String operation; - private final Side side; - public CustomPacketRegistrationEvent(NetworkManager manager, Set registrations, String operation, Side side, Class type) - { - super(type.cast(manager.getNetHandler()), type, manager); - this.registrations = ImmutableSet.copyOf(registrations); - this.side = side; - this.operation = operation; - } - - public ImmutableSet getRegistrations() - { - return registrations; - } - - public String getOperation() - { - return operation; - } - - public Side getSide() - { - return side; - } - } - - public static abstract class CustomPacketEvent extends FMLNetworkEvent { - private final FMLProxyPacket packet; - - private FMLProxyPacket reply; - CustomPacketEvent(S thing, Class type, NetworkManager manager, FMLProxyPacket packet) - { - super(thing, type, manager); - this.packet = packet; - } - - public abstract Side side(); - - /** - * The packet that generated the event - */ - public FMLProxyPacket getPacket() - { - return packet; - } - - /** - * Set this packet to reply to the originator - */ - public FMLProxyPacket getReply() - { - return reply; - } - - public void setReply(FMLProxyPacket reply) - { - this.reply = reply; - } - } - - /** - * Fired when a custom packet is received on the client for the channel - * @author cpw - * - */ - public static class ClientCustomPacketEvent extends CustomPacketEvent { - public ClientCustomPacketEvent(NetworkManager manager, FMLProxyPacket packet) - { - super((INetHandlerPlayClient) manager.getNetHandler(), INetHandlerPlayClient.class, manager, packet); - } - - @Override - public Side side() - { - return Side.CLIENT; - } - } - - /** - * Fired when a custom packet is received at the server for the channel - * @author cpw - * - */ - public static class ServerCustomPacketEvent extends CustomPacketEvent { - public ServerCustomPacketEvent(NetworkManager manager, FMLProxyPacket packet) - { - super((INetHandlerPlayServer) manager.getNetHandler(), INetHandlerPlayServer.class, manager, packet); - } - - @Override - public Side side() - { - return Side.SERVER; - } - } - - /** - * Fired when a custom event, such as {@link NetworkHandshakeEstablished} is fired for the channel - * - * @author cpw - * - */ - public static class CustomNetworkEvent extends net.minecraftforge.eventbus.api.Event - { - private final Object wrappedEvent; - public CustomNetworkEvent(Object wrappedEvent) - { - this.wrappedEvent = wrappedEvent; - } - - public Object getWrappedEvent() - { - return wrappedEvent; - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java b/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java deleted file mode 100644 index 7f4d2f2ee..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network; - -public class FMLNetworkException extends RuntimeException -{ - private static final long serialVersionUID = 1L; - - public FMLNetworkException(Exception e) - { - super(e); - } - - public FMLNetworkException() - { - } - - public FMLNetworkException(String string) - { - super(string); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java b/src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java deleted file mode 100644 index 1aabe8c95..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.util.AttributeKey; - -import java.util.List; -import java.util.Set; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.network.NetworkManager; -import net.minecraft.server.management.PlayerChunkMap; -import net.minecraft.server.management.PlayerChunkMapEntry; -import net.minecraft.util.math.MathHelper; -import net.minecraft.world.WorldServer; -import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.network.NetworkRegistry.TargetPoint; -import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; -import net.minecraftforge.api.distmarker.Dist; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; - -import javax.annotation.Nullable; - -public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter { - public static final AttributeKey FML_MESSAGETARGET = AttributeKey.valueOf("fml:outboundTarget"); - public static final AttributeKey FML_MESSAGETARGETARGS = AttributeKey.valueOf("fml:outboundTargetArgs"); - public enum OutboundTarget { - /** - * The packet is sent nowhere. It will be on the {@link EmbeddedChannel#outboundMessages()} Queue. - * - * @author cpw - * - */ - NOWHERE(Sets.immutableEnumSet(Side.CLIENT, Side.SERVER)) - { - @Override - public void validateArgs(Object args) - { - // NOOP - } - - @Override - @Nullable - public List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet) - { - return null; - } - - }, - /** - * The packet is sent to the {@link NetworkDispatcher} supplied as an argument. - * - * @author cpw - * - */ - DISPATCHER(Sets.immutableEnumSet(Side.SERVER)) - { - @Override - public void validateArgs(Object args) - { - if (!(args instanceof NetworkDispatcher)) - { - throw new RuntimeException("DISPATCHER expects a NetworkDispatcher"); - } - } - - @Override - public List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet) - { - return ImmutableList.of((NetworkDispatcher)args); - } - }, - /** - * The packet is sent to the originator of the packet. This requires the inbound packet - * to have it's originator information set. - * - * @author cpw - * - */ - REPLY(Sets.immutableEnumSet(Side.SERVER)) - { - @Override - public void validateArgs(Object args) - { - // NOOP - } - - @Override - public List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet) - { - return ImmutableList.of(packet.getDispatcher()); - } - }, - /** - * The packet is sent to the {@link EntityPlayerMP} supplied as an argument. - * - * @author cpw - * - */ - PLAYER(Sets.immutableEnumSet(Side.SERVER)) - { - @Override - public void validateArgs(Object args) - { - if (!(args instanceof EntityPlayerMP)) - { - throw new RuntimeException("PLAYER target expects a Player arg"); - } - } - @Override - public List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet) - { - EntityPlayerMP player = (EntityPlayerMP) args; - NetworkDispatcher dispatcher = (player == null || player instanceof FakePlayer) ? null : player.connection.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - return dispatcher == null ? ImmutableList.of() : ImmutableList.of(dispatcher); - } - }, - /** - * The packet is dispatched to all players connected to the server. - * @author cpw - * - */ - ALL(Sets.immutableEnumSet(Side.SERVER)) - { - @Override - public void validateArgs(Object args) - { - } - @Override - public List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet) - { - ImmutableList.Builder builder = ImmutableList.builder(); - for (EntityPlayerMP player : FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayers()) - { - NetworkDispatcher dispatcher = player.connection.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - if (dispatcher != null) builder.add(dispatcher); - } - return builder.build(); - } - }, - /** - * The packet is sent to all players in the dimension identified by the integer argument. - * @author cpw - * - */ - DIMENSION(Sets.immutableEnumSet(Side.SERVER)) - { - @Override - public void validateArgs(Object args) - { - if (!(args instanceof Integer)) - { - throw new RuntimeException("DIMENSION expects an integer argument"); - } - } - @Override - public List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet) - { - int dimension = (Integer)args; - ImmutableList.Builder builder = ImmutableList.builder(); - for (EntityPlayerMP player : FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayers()) - { - if (dimension == player.dimension) - { - NetworkDispatcher dispatcher = player.connection.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - // Null dispatchers may exist for fake players - skip them - if (dispatcher != null) builder.add(dispatcher); - } - } - return builder.build(); - } - }, - /** - * The packet is sent to all players within range of the {@link TargetPoint} argument supplied. - * - * @author cpw - * - */ - ALLAROUNDPOINT(Sets.immutableEnumSet(Side.SERVER)) - { - @Override - public void validateArgs(Object args) - { - if (!(args instanceof TargetPoint)) - { - throw new RuntimeException("ALLAROUNDPOINT expects a TargetPoint argument"); - } - } - - @Override - public List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet) - { - TargetPoint tp = (TargetPoint)args; - ImmutableList.Builder builder = ImmutableList.builder(); - for (EntityPlayerMP player : FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayers()) - { - if (player.dimension == tp.dimension) - { - double d4 = tp.x - player.posX; - double d5 = tp.y - player.posY; - double d6 = tp.z - player.posZ; - - if (d4 * d4 + d5 * d5 + d6 * d6 < tp.range * tp.range) - { - NetworkDispatcher dispatcher = player.connection.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - if (dispatcher != null) builder.add(dispatcher); - } - } - } - return builder.build(); - } - }, - /** - * The packet is sent to all players that are watching the Chunk containing the supplied {@link TargetPoint}. - * The {@code range} field of the {@link TargetPoint} is ignored. - */ - TRACKING_POINT(Sets.immutableEnumSet(Side.SERVER)) - { - @Override - public void validateArgs(Object args) - { - if (!(args instanceof TargetPoint)) - { - throw new RuntimeException("TRACKING_POINT expects a TargetPoint argument"); - } - } - - @Nullable - @Override - public List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet) - { - TargetPoint tp = (TargetPoint)args; - WorldServer world = DimensionManager.getWorld(tp.dimension); - if (world == null) - { - return ImmutableList.of(); - } - - PlayerChunkMapEntry entry = world.getPlayerChunkMap().getEntry(MathHelper.floor(tp.x) >> 4, MathHelper.floor(tp.z) >> 4); - if (entry == null) - { - return ImmutableList.of(); - } - - ImmutableList.Builder builder = ImmutableList.builder(); - for (EntityPlayerMP player : entry.getWatchingPlayers()) - { - NetworkDispatcher dispatcher = player.connection.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - if (dispatcher != null) builder.add(dispatcher); - } - return builder.build(); - } - }, - /** - * The packet is sent to all players tracking the supplied {@link Entity}. This is different from {@link #TRACKING_POINT} because Entities - * can have different tracking distances depending on their type. - */ - TRACKING_ENTITY(Sets.immutableEnumSet(Side.SERVER)) - { - @Override - public void validateArgs(Object args) - { - if (!(args instanceof Entity)) - { - throw new RuntimeException("TRACKING_ENTITY expects an Entity argument"); - } - } - - @Nullable - @Override - public List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet) - { - Entity e = (Entity)args; - Set players = FMLCommonHandler.instance().getMinecraftServerInstance() - .getWorld(e.dimension).getEntityTracker().getTrackingPlayers(e); - - ImmutableList.Builder builder = ImmutableList.builder(); - for (EntityPlayer player : players) - { - NetworkDispatcher dispatcher = ((EntityPlayerMP) player).connection.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - if (dispatcher != null) builder.add(dispatcher); - } - return builder.build(); - } - }, - /** - * The packet is sent to the server this client is currently conversing with. - * @author cpw - * - */ - TOSERVER(Sets.immutableEnumSet(Side.CLIENT)) - { - @Override - public void validateArgs(Object args) - { - } - @Override - public List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet) - { - NetworkManager clientConnection = FMLCommonHandler.instance().getClientToServerNetworkManager(); - return clientConnection == null || clientConnection.channel().attr(NetworkDispatcher.FML_DISPATCHER).get() == null ? ImmutableList.of() : ImmutableList.of(clientConnection.channel().attr(NetworkDispatcher.FML_DISPATCHER).get()); - } - }; - - private OutboundTarget(ImmutableSet sides) - { - this.allowed = sides; - } - public final ImmutableSet allowed; - public abstract void validateArgs(Object args); - @Nullable - public abstract List selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet); - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception - { - if (!(msg instanceof FMLProxyPacket)) - { - return; - } - FMLProxyPacket pkt = (FMLProxyPacket) msg; - OutboundTarget outboundTarget; - Object args = null; - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - // INTERNAL message callback - let it pass out - if (dispatcher != null) - { - ctx.write(msg, promise); - return; - } - - outboundTarget = ctx.channel().attr(FML_MESSAGETARGET).get(); - Side channelSide = ctx.channel().attr(NetworkRegistry.CHANNEL_SOURCE).get(); - if (outboundTarget != null && outboundTarget.allowed.contains(channelSide)) - { - args = ctx.channel().attr(FML_MESSAGETARGETARGS).get(); - outboundTarget.validateArgs(args); - } - else if (channelSide == Side.CLIENT) - { - outboundTarget = OutboundTarget.TOSERVER; - } - else - { - throw new FMLNetworkException("Packet arrived at the outbound handler without a valid target!"); - } - - List dispatchers = outboundTarget.selectNetworks(args, ctx, pkt); - - // This will drop the messages into the output queue at the embedded channel - if (dispatchers == null) - { - ctx.write(msg, promise); - return; - } - for (NetworkDispatcher targetDispatcher : dispatchers) - { - pkt.payload().retain(); - targetDispatcher.sendProxy(pkt); - } - pkt.payload().release(); - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java b/src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java deleted file mode 100644 index b753432eb..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network; - -import net.minecraftforge.api.distmarker.Dist; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A method annotated with this will be called when a remote network connection is offered. - * The method should have two parameters, of types Map and {@link Side}. It should return a boolean - * true indicating that the remote party is acceptable, or false if not. - * - *

- * When the method is invoked, the map will contain String keys and values listing all mods and their versions present. - * The side represents the side of the remote party. So if you're on the server, it'll be CLIENT, and vice versa. - * - *

- * This method will be invoked both when querying the status of the remote server, and when connecting to the remote server. - * - *

- * NOTE: the server will not be setup at any point when this method is called. Do not try and interact with the server - * or the client in any way, except to accept or reject the list of mods. - * - * @author cpw - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface NetworkCheckHandler -{ - -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java b/src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java deleted file mode 100644 index b88bd62ac..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network; - -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; - -import org.apache.logging.log4j.Level; - -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; - -/** - * Use this handler as the only thing in your channel, to receive network events - * whenever your channel receives a message. - * Note: it will not forward on to other handlers. - * - * @author cpw - * - */ -@Sharable -public class NetworkEventFiringHandler extends SimpleChannelInboundHandler { - private FMLEventChannel eventChannel; - - NetworkEventFiringHandler(FMLEventChannel fmlEventChannel) - { - this.eventChannel = fmlEventChannel; - } - - @Override - protected void channelRead0(ChannelHandlerContext ctx, FMLProxyPacket msg) throws Exception - { - eventChannel.fireRead(msg,ctx); - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception - { - eventChannel.fireUserEvent(evt,ctx); - } - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception - { - FMLLog.log.error("NetworkEventFiringHandler exception", cause); - super.exceptionCaught(ctx, cause); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java b/src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java deleted file mode 100644 index f037893d3..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network; - -import net.minecraft.network.INetHandler; -import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; -import net.minecraftforge.api.distmarker.Dist; - -/** - * This message is sent through all channels affected by a currently occurring handshake. It is guaranteed to - * be able to send a custom payload packet, however, interaction with minecraft and world state is NOT assured - * as it is likely this is fired on a netty handler thread, not a world processing thread. - * - * If you wish to send an outbound message through your channel, bind the {@link FMLOutboundHandler#FML_MESSAGETARGET} - * property of your channel to the supplied dispatcher. - * @author cpw - * - */ -public class NetworkHandshakeEstablished { - public final NetworkDispatcher dispatcher; - public final Side side; - public final INetHandler netHandler; - - public NetworkHandshakeEstablished(NetworkDispatcher dispatcher, INetHandler netHandler, Side origin) - { - this.netHandler = netHandler; - this.dispatcher = dispatcher; - this.side = origin; - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java b/src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java deleted file mode 100644 index b605c8113..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToMessageCodec; -import io.netty.util.AttributeKey; - -import java.util.Collection; -import java.util.EnumMap; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.inventory.Container; -import net.minecraft.network.INetHandler; -import net.minecraft.world.World; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.LogicalSide; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; -import net.minecraftforge.fml.common.network.internal.NetworkModHolder; -import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; - -import javax.annotation.Nullable; - -/** - * @author cpw - * - */ -public class NetworkRegistry -{ - public static final NetworkRegistry INSTANCE = new NetworkRegistry(); - private EnumMap> channels = Maps.newEnumMap(LogicalSide.class); - private Map registry = Maps.newHashMap(); - private Map serverGuiHandlers = Maps.newHashMap(); - private Map clientGuiHandlers = Maps.newHashMap(); - - /** - * Set in the {@link ChannelHandlerContext} - */ - public static final AttributeKey FML_CHANNEL = AttributeKey.valueOf("fml:channelName"); - public static final AttributeKey CHANNEL_SOURCE = AttributeKey.valueOf("fml:channelSource"); - public static final AttributeKey MOD_CONTAINER = AttributeKey.valueOf("fml:modContainer"); - public static final AttributeKey NET_HANDLER = AttributeKey.valueOf("fml:netHandler"); - - // Version 1: ServerHello only contains this value as a byte - // Version 2: ServerHello additionally contains a 4 byte (int) dimension for the logging in client - public static final byte FML_PROTOCOL = 2; - - private NetworkRegistry() - { - channels.put(LogicalSide.CLIENT, Maps.newConcurrentMap()); - channels.put(LogicalSide.SERVER, Maps.newConcurrentMap()); - } - - /** - * Represents a target point for the ALLROUNDPOINT target. - * - * @author cpw - * - */ - public static class TargetPoint { - /** - * A target point - * @param dimension The dimension to target - * @param x The X coordinate - * @param y The Y coordinate - * @param z The Z coordinate - * @param range The range - */ - public TargetPoint(int dimension, double x, double y, double z, double range) - { - this.x = x; - this.y = y; - this.z = z; - this.range = range; - this.dimension = dimension; - } - public final double x; - public final double y; - public final double z; - public final double range; - public final int dimension; - } - /** - * Create a new synchronous message channel pair based on netty. - * - * There are two preconstructed models available: - *

    - *
  • {@link #newSimpleChannel(String)} provides {@link SimpleNetworkWrapper}, a simple implementation of a netty handler, suitable for those who don't - * wish to dive too deeply into netty. - *
  • {@link #newEventDrivenChannel(String)} (String)} provides {@link FMLEventChannel} an event driven implementation, with lower level - * access to the network data stream, for those with advanced bitbanging needs that don't wish to poke netty too hard. - *
  • Alternatively, simply use the netty features provided here and implement the full power of the netty stack. - *
- * - * There are two channels created : one for each logical Dist (conDistred as the source of an outbound message) - * The returned map will contain a value for each logical Dist, though both will only be working in the - * integrated server case. - * - * The channel expects to read and write using {@link FMLProxyPacket}. All operation is synchronous, as the - * asynchronous behaviour occurs at a lower level in netty. - * - * The first handler in the pipeline is special and should not be removed or moved from the head - it transforms - * packets from the outbound of this pipeline into custom packets, based on the current {@link AttributeKey} value - * {@link FMLOutboundHandler#FML_MESSAGETARGET} and {@link FMLOutboundHandler#FML_MESSAGETARGETARGS} set on the channel. - * For the client to server channel (source Dist : CLIENT) this is fixed as "TOSERVER". For SERVER to CLIENT packets, - * several possible values exist. - * - * Mod Messages should be transformed using a something akin to a {@link MessageToMessageCodec}. FML provides - * a utility codec, {@link FMLIndexedMessageToMessageCodec} that transforms from {@link FMLProxyPacket} to a mod - * message using a message discriminator byte. This is optional, but highly recommended for use. - * - * Note also that the handlers supplied need to be {@link ChannelHandler.Sharable} - they are injected into two - * channels. - * - * @param name - * @param handlers - * @return - */ - public EnumMap newChannel(String name, ChannelHandler... handlers) - { - if (channels.get(LogicalSide.CLIENT).containsKey(name) || channels.get(LogicalSide.SERVER).containsKey(name) || name.startsWith("MC|") || name.startsWith("\u0001") || name.startsWith("FML")) - { - throw new RuntimeException("That channel is already registered"); - } - EnumMap result = Maps.newEnumMap(LogicalSide.class); - - for (LogicalSide side : LogicalSide.values()) - { - FMLEmbeddedChannel channel = new FMLEmbeddedChannel(name, side, handlers); - channels.get(side).put(name,channel); - result.put(side, channel); - } - return result; - } - - /** - * Construct a new {@link SimpleNetworkWrapper} for the channel. - * - * @param name The name of the channel - * @return A {@link SimpleNetworkWrapper} for handling this channel - */ - public SimpleNetworkWrapper newSimpleChannel(String name) - { - return new SimpleNetworkWrapper(name); - } - /** - * Construct a new {@link FMLEventChannel} for the channel. - * - * @param name The name of the channel - * @return An {@link FMLEventChannel} for handling this channel - */ - public FMLEventChannel newEventDrivenChannel(String name) - { - return new FMLEventChannel(name); - } - /** - * INTERNAL Create a new channel pair with the specified name and channel handlers. - * This is used internally in forge and FML - * - * @param container The container to associate the channel with - * @param name The name for the channel - * @param handlers Some {@link ChannelHandler} for the channel - * @return an {@link EnumMap} of the pair of channels. keys are {@link Dist}. There will always be two entries. - */ - public EnumMap newChannel(ModContainer container, String name, ChannelHandler... handlers) - { - if (channels.get(Dist.CLIENT).containsKey(name) || channels.get(Dist.DEDICATED_SERVER).containsKey(name) || name.startsWith("MC|") || name.startsWith("\u0001") || (name.startsWith("FML") && !("FML".equals(container.getModId())))) - { - throw new RuntimeException("That channel is already registered"); - } - EnumMap result = Maps.newEnumMap(LogicalSide.class); - - for (LogicalSide Dist : LogicalSide.values()) - { - FMLEmbeddedChannel channel = new FMLEmbeddedChannel(container, name, Dist, handlers); - channels.get(Dist).put(name,channel); - result.put(Dist, channel); - } - return result; - } - - public FMLEmbeddedChannel getChannel(String name, Dist source) - { - return channels.get(source).get(name); - } - /** - * Register an {@link IGuiHandler} for the supplied mod object. - * - * @param mod The mod to handle GUIs for - * @param handler A handler for creating GUI related objects - */ - public void registerGuiHandler(Object mod, IGuiHandler handler) - { - ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod); - if (mc == null) - { - FMLLog.log.error("Mod of type {} attempted to register a gui network handler during a construction phase", mod.getClass().getName()); - throw new RuntimeException("Invalid attempt to create a GUI during mod construction. Use an EventHandler instead"); - } - serverGuiHandlers.put(mc, handler); - clientGuiHandlers.put(mc, handler); - } - - /** - * INTERNAL method for accessing the Gui registry - * @param mc Mod Container - * @param player Player - * @param modGuiId guiId - * @param world World - * @param x X coord - * @param y Y coord - * @param z Z coord - * @return The server Dist GUI object (An instance of {@link Container}) - */ - @Nullable - public Container getRemoteGuiContainer(ModContainer mc, EntityPlayerMP player, int modGuiId, World world, int x, int y, int z) - { - IGuiHandler handler = serverGuiHandlers.get(mc); - - if (handler != null) - { - return (Container)handler.getServerGuiElement(modGuiId, player, world, x, y, z); - } - else - { - return null; - } - } - - /** - * INTERNAL method for accessing the Gui registry - * @param mc Mod Container - * @param player Player - * @param modGuiId guiId - * @param world World - * @param x X coord - * @param y Y coord - * @param z Z coord - * @return The client Dist GUI object (An instance of {@link net.minecraft.client.gui.Gui}) - */ - @Nullable - public Object getLocalGuiContainer(ModContainer mc, EntityPlayer player, int modGuiId, World world, int x, int y, int z) - { - IGuiHandler handler = clientGuiHandlers.get(mc); - return handler.getClientGuiElement(modGuiId, player, world, x, y, z); - } - - /** - * Is there a channel with this name on this Dist? - * @param channelName The name - * @param source the Dist - * @return if there's a channel - */ - public boolean hasChannel(String channelName, Dist source) - { - return channels.get(source).containsKey(channelName); - } - - /** - * INTERNAL method for registering a mod as a network capable thing - * @param fmlModContainer The fml mod container - * @param clazz a class - * @param remoteVersionRange the acceptable remote range - * @param asmHarvestedData internal data - */ -/* - public void register(ModContainer fmlModContainer, Class clazz, @Nullable String remoteVersionRange, ASMDataTable asmHarvestedData) - { - NetworkModHolder networkModHolder = new NetworkModHolder(fmlModContainer, clazz, remoteVersionRange, asmHarvestedData); - registry.put(fmlModContainer, networkModHolder); - networkModHolder.testVanillaAcceptance(); - } -*/ - -/* - public boolean isVanillaAccepted(Dist from) - { - return registry.values().stream() - .allMatch(mod -> mod.acceptsVanilla(from)); - } - - public Collection getRequiredMods(Dist from) - { - return registry.values().stream() - .filter(mod -> !mod.acceptsVanilla(from)) - .map(mod -> mod.getContainer().getModId()) - .sorted() - .collect(Collectors.toList()); - } -*/ - - public Map registry() - { - return ImmutableMap.copyOf(registry); - } - - /** - * All the valid channel names for a Dist - * @param Dist the Dist - * @return the set of channel names - */ - public Set channelNamesFor(Dist Dist) - { - return channels.get(Dist).keySet(); - } - - /** - * INTERNAL fire a handshake to all channels - * @param networkDispatcher The dispatcher firing - * @param origin which Dist the dispatcher is on - */ - public void fireNetworkHandshake(NetworkDispatcher networkDispatcher, Dist origin) - { -/* - NetworkHandshakeEstablished handshake = new NetworkHandshakeEstablished(networkDispatcher, networkDispatcher.getNetHandler(), origin); - for (FMLEmbeddedChannel channel : channels.get(origin).values()) - { - channel.attr(FMLOutboundHandler.FML_MESSAGETARGET).set(OutboundTarget.DISPATCHER); - channel.attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(networkDispatcher); - channel.pipeline().fireUserEventTriggered(handshake); - } -*/ - } - - public void cleanAttributes() - { - channels.values().forEach(map -> map.values().forEach(FMLEmbeddedChannel::cleanAttributes)); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java b/src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java index 95cf4dc01..f3406d125 100644 --- a/src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java +++ b/src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java @@ -30,7 +30,6 @@ import io.netty.channel.SimpleChannelInboundHandler; import java.util.Iterator; import java.util.List; -import org.apache.logging.log4j.Level; import net.minecraft.network.EnumPacketDirection; import net.minecraft.network.NettyVarint21FrameDecoder; @@ -38,10 +37,12 @@ import net.minecraft.network.NettyVarint21FrameEncoder; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fml.common.FMLLog; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class PacketLoggingHandler { + private static final Logger LOGGER = LogManager.getLogger(); public static void register(NetworkManager manager) { ChannelPipeline pipeline = manager.channel().pipeline(); @@ -56,7 +57,7 @@ public class PacketLoggingHandler { PacketBuffer buf = new PacketBuffer(Unpooled.buffer()); msg.writePacketData(buf); - FMLLog.log.debug("{} {}:\n{}", prefix, msg.getClass().getSimpleName(), ByteBufUtils.getContentDump(buf)); + LOGGER.debug("{} {}:\n{}", prefix, msg.getClass().getSimpleName(), ByteBufUtils.getContentDump(buf)); ctx.fireChannelRead(msg); } }); @@ -70,7 +71,7 @@ public class PacketLoggingHandler { PacketBuffer buf = new PacketBuffer(Unpooled.buffer()); ((Packet)msg).writePacketData(buf); - FMLLog.log.debug("{} {}:\n{}", prefix, msg.getClass().getSimpleName(), ByteBufUtils.getContentDump(buf)); + LOGGER.debug("{} {}:\n{}", prefix, msg.getClass().getSimpleName(), ByteBufUtils.getContentDump(buf)); } ctx.write(msg, promise); } @@ -90,7 +91,7 @@ public class PacketLoggingHandler { ByteBuf pkt = (ByteBuf)itr.next(); pkt.markReaderIndex(); - FMLLog.log.debug("{}:\n{}", prefix, ByteBufUtils.getContentDump(pkt)); + LOGGER.debug("{}:\n{}", prefix, ByteBufUtils.getContentDump(pkt)); pkt.resetReaderIndex(); } } @@ -102,7 +103,7 @@ public class PacketLoggingHandler protected void encode(ChannelHandlerContext context, ByteBuf input, ByteBuf output) throws Exception { input.markReaderIndex(); - FMLLog.log.debug("{}:\n{}", prefix, ByteBufUtils.getContentDump(input)); + LOGGER.debug("{}:\n{}", prefix, ByteBufUtils.getContentDump(input)); input.resetReaderIndex(); super.encode(context, input, output); } diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java deleted file mode 100644 index be15867e6..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - @Override - public void update() { - // This method is called every tick (20 times per second normally) - - if (world.isRemote) { - // We only do something on the client so we don't have to bother about client-server communication. - // The effect that we want to have (blinking the block) is client-side as well. - updateCounter(); - counter -= lastCount * 3; - if (counter <= 0) { - lit = !lit; - counter = 400; // This is 20 seconds. Rate increases if more mods are near - world.markBlockRangeForRenderUpdate(getPos(), getPos()); - } - } - } - - private void updateCounter() { - -package net.minecraftforge.fml.common.network.handshake; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; - -import java.nio.charset.StandardCharsets; -import java.util.Set; - -import net.minecraft.network.NetworkManager; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; -import net.minecraftforge.fml.relauncher.Side; - -import com.google.common.collect.ImmutableSet; - -public class ChannelRegistrationHandler extends SimpleChannelInboundHandler { - @Override - protected void channelRead0(ChannelHandlerContext ctx, FMLProxyPacket msg) throws Exception - { - Side side = msg.getTarget(); - NetworkManager manager = msg.getOrigin(); - if (msg.channel().equals("REGISTER") || msg.channel().equals("UNREGISTER")) - { - byte[] data = new byte[msg.payload().readableBytes()]; - msg.payload().readBytes(data); - String channels = new String(data, StandardCharsets.UTF_8); - String[] split = channels.split("\0"); - Set channelSet = ImmutableSet.copyOf(split); - FMLCommonHandler.instance().fireNetRegistrationEvent(manager, channelSet, msg.channel(), side); - msg.payload().release(); - } - else - { - ctx.fireChannelRead(msg); - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception - { - FMLLog.log.error("ChannelRegistrationHandler exception", cause); - super.exceptionCaught(ctx, cause); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java deleted file mode 100644 index 397d10524..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.handshake; - -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; - -import java.util.Map; -import java.util.function.Consumer; - -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.util.concurrent.Futures; - -import net.minecraft.client.Minecraft; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.handshake.FMLHandshakeMessage.ServerHello; -import net.minecraftforge.fml.common.network.internal.FMLMessage; -import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; -import net.minecraftforge.registries.ForgeRegistry; -import net.minecraftforge.registries.GameData; - -/** - * Packet handshake sequence manager- client side (responding to remote server) - * - * Flow: - * 1. Wait for server hello. (START). Move to HELLO state. - * 2. Receive Server Hello. Send customchannel registration. Send Client Hello. Send our modlist. Move to WAITINGFORSERVERDATA state. - * 3. Receive server modlist. Send ack if acceptable, else send nack and exit error. Receive server IDs. Move to COMPLETE state. Send ack. - * - * @author cpw - * - */ -enum FMLHandshakeClientState implements IHandshakeState -{ - START - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - cons.accept(HELLO); - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - dispatcher.clientListenForServerHandshake(); - } - }, - HELLO - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - boolean isVanilla = msg == null; - if (isVanilla) - { - cons.accept(DONE); - } - else - { - cons.accept(WAITINGSERVERDATA); - } - // write our custom packet registration, always - ctx.writeAndFlush(FMLHandshakeMessage.makeCustomChannelRegistration(NetworkRegistry.INSTANCE.channelNamesFor(Side.CLIENT))); - if (isVanilla) - { - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - dispatcher.abortClientHandshake("VANILLA"); - // VANILLA login - return; - } - - ServerHello serverHelloPacket = (FMLHandshakeMessage.ServerHello)msg; - FMLLog.log.info("Server protocol version {}", Integer.toHexString(serverHelloPacket.protocolVersion())); - if (serverHelloPacket.protocolVersion() > 1) - { - // Server sent us an extra dimension for the logging in player - stash it for retrieval later - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - dispatcher.setOverrideDimension(serverHelloPacket.overrideDim()); - } - ctx.writeAndFlush(new FMLHandshakeMessage.ClientHello()).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - ctx.writeAndFlush(new FMLHandshakeMessage.ModList(Loader.instance().getActiveModList())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - }, - - WAITINGSERVERDATA - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - String modRejections = FMLNetworkHandler.checkModList((FMLHandshakeMessage.ModList) msg, Side.SERVER); - if (modRejections != null) - { - cons.accept(ERROR); - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - dispatcher.rejectHandshake(modRejections); - return; - } - if (!ctx.channel().attr(NetworkDispatcher.IS_LOCAL).get()) - { - cons.accept(WAITINGSERVERCOMPLETE); - } - else - { - cons.accept(PENDINGCOMPLETE); - } - ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck(ordinal())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - - } - }, - WAITINGSERVERCOMPLETE - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - FMLHandshakeMessage.RegistryData pkt = (FMLHandshakeMessage.RegistryData)msg; - Map snap = ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).get(); - if (snap == null) - { - snap = Maps.newHashMap(); - ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).set(snap); - } - - ForgeRegistry.Snapshot entry = new ForgeRegistry.Snapshot(); - entry.ids.putAll(pkt.getIdMap()); - entry.dummied.addAll(pkt.getDummied()); - entry.overrides.putAll(pkt.getOverrides()); - snap.put(pkt.getName(), entry); - - if (pkt.hasMore()) - { - cons.accept(WAITINGSERVERCOMPLETE); - FMLLog.log.debug("Received Mod Registry mapping for {}: {} IDs {} overrides {} dummied", pkt.getName(), entry.ids.size(), entry.overrides.size(), entry.dummied.size()); - return; - } - - ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).set(null); - - //Do the remapping on the Client's thread in case things are reset while the client is running. We stall the network thread until this is finished which can cause the IO thread to time out... Not sure if we can do anything about that. - final Map snap_f = snap; - Multimap locallyMissing = Futures.getUnchecked(Minecraft.getMinecraft().addScheduledTask(() -> GameData.injectSnapshot(snap_f, false, false))); - if (!locallyMissing.isEmpty()) - { - cons.accept(ERROR); - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - dispatcher.rejectHandshake("Fatally missing registry entries"); - FMLLog.log.fatal("Failed to connect to server: there are {} missing registry items", locallyMissing.size()); - locallyMissing.asMap().forEach((key, value) -> FMLLog.log.debug("Missing {} Entries: {}", key, value)); - return; - } - cons.accept(PENDINGCOMPLETE); - ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck(ordinal())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - }, - PENDINGCOMPLETE - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - cons.accept(COMPLETE); - ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck(ordinal())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - }, - COMPLETE - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - cons.accept(DONE); - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - dispatcher.completeClientHandshake(); - FMLMessage.CompleteHandshake complete = new FMLMessage.CompleteHandshake(Side.CLIENT); - ctx.fireChannelRead(complete); - ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck(ordinal())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - }, - DONE - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - if (msg instanceof FMLHandshakeMessage.HandshakeReset) - { - cons.accept(HELLO); - //Run the revert on the client thread in case things are currently running to prevent race conditions while rebuilding the registries. - Minecraft.getMinecraft().addScheduledTask(GameData::revertToFrozen); - } - } - }, - ERROR - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - } - }; -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java deleted file mode 100644 index 01dead93f..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.handshake; - -import net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; - -public class FMLHandshakeCodec extends FMLIndexedMessageToMessageCodec { - public FMLHandshakeCodec() - { - addDiscriminator((byte)0, FMLHandshakeMessage.ServerHello.class); - addDiscriminator((byte)1, FMLHandshakeMessage.ClientHello.class); - addDiscriminator((byte)2, FMLHandshakeMessage.ModList.class); - addDiscriminator((byte)3, FMLHandshakeMessage.RegistryData.class); - addDiscriminator((byte)-1, FMLHandshakeMessage.HandshakeAck.class); - addDiscriminator((byte)-2, FMLHandshakeMessage.HandshakeReset.class); - } - @Override - public void encodeInto(ChannelHandlerContext ctx, FMLHandshakeMessage msg, ByteBuf target) throws Exception - { - msg.toBytes(target); - } - - @Override - public void decodeInto(ChannelHandlerContext ctx, ByteBuf source, FMLHandshakeMessage msg) - { - msg.fromBytes(source); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java deleted file mode 100644 index 96fd3fbed..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.handshake; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.common.network.ByteBufUtils; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; -import net.minecraftforge.registries.ForgeRegistry; - -import com.google.common.base.Joiner; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -public abstract class FMLHandshakeMessage { - public static FMLProxyPacket makeCustomChannelRegistration(Set channels) - { - String salutation = Joiner.on('\0').join(Iterables.concat(Arrays.asList("FML|HS","FML", "FML|MP"),channels)); - FMLProxyPacket proxy = new FMLProxyPacket(new PacketBuffer(Unpooled.wrappedBuffer(salutation.getBytes(StandardCharsets.UTF_8))), "REGISTER"); - return proxy; - } - public static class ServerHello extends FMLHandshakeMessage { - private byte serverProtocolVersion; - private int overrideDimension; - public ServerHello() - { - // noargs for the proto - } - public ServerHello(int overrideDim) - { - this.overrideDimension = overrideDim; - } - - @Override - public void toBytes(ByteBuf buffer) - { - buffer.writeByte(NetworkRegistry.FML_PROTOCOL); - buffer.writeInt(overrideDimension); - } - - @Override - public void fromBytes(ByteBuf buffer) - { - serverProtocolVersion = buffer.readByte(); - // Extended dimension support during login - if (serverProtocolVersion > 1) - { - overrideDimension = buffer.readInt(); - FMLLog.log.debug("Server FML protocol version {}, 4 byte dimension received {}", serverProtocolVersion, overrideDimension); - } - else - { - FMLLog.log.info("Server FML protocol version {}, no additional data received", serverProtocolVersion); - } - } - - public byte protocolVersion() - { - return serverProtocolVersion; - } - - public int overrideDim() { - return overrideDimension; - } - } - public static class ClientHello extends FMLHandshakeMessage { - private byte serverProtocolVersion; - @Override - public void toBytes(ByteBuf buffer) - { - buffer.writeByte(NetworkRegistry.FML_PROTOCOL); - } - - @Override - public void fromBytes(ByteBuf buffer) - { - serverProtocolVersion = buffer.readByte(); - } - - public byte protocolVersion() - { - return serverProtocolVersion; - } - } - public static class ModList extends FMLHandshakeMessage { - public ModList() - { - - } - public ModList(List modList) - { - for (ModContainer mod : modList) - { - modTags.put(mod.getModId(), mod.getVersion()); - } - } - private Map modTags = Maps.newHashMap(); - - @Override - public void toBytes(ByteBuf buffer) - { - super.toBytes(buffer); - ByteBufUtils.writeVarInt(buffer, modTags.size(), 2); - for (Map.Entry modTag: modTags.entrySet()) - { - ByteBufUtils.writeUTF8String(buffer, modTag.getKey()); - ByteBufUtils.writeUTF8String(buffer, modTag.getValue()); - } - } - - @Override - public void fromBytes(ByteBuf buffer) - { - super.fromBytes(buffer); - int modCount = ByteBufUtils.readVarInt(buffer, 2); - for (int i = 0; i < modCount; i++) - { - modTags.put(ByteBufUtils.readUTF8String(buffer), ByteBufUtils.readUTF8String(buffer)); - } - } - - public String modListAsString() - { - return Joiner.on(',').withKeyValueSeparator("@").join(modTags); - } - - public int modListSize() - { - return modTags.size(); - } - public Map modList() - { - return modTags; - } - - @Override - public String toString(Class> side) - { - return super.toString(side)+":"+modTags.size()+" mods"; - } - } - - public static class RegistryData extends FMLHandshakeMessage - { - public RegistryData() - { - - } - - public RegistryData(boolean hasMore, ResourceLocation name, ForgeRegistry.Snapshot entry) - { - this.hasMore = hasMore; - this.name = name; - this.ids = entry.ids; - this.dummied = entry.dummied; - this.overrides = entry.overrides; - } - - private boolean hasMore; - private ResourceLocation name; - private Map ids; - private Set dummied; - private Map overrides; - - @Override - public void fromBytes(ByteBuf buffer) - { - this.hasMore = buffer.readBoolean(); - this.name = new ResourceLocation(ByteBufUtils.readUTF8String(buffer)); - - int length = ByteBufUtils.readVarInt(buffer, 3); - ids = Maps.newHashMap(); - - for (int i = 0; i < length; i++) - { - ids.put(new ResourceLocation(ByteBufUtils.readUTF8String(buffer)), ByteBufUtils.readVarInt(buffer, 3)); - } - - length = ByteBufUtils.readVarInt(buffer, 3); - dummied = Sets.newHashSet(); - - for (int i = 0; i < length; i++) - { - dummied.add(new ResourceLocation(ByteBufUtils.readUTF8String(buffer))); - } - - length = ByteBufUtils.readVarInt(buffer, 3); - overrides = Maps.newHashMap(); - - for (int i = 0; i < length; i++) - { - overrides.put(new ResourceLocation(ByteBufUtils.readUTF8String(buffer)), ByteBufUtils.readUTF8String(buffer)); - } - } - - @Override - public void toBytes(ByteBuf buffer) - { - buffer.writeBoolean(this.hasMore); - ByteBufUtils.writeUTF8String(buffer, this.name.toString()); - - ByteBufUtils.writeVarInt(buffer, ids.size(), 3); - for (Entry entry: ids.entrySet()) - { - ByteBufUtils.writeUTF8String(buffer, entry.getKey().toString()); - ByteBufUtils.writeVarInt(buffer, entry.getValue(), 3); - } - - ByteBufUtils.writeVarInt(buffer, dummied.size(), 3); - for (ResourceLocation entry: dummied) - { - ByteBufUtils.writeUTF8String(buffer, entry.toString()); - } - - ByteBufUtils.writeVarInt(buffer, overrides.size(), 3); - for (Entry entry: overrides.entrySet()) - { - ByteBufUtils.writeUTF8String(buffer, entry.getKey().toString()); - ByteBufUtils.writeUTF8String(buffer, entry.getValue().toString()); - } - } - - public Map getIdMap() - { - return ids; - } - - public Set getDummied() - { - return dummied; - } - - public Map getOverrides() - { - return overrides; - } - - public ResourceLocation getName() - { - return this.name; - } - - public boolean hasMore() - { - return this.hasMore; - } - - @Override - public String toString(Class> side) - { - return super.toString(side) + ":"+ids.size()+" mappings"; - } - } - public static class HandshakeAck extends FMLHandshakeMessage { - int phase; - public HandshakeAck() {} - HandshakeAck(int phase) - { - this.phase = phase; - } - @Override - public void fromBytes(ByteBuf buffer) - { - phase = buffer.readByte(); - } - - @Override - public void toBytes(ByteBuf buffer) - { - buffer.writeByte(phase); - } - @Override - public String toString(Class> side) - { - return super.toString(side) + ":{"+phase+"}"; - } - } - public static class HandshakeReset extends FMLHandshakeMessage { - public HandshakeReset() {} - } - public void fromBytes(ByteBuf buffer) - { - } - - public void toBytes(ByteBuf buffer) - { - } - - public String toString(Class> side) - { - return getClass().getName().substring(getClass().getName().lastIndexOf('$')); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java deleted file mode 100644 index f8a13cb8d..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.handshake; - -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; - -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.function.Consumer; - -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.internal.FMLMessage; -import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.registries.ForgeRegistry; -import net.minecraftforge.registries.RegistryManager; - -enum FMLHandshakeServerState implements IHandshakeState -{ - START - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - cons.accept(HELLO); - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - int overrideDim = dispatcher.serverInitiateHandshake(); - ctx.writeAndFlush(FMLHandshakeMessage.makeCustomChannelRegistration(NetworkRegistry.INSTANCE.channelNamesFor(Side.SERVER))).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - ctx.writeAndFlush(new FMLHandshakeMessage.ServerHello(overrideDim)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - }, - HELLO - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - // Hello packet first - if (msg instanceof FMLHandshakeMessage.ClientHello) - { - FMLLog.log.info("Client protocol version {}", Integer.toHexString(((FMLHandshakeMessage.ClientHello)msg).protocolVersion())); - return; - } - - FMLHandshakeMessage.ModList client = (FMLHandshakeMessage.ModList)msg; - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); - dispatcher.setModList(client.modList()); - FMLLog.log.info("Client attempting to join with {} mods : {}", client.modListSize(), client.modListAsString()); - String modRejections = FMLNetworkHandler.checkModList(client, Side.CLIENT); - if (modRejections != null) - { - cons.accept(ERROR); - dispatcher.rejectHandshake(modRejections); - return; - } - cons.accept(WAITINGCACK); - ctx.writeAndFlush(new FMLHandshakeMessage.ModList(Loader.instance().getActiveModList())); - } - }, - WAITINGCACK - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - cons.accept(COMPLETE); - if (!ctx.channel().attr(NetworkDispatcher.IS_LOCAL).get()) - { - Map snapshot = RegistryManager.ACTIVE.takeSnapshot(false); - Iterator> itr = snapshot.entrySet().iterator(); - while (itr.hasNext()) - { - Entry e = itr.next(); - ctx.writeAndFlush(new FMLHandshakeMessage.RegistryData(itr.hasNext(), e.getKey(), e.getValue())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - } - ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck(ordinal())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - NetworkRegistry.INSTANCE.fireNetworkHandshake(ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(), Side.SERVER); - } - }, - COMPLETE - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - cons.accept(DONE); - // Poke the client - ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck(ordinal())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - FMLMessage.CompleteHandshake complete = new FMLMessage.CompleteHandshake(Side.SERVER); - ctx.fireChannelRead(complete); - } - }, - DONE - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - } - }, - ERROR - { - @Override - public void accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg, Consumer cons) - { - } - }; -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java deleted file mode 100644 index 86da0938d..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.handshake; - -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; - -public class HandshakeInjector extends ChannelOutboundHandlerAdapter { - - private NetworkDispatcher dispatcher; - public HandshakeInjector(NetworkDispatcher networkDispatcher) - { - this.dispatcher = networkDispatcher; - } - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception - { - if (msg instanceof FMLProxyPacket) - { - this.dispatcher.sendProxy((FMLProxyPacket) msg); - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java deleted file mode 100644 index 273747573..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.handshake; - -import net.minecraftforge.fml.common.FMLLog; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.util.AttributeKey; - -public class HandshakeMessageHandler & IHandshakeState> extends SimpleChannelInboundHandler { - private static final AttributeKey> STATE = AttributeKey.valueOf("fml:handshake-state"); - private final AttributeKey fmlHandshakeState; - private final S initialState; - private final S errorState; - private final Class stateType; - - @SuppressWarnings("unchecked") - public HandshakeMessageHandler(Class stateType) - { - fmlHandshakeState = (AttributeKey) ((Object)STATE); - initialState = Enum.valueOf(stateType, "START"); - errorState = Enum.valueOf(stateType, "ERROR"); - this.stateType = stateType; - } - @Override - protected void channelRead0(ChannelHandlerContext ctx, FMLHandshakeMessage msg) throws Exception - { - S state = ctx.channel().attr(fmlHandshakeState).get(); - FMLLog.log.debug("{}: {}->{}:{}", stateType.getSimpleName(), msg.toString(stateType), state.getClass().getName().substring(state.getClass().getName().lastIndexOf('.')+1), state); - state.accept(ctx, msg, s -> - { - FMLLog.log.debug(" Next: {}", s.name()); - ctx.channel().attr(fmlHandshakeState).set(s); - }); - } - - @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception - { - ctx.channel().attr(fmlHandshakeState).set(initialState); - } - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception - { - S state = ctx.channel().attr(fmlHandshakeState).get(); - FMLLog.log.debug("{}: null->{}:{}", stateType.getSimpleName(), state.getClass().getName().substring(state.getClass().getName().lastIndexOf('.')+1), state); - state.accept(ctx, null, s -> - { - FMLLog.log.debug(" Next: {}", s.name()); - ctx.channel().attr(fmlHandshakeState).set(s); - }); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception - { - FMLLog.log.error("HandshakeMessageHandler exception", cause); - ctx.channel().attr(fmlHandshakeState).set(errorState); - super.exceptionCaught(ctx, cause); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java deleted file mode 100644 index 471b6b0e1..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.handshake; - -import io.netty.channel.ChannelHandlerContext; - -import java.util.function.Consumer; - -import javax.annotation.Nullable; - -public interface IHandshakeState { - /** - * Accepts FML handshake message for this state, and if needed - switches to another handshake state - * using the provided consumer. - * - * The consumer allows to set new state before sending any messages to avoid race conditions. - */ - void accept(ChannelHandlerContext ctx, @Nullable FMLHandshakeMessage msg, Consumer cons); -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java deleted file mode 100644 index a986127ab..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.handshake; - -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOutboundHandler; -import io.netty.channel.ChannelPromise; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; - -import java.io.IOException; -import java.net.SocketAddress; -import java.nio.channels.ClosedChannelException; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.EnumConnectionState; -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.network.NetworkManager; -import net.minecraft.network.Packet; -import net.minecraft.network.PacketBuffer; -import net.minecraft.network.play.INetHandlerPlayClient; -import net.minecraft.network.play.client.CPacketCustomPayload; -import net.minecraft.network.play.server.SPacketJoinGame; -import net.minecraft.network.play.server.SPacketCustomPayload; -import net.minecraft.network.play.server.SPacketDisconnect; -import net.minecraft.server.management.PlayerList; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.TextComponentString; -import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.network.FMLNetworkEvent; -import net.minecraftforge.fml.common.network.FMLNetworkException; -import net.minecraftforge.fml.common.network.FMLOutboundHandler; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.PacketLoggingHandler; -import net.minecraftforge.fml.common.network.internal.FMLMessage; -import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; -import net.minecraftforge.fml.network.ConnectionType; -import net.minecraftforge.registries.ForgeRegistry; - -// TODO build test suites to validate the behaviour of this stuff and make it less annoyingly magical -public class NetworkDispatcher extends SimpleChannelInboundHandler> implements ChannelOutboundHandler { - private static boolean DEBUG_HANDSHAKE = Boolean.parseBoolean(System.getProperty("fml.debugNetworkHandshake", "false")); - private static enum ConnectionState { - OPENING, AWAITING_HANDSHAKE, HANDSHAKING, HANDSHAKECOMPLETE, FINALIZING, CONNECTED - } - - public static NetworkDispatcher get(NetworkManager manager) - { - return manager.channel().attr(FML_DISPATCHER).get(); - } - - public static NetworkDispatcher allocAndSet(NetworkManager manager) - { - NetworkDispatcher net = new NetworkDispatcher(manager); - manager.channel().attr(FML_DISPATCHER).getAndSet(net); - return net; - } - - public static NetworkDispatcher allocAndSet(NetworkManager manager, PlayerList scm) - { - NetworkDispatcher net = new NetworkDispatcher(manager, scm); - manager.channel().attr(FML_DISPATCHER).getAndSet(net); - return net; - } - - public static final AttributeKey FML_DISPATCHER = AttributeKey.valueOf("fml:dispatcher"); - public static final AttributeKey IS_LOCAL = AttributeKey.valueOf("fml:isLocal"); - public static final AttributeKey> FML_GAMEDATA_SNAPSHOT = AttributeKey.valueOf("fml:gameDataSnapshot"); - public final NetworkManager manager; - private final PlayerList scm; - private EntityPlayerMP player; - private ConnectionState state; - private ConnectionType connectionType; - private final Side side; - private final EmbeddedChannel handshakeChannel; - private NetHandlerPlayServer serverHandler; - private INetHandler netHandler; - private Map modList = Collections.emptyMap(); - private int overrideLoginDim; - - public NetworkDispatcher(NetworkManager manager) - { - super(false); - this.manager = manager; - this.scm = null; - this.side = Side.CLIENT; - this.handshakeChannel = new EmbeddedChannel(new HandshakeInjector(this), new ChannelRegistrationHandler(), new FMLHandshakeCodec(), new HandshakeMessageHandler(FMLHandshakeClientState.class)); - this.handshakeChannel.attr(FML_DISPATCHER).set(this); - this.handshakeChannel.attr(NetworkRegistry.CHANNEL_SOURCE).set(Side.SERVER); - this.handshakeChannel.attr(NetworkRegistry.FML_CHANNEL).set("FML|HS"); - this.handshakeChannel.attr(IS_LOCAL).set(manager.isLocalChannel()); - if (DEBUG_HANDSHAKE) - PacketLoggingHandler.register(manager); - } - - public NetworkDispatcher(NetworkManager manager, PlayerList scm) - { - super(false); - this.manager = manager; - this.scm = scm; - this.side = Side.SERVER; - this.handshakeChannel = new EmbeddedChannel(new HandshakeInjector(this), new ChannelRegistrationHandler(), new FMLHandshakeCodec(), new HandshakeMessageHandler(FMLHandshakeServerState.class)); - this.handshakeChannel.attr(FML_DISPATCHER).set(this); - this.handshakeChannel.attr(NetworkRegistry.CHANNEL_SOURCE).set(Side.CLIENT); - this.handshakeChannel.attr(NetworkRegistry.FML_CHANNEL).set("FML|HS"); - this.handshakeChannel.attr(IS_LOCAL).set(manager.isLocalChannel()); - if (DEBUG_HANDSHAKE) - PacketLoggingHandler.register(manager); - } - - public void serverToClientHandshake(EntityPlayerMP player) - { - this.player = player; - Boolean fml = this.manager.channel().attr(net.minecraftforge.fml.network.NetworkRegistry.FML_MARKER).get(); - if (fml != null && fml) - { - //FML on client, send server hello - //TODO: Make this cleaner as it uses netty magic 0.o - insertIntoChannel(); - } - else - { - serverInitiateHandshake(); - FMLLog.log.info("Connection received without FML marker, assuming vanilla."); - insertIntoChannel(); - this.completeServerSideConnection(ConnectionType.VANILLA); - } - } - - protected void setModList(Map modList) - { - this.modList = modList; - } - - private void insertIntoChannel() - { - this.manager.channel().config().setAutoRead(false); - // Insert ourselves into the pipeline - this.manager.channel().pipeline().addBefore("packet_handler", "fml:packet_handler", this); - if (this.state != null) { - FMLLog.log.info("Opening channel which already seems to have a state set. This is a vanilla connection. Handshake handler will stop now"); - this.manager.channel().config().setAutoRead(true); - return; - } - FMLLog.log.trace("Handshake channel activating"); - this.state = ConnectionState.OPENING; - // send ourselves as a user event, to kick the pipeline active - this.handshakeChannel.pipeline().fireUserEventTriggered(this); - this.manager.channel().config().setAutoRead(true); - } - - public void clientToServerHandshake() - { - insertIntoChannel(); - } - - int serverInitiateHandshake() - { - // Send mod salutation to the client - // This will be ignored by vanilla clients - this.state = ConnectionState.AWAITING_HANDSHAKE; - // Need to start the handler here, so we can send custompayload packets - serverHandler = new NetHandlerPlayServer(scm.getServerInstance(), manager, player) - { - @Override - public void update() - { - if (NetworkDispatcher.this.state == ConnectionState.FINALIZING) - { - completeServerSideConnection(ConnectionType.MODDED); - } - // FORGE: sometimes the netqueue will tick while login is occurring, causing an NPE. We shouldn't tick until the connection is complete - if (this.player.connection != this) return; - super.update(); - } - }; - this.netHandler = serverHandler; - // NULL the play server here - we restore it further on. If not, there are packets sent before the login - player.connection = null; - // manually for the manager into the PLAY state, so we can send packets later - this.manager.setConnectionState(EnumConnectionState.PLAY); - - // Return the dimension the player is in, so it can be pre-sent to the client in the ServerHello v2 packet - // Requires some hackery to the serverconfigmanager and stuff for this to work - NBTTagCompound playerNBT = scm.getPlayerNBT(player); - if (playerNBT!=null) - { - int dimension = playerNBT.getInteger("Dimension"); - if (DimensionManager.isDimensionRegistered(dimension)) - { - return dimension; - } - } - return 0; - } - - void clientListenForServerHandshake() - { - manager.setConnectionState(EnumConnectionState.PLAY); - //FMLCommonHandler.instance().waitForPlayClient(); - this.netHandler = FMLCommonHandler.instance().getClientPlayHandler(); - this.state = ConnectionState.AWAITING_HANDSHAKE; - } - - private void completeClientSideConnection(ConnectionType type) - { - this.connectionType = type; - FMLLog.log.info("[{}] Client side {} connection established", Thread.currentThread().getName(), this.connectionType.name().toLowerCase(Locale.ENGLISH)); - this.state = ConnectionState.CONNECTED; - MinecraftForge.EVENT_BUS.post(new FMLNetworkEvent.ClientConnectedToServerEvent(manager, this.connectionType.name())); - } - - private synchronized void completeServerSideConnection(ConnectionType type) - { - this.connectionType = type; - FMLLog.log.info("[{}] Server side {} connection established", Thread.currentThread().getName(), this.connectionType.name().toLowerCase(Locale.ENGLISH)); - this.state = ConnectionState.CONNECTED; - if (DEBUG_HANDSHAKE) - manager.closeChannel(new TextComponentString("Handshake Complete review log file for details.")); - scm.initializeConnectionToPlayer(manager, player, serverHandler); - } - - @Override - protected void channelRead0(ChannelHandlerContext ctx, Packet msg) throws Exception - { - boolean handled = false; - if (msg instanceof CPacketCustomPayload) - { - handled = handleServerSideCustomPacket((CPacketCustomPayload) msg, ctx); - } - else if (msg instanceof SPacketCustomPayload) - { - handled = handleClientSideCustomPacket((SPacketCustomPayload)msg, ctx); - } - else if (state != ConnectionState.CONNECTED && state != ConnectionState.HANDSHAKECOMPLETE) - { - handled = handleVanilla(msg); - } - if (!handled) - { - ctx.fireChannelRead(msg); - } - } - - private boolean handleVanilla(Packet msg) - { - if (state == ConnectionState.AWAITING_HANDSHAKE && msg instanceof SPacketJoinGame) - { - handshakeChannel.pipeline().fireUserEventTriggered(msg); - } - else - { - FMLLog.log.info("Unexpected packet during modded negotiation - assuming vanilla or keepalives : {}", msg.getClass().getName()); - } - return false; - } - - public INetHandler getNetHandler() - { - return netHandler; - } - - /** - * The mod list returned by this method is in no way reliable because it is provided by the client - * - * @return a map that will contain String keys and values listing all mods and their versions - */ - public Map getModList() - { - return Collections.unmodifiableMap(modList); - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception - { - if (evt instanceof ConnectionType && side == Side.SERVER) - { - FMLLog.log.info("Timeout occurred, assuming a vanilla client"); - kickVanilla(); - } - } - - private void kickVanilla() - { - kickWithMessage("This is modded. No modded response received. Bye!"); - } - - private void kickWithMessage(String message) - { - FMLLog.log.error("NetworkDirection Disconnect: {}", message); - final TextComponentString TextComponentString = new TextComponentString(message); - if (side == Side.CLIENT) - { - manager.closeChannel(TextComponentString); - } - else - { - manager.sendPacket(new SPacketDisconnect(TextComponentString), new GenericFutureListener>() - { - @Override - public void operationComplete(Future result) - { - manager.closeChannel(TextComponentString); - } - }, (GenericFutureListener>[])null); - } - manager.channel().config().setAutoRead(false); - } - - private MultiPartCustomPayload multipart = null; - - private boolean handleClientSideCustomPacket(SPacketCustomPayload msg, ChannelHandlerContext context) - { - String channelName = msg.getChannelName(); - if ("FML|MP".equals(channelName)) - { - boolean result = handleMultiPartCustomPacket(msg, context); - if (result) - { - msg.getBufferData().release(); - } - return result; - } - if ("FML|HS".equals(channelName) || "REGISTER".equals(channelName) || "UNREGISTER".equals(channelName)) - { - FMLProxyPacket proxy = new FMLProxyPacket(msg); - proxy.setDispatcher(this); - handshakeChannel.writeInbound(proxy); - // forward any messages into the regular channel - for (Object push : handshakeChannel.inboundMessages()) - { - List messageResult = FMLNetworkHandler.forwardHandshake((FMLMessage.CompleteHandshake)push, this, Side.CLIENT); - for (FMLProxyPacket result: messageResult) - { - result.setTarget(Side.CLIENT); - result.payload().resetReaderIndex(); - context.fireChannelRead(result); - } - } - handshakeChannel.inboundMessages().clear(); - return true; - } - else if (NetworkRegistry.INSTANCE.hasChannel(channelName, Side.CLIENT)) - { - FMLProxyPacket proxy = new FMLProxyPacket(msg); - proxy.setDispatcher(this); - context.fireChannelRead(proxy); - return true; - } - return false; - } - - private boolean handleMultiPartCustomPacket(SPacketCustomPayload msg, ChannelHandlerContext context) - { - try - { - if (multipart == null) - { - multipart = new MultiPartCustomPayload(msg.getBufferData()); - } - else - { - multipart.processPart(msg.getBufferData()); - } - } - catch (IOException e) - { - this.kickWithMessage(e.getMessage()); - multipart = null; - return true; - } - if (multipart.isComplete()) - { - boolean result = handleClientSideCustomPacket(multipart, context); - multipart = null; - return result; - } - else - { - return true; // Haven't received all so return till we have. - } - } - - private boolean handleServerSideCustomPacket(CPacketCustomPayload msg, ChannelHandlerContext context) - { - if (state == ConnectionState.AWAITING_HANDSHAKE) - { - synchronized (this) { // guard from other threads changing the state on us - if (state == ConnectionState.AWAITING_HANDSHAKE) { - state = ConnectionState.HANDSHAKING; - } - } - } - String channelName = msg.getChannelName(); - if ("FML|HS".equals(channelName) || "REGISTER".equals(channelName) || "UNREGISTER".equals(channelName)) - { - FMLProxyPacket proxy = new FMLProxyPacket(msg); - proxy.setDispatcher(this); - handshakeChannel.writeInbound(proxy); - for (Object push : handshakeChannel.inboundMessages()) - { - List messageResult = FMLNetworkHandler.forwardHandshake((FMLMessage.CompleteHandshake)push, this, Side.SERVER); - for (FMLProxyPacket result: messageResult) - { - result.setTarget(Side.SERVER); - result.payload().resetReaderIndex(); - context.fireChannelRead(result); - } - } - handshakeChannel.inboundMessages().clear(); - return true; - } - else if (NetworkRegistry.INSTANCE.hasChannel(channelName, Side.SERVER)) - { - FMLProxyPacket proxy = new FMLProxyPacket(msg); - proxy.setDispatcher(this); - context.fireChannelRead(proxy); - return true; - } - return false; - } - - public void sendProxy(FMLProxyPacket msg) - { - if (!manager.isChannelOpen()) - msg = msg.copy(); - manager.sendPacket(msg); - } - - public void rejectHandshake(String result) - { - kickWithMessage(result); - } - - @Override - public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception - { - ctx.bind(localAddress, promise); - } - - @Override - public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) throws Exception - { - ctx.connect(remoteAddress, localAddress, promise); - } - - @Override - public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception - { - if (side == Side.CLIENT) - { - MinecraftForge.EVENT_BUS.post(new FMLNetworkEvent.ClientDisconnectionFromServerEvent(manager)); - } - else - { - MinecraftForge.EVENT_BUS.post(new FMLNetworkEvent.ServerDisconnectionFromClientEvent(manager)); - } - cleanAttributes(ctx); - ctx.disconnect(promise); - } - - @Override - public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception - { - if (side == Side.CLIENT) - { - MinecraftForge.EVENT_BUS.post(new FMLNetworkEvent.ClientDisconnectionFromServerEvent(manager)); - } - else - { - MinecraftForge.EVENT_BUS.post(new FMLNetworkEvent.ServerDisconnectionFromClientEvent(manager)); - } - cleanAttributes(ctx); - ctx.close(promise); - } - - @Override - @Deprecated - public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception - { - ctx.deregister(promise); - } - - @Override - public void read(ChannelHandlerContext ctx) throws Exception - { - ctx.read(); - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception - { - if (msg instanceof FMLProxyPacket) - { - if (side == Side.CLIENT) - { - //Client to server large packets are not supported to prevent client being bad. - ctx.write(((FMLProxyPacket) msg).toC17Packet(), promise); - } - else - { - List> parts = ((FMLProxyPacket)msg).toS3FPackets(); - int sizeMinusOne = parts.size() - 1; - for (int i = 0; i < sizeMinusOne; i++) - { - ctx.write(parts.get(i), ctx.voidPromise()); - } - ctx.write(parts.get(sizeMinusOne), promise); - } - } - else - { - ctx.write(msg, promise); - } - } - - @Override - public void flush(ChannelHandlerContext ctx) throws Exception - { - ctx.flush(); - } - - public void completeHandshake(Side target) - { - if (state == ConnectionState.CONNECTED) - { - FMLLog.log.fatal("Attempt to double complete the network connection!"); - throw new FMLNetworkException("Attempt to double complete!"); - } - if (side == Side.CLIENT) - { - completeClientSideConnection(ConnectionType.MODDED); - } - else - { - this.state = ConnectionState.FINALIZING; //Delay and finalize in the world tick loop. - } - } - - public void completeClientHandshake() - { - state = ConnectionState.HANDSHAKECOMPLETE; - } - - public void abortClientHandshake(String type) - { - FMLLog.log.info("Aborting client handshake \"{}\"", type); - //FMLCommonHandler.instance().waitForPlayClient(); - completeClientSideConnection(ConnectionType.valueOf(type)); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception - { - // Stop the epic channel closed spam at close - if (!(cause instanceof ClosedChannelException)) - { - // Mute the reset by peer exception - it's disconnection noise - if (cause.getMessage() != null && cause.getMessage().contains("Connection reset by peer")) - { - FMLLog.log.debug("Muted NetworkDispatcher exception", cause); - } - else - { - FMLLog.log.error("NetworkDispatcher exception", cause); - } - } - super.exceptionCaught(ctx, cause); - } - - // If we add any attributes, we should force removal of them here so that - // they do not hold references to the world and cause it to leak. - private void cleanAttributes(ChannelHandlerContext ctx) - { - ctx.channel().attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(null); - ctx.channel().attr(NetworkRegistry.NET_HANDLER).set(null); - ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).set(null); - this.handshakeChannel.attr(FML_DISPATCHER).set(null); - this.manager.channel().attr(FML_DISPATCHER).set(null); - NetworkRegistry.INSTANCE.cleanAttributes(); - } - - public void setOverrideDimension(int overrideDim) { - this.overrideLoginDim = overrideDim; - FMLLog.log.debug("Received override dimension {}", overrideDim); - } - - public int getOverrideDimension(SPacketJoinGame packetIn) { - FMLLog.log.debug("Overriding dimension: using {}", this.overrideLoginDim); - return this.overrideLoginDim != 0 ? this.overrideLoginDim : packetIn.getDimension(); - } - - private class MultiPartCustomPayload extends SPacketCustomPayload - { - private String channel; - private byte[] data; - private PacketBuffer data_buf = null; - private int part_count = 0; - private int part_expected = 0; - private int offset = 0; - - private MultiPartCustomPayload(PacketBuffer preamble) throws IOException - { - channel = preamble.readString(20); - part_count = preamble.readUnsignedByte(); - int length = preamble.readInt(); - if (length <= 0 || length >= FMLProxyPacket.MAX_LENGTH) - { - throw new IOException("The received FML MultiPart packet outside of valid length bounds, Max: " + FMLProxyPacket.MAX_LENGTH + ", Received: " + length); - } - data = new byte[length]; - data_buf = new PacketBuffer(Unpooled.wrappedBuffer(data)); - } - - public void processPart(PacketBuffer input) throws IOException - { - int part = input.readByte() & 0xFF; - if (part != part_expected) - { - throw new IOException("Received FML MultiPart packet out of order, Expected " + part_expected + " Got " + part); - } - int len = input.readableBytes(); - input.readBytes(data, offset, len); - part_expected++; - offset += len; - } - - public boolean isComplete() - { - return part_expected == part_count; - } - - @Override - public String getChannelName() // getChannel - { - return this.channel; - } - - @Override - public PacketBuffer getBufferData() // getData - { - return this.data_buf; - } - } - - public ConnectionType getConnectionType() - { - return this.connectionType; - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java b/src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java deleted file mode 100644 index eef0b1c33..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.internal; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; - -import net.minecraft.client.entity.EntityPlayerSP; -import net.minecraft.client.multiplayer.WorldClient; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityTracker; -import net.minecraft.util.IThreadListener; -import net.minecraft.world.World; -import net.minecraftforge.fml.client.FMLClientHandler; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.internal.FMLMessage.EntityMessage; -import net.minecraftforge.fml.common.registry.EntityRegistry; -import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; -import net.minecraftforge.fml.common.registry.IThrowableEntity; -import net.minecraftforge.fml.common.registry.EntityRegistry.EntityRegistration; - -public class EntitySpawnHandler extends SimpleChannelInboundHandler { - @Override - protected void channelRead0(ChannelHandlerContext ctx, final EntityMessage msg) throws Exception - { - IThreadListener thread = FMLCommonHandler.instance().getWorldThread(ctx.channel().attr(NetworkRegistry.NET_HANDLER).get()); - if (thread.isCallingFromMinecraftThread()) - { - process(msg); - } - else - { - thread.addScheduledTask(() -> EntitySpawnHandler.this.process(msg)); - } - } - - private void process(EntityMessage msg) - { - if (msg.getClass().equals(FMLMessage.EntitySpawnMessage.class)) - { - FMLMessage.EntitySpawnMessage spawnMsg = (FMLMessage.EntitySpawnMessage) msg; - spawnEntity(spawnMsg); - spawnMsg.dataStream.release(); - } - } - - private void spawnEntity(FMLMessage.EntitySpawnMessage spawnMsg) - { - ModContainer mc = Loader.instance().getIndexedModList().get(spawnMsg.modId); - EntityRegistration er = EntityRegistry.instance().lookupModSpawn(mc, spawnMsg.modEntityTypeId); - if (er == null) - { - throw new RuntimeException( "Could not spawn mod entity ModID: " + spawnMsg.modId + " EntityID: " + spawnMsg.modEntityTypeId + - " at ( " + spawnMsg.rawX + "," + spawnMsg.rawY + ", " + spawnMsg.rawZ + ") Please contact mod author or server admin."); - } - WorldClient wc = FMLClientHandler.instance().getWorldClient(); - try - { - Entity entity; - if (er.hasCustomSpawning()) - { - entity = er.doCustomSpawning(spawnMsg); - } else - { - entity = er.newInstance(wc); - - int offset = spawnMsg.entityId - entity.getEntityId(); - entity.setEntityId(spawnMsg.entityId); - entity.setUniqueId(spawnMsg.entityUUID); - entity.setLocationAndAngles(spawnMsg.rawX, spawnMsg.rawY, spawnMsg.rawZ, spawnMsg.scaledYaw, spawnMsg.scaledPitch); - if (entity instanceof EntityLiving) - { - ((EntityLiving) entity).rotationYawHead = spawnMsg.scaledHeadYaw; - } - - Entity parts[] = entity.getParts(); - if (parts != null) - { - for (int j = 0; j < parts.length; j++) - { - parts[j].setEntityId(parts[j].getEntityId() + offset); - } - } - } - - EntityTracker.updateServerPosition(entity, spawnMsg.rawX, spawnMsg.rawY, spawnMsg.rawZ); - - EntityPlayerSP clientPlayer = FMLClientHandler.instance().getClientPlayerEntity(); - if (entity instanceof IThrowableEntity) - { - Entity thrower = clientPlayer.getEntityId() == spawnMsg.throwerId ? clientPlayer : wc.getEntityByID(spawnMsg.throwerId); - ((IThrowableEntity) entity).setThrower(thrower); - } - - if (spawnMsg.dataWatcherList != null) - { - entity.getDataManager().setEntryValues(spawnMsg.dataWatcherList); - } - - if (spawnMsg.throwerId > 0) - { - entity.setVelocity(spawnMsg.speedScaledX, spawnMsg.speedScaledY, spawnMsg.speedScaledZ); - } - - if (entity instanceof IEntityAdditionalSpawnData) - { - ((IEntityAdditionalSpawnData) entity).readSpawnData(spawnMsg.dataStream); - } - wc.addEntityToWorld(spawnMsg.entityId, entity); - } - catch (Exception e) - { - throw new RuntimeException("A severe problem occurred during the spawning of an entity at (" + spawnMsg.rawX + ", " + spawnMsg.rawY + ", " + spawnMsg.rawZ + ")", e); - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception - { - FMLLog.log.error("EntitySpawnHandler exception", cause); - super.exceptionCaught(ctx, cause); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java b/src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java deleted file mode 100644 index dc3112afe..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.internal; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - -import java.io.IOException; -import java.util.List; -import java.util.UUID; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.network.PacketBuffer; -import net.minecraft.network.datasync.EntityDataManager; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.common.network.ByteBufUtils; -import net.minecraftforge.fml.common.registry.EntityRegistry.EntityRegistration; -import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; -import net.minecraftforge.fml.common.registry.IThrowableEntity; -import net.minecraftforge.api.distmarker.Dist; - -public abstract class FMLMessage { - public static class CompleteHandshake extends FMLMessage { - Side target; - public CompleteHandshake() { - } - public CompleteHandshake(Side target) - { - this.target = target; - } - @Override - void fromBytes(ByteBuf buf) - { - target = Side.values()[buf.readByte()]; - } - @Override - void toBytes(ByteBuf buf) - { - buf.writeByte(target.ordinal()); - } - } - public static class OpenGui extends FMLMessage { - int windowId; - String modId; - int modGuiId; - int x; - int y; - int z; - - public OpenGui() {} - OpenGui(int windowId, String modId, int modGuiId, int x, int y, int z) - { - this.windowId = windowId; - this.modId = modId; - this.modGuiId = modGuiId; - this.x = x; - this.y = y; - this.z = z; - } - - @Override - void toBytes(ByteBuf buf) - { - buf.writeInt(windowId); - ByteBufUtils.writeUTF8String(buf, modId); - buf.writeInt(modGuiId); - buf.writeInt(x); - buf.writeInt(y); - buf.writeInt(z); - } - - @Override - void fromBytes(ByteBuf buf) - { - windowId = buf.readInt(); - modId = ByteBufUtils.readUTF8String(buf); - modGuiId = buf.readInt(); - x = buf.readInt(); - y = buf.readInt(); - z = buf.readInt(); - } - } - - public abstract static class EntityMessage extends FMLMessage { - Entity entity; - int entityId; - public EntityMessage() - { - - } - EntityMessage(Entity entity) - { - this.entity = entity; - } - @Override - void toBytes(ByteBuf buf) - { - buf.writeInt(entity.getEntityId()); - } - - @Override - void fromBytes(ByteBuf buf) - { - entityId = buf.readInt(); - } - } - - public static class EntitySpawnMessage extends EntityMessage { - String modId; - int modEntityTypeId; - UUID entityUUID; - double rawX; - double rawY; - double rawZ; - float scaledYaw; - float scaledPitch; - float scaledHeadYaw; - int throwerId; - double speedScaledX; - double speedScaledY; - double speedScaledZ; - List> dataWatcherList; - ByteBuf dataStream; - - public EntitySpawnMessage() {} - public EntitySpawnMessage(EntityRegistration er, Entity entity, ModContainer modContainer) - { - super(entity); - modId = modContainer.getModId(); - modEntityTypeId = er.getModEntityId(); - } - @Override - void toBytes(ByteBuf buf) - { - super.toBytes(buf); - ByteBufUtils.writeUTF8String(buf, modId); - buf.writeInt(modEntityTypeId); - buf.writeLong(entity.getUniqueID().getMostSignificantBits()); - buf.writeLong(entity.getUniqueID().getLeastSignificantBits()); - // posX, posY, posZ - buf.writeDouble(entity.posX); - buf.writeDouble(entity.posY); - buf.writeDouble(entity.posZ); - // yaw, pitch - buf.writeByte((byte)(entity.rotationYaw * 256.0F / 360.0F)); - buf.writeByte((byte) (entity.rotationPitch * 256.0F / 360.0F)); - // head yaw - if (entity instanceof EntityLivingBase) - { - buf.writeByte((byte) (((EntityLivingBase)entity).rotationYawHead * 256.0F / 360.0F)); - } - else - { - buf.writeByte(0); - } - ByteBuf tmpBuf = Unpooled.buffer(); - PacketBuffer pb = new PacketBuffer(tmpBuf); - try - { - entity.getDataManager().writeEntries(pb); - } - catch (IOException e) - { - FMLLog.log.fatal("Encountered fatal exception trying to send entity spawn data watchers", e); - throw new RuntimeException(e); - } - buf.writeBytes(tmpBuf); - - if (entity instanceof IThrowableEntity) - { - Entity owner = ((IThrowableEntity)entity).getThrower(); - buf.writeInt(owner == null ? entity.getEntityId() : owner.getEntityId()); - double maxVel = 3.9D; - double mX = entity.motionX; - double mY = entity.motionY; - double mZ = entity.motionZ; - if (mX < -maxVel) mX = -maxVel; - if (mY < -maxVel) mY = -maxVel; - if (mZ < -maxVel) mZ = -maxVel; - if (mX > maxVel) mX = maxVel; - if (mY > maxVel) mY = maxVel; - if (mZ > maxVel) mZ = maxVel; - buf.writeInt((int)(mX * 8000D)); - buf.writeInt((int)(mY * 8000D)); - buf.writeInt((int)(mZ * 8000D)); - } - else - { - buf.writeInt(0); - } - if (entity instanceof IEntityAdditionalSpawnData) - { - tmpBuf = Unpooled.buffer(); - ((IEntityAdditionalSpawnData)entity).writeSpawnData(tmpBuf); - buf.writeBytes(tmpBuf); - } - } - @Override - void fromBytes(ByteBuf dat) - { - super.fromBytes(dat); - modId = ByteBufUtils.readUTF8String(dat); - modEntityTypeId = dat.readInt(); - entityUUID = new UUID(dat.readLong(), dat.readLong()); - rawX = dat.readDouble(); - rawY = dat.readDouble(); - rawZ = dat.readDouble(); - scaledYaw = dat.readByte() * 360F / 256F; - scaledPitch = dat.readByte() * 360F / 256F; - scaledHeadYaw = dat.readByte() * 360F / 256F; - try - { - dataWatcherList = EntityDataManager.readEntries(new PacketBuffer(dat)); - } - catch (IOException e) - { - FMLLog.log.fatal("There was a critical error decoding the datawatcher stream for a mod entity.", e); - throw new RuntimeException(e); - } - - throwerId = dat.readInt(); - if (throwerId != 0) - { - speedScaledX = dat.readInt() / 8000D; - speedScaledY = dat.readInt() / 8000D; - speedScaledZ = dat.readInt() / 8000D; - } - this.dataStream = dat.retain(); - } - } - abstract void toBytes(ByteBuf buf); - abstract void fromBytes(ByteBuf buf); -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java b/src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java deleted file mode 100644 index bb39e6933..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.internal; - -import io.netty.channel.ChannelPipeline; -import io.netty.channel.embedded.EmbeddedChannel; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.inventory.Container; -import net.minecraft.network.NetworkManager; -import net.minecraft.network.Packet; -import net.minecraft.server.management.PlayerList; -import net.minecraft.world.World; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.fml.LogicalSide; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.FMLWorldPersistenceHook; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.common.network.FMLEmbeddedChannel; -import net.minecraftforge.fml.common.network.FMLOutboundHandler; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.FMLOutboundHandler.OutboundTarget; -import net.minecraftforge.fml.common.network.handshake.FMLHandshakeMessage; -import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; -import net.minecraftforge.fml.common.network.internal.FMLMessage.CompleteHandshake; -import net.minecraftforge.fml.common.registry.EntityRegistry; -import net.minecraftforge.fml.common.registry.EntityRegistry.EntityRegistration; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import org.apache.commons.lang3.tuple.Pair; - -import javax.annotation.Nullable; - -public class FMLNetworkHandler -{ - public static final int READ_TIMEOUT = Integer.parseInt(System.getProperty("fml.readTimeout","30")); - public static final int LOGIN_TIMEOUT = Integer.parseInt(System.getProperty("fml.loginTimeout","600")); - private static EnumMap channelPair; - - public static void fmlServerHandshake(PlayerList scm, NetworkManager manager, EntityPlayerMP player) - { - NetworkDispatcher dispatcher = NetworkDispatcher.allocAndSet(manager, scm); - dispatcher.serverToClientHandshake(player); - } - - public static void fmlClientHandshake(NetworkManager networkManager) - { - NetworkDispatcher dispatcher = NetworkDispatcher.allocAndSet(networkManager); - dispatcher.clientToServerHandshake(); - } - - public static void openGui(EntityPlayer entityPlayer, Object mod, int modGuiId, World world, int x, int y, int z) - { - ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod); - if (entityPlayer instanceof EntityPlayerMP && !(entityPlayer instanceof FakePlayer)) - { - EntityPlayerMP entityPlayerMP = (EntityPlayerMP) entityPlayer; - Container remoteGuiContainer = NetworkRegistry.INSTANCE.getRemoteGuiContainer(mc, entityPlayerMP, modGuiId, world, x, y, z); - if (remoteGuiContainer != null) - { - entityPlayerMP.getNextWindowId(); - entityPlayerMP.closeContainer(); - int windowId = entityPlayerMP.currentWindowId; - FMLMessage.OpenGui openGui = new FMLMessage.OpenGui(windowId, mc.getModId(), modGuiId, x, y, z); - EmbeddedChannel embeddedChannel = channelPair.get(Side.SERVER); - embeddedChannel.attr(FMLOutboundHandler.FML_MESSAGETARGET).set(OutboundTarget.PLAYER); - embeddedChannel.attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(entityPlayerMP); - embeddedChannel.writeOutbound(openGui); - entityPlayerMP.openContainer = remoteGuiContainer; - entityPlayerMP.openContainer.windowId = windowId; - entityPlayerMP.openContainer.addListener(entityPlayerMP); - net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(entityPlayer, entityPlayer.openContainer)); - } - } - else if (entityPlayer instanceof FakePlayer) - { - // NO OP - I won't even log a message! - } - else if (FMLCommonHandler.instance().getSide().equals(Side.CLIENT)) - { - Object guiContainer = NetworkRegistry.INSTANCE.getLocalGuiContainer(mc, entityPlayer, modGuiId, world, x, y, z); - FMLCommonHandler.instance().showGuiScreen(guiContainer); - } - else - { - FMLLog.log.debug("Invalid attempt to open a local GUI on a dedicated server. This is likely a bug. GUI ID: {},{}", mc.getModId(), modGuiId); - } - - } - - @Nullable - public static Packet getEntitySpawningPacket(Entity entity) - { - EntityRegistration er = EntityRegistry.instance().lookupModSpawn(entity.getClass(), false); - if (er == null) - { - return null; - } - if (er.usesVanillaSpawning()) - { - return null; - } - - return channelPair.get(Side.SERVER).generatePacketFrom(new FMLMessage.EntitySpawnMessage(er, entity, er.getContainer())); - } - - @Nullable - public static String checkModList(FMLHandshakeMessage.ModList modListPacket, Side side) - { - Map modList = modListPacket.modList(); - return checkModList(modList, side); - } - - /** - * @param listData map of modId string to version string, represents the mods available on the given side - * @param side the side that listData is coming from, either client or server - * @return null if everything is fine, returns a string error message if there are mod rejections - */ - @Nullable - public static String checkModList(Map listData, LogicalSide side) - { - return null; -/* - List> rejects = NetworkRegistry.INSTANCE.registry().entrySet().stream() - .map(entry -> Pair.of(entry.getKey(), entry.getValue().checkCompatible(listData, side))) - .filter(pair -> pair.getValue() != null) - .sorted(Comparator.comparing(o -> o.getKey().getName())) - .collect(Collectors.toList()); - if (rejects.isEmpty()) - { - return null; - } - else - { - List rejectStrings = new ArrayList<>(); - for (Pair reject : rejects) - { - ModContainer modContainer = reject.getKey(); - rejectStrings.add(modContainer.getName() + ": " + reject.getValue()); - } - String rejectString = String.join("\n", rejectStrings); - FMLLog.log.info("Rejecting connection {}: {}", side, rejectString); - return String.format("Server Mod rejections:\n%s", rejectString); - } -*/ - } - - @OnlyIn(Dist.CLIENT) - private static void addClientHandlers() - { - ChannelPipeline pipeline = channelPair.get(Side.CLIENT).pipeline(); - String targetName = channelPair.get(Side.CLIENT).findChannelHandlerNameForType(FMLRuntimeCodec.class); - pipeline.addAfter(targetName, "GuiHandler", new OpenGuiHandler()); - pipeline.addAfter(targetName, "EntitySpawnHandler", new EntitySpawnHandler()); - } - public static void registerChannel(FMLWorldPersistenceHook container, Side side) - { - channelPair = NetworkRegistry.INSTANCE.newChannel(container, "FML", new FMLRuntimeCodec(), new HandshakeCompletionHandler()); - EmbeddedChannel embeddedChannel = channelPair.get(Side.SERVER); - embeddedChannel.attr(FMLOutboundHandler.FML_MESSAGETARGET).set(OutboundTarget.NOWHERE); - - if (side == Side.CLIENT) - { - addClientHandlers(); - } - } - - public static List forwardHandshake(CompleteHandshake push, NetworkDispatcher target, Side side) - { - channelPair.get(side).attr(NetworkDispatcher.FML_DISPATCHER).set(target); - channelPair.get(side).writeOutbound(push); - - ArrayList list = new ArrayList(); - for (Object o: channelPair.get(side).outboundMessages()) - { - list.add((FMLProxyPacket)o); - } - channelPair.get(side).outboundMessages().clear(); - return list; - } - - - public static void enhanceStatusQuery(JsonObject jsonobject) - { - JsonObject fmlData = new JsonObject(); - fmlData.addProperty("type", "FML"); - JsonArray modList = new JsonArray(); - for (ModContainer mc : Loader.instance().getActiveModList()) - { - JsonObject modData = new JsonObject(); - modData.addProperty("modid", mc.getModId()); - modData.addProperty("version", mc.getVersion()); - modList.add(modData); - } - fmlData.add("modList", modList); - jsonobject.add("modinfo", fmlData); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java b/src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java deleted file mode 100644 index 90eca160b..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.internal; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.embedded.EmbeddedChannel; - -import java.io.IOException; -import java.util.List; - -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetworkManager; -import net.minecraft.network.Packet; -import net.minecraft.network.PacketBuffer; -import net.minecraft.network.play.INetHandlerPlayClient; -import net.minecraft.network.play.INetHandlerPlayServer; -import net.minecraft.network.play.client.CPacketCustomPayload; -import net.minecraft.network.play.server.SPacketCustomPayload; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.network.FMLNetworkException; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; -import net.minecraftforge.api.distmarker.Dist; - -import com.google.common.collect.ConcurrentHashMultiset; -import com.google.common.collect.Lists; -import com.google.common.collect.Multiset; -import com.google.common.collect.Multiset.Entry; -import com.google.common.collect.Multisets; - -import javax.annotation.Nullable; - -public class FMLProxyPacket implements Packet { - final String channel; - private Side target; - private final PacketBuffer payload; - private INetHandler netHandler; - private NetworkDispatcher dispatcher; - private static Multiset badPackets = ConcurrentHashMultiset.create(); - private static int packetCountWarning = Integer.parseInt(System.getProperty("fml.badPacketCounter", "100")); - - public FMLProxyPacket(SPacketCustomPayload original) - { - this(original.getBufferData(), original.getChannelName()); - this.target = Side.CLIENT; - } - - public FMLProxyPacket(CPacketCustomPayload original) - { - this(original.getBufferData(), original.getChannelName()); - this.target = Side.SERVER; - } - - public FMLProxyPacket(PacketBuffer payload, String channel) - { - this.channel = channel; - this.payload = payload; - } - @Override - public void readPacketData(PacketBuffer packetbuffer) throws IOException - { - // NOOP - we are not built this way - } - - @Override - public void writePacketData(PacketBuffer packetbuffer) throws IOException - { - // NOOP - we are not built this way - } - - @Override - public void processPacket(INetHandler inethandler) - { - this.netHandler = inethandler; - EmbeddedChannel internalChannel = NetworkRegistry.INSTANCE.getChannel(this.channel, this.target); - if (internalChannel != null) - { - internalChannel.attr(NetworkRegistry.NET_HANDLER).set(this.netHandler); - try - { - if (internalChannel.writeInbound(this)) - { - badPackets.add(this.channel); - if (badPackets.size() % packetCountWarning == 0) - { - FMLLog.log.fatal("Detected ongoing potential memory leak. {} packets have leaked. Top offenders", badPackets.size()); - int i = 0; - for (Entry s : Multisets.copyHighestCountFirst(badPackets).entrySet()) - { - if (i++ > 10) break; - FMLLog.log.fatal("\t {} : {}", s.getElement(), s.getCount()); - } - } - } - internalChannel.inboundMessages().clear(); - } - catch (FMLNetworkException ne) - { - FMLLog.log.error("There was a network exception handling a packet on channel {}", channel, ne); - dispatcher.rejectHandshake(ne.getMessage()); - } - catch (Throwable t) - { - FMLLog.log.error("There was a critical exception handling a packet on channel {}", channel, t); - dispatcher.rejectHandshake("A fatal error has occurred, this connection is terminated"); - } - } - } - - public String channel() - { - return channel; - } - public ByteBuf payload() - { - return payload; - } - public INetHandler handler() - { - return netHandler; - } - public Packet toC17Packet() - { - return new CPacketCustomPayload(channel, payload); - } - - static final int PART_SIZE = 0x100000 - 0x50; // Make it a constant so that it gets inlined below. - // FIXME int overflow - public static final int MAX_LENGTH = PART_SIZE * 255; - public List> toS3FPackets() throws IOException - { - List> ret = Lists.newArrayList(); - byte[] data = payload.array(); - - if (data.length < PART_SIZE) - { - ret.add(new SPacketCustomPayload(channel, new PacketBuffer(payload.duplicate()))); - } - else - { - int parts = (int)Math.ceil(data.length / (double)(PART_SIZE - 1)); //We add a byte header so -1 - if (parts > 255) - { - throw new IllegalArgumentException("Payload may not be larger than " + MAX_LENGTH + " bytes"); - } - PacketBuffer preamble = new PacketBuffer(Unpooled.buffer()); - preamble.writeString(channel); - preamble.writeByte(parts); - preamble.writeInt(data.length); - ret.add(new SPacketCustomPayload("FML|MP", preamble)); - - int offset = 0; - for (int x = 0; x < parts; x++) - { - int length = Math.min(PART_SIZE, data.length - offset + 1); - byte[] tmp = new byte[length]; - tmp[0] = (byte)(x & 0xFF); - System.arraycopy(data, offset, tmp, 1, tmp.length - 1); - offset += tmp.length - 1; - ret.add(new SPacketCustomPayload("FML|MP", new PacketBuffer(Unpooled.wrappedBuffer(tmp)))); - } - } - return ret; - } - - public void setTarget(Side target) - { - this.target = target; - } - - public void setDispatcher(NetworkDispatcher networkDispatcher) - { - this.dispatcher = networkDispatcher; - } - - @Nullable - public NetworkManager getOrigin() - { - return this.dispatcher != null ? this.dispatcher.manager : null; - } - - public NetworkDispatcher getDispatcher() - { - return this.dispatcher; - } - - public Side getTarget() - { - return target; - } - - public FMLProxyPacket copy() - { - FMLProxyPacket pkt = new FMLProxyPacket(new PacketBuffer(payload.duplicate()), channel); - pkt.dispatcher = dispatcher; - pkt.netHandler = netHandler; - pkt.target = target; - return pkt; - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java b/src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java deleted file mode 100644 index 5344d582f..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.internal; - -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.network.ByteBufUtils; -import net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec; -import net.minecraftforge.fml.common.network.FMLNetworkException; - -import com.google.common.base.Splitter; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; - -public class FMLRuntimeCodec extends FMLIndexedMessageToMessageCodec { - public FMLRuntimeCodec() - { - addDiscriminator(0,FMLMessage.CompleteHandshake.class); - addDiscriminator(1,FMLMessage.OpenGui.class); - addDiscriminator(2,FMLMessage.EntitySpawnMessage.class); - } - @Override - public void encodeInto(ChannelHandlerContext ctx, FMLMessage msg, ByteBuf target) throws Exception - { - msg.toBytes(target); - } - - @Override - public void decodeInto(ChannelHandlerContext ctx, ByteBuf source, FMLMessage msg) - { - msg.fromBytes(source); - } - - @Override - protected void testMessageValidity(FMLProxyPacket msg) - { - if (msg.payload().getByte(0) == 0 && msg.payload().readableBytes() > 2) - { - FMLLog.log.fatal("The connection appears to have sent an invalid FML packet of type 0, this is likely because it think's it's talking to 1.6.4 FML"); - FMLLog.log.info("Bad data :"); - for (String l : Splitter.on('\n').split(ByteBufUtils.getContentDump(msg.payload()))) { - FMLLog.log.info("\t{}",l); - } - throw new FMLNetworkException("Invalid FML packet"); - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java b/src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java deleted file mode 100644 index d19521d3f..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.internal; - -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; -import net.minecraftforge.fml.common.network.internal.FMLMessage.CompleteHandshake; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.channel.ChannelHandler.Sharable; - -@Sharable -public class HandshakeCompletionHandler extends SimpleChannelInboundHandler { - @Override - protected void channelRead0(ChannelHandlerContext ctx, CompleteHandshake msg) throws Exception - { - NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).getAndSet(null); - dispatcher.completeHandshake(msg.target); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception - { - FMLLog.log.error("HandshakeCompletionHandler exception", cause); - super.exceptionCaught(ctx, cause); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java b/src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java deleted file mode 100644 index c46992691..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.internal; - -import java.lang.reflect.Method; -import java.util.Map; -import java.util.Set; - -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.common.network.NetworkCheckHandler; -import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion; -import net.minecraftforge.fml.common.versioning.InvalidVersionSpecificationException; -import net.minecraftforge.fml.common.versioning.VersionRange; - -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.SetMultimap; - -import javax.annotation.Nullable; - -public class NetworkModHolder -{ - /** - * Validates that the mods versions on the client and server are compatible with mod. - */ - public abstract class NetworkChecker { - /** - * @deprecated use {@link #checkCompatible(Map, Side)} - */ - @Deprecated // TODO remove in 1.13 - public abstract boolean check(Map remoteVersions, Side side); - - /** - * @param remoteVersions map of modIds to version strings, represents all the mods on the given side - * @param side the side that the remoteVersions are from - * @return null if these mod versions are compatible with this mod, - * an error string reason if these mod versions are not compatible with this mod. - */ - @Nullable - public String checkCompatible(Map remoteVersions, Side side) - { - return check(remoteVersions, side) ? toString() : null; - } - } - - private class IgnoredChecker extends NetworkChecker { - @Override - public boolean check(Map remoteVersions, Side side) - { - return true; - } - - @Nullable - @Override - public String checkCompatible(Map remoteVersions, Side side) - { - return null; - } - - @Override - public String toString() - { - return "No network checking performed"; - } - } - private class DefaultNetworkChecker extends NetworkChecker { - @Override - public boolean check(Map remoteVersions, Side side) - { - return checkCompatible(remoteVersions, side) == null; - } - - @Nullable - @Override - public String checkCompatible(Map remoteVersions, Side side) - { - String version = remoteVersions.get(container.getModId()); - if (version != null && acceptVersion(version)) - { - return null; - } - if (side == Side.SERVER) - { - return null; - } - String versionString; - if (acceptableRange != null) - { - if (acceptableRange.hasRestrictions()) - { - versionString = String.format("version %s", acceptableRange.toStringFriendly()); - } - else - { - versionString = String.format("version range %s", acceptableRange.toStringFriendly()); - } - } - else - { - versionString = String.format("version %s", container.getVersion()); - } - if (version != null) - { - return String.format("Requires %s but client has %s.", versionString, version); - } - else - { - return String.format("Requires %s but mod is not found on client.", versionString); - } - } - - @Override - public String toString() - { - return acceptableRange != null ? String.format("Accepting range %s", acceptableRange.toStringFriendly()) : String.format("Accepting version %s", container.getVersion()); - } - } - private class MethodNetworkChecker extends NetworkChecker { - @Override - public boolean check(Map remoteVersions, Side side) - { - return checkCompatible(remoteVersions, side) == null; - } - - @Nullable - @Override - public String checkCompatible(Map remoteVersions, Side side) - { - try - { - Boolean result = (Boolean) checkHandler.invoke(container.getMod(), remoteVersions, side); - if (result != null && result) - { - return null; - } - return String.format("Failed mod's custom NetworkCheckHandler %s", container); - } - catch (Exception e) - { - FMLLog.log.error("Error occurred invoking NetworkCheckHandler {} at {}", container, e); - return String.format("Error occurred invoking NetworkCheckHandler %s", container); - } - } - - @Override - public String toString() - { - return String.format("Invoking method %s", checkHandler.getName()); - } - } - private static int assignedIds = 1; - - private int localId; - private int networkId; - - private ModContainer container; - private Method checkHandler; - - private VersionRange acceptableRange; - - private NetworkChecker checker; - - private boolean acceptsVanillaClient; - private boolean acceptsVanillaServer; - - public NetworkModHolder(ModContainer container) - { - this.container = container; - this.localId = assignedIds++; - this.networkId = this.localId; - } - public NetworkModHolder(ModContainer container, NetworkChecker checker) - { - this(container); - this.checker = Preconditions.checkNotNull(checker); - FMLLog.log.debug("The mod {} is using a custom checker {}", container.getModId(), checker.getClass().getName()); - } - public NetworkModHolder(ModContainer container, Class modClass, @Nullable String acceptableVersionRange, ASMDataTable table) - { - this(container); - SetMultimap annotationTable = table.getAnnotationsFor(container); - Set versionCheckHandlers; - if (annotationTable != null) - { - versionCheckHandlers = annotationTable.get(NetworkCheckHandler.class.getName()); - } - else - { - versionCheckHandlers = ImmutableSet.of(); - } - String networkCheckHandlerMethod = null; - for (ASMData vch : versionCheckHandlers) - { - if (vch.getClassName().equals(modClass.getName())) - { - networkCheckHandlerMethod = vch.getObjectName(); - networkCheckHandlerMethod = networkCheckHandlerMethod.substring(0,networkCheckHandlerMethod.indexOf('(')); - break; - } - } - if (versionCheckHandlers.isEmpty()) - { - for (Method m : modClass.getMethods()) - { - if (m.isAnnotationPresent(NetworkCheckHandler.class)) - { - if (m.getParameterTypes().length == 2 && m.getParameterTypes()[0].equals(Map.class) && m.getParameterTypes()[1].equals(Side.class)) - { - this.checkHandler = m; - break; - } - else - { - FMLLog.log.fatal("Found unexpected method signature for annotation NetworkCheckHandler"); - } - } - } - } - if (networkCheckHandlerMethod != null) - { - try - { - Method checkHandlerMethod = modClass.getDeclaredMethod(networkCheckHandlerMethod, Map.class, Side.class); - if (checkHandlerMethod.isAnnotationPresent(NetworkCheckHandler.class)) - { - this.checkHandler = checkHandlerMethod; - } - } - catch (Exception e) - { - FMLLog.log.warn("The declared version check handler method {} on network mod id {} is not accessible", networkCheckHandlerMethod, container.getModId(), e); - } - } - if (this.checkHandler != null) - { - this.checker = new MethodNetworkChecker(); - } - else if (!Strings.isNullOrEmpty(acceptableVersionRange) && acceptableVersionRange.equals("*")) - { - this.checker = new IgnoredChecker(); - } - else - { - try - { - this.acceptableRange = VersionRange.createFromVersionSpec(acceptableVersionRange); - } - catch (InvalidVersionSpecificationException e) - { - FMLLog.log.warn("Invalid bounded range {} specified for network mod id {}", acceptableVersionRange, container.getModId(), e); - } - this.checker = new DefaultNetworkChecker(); - } - FMLLog.log.trace("Mod {} is using network checker : {}", container.getModId(), this.checker); - FMLLog.log.trace("Testing mod {} to verify it accepts its own version in a remote connection", container.getModId()); - boolean acceptsSelf = acceptVersion(container.getVersion()); - if (!acceptsSelf) - { - FMLLog.log.fatal("The mod {} appears to reject its own version number ({}) in its version handling. This is likely a severe bug in the mod!", container.getModId(), container.getVersion()); - } - else - { - FMLLog.log.trace("The mod {} accepts its own version ({})", container.getModId(), container.getVersion()); - } - } - - public boolean acceptVersion(String version) - { - if (acceptableRange != null) - { - return acceptableRange.containsVersion(new DefaultArtifactVersion(version)); - } - - return container.getVersion().equals(version); - } - - public boolean check(Map data, Side side) - { - return checker.checkCompatible(data, side) == null; - } - - @Nullable - public String checkCompatible(Map data, Side side) - { - return checker.checkCompatible(data, side); - } - - public int getLocalId() - { - return localId; - } - - public int getNetworkId() - { - return networkId; - } - - public ModContainer getContainer() - { - return container; - } - - public void setNetworkId(int value) - { - this.networkId = value; - } - - public void testVanillaAcceptance() { - acceptsVanillaClient = check(ImmutableMap.of(), Side.CLIENT); - acceptsVanillaServer = check(ImmutableMap.of(), Side.SERVER); - } - public boolean acceptsVanilla(Side from) { - return from == Side.CLIENT ? acceptsVanillaClient : acceptsVanillaServer; - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java b/src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java deleted file mode 100644 index 46b3a310c..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.internal; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.IThreadListener; -import net.minecraftforge.fml.client.FMLClientHandler; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.internal.FMLMessage.OpenGui; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; - -public class OpenGuiHandler extends SimpleChannelInboundHandler { - @Override - protected void channelRead0(ChannelHandlerContext ctx, final OpenGui msg) throws Exception - { - IThreadListener thread = FMLCommonHandler.instance().getWorldThread(ctx.channel().attr(NetworkRegistry.NET_HANDLER).get()); - if (thread.isCallingFromMinecraftThread()) - { - process(msg); - } - else - { - thread.addScheduledTask(() -> OpenGuiHandler.this.process(msg)); - } - } - - private void process(OpenGui msg) - { - EntityPlayer player = FMLClientHandler.instance().getClient().player; - player.openGui(msg.modId, msg.modGuiId, player.world, msg.x, msg.y, msg.z); - player.openContainer.windowId = msg.windowId; - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception - { - FMLLog.log.error("OpenGuiHandler exception", cause); - super.exceptionCaught(ctx, cause); - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java b/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java deleted file mode 100644 index 3ee6e7b3f..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.simpleimpl; - -import io.netty.buffer.ByteBuf; - -/** - * Implement this interface for each message you wish to define. - * - * @author cpw - * - */ -public interface IMessage { - /** - * Convert from the supplied buffer into your specific message type - * - * @param buf - */ - void fromBytes(ByteBuf buf); - - /** - * Deconstruct your message into the supplied byte buffer - * @param buf - */ - void toBytes(ByteBuf buf); -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java b/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java deleted file mode 100644 index 962f5a3b4..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.simpleimpl; - - -import net.minecraftforge.fml.network.NetworkEvent; - -/** - * A message handler based on {@link IMessage}. Implement and override {@link #onMessage(IMessage, NetworkEvent.Context)} to - * process your packet. Supply the class to {@link SimpleNetworkWrapper#registerMessage(Class, Class, int, Side)} - * to register both the message type and it's associated handler. - * - * @author cpw - * - * @param This is the request type - it is the message you expect to receive from remote. - * @param This is the reply type - it is the message you expect to send in reply. You can use IMessage as the type here - * if you don't anticipate sending a reply. - */ -public interface IMessageHandler { - /** - * Called when a message is received of the appropriate type. You can optionally return a reply message, or null if no reply - * is needed. - * - * @param message The message - * @return an optional return message - */ - REPLY onMessage(REQ message, NetworkEvent.Context ctx); -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java b/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java deleted file mode 100644 index 9da6a432d..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.simpleimpl; - -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.network.NetworkEvent; - -import net.minecraft.network.INetHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.network.FMLOutboundHandler; -import net.minecraftforge.fml.common.network.NetworkRegistry; - -import com.google.common.base.Preconditions; - -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; - -public class SimpleChannelHandlerWrapper extends SimpleChannelInboundHandler { - private final IMessageHandler messageHandler; - private final Dist side; - - public SimpleChannelHandlerWrapper(Class> handler, Dist side, Class requestType) - { - this(SimpleNetworkWrapper.instantiate(handler), side, requestType); - } - - public SimpleChannelHandlerWrapper(IMessageHandler handler, Dist side, Class requestType) - { - super(requestType); - messageHandler = Preconditions.checkNotNull(handler, "IMessageHandler must not be null"); - this.side = side; - } - @Override - protected void channelRead0(ChannelHandlerContext ctx, REQ msg) throws Exception - { - INetHandler iNetHandler = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get(); - NetworkEvent.Context context = new NetworkEvent.Context(iNetHandler, side); - REPLY result = messageHandler.onMessage(msg, context); - if (result != null) - { - ctx.channel().attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.REPLY); - ctx.writeAndFlush(result).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception - { - FMLLog.log.error("SimpleChannelHandlerWrapper exception", cause); - super.exceptionCaught(ctx, cause); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java b/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java deleted file mode 100644 index fb70d2035..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.simpleimpl; - -import net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; - -public class SimpleIndexedCodec extends FMLIndexedMessageToMessageCodec { - @Override - public void encodeInto(ChannelHandlerContext ctx, IMessage msg, ByteBuf target) throws Exception - { - msg.toBytes(target); - } - - @Override - public void decodeInto(ChannelHandlerContext ctx, ByteBuf source, IMessage msg) - { - msg.fromBytes(source); - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java b/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java deleted file mode 100644 index 2ee715221..000000000 --- a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.network.simpleimpl; - -import io.netty.channel.ChannelFutureListener; - -import java.lang.reflect.Method; -import java.util.EnumMap; - -import net.minecraft.entity.Entity; -import net.minecraft.util.IThreadListener; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelPipeline; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.network.INetHandler; -import net.minecraft.network.Packet; -import net.minecraft.tileentity.TileEntity; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.LogicalSide; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.network.FMLEmbeddedChannel; -import net.minecraftforge.fml.common.network.FMLOutboundHandler; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.NetworkRegistry.TargetPoint; - -/** - * This class is a simplified netty wrapper for those not wishing to deal with the full power of netty. - * It provides a simple message driven system, based on a discriminator byte over the custom packet channel. - * It assumes that you have a series of unique message types with each having a unique handler. Generally, context should be - * derived at message handling time. - * - * Usage is simple:
    - *
  • construct, and store, an instance of this class. It will automatically register and configure your underlying netty channel. - * - *
  • Then, call {@link #registerMessage(Class, Class, int, Dist)} for each message type you want to exchange - * providing an {@link IMessageHandler} implementation class as well as an {@link IMessage} implementation class. The side parameter - * to that method indicates which side (server or client) the message processing will occur on. The discriminator byte - * should be unique for this channelName - it is used to discriminate between different types of message that might - * occur on this channel (a simple form of message channel multiplexing, if you will). - *
  • To get a packet suitable for presenting to the rest of minecraft, you can call {@link #getPacketFrom(IMessage)}. The return result - * is suitable for returning from things like {@link TileEntity#getDescriptionPacket()} for example. - *
  • Finally, use the sendXXX to send unsolicited messages to various classes of recipients. - *
- * - * Example - * - *
- *  // Request message
- *  public Message1 implements IMessage {
- *  // message structure
- *   public fromBytes(ByteBuf buf) {
- *    // build message from byte array
- *   }
- *   public toBytes(ByteBuf buf) {
- *    // put message content into byte array
- *   }
- *  }
- *  // Reply message
- *  public Message2 implements IMessage {
- *   // stuff as before
- *  }
- *  // Message1Handler expects input of type Message1 and returns type Message2
- *  public Message1Handler implements IMessageHandler {
- *   public Message2 onMessage(Message1 message, Context ctx) {
- *    // do something and generate reply message
- *    return aMessage2Object;
- *   }
- *  }
- *  // Message2Handler expects input of type Message2 and returns no message (IMessage)
- *  public Message2Handler implements IMessageHandler {
- *   public IMessage onMessage(Message2 message, Context ctx) {
- *    // handle the message 2 response message at the other end
- *    // no reply for this message - return null
- *    return null;
- *   }
- *  }
- *
- *  // Code in a {@link FMLPreInitializationEvent} or {@link FMLInitializationEvent} handler
- *  SimpleNetworkWrapper wrapper = NetworkRegistry.newSimpleChannel("MYCHANNEL");
- *  // Message1 is handled by the Message1Handler class, it has discriminator id 1 and it's on the client
- *  wrapper.registerMessage(Message1Handler.class, Message1.class, 1, Dist.CLIENT);
- *  // Message2 is handled by the Message2Handler class, it has discriminator id 2 and it's on the server
- *  wrapper.registerMessage(Message2Handler.class, Message2.class, 2, Dist.DEDICATED_SERVER);
- *  
- *
- * - * Note: As of Minecraft 1.8 packets are by default handled on the network thread. - * That means that your {@link IMessageHandler} can not interact with most game objects directly. - * Minecraft provides a convenient way to make your code execute on the main thread instead using {@link IThreadListener#addScheduledTask(Runnable)}. - * The way to obtain an {@link IThreadListener} is using either the {@link net.minecraft.client.Minecraft} instance (client side) or a {@link net.minecraft.world.WorldServer} instance (server side). - * - * @author cpw - * - */ -public class SimpleNetworkWrapper { - private EnumMap channels; - private SimpleIndexedCodec packetCodec; - private static Class defaultChannelPipeline; - private static Method generateName; - { - try - { - defaultChannelPipeline = Class.forName("io.netty.channel.DefaultChannelPipeline"); - generateName = defaultChannelPipeline.getDeclaredMethod("generateName", ChannelHandler.class); - generateName.setAccessible(true); - } - catch (Exception e) - { - // How is this possible? - throw new RuntimeException("What? Netty isn't installed, what magic is this?", e); - } - } - public SimpleNetworkWrapper(String channelName) - { - packetCodec = new SimpleIndexedCodec(); - channels = NetworkRegistry.INSTANCE.newChannel(channelName, packetCodec); - } - - private String generateName(ChannelPipeline pipeline, ChannelHandler handler) - { - try - { - return (String)generateName.invoke(defaultChannelPipeline.cast(pipeline), handler); - } - catch (Exception e) - { - throw new RuntimeException("It appears we somehow have a not-standard pipeline. Huh", e); - } - } - /** - * Register a message and it's associated handler. The message will have the supplied discriminator byte. The message handler will - * be registered on the supplied side (this is the side where you want the message to be processed and acted upon). - * - * @param messageHandler the message handler type - * @param requestMessageType the message type - * @param discriminator a discriminator byte - * @param side the side for the handler - */ - public void registerMessage(Class> messageHandler, Class requestMessageType, int discriminator, Dist side) - { - registerMessage(instantiate(messageHandler), requestMessageType, discriminator, side); - } - - static IMessageHandler instantiate(Class> handler) - { - try - { - return handler.newInstance(); - } - catch (ReflectiveOperationException e) - { - throw new RuntimeException(e); - } - } - - /** - * Register a message and it's associated handler. The message will have the supplied discriminator byte. The message handler will - * be registered on the supplied side (this is the side where you want the message to be processed and acted upon). - * - * @param messageHandler the message handler instance - * @param requestMessageType the message type - * @param discriminator a discriminator byte - * @param side the side for the handler - */ - public void registerMessage(IMessageHandler messageHandler, Class requestMessageType, int discriminator, Dist side) - { - packetCodec.addDiscriminator(discriminator, requestMessageType); - FMLEmbeddedChannel channel = channels.get(side); - String type = channel.findChannelHandlerNameForType(SimpleIndexedCodec.class); - if (side == Dist.DEDICATED_SERVER) - { - addServerHandlerAfter(channel, type, messageHandler, requestMessageType); - } - else - { - addClientHandlerAfter(channel, type, messageHandler, requestMessageType); - } - } - - private void addServerHandlerAfter(FMLEmbeddedChannel channel, String type, IMessageHandler messageHandler, Class requestType) - { - SimpleChannelHandlerWrapper handler = getHandlerWrapper(messageHandler, Dist.DEDICATED_SERVER, requestType); - channel.pipeline().addAfter(type, generateName(channel.pipeline(), handler), handler); - } - - private void addClientHandlerAfter(FMLEmbeddedChannel channel, String type, IMessageHandler messageHandler, Class requestType) - { - SimpleChannelHandlerWrapper handler = getHandlerWrapper(messageHandler, Dist.CLIENT, requestType); - channel.pipeline().addAfter(type, generateName(channel.pipeline(), handler), handler); - } - - private SimpleChannelHandlerWrapper getHandlerWrapper(IMessageHandler messageHandler, Dist side, Class requestType) - { - return new SimpleChannelHandlerWrapper(messageHandler, side, requestType); - } - - /** - * Construct a minecraft packet from the supplied message. Can be used where minecraft packets are required, such as - * {@link TileEntity#getDescriptionPacket()}. - * - * @param message The message to translate into packet form - * @return A minecraft {@link Packet} suitable for use in minecraft APIs - */ - public Packet getPacketFrom(IMessage message) - { - return channels.get(Dist.DEDICATED_SERVER).generatePacketFrom(message); - } - - /** - * Send this message to everyone. - * The {@link IMessageHandler} for this message type should be on the CLIENT side. - * - * @param message The message to send - */ - public void sendToAll(IMessage message) - { - channels.get(Dist.DEDICATED_SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL); - channels.get(Dist.DEDICATED_SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Send this message to the specified player. - * The {@link IMessageHandler} for this message type should be on the CLIENT side. - * - * @param message The message to send - * @param player The player to send it to - */ - public void sendTo(IMessage message, EntityPlayerMP player) - { - channels.get(Dist.DEDICATED_SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER); - channels.get(Dist.DEDICATED_SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player); - channels.get(Dist.DEDICATED_SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Send this message to everyone within a certain range of a point. - * The {@link IMessageHandler} for this message type should be on the CLIENT side. - * - * @param message The message to send - * @param point The {@link TargetPoint} around which to send - */ - public void sendToAllAround(IMessage message, NetworkRegistry.TargetPoint point) - { - channels.get(Dist.DEDICATED_SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT); - channels.get(Dist.DEDICATED_SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point); - channels.get(Dist.DEDICATED_SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Sends this message to everyone tracking a point. - * The {@link IMessageHandler} for this message type should be on the CLIENT side. - * The {@code range} field of the {@link TargetPoint} is ignored. - * - * @param message The message to send - * @param point The tracked {@link TargetPoint} around which to send - */ - public void sendToAllTracking(IMessage message, NetworkRegistry.TargetPoint point) - { - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TRACKING_POINT); - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point); - channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Sends this message to everyone tracking an entity. - * The {@link IMessageHandler} for this message type should be on the CLIENT side. - * This is not equivalent to {@link #sendToAllTracking(IMessage, TargetPoint)} - * because entities have different tracking distances based on their type. - * - * @param message The message to send - * @param entity The tracked entity around which to send - */ - public void sendToAllTracking(IMessage message, Entity entity) - { - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TRACKING_ENTITY); - channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(entity); - channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Send this message to everyone within the supplied dimension. - * The {@link IMessageHandler} for this message type should be on the CLIENT side. - * - * @param message The message to send - * @param dimensionId The dimension id to target - */ - public void sendToDimension(IMessage message, int dimensionId) - { - channels.get(Dist.DEDICATED_SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION); - channels.get(Dist.DEDICATED_SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(dimensionId); - channels.get(Dist.DEDICATED_SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - /** - * Send this message to the server. - * The {@link IMessageHandler} for this message type should be on the SERVER side. - * - * @param message The message to send - */ - public void sendToServer(IMessage message) - { - channels.get(Dist.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER); - channels.get(Dist.CLIENT).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java b/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java deleted file mode 100644 index c6459bcb9..000000000 --- a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.patcher; - -public class ClassPatch { - public final String name; - public final String sourceClassName; - public final String targetClassName; - public final boolean existsAtTarget; - public final byte[] patch; - public final int inputChecksum; - public ClassPatch(String name, String sourceClassName, String targetClassName, boolean existsAtTarget, int inputChecksum, byte[] patch) - { - this.name = name; - this.sourceClassName = sourceClassName; - this.targetClassName = targetClassName; - this.existsAtTarget = existsAtTarget; - this.inputChecksum = inputChecksum; - this.patch = patch; - } - - @Override - public String toString() - { - return String.format("%s : %s => %s (%b) size %d", name, sourceClassName, targetClassName, existsAtTarget, patch.length); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java b/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java deleted file mode 100644 index 81c50cea3..000000000 --- a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.patcher; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; -import java.util.jar.JarOutputStream; -import java.util.jar.Pack200; -import java.util.regex.Pattern; - -import net.minecraft.launchwrapper.Launch; -import net.minecraft.launchwrapper.LaunchClassLoader; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.repackage.com.nothome.delta.GDiffPatcher; -import LZMA.LzmaInputStream; - -import com.google.common.base.Joiner; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.Maps; -import com.google.common.hash.Hashing; -import com.google.common.io.ByteArrayDataInput; -import com.google.common.io.ByteStreams; -import com.google.common.io.Files; - -public class ClassPatchManager { - //Must be ABOVE INSTANCE so they get set in time for the constructor. - public static final boolean dumpPatched = Boolean.parseBoolean(System.getProperty("fml.dumpPatchedClasses", "false")); - public static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("fml.debugClassPatchManager", "false")); - - public static final ClassPatchManager INSTANCE = new ClassPatchManager(); - - private GDiffPatcher patcher = new GDiffPatcher(); - private ListMultimap patches; - - private Map patchedClasses = Maps.newHashMap(); - private File tempDir; - private ClassPatchManager() - { - if (dumpPatched) - { - tempDir = Files.createTempDir(); - FMLLog.log.info("Dumping patched classes to {}",tempDir.getAbsolutePath()); - } - } - - public byte[] getPatchedResource(String name, String mappedName, LaunchClassLoader loader) throws IOException - { - byte[] rawClassBytes = loader.getClassBytes(name); - return applyPatch(name, mappedName, rawClassBytes); - } - public byte[] applyPatch(String name, String mappedName, byte[] inputData) - { - if (patches == null) - { - return inputData; - } - if (patchedClasses.containsKey(name)) - { - return patchedClasses.get(name); - } - List list = patches.get(name); - if (list.isEmpty()) - { - return inputData; - } - boolean ignoredError = false; - if (DEBUG) - FMLLog.log.debug("Runtime patching class {} (input size {}), found {} patch{}", mappedName, (inputData == null ? 0 : inputData.length), list.size(), list.size()!=1 ? "es" : ""); - for (ClassPatch patch: list) - { - if (!patch.targetClassName.equals(mappedName) && !patch.sourceClassName.equals(name)) - { - FMLLog.log.warn("Binary patch found {} for wrong class {}", patch.targetClassName, mappedName); - } - if (!patch.existsAtTarget && (inputData == null || inputData.length == 0)) - { - inputData = new byte[0]; - } - else if (!patch.existsAtTarget) - { - FMLLog.log.warn("Patcher expecting empty class data file for {}, but received non-empty", patch.targetClassName); - } - else if (patch.existsAtTarget && (inputData == null || inputData.length == 0)) - { - FMLLog.log.fatal("Patcher expecting non-empty class data file for {}, but received empty.", patch.targetClassName); - throw new RuntimeException(String.format("Patcher expecting non-empty class data file for %s, but received empty, your vanilla jar may be corrupt.", patch.targetClassName)); - } - else - { - int inputChecksum = Hashing.adler32().hashBytes(inputData).asInt(); - if (patch.inputChecksum != inputChecksum) - { - FMLLog.log.fatal("There is a binary discrepancy between the expected input class {} ({}) and the actual class. Checksum on disk is {}, in patch {}. Things are probably about to go very wrong. Did you put something into the jar file?", mappedName, name, Integer.toHexString(inputChecksum), Integer.toHexString(patch.inputChecksum)); - if (!Boolean.parseBoolean(System.getProperty("fml.ignorePatchDiscrepancies","false"))) - { - FMLLog.log.fatal("The game is going to exit, because this is a critical error, and it is very improbable that the modded game will work, please obtain clean jar files."); - System.exit(1); - } - else - { - FMLLog.log.fatal("FML is going to ignore this error, note that the patch will not be applied, and there is likely to be a malfunctioning behaviour, including not running at all"); - ignoredError = true; - continue; - } - } - } - synchronized (patcher) - { - try - { - inputData = patcher.patch(inputData, patch.patch); - } - catch (IOException e) - { - FMLLog.log.error("Encountered problem runtime patching class {}", name, e); - continue; - } - } - } - if (!ignoredError && DEBUG) - { - FMLLog.log.debug("Successfully applied runtime patches for {} (new size {})", mappedName, inputData.length); - } - if (dumpPatched) - { - try - { - Files.write(inputData, new File(tempDir,mappedName)); - } - catch (IOException e) - { - FMLLog.log.error(FMLLog.log.getMessageFactory().newMessage("Failed to write {} to {}", mappedName, tempDir.getAbsolutePath()), e); - } - } - patchedClasses.put(name,inputData); - return inputData; - } - - public void setup(Side side) - { - Pattern binpatchMatcher = Pattern.compile(String.format("binpatch/%s/.*.binpatch", side.toString().toLowerCase(Locale.ENGLISH))); - JarInputStream jis; - try - { - InputStream binpatchesCompressed = getClass().getResourceAsStream("/binpatches.pack.lzma"); - if (binpatchesCompressed==null) - { - if (!((Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"))) - { - FMLLog.log.fatal("The binary patch set is missing, things are not going to work!"); - } - return; - } - LzmaInputStream binpatchesDecompressed = new LzmaInputStream(binpatchesCompressed); - ByteArrayOutputStream jarBytes = new ByteArrayOutputStream(); - JarOutputStream jos = new JarOutputStream(jarBytes); - Pack200.newUnpacker().unpack(binpatchesDecompressed, jos); - jis = new JarInputStream(new ByteArrayInputStream(jarBytes.toByteArray())); - } - catch (Exception e) - { - throw new RuntimeException("Error occurred reading binary patches. Expect severe problems!", e); - } - - patches = ArrayListMultimap.create(); - - do - { - try - { - JarEntry entry = jis.getNextJarEntry(); - if (entry == null) - { - break; - } - if (binpatchMatcher.matcher(entry.getName()).matches()) - { - ClassPatch cp = readPatch(entry, jis); - if (cp != null) - { - patches.put(cp.sourceClassName, cp); - } - } - else - { - jis.closeEntry(); - } - } - catch (IOException e) - { - } - } while (true); - FMLLog.log.debug("Read {} binary patches", patches.size()); - if (DEBUG) - FMLLog.log.debug("Patch list :\n\t{}", Joiner.on("\t\n").join(patches.asMap().entrySet())); - patchedClasses.clear(); - } - - private ClassPatch readPatch(JarEntry patchEntry, JarInputStream jis) - { - if (DEBUG) - FMLLog.log.trace("Reading patch data from {}", patchEntry.getName()); - ByteArrayDataInput input; - try - { - input = ByteStreams.newDataInput(ByteStreams.toByteArray(jis)); - } - catch (IOException e) - { - FMLLog.log.warn(FMLLog.log.getMessageFactory().newMessage("Unable to read binpatch file {} - ignoring", patchEntry.getName()), e); - return null; - } - String name = input.readUTF(); - String sourceClassName = input.readUTF(); - String targetClassName = input.readUTF(); - boolean exists = input.readBoolean(); - int inputChecksum = 0; - if (exists) - { - inputChecksum = input.readInt(); - } - int patchLength = input.readInt(); - byte[] patchBytes = new byte[patchLength]; - input.readFully(patchBytes); - - return new ClassPatch(name, sourceClassName, targetClassName, exists, inputChecksum, patchBytes); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java b/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java deleted file mode 100644 index 7d8ebb8d1..000000000 --- a/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.patcher; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import net.minecraftforge.fml.common.asm.deobf.FMLDeobfuscatingRemapper; -import net.minecraftforge.fml.repackage.com.nothome.delta.Delta; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; - -import java.util.logging.Logger; - -import com.google.common.hash.Hashing; -import com.google.common.io.ByteArrayDataOutput; -import com.google.common.io.ByteStreams; -import com.google.common.io.Files; -import org.apache.logging.log4j.Logger; - -import javax.annotation.Nullable; - -public class GenDiffSet { - - private static final List RESERVED_NAMES = Arrays.asList("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"); - - public static void main(String[] args) throws IOException - { - String sourceJar = args[0]; //Clean Vanilla jar minecraft.jar or minecraft_server.jar - String targetDir = args[1]; //Directory containing obfed output classes, typically mcp/reobf/minecraft - String deobfData = args[2]; //Path to FML's deobfusication_data.lzma - String outputDir = args[3]; //Path to place generated .binpatch - String killTarget = args[4]; //"true" if we should destroy the target file if it generated a successful .binpatch - - LogManager.getLogger("GENDIFF").log(Level.INFO, String.format("Creating patches at %s for %s from %s", outputDir, sourceJar, targetDir)); - Delta delta = new Delta(); - FMLDeobfuscatingRemapper remapper = FMLDeobfuscatingRemapper.INSTANCE; - remapper.setupLoadOnly(deobfData, false); - JarFile sourceZip = new JarFile(sourceJar); - boolean kill = killTarget.equalsIgnoreCase("true"); - - File f = new File(outputDir); - f.mkdirs(); - - for (String name : remapper.getObfedClasses()) - { -// Logger.getLogger("GENDIFF").info(String.format("Evaluating path for data :%s",name)); - String fileName = name; - String jarName = name; - if (RESERVED_NAMES.contains(name.toUpperCase(Locale.ENGLISH))) - { - fileName = "_"+name; - } - File targetFile = new File(targetDir, fileName.replace('/', File.separatorChar) + ".class"); - jarName = jarName+".class"; - if (targetFile.exists()) - { - String sourceClassName = name.replace('/', '.'); - String targetClassName = remapper.map(name).replace('/', '.'); - JarEntry entry = sourceZip.getJarEntry(jarName); - byte[] vanillaBytes = toByteArray(sourceZip, entry); - byte[] patchedBytes = Files.toByteArray(targetFile); - - byte[] diff = delta.compute(vanillaBytes, patchedBytes); - - - ByteArrayDataOutput diffOut = ByteStreams.newDataOutput(diff.length + 50); - // Original name - diffOut.writeUTF(name); - // Source name - diffOut.writeUTF(sourceClassName); - // Target name - diffOut.writeUTF(targetClassName); - // exists at original - diffOut.writeBoolean(entry != null); - if (entry != null) - { - diffOut.writeInt(Hashing.adler32().hashBytes(vanillaBytes).asInt()); - } - // length of patch - diffOut.writeInt(diff.length); - // patch - diffOut.write(diff); - - File target = new File(outputDir, targetClassName+".binpatch"); - target.getParentFile().mkdirs(); - Files.write(diffOut.toByteArray(), target); - logger.info("Wrote patch for {} ({}) at {}", name, targetClassName, target.getAbsolutePath()); - if (kill) - { - targetFile.delete(); - logger.info(" Deleted target: {}", targetFile); - } - } - } - sourceZip.close(); - } - - private static byte[] toByteArray(JarFile sourceZip, @Nullable JarEntry entry) throws IOException - { - if (entry == null) - { - return new byte[0]; - } - - try (InputStream sourceZipInputStream = sourceZip.getInputStream(entry)) - { - return ByteStreams.toByteArray(sourceZipInputStream); - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java b/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java deleted file mode 100644 index 1bd6157db..000000000 --- a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.registry; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityList; -import net.minecraft.entity.EntityList.EntityEggInfo; -import net.minecraft.world.World; -import net.minecraftforge.registries.IForgeRegistryEntry.Impl; - -import java.util.function.Function; - -public class EntityEntry extends Impl -{ - private Class cls; - private String name; - private EntityEggInfo egg; - Function factory; - - public EntityEntry(Class cls, String name) - { - this.cls = cls; - this.name = name; - init(); - } - - //Protected method, to make this optional, in case people subclass this to have a better factory. - protected void init() - { - this.factory = new EntityEntryBuilder.ConstructorFactory(this.cls) { - @Override - protected String describeEntity() { - return String.valueOf(EntityEntry.this.getRegistryName()); - } - }; - } - - public Class getEntityClass(){ return this.cls; } - public String getName(){ return this.name; } - public EntityEggInfo getEgg(){ return this.egg; } - - public void setEgg(EntityEggInfo egg) - { - this.egg = egg; - if (this.getRegistryName() != null) - EntityList.ENTITY_EGGS.put(this.getRegistryName(), egg); - } - - public Entity newInstance(World world) - { - return this.factory.apply(world); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java b/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java deleted file mode 100644 index 913d11796..000000000 --- a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.registry; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityList; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EnumCreatureType; -import net.minecraft.stats.StatBase; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.relauncher.ReflectionHelper; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.function.Function; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -/** - * An entity registry entry builder. - * - * @param The entity type - */ -public final class EntityEntryBuilder -{ - private final ModContainer mod; - @Nullable private Class entity; - @Nullable private Function factory; - @Nullable private ResourceLocation id; - private int network; - @Nullable private String name; - private int trackingRange; - private int trackingUpdateFrequency; - private boolean trackingVelocityUpdates; - private boolean eggProvided; - private int primaryEggColor; - private int secondaryEggColor; - private boolean statisticsRegistered; - @Nullable private StatBase killEntityStatistic; - @Nullable private StatBase entityKilledByStatistic; - @Nullable private Collection spawns; - - /** - * Creates a new entity entry builder. - * - * @param The entity type - * @return A new entity entry builder - */ - @Nonnull - public static EntityEntryBuilder create() - { - return new EntityEntryBuilder<>(); - } - - private EntityEntryBuilder() - { - this.mod = Loader.instance().activeModContainer(); - } - - /** - * Sets the class of the entity. - * - *

Entities will be constructed using a constructor accepting {@link World}. If you wish - * to use your own factory, use {@link #factory(Function)}.

- * - * @param entity The entity class - * @return This builder - * @throws NullPointerException If {@code entity} is {@code null} - */ - @Nonnull - public final EntityEntryBuilder entity(@Nonnull final Class entity) - { - this.entity = checkNotNull(entity, "entity class"); - return this; - } - - /** - * Sets the factory of the entity. - * - * @param factory The entity factory - * @return This builder - * @throws NullPointerException If {@code entity} is {@code null} - */ - @Nonnull - public final EntityEntryBuilder factory(@Nonnull final Function factory) - { - this.factory = checkNotNull(factory, "entity factory"); - return this; - } - - /** - * Sets the id of the entity. - * - * @param id The entity id - * @param network The network id - * @return This builder - * @throws NullPointerException If {@code id} is {@code null} - */ - @Nonnull - public final EntityEntryBuilder id(@Nonnull final ResourceLocation id, final int network) - { - this.id = checkNotNull(id, "id"); - this.network = network; - return this; - } - - /** - * Sets the id of the entity. - * - * @param id The entity id - * @param network The network id - * @return This builder - * @throws NullPointerException If {@code id} is {@code null} - */ - @Nonnull - public final EntityEntryBuilder id(@Nonnull final String id, final int network) - { - checkNotNull(id, "id"); - return this.id(new ResourceLocation(id.indexOf(':') == -1 ? this.mod.getModId() + ':' + id : id), network); - } - - /** - * Sets the name of the entity. - * - * @param name The entity name - * @return This builder - * @throws NullPointerException If {@code name} is {@code null} - */ - @Nonnull - public final EntityEntryBuilder name(@Nonnull final String name) - { - this.name = checkNotNull(name, "name"); - return this; - } - - /** - * Sets entity tracking information. - * - * @param range The tracking range - * @param updateFrequency The tracking update frequency - * @param sendVelocityUpdates If the entity should send velocity updates - * @return This builder - */ - @Nonnull - public final EntityEntryBuilder tracker(final int range, final int updateFrequency, final boolean sendVelocityUpdates) - { - this.trackingRange = range; - this.trackingUpdateFrequency = updateFrequency; - this.trackingVelocityUpdates = sendVelocityUpdates; - return this; - } - - /** - * Adds a spawn entry. - * - * @param type The creature type - * @param weight The spawn entry weight - * @param min The minimum spawn count - * @param max The maximum spawn count - * @param biomes The biomes to add an entry in - * @return This builder - * @throws IllegalArgumentException If the entity is not a {@link EntityLiving} - * @throws NullPointerException If {@code type} is {@code null} - * @throws NullPointerException If {@code biomes} is {@code null} - */ - @Nonnull - public final EntityEntryBuilder spawn(@Nonnull final EnumCreatureType type, final int weight, final int min, final int max, @Nonnull final Biome... biomes) - { - checkNotNull(biomes, "biomes"); - return this.spawn(type, weight, min, max, Arrays.asList(biomes)); - } - - /** - * Adds a spawn entry. - * - * @param type The creature type - * @param weight The spawn entry weight - * @param min The minimum spawn count - * @param max The maximum spawn count - * @param biomes The biomes to add an entry in - * @return This builder - * @throws IllegalArgumentException If the entity is not a {@link EntityLiving} - * @throws NullPointerException If {@code type} is {@code null} - * @throws NullPointerException If {@code biomes} is {@code null} - */ - @Nonnull - public final EntityEntryBuilder spawn(@Nonnull final EnumCreatureType type, final int weight, final int min, final int max, @Nonnull final Iterable biomes) - { - checkNotNull(type, "type"); - checkNotNull(biomes, "biomes"); - if (this.entity != null) checkArgument(EntityLiving.class.isAssignableFrom(this.entity), "Cannot add spawns to a non-%s", EntityLiving.class.getSimpleName()); - if (this.spawns == null) this.spawns = new ArrayList<>(); - this.spawns.add(new Spawn(type, weight, min, max, biomes)); - return this; - } - - /** - * Sets the egg of the entity. - * - * @param primaryColor the primary egg color - * @param secondaryColor the secondary egg color - * @return This builder - */ - @Nonnull - public final EntityEntryBuilder egg(final int primaryColor, final int secondaryColor) - { - this.eggProvided = true; - this.primaryEggColor = primaryColor; - this.secondaryEggColor = secondaryColor; - return this; - } - - /** - * Create an entity entry based on the data in this builder. - * - * @return The entity entry - * @throws IllegalStateException If the entity class has not been provided - * @throws IllegalStateException If the entity id has not been provided - * @throws IllegalStateException If the entity name has not been provided - * @throws IllegalStateException If spawns have been provided for a non {@link EntityLiving} - * @throws ReflectionHelper.UnknownConstructorException If a {@link #factory} has not been provided - * and {@link #entity} does not have a constructor accepting {@link World} - */ - @Nonnull - public EntityEntry build() - { - checkState(this.entity != null, "entity class not provided"); - checkState(this.id != null, "entity id not provided"); - checkState(this.name != null, "entity name not provided"); - if (this.spawns != null) checkState(EntityLiving.class.isAssignableFrom(EntityEntryBuilder.this.entity), "Cannot add spawns to a non-%s", EntityLiving.class.getSimpleName()); - final BuiltEntityEntry entry = new BuiltEntityEntry(this.entity, this.name); - entry.factory = this.factory != null ? this.factory : new ConstructorFactory(this.entity) { - @Override - protected String describeEntity() { - return String.valueOf(EntityEntryBuilder.this.id); - } - }; - entry.setRegistryName(this.id); - if (this.eggProvided) - { - this.killEntityStatistic = new StatBase("stat.killEntity." + this.name, new TextComponentTranslation("stat.entityKill", new TextComponentTranslation("entity." + this.name + ".name"))); - this.entityKilledByStatistic = new StatBase("stat.entityKilledBy." + this.name, new TextComponentTranslation("stat.entityKilledBy", new TextComponentTranslation("entity." + this.name + ".name"))); - entry.setEgg(new EntityList.EntityEggInfo(this.id, this.primaryEggColor, this.secondaryEggColor, this.killEntityStatistic, this.entityKilledByStatistic)); - } - return entry; - } - - private void registerStatistics() - { - if (!this.statisticsRegistered && (this.killEntityStatistic != null && this.entityKilledByStatistic != null)) - { - this.killEntityStatistic.registerStat(); - this.entityKilledByStatistic.registerStat(); - this.statisticsRegistered = true; - } - } - - static abstract class ConstructorFactory implements Function - { - private final Constructor constructor; - - ConstructorFactory(final Class entity) - { - this.constructor = ReflectionHelper.findConstructor(entity, World.class); - } - - @Override - public E apply(final World world) - { - try - { - return this.constructor.newInstance(world); - } - catch (final IllegalAccessException | InstantiationException | InvocationTargetException e) - { - FMLLog.log.error("Encountered an exception while constructing entity '{}'", this.describeEntity(), e); - return null; - } - } - - protected abstract String describeEntity(); - } - - public final class BuiltEntityEntry extends EntityEntry - { - private boolean added; - - BuiltEntityEntry(final Class cls, final String name) - { - super(cls, name); - } - - @Override - protected final void init() { - // NOOP - we handle this in build - } - - public final void addedToRegistry() - { - if (this.added) return; - this.added = true; - EntityEntryBuilder.this.registerStatistics(); - EntityRegistry.instance().insert(EntityEntryBuilder.this.entity, createRegistration()); - if (EntityEntryBuilder.this.spawns != null) - { - for (final Spawn spawn : EntityEntryBuilder.this.spawns) - { - spawn.insert(); - } - EntityEntryBuilder.this.spawns = null; - } - } - - @Nonnull - private EntityRegistry.EntityRegistration createRegistration() - { - EntityEntryBuilder builder = EntityEntryBuilder.this; - return EntityRegistry.instance().new EntityRegistration( - builder.mod, builder.id, builder.entity, builder.name, builder.network, - builder.trackingRange, builder.trackingUpdateFrequency, builder.trackingVelocityUpdates, this.factory - ); - } - - } - - public final class Spawn - { - private final EnumCreatureType type; - private final int weight; - private final int min; - private final int max; - private final Iterable biomes; - - public Spawn(final EnumCreatureType type, final int weight, final int min, final int max, final Iterable biomes) - { - this.type = type; - this.weight = weight; - this.min = min; - this.max = max; - this.biomes = biomes; - } - - @SuppressWarnings("unchecked") - final void insert() - { - for (final Biome biome : this.biomes) { - final List entries = biome.getSpawnableList(this.type); - boolean found = false; - for (final Biome.SpawnListEntry entry : entries) { - if (entry.entityClass == EntityEntryBuilder.this.entity) { - entry.itemWeight = this.weight; - entry.minGroupCount = this.min; - entry.maxGroupCount = this.max; - found = true; - break; - } - } - if (!found) entries.add(new Biome.SpawnListEntry((Class) EntityEntryBuilder.this.entity, this.weight, this.min, this.max)); - } - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java deleted file mode 100644 index 2ca959d13..000000000 --- a/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.registry; - -import java.util.List; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityList.EntityEggInfo; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityTracker; -import net.minecraft.entity.EnumCreatureType; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.Biome.SpawnListEntry; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.common.network.internal.FMLMessage.EntitySpawnMessage; - -import java.util.function.Function; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.ListMultimap; - -import javax.annotation.Nullable; - -public class EntityRegistry -{ - public class EntityRegistration - { - @Deprecated - private Class entityClass; - private Function factory; - private ModContainer container; - private ResourceLocation regName; - private String entityName; - private int modId; - private int trackingRange; - private int updateFrequency; - private boolean sendsVelocityUpdates; - private Function customSpawnCallback; - private boolean usesVanillaSpawning; - - @Deprecated //1.13 - public EntityRegistration(ModContainer mc, ResourceLocation registryName, Class entityClass, String entityName, int id, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates) - { - this(mc, registryName, entityClass, entityName, id, trackingRange, updateFrequency, sendsVelocityUpdates, null); - } - - public EntityRegistration(ModContainer mc, ResourceLocation registryName, Class entityClass, String entityName, int id, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates, Function factory) - { - this.container = mc; - this.regName = registryName; - this.entityClass = entityClass; - this.entityName = entityName; - this.modId = id; - this.trackingRange = trackingRange; - this.updateFrequency = updateFrequency; - this.sendsVelocityUpdates = sendsVelocityUpdates; - this.factory = factory != null ? factory : - new EntityEntryBuilder.ConstructorFactory(entityClass) { - @Override - protected String describeEntity() { - return String.valueOf(EntityRegistration.this.getRegistryName()); - } - }; - } - public ResourceLocation getRegistryName() - { - return regName; - } - @Deprecated //Used only for creating a new instance in EntitySpawnHandler, use newInstance(world) instead. - public Class getEntityClass() - { - return entityClass; - } - public Entity newInstance(World world) - { - return this.factory.apply(world); - } - public ModContainer getContainer() - { - return container; - } - public String getEntityName() - { - return entityName; - } - public int getModEntityId() - { - return modId; - } - public int getTrackingRange() - { - return trackingRange; - } - public int getUpdateFrequency() - { - return updateFrequency; - } - public boolean sendsVelocityUpdates() - { - return sendsVelocityUpdates; - } - - public boolean usesVanillaSpawning() - { - return usesVanillaSpawning; - } - public boolean hasCustomSpawning() - { - return customSpawnCallback != null; - } - public Entity doCustomSpawning(EntitySpawnMessage spawnMsg) throws Exception - { - return customSpawnCallback.apply(spawnMsg); - } - public void setCustomSpawning(Function callable, boolean usesVanillaSpawning) - { - this.customSpawnCallback = callable; - this.usesVanillaSpawning = usesVanillaSpawning; - } - } - - private static final EntityRegistry INSTANCE = new EntityRegistry(); - - private ListMultimap entityRegistrations = ArrayListMultimap.create(); - private BiMap, EntityRegistration> entityClassRegistrations = HashBiMap.create(); - - public static EntityRegistry instance() - { - return INSTANCE; - } - - private EntityRegistry() - { - } - - /** - * Register the mod entity type with FML - - * @param entityClass The entity class - * @param entityName A unique name for the entity - * @param id A mod specific ID for the entity - * @param mod The mod - * @param trackingRange The range at which MC will send tracking updates - * @param updateFrequency The frequency of tracking updates - * @param sendsVelocityUpdates Whether to send velocity information packets as well - */ - public static void registerModEntity(ResourceLocation registryName, Class entityClass, String entityName, int id, Object mod, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates) - { - instance().doModEntityRegistration(registryName, entityClass, entityName, id, mod, trackingRange, updateFrequency, sendsVelocityUpdates); - } - - /** - * Register the mod entity type with FML - * This will also register a spawn egg. - - * @param entityClass The entity class - * @param entityName A unique name for the entity - * @param id A mod specific ID for the entity - * @param mod The mod - * @param trackingRange The range at which MC will send tracking updates - * @param updateFrequency The frequency of tracking updates - * @param sendsVelocityUpdates Whether to send velocity information packets as well - * @param eggPrimary Primary egg color - * @param eggSecondary Secondary egg color - */ - public static void registerModEntity(ResourceLocation registryName, Class entityClass, String entityName, int id, Object mod, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates, int eggPrimary, int eggSecondary) - { - instance().doModEntityRegistration(registryName, entityClass, entityName, id, mod, trackingRange, updateFrequency, sendsVelocityUpdates); - EntityRegistry.registerEgg(registryName, eggPrimary, eggSecondary); - } - - private void doModEntityRegistration(ResourceLocation registryName, Class entityClass, String entityName, int id, Object mod, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates) - { - ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod); - EntityRegistration er = new EntityRegistration(mc, registryName, entityClass, entityName, id, trackingRange, updateFrequency, sendsVelocityUpdates); - try - { - entityClassRegistrations.put(entityClass, er); - if (!ForgeRegistries.ENTITIES.containsKey(registryName)) - { - EntityEntry entry = new EntityEntry(entityClass, entityName).setRegistryName(registryName); - ForgeRegistries.ENTITIES.register(entry); - FMLLog.log.trace("Automatically registered mod {} entity {} as {}", mc.getModId(), entityName, entry.getRegistryName()); - } - else - { - FMLLog.log.debug("Skipping automatic mod {} entity registration for already registered entry {} class {}", mc.getModId(), registryName, entityClass.getName()); - } - } - catch (IllegalArgumentException e) - { - FMLLog.log.warn("The mod {} tried to register the entity (registry,name,class) ({},{},{}) one or both of which are already registered", mc.getModId(), registryName, entityName, entityClass.getName(), e); - return; - } - entityRegistrations.put(mc, er); - } - - /** - * Registers a spawn egg for the specified entity class. - * The class must already be registered in the EntityList.classToStringMapping. - * This can be done either by using the global ID system, or preferably the registerModEntity functions above. - * Once registered mob eggs can be created by using minecraft:spawn_egg with NBT entry 'entity_name' with - * value of the name this class is registered in the classToStringMapping with. - * - * @param name The entity ResourceLocation - * @param primary Primary egg color - * @param secondary Secondary egg color - * - */ - public static void registerEgg(ResourceLocation name, int primary, int secondary) - { - EntityEntry entry = ForgeRegistries.ENTITIES.getValue(name); - if (entry == null) - { - FMLLog.bigWarning("Attempted to registry a entity egg for entity ({}) that is not in the Entity Registry", name); - return; - } - entry.setEgg(new EntityEggInfo(name, primary, secondary)); - } - - /** - * Add a spawn entry for the supplied entity in the supplied {@link Biome} list - * @param entityClass Entity class added - * @param weightedProb Probability - * @param min Min spawn count - * @param max Max spawn count - * @param typeOfCreature Type of spawn - * @param biomes List of biomes - */ - public static void addSpawn(Class entityClass, int weightedProb, int min, int max, EnumCreatureType typeOfCreature, Biome... biomes) - { - for (Biome biome : biomes) - { - List spawns = biome.getSpawnableList(typeOfCreature); - - boolean found = false; - for (SpawnListEntry entry : spawns) - { - //Adjusting an existing spawn entry - if (entry.entityClass == entityClass) - { - entry.itemWeight = weightedProb; - entry.minGroupCount = min; - entry.maxGroupCount = max; - found = true; - break; - } - } - - if (!found) - spawns.add(new SpawnListEntry(entityClass, weightedProb, min, max)); - } - } - - /** - * Add a spawn entry for the supplied entity in the supplied {@link Biome} list - * @param entityName The entity name - * @param weightedProb Probability - * @param min Min spawn count - * @param max Max spawn count - * @param typeOfCreature type of spawn - * @param biomes List of biomes - */ - @SuppressWarnings("unchecked") - public static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType typeOfCreature, Biome... biomes) - { - Class entityClazz = null; - - if (EntityLiving.class.isAssignableFrom(entityClazz)) - { - addSpawn((Class ) entityClazz, weightedProb, min, max, typeOfCreature, biomes); - } - } - - /** - * Remove the spawn entry for the supplied entity - * @param entityClass The entity class - * @param typeOfCreature type of spawn - * @param biomes Biomes to remove from - */ - public static void removeSpawn(Class entityClass, EnumCreatureType typeOfCreature, Biome... biomes) - { - for (Biome biome : biomes) - { - biome.getSpawnableList(typeOfCreature).removeIf(entry -> entry.entityClass == entityClass); - } - } - - /** - * Remove the spawn entry for the supplied entity - * @param entityName Name of entity being removed - * @param typeOfCreature type of spawn - * @param biomes Biomes to remove from - */ - @SuppressWarnings("unchecked") - public static void removeSpawn(String entityName, EnumCreatureType typeOfCreature, Biome... biomes) - { - Class entityClazz = null; - - if (EntityLiving.class.isAssignableFrom(entityClazz)) - { - removeSpawn((Class ) entityClazz, typeOfCreature, biomes); - } - } - - @Nullable - public EntityRegistration lookupModSpawn(Class clazz, boolean keepLooking) - { - Class localClazz = clazz; - - do - { - EntityRegistration er = entityClassRegistrations.get(localClazz); - if (er != null) - { - return er; - } - localClazz = localClazz.getSuperclass(); - keepLooking &= (!Object.class.equals(localClazz)); - } - while (keepLooking); - - return null; - } - - @Nullable - public EntityRegistration lookupModSpawn(ModContainer mc, int modEntityId) - { - for (EntityRegistration er : entityRegistrations.get(mc)) - { - if (er.getModEntityId() == modEntityId) - { - return er; - } - } - return null; - } - - public boolean tryTrackingEntity(EntityTracker entityTracker, Entity entity) - { - - EntityRegistration er = lookupModSpawn(entity.getClass(), true); - if (er != null) - { - entityTracker.track(entity, er.getTrackingRange(), er.getUpdateFrequency(), er.sendsVelocityUpdates()); - return true; - } - return false; - } - - //Helper function - @Nullable - public static EntityEntry getEntry(Class entry) - { - //TODO: Slave map for faster lookup? - for (EntityEntry e : ForgeRegistries.ENTITIES) - { - if (e.getEntityClass() == entry) - return e; - } - return null; - } - - // This is an internal method - do not touch. - final void insert(final Class entity, final EntityRegistration registration) - { - this.entityClassRegistrations.put(entity, registration); - this.entityRegistrations.put(registration.container, registration); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java b/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java index 67b9f7b03..624368584 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java @@ -21,6 +21,7 @@ package net.minecraftforge.fml.common.registry; import net.minecraft.block.Block; import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.Entity; import net.minecraft.init.Bootstrap; import net.minecraft.item.Item; import net.minecraft.item.crafting.IRecipe; @@ -31,6 +32,7 @@ import net.minecraft.world.biome.Biome; import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession; import net.minecraftforge.registries.GameData; import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.RegistryManager; /** * A class that exposes static references to all vanilla and Forge registries. @@ -41,16 +43,16 @@ public class ForgeRegistries { static { init(); } // This must be above the fields so we guarantee it's run before findRegistry is called. Yay static inializers - public static final IForgeRegistry BLOCKS = GameRegistry.findRegistry(Block.class); - public static final IForgeRegistry ITEMS = GameRegistry.findRegistry(Item.class); - public static final IForgeRegistry POTIONS = GameRegistry.findRegistry(Potion.class); - public static final IForgeRegistry BIOMES = GameRegistry.findRegistry(Biome.class); - public static final IForgeRegistry SOUND_EVENTS = GameRegistry.findRegistry(SoundEvent.class); - public static final IForgeRegistry POTION_TYPES = GameRegistry.findRegistry(PotionType.class); - public static final IForgeRegistry ENCHANTMENTS = GameRegistry.findRegistry(Enchantment.class); - public static final IForgeRegistry VILLAGER_PROFESSIONS = GameRegistry.findRegistry(VillagerProfession.class); - public static final IForgeRegistry ENTITIES = GameRegistry.findRegistry(EntityEntry.class); - public static final IForgeRegistry RECIPES = GameRegistry.findRegistry(IRecipe.class); + public static final IForgeRegistry BLOCKS = RegistryManager.ACTIVE.getRegistry(Block.class); + public static final IForgeRegistry ITEMS = RegistryManager.ACTIVE.getRegistry(Item.class); + public static final IForgeRegistry POTIONS = RegistryManager.ACTIVE.getRegistry(Potion.class); + public static final IForgeRegistry BIOMES = RegistryManager.ACTIVE.getRegistry(Biome.class); + public static final IForgeRegistry SOUND_EVENTS = RegistryManager.ACTIVE.getRegistry(SoundEvent.class); + public static final IForgeRegistry POTION_TYPES = RegistryManager.ACTIVE.getRegistry(PotionType.class); + public static final IForgeRegistry ENCHANTMENTS = RegistryManager.ACTIVE.getRegistry(Enchantment.class); + public static final IForgeRegistry VILLAGER_PROFESSIONS = RegistryManager.ACTIVE.getRegistry(VillagerProfession.class); + public static final IForgeRegistry ENTITIES = RegistryManager.ACTIVE.getRegistry(Entity.class); + public static final IForgeRegistry RECIPES = RegistryManager.ACTIVE.getRegistry(IRecipe.class); /** diff --git a/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java index 5c2f09674..9cb165999 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java @@ -19,171 +19,13 @@ package net.minecraftforge.fml.common.registry; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; - -import com.google.common.base.Predicate; -import net.minecraft.block.Block; -import net.minecraft.command.EntitySelector; -import net.minecraft.command.ICommandSender; -import net.minecraft.entity.Entity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.FurnaceRecipes; -import net.minecraft.item.crafting.Ingredient; -import net.minecraft.item.crafting.ShapedRecipes; -import net.minecraft.item.crafting.ShapelessRecipes; -import net.minecraft.nbt.JsonToNBT; -import net.minecraft.nbt.NBTException; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.NonNullList; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; -import net.minecraft.world.chunk.IChunkProvider; -import net.minecraft.world.gen.IChunkGenerator; -import net.minecraftforge.common.crafting.CraftingHelper; -import net.minecraftforge.common.crafting.CraftingHelper.ShapedPrimer; -import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.IFuelHandler; -import net.minecraftforge.fml.common.IWorldGenerator; -import net.minecraftforge.registries.GameData; import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.registries.IForgeRegistryEntry; import net.minecraftforge.registries.RegistryManager; -import net.minecraftforge.fml.common.IEntitySelectorFactory; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -import javax.annotation.Nonnull; public class GameRegistry { - private static Set worldGenerators = Sets.newHashSet(); - private static Map worldGeneratorIndex = Maps.newHashMap(); - private static List fuelHandlers = Lists.newArrayList(); - private static List sortedGeneratorList; - private static List entitySelectorFactories = Lists.newArrayList(); - - /** - * Register a world generator - something that inserts new block types into the world - * - * @param generator the generator - * @param modGenerationWeight a weight to assign to this generator. Heavy weights tend to sink to the bottom of - * list of world generators (i.e. they run later) - */ - public static void registerWorldGenerator(IWorldGenerator generator, int modGenerationWeight) - { - worldGenerators.add(generator); - worldGeneratorIndex.put(generator, modGenerationWeight); - if (sortedGeneratorList != null) - { - sortedGeneratorList = null; - } - } - - /** - * Registers a entity selector factory which is used to create predicates whenever a command containing selectors is executed - * Any non vanilla arguments that you expect has to be registered. Otherwise Minecraft will throw an CommandException on usage. - * - * If you want to react to a command like "/kill @e[xyz=5]", you would have to register the argument "xyz" here and check for that argument in the factory. - * One factory can listen to any number of arguments as long as they are registered here. - * - * For inter mod compatibility you might want to use "modid:xyz" (e.g. "forge:min_health") as argument. - * - * For an example usage, see CustomEntitySelectorTest - * @param arguments Expected string arguments in commands - */ - public static void registerEntitySelector(IEntitySelectorFactory factory, String... arguments) - { - entitySelectorFactories.add(factory); - for (String s : arguments) - { - EntitySelector.addArgument(s); - } - } - - /** - * Creates a list of entity selectors using the registered factories. - * Should probably only be called by Forge - */ - public static List> createEntitySelectors(Map arguments, String mainSelector, ICommandSender sender, Vec3d position) - { - List> selectors = Lists.newArrayList(); - for (IEntitySelectorFactory factory : entitySelectorFactories) - { - try - { - selectors.addAll(factory.createPredicates(arguments, mainSelector, sender, position)); - } - catch (Exception e) - { - FMLLog.log.error("Exception caught during entity selector creation with {} for argument map {} of {} for {} at {}", factory, - arguments, mainSelector, sender, position, e); - } - } - return selectors; - } - - /** - * Callback hook for world gen - if your mod wishes to add extra mod related generation to the world - * call this - * - * @param chunkX Chunk X coordinate - * @param chunkZ Chunk Z coordinate - * @param world World we're generating into - * @param chunkGenerator The chunk generator - * @param chunkProvider The chunk provider - */ - public static void generateWorld(int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) - { - if (sortedGeneratorList == null) - { - computeSortedGeneratorList(); - } - long worldSeed = world.getSeed(); - Random fmlRandom = new Random(worldSeed); - long xSeed = fmlRandom.nextLong() >> 2 + 1L; - long zSeed = fmlRandom.nextLong() >> 2 + 1L; - long chunkSeed = (xSeed * chunkX + zSeed * chunkZ) ^ worldSeed; - - for (IWorldGenerator generator : sortedGeneratorList) - { - fmlRandom.setSeed(chunkSeed); - generator.generate(fmlRandom, chunkX, chunkZ, world, chunkGenerator, chunkProvider); - } - } - - private static void computeSortedGeneratorList() - { - ArrayList list = Lists.newArrayList(worldGenerators); - list.sort(Comparator.comparingInt(o -> worldGeneratorIndex.get(o))); - sortedGeneratorList = ImmutableList.copyOf(list); - } - - /** - * This is now private, you should use either ForgeRegistries constants. - * Or the registry passed in during the RegistryEvent.Register event. - */ - private static > K register(K object) - { - return (K)GameData.register_impl(object); - } - /** * Retrieves the registry associated with this super class type. * If the return is non-null it is HIGHLY recommended that modders cache this @@ -196,170 +38,4 @@ public class GameRegistry { return RegistryManager.ACTIVE.getRegistry(registryType); } - - public static void addShapedRecipe(ResourceLocation name, ResourceLocation group, @Nonnull ItemStack output, Object... params) - { - ShapedPrimer primer = CraftingHelper.parseShaped(params); - register(new ShapedRecipes(group == null ? "" : group.toString(), primer.width, primer.height, primer.input, output).setRegistryName(name)); - } - - public static void addShapelessRecipe(ResourceLocation name, ResourceLocation group, @Nonnull ItemStack output, Ingredient... params) - { - NonNullList lst = NonNullList.create(); - for (Ingredient i : params) - lst.add(i); - register(new ShapelessRecipes(group == null ? "" : group.toString(), output, lst).setRegistryName(name)); - } - - public static void addSmelting(Block input, @Nonnull ItemStack output, float xp) - { - FurnaceRecipes.instance().addSmeltingRecipeForBlock(input, output, xp); - } - - public static void addSmelting(Item input, @Nonnull ItemStack output, float xp) - { - FurnaceRecipes.instance().addSmelting(input, output, xp); - } - - public static void addSmelting(@Nonnull ItemStack input, @Nonnull ItemStack output, float xp) - { - FurnaceRecipes.instance().addSmeltingRecipe(input, output, xp); - } - - @Deprecated //TODO: Remove in 1.13, Use ResourceLocation version. - public static void registerTileEntity(Class tileEntityClass, String key) - { - // As return is ignored for compatibility, always check namespace - GameData.checkPrefix(new ResourceLocation(key).toString()); - TileEntity.register(key, tileEntityClass); - } - - public static void registerTileEntity(Class tileEntityClass, ResourceLocation key) - { - registerTileEntity(tileEntityClass, key.toString()); - } - - /** - * @deprecated set your item's {@link Item#getItemBurnTime(ItemStack)} or subscribe to {@link FurnaceFuelBurnTimeEvent} instead. - */ - @Deprecated - public static void registerFuelHandler(IFuelHandler handler) - { - fuelHandlers.add(handler); - } - - /** - * @deprecated use {@link ForgeEventFactory#getItemBurnTime(ItemStack)} - */ - @Deprecated - public static int getFuelValue(@Nonnull ItemStack itemStack) - { - return ForgeEventFactory.getItemBurnTime(itemStack); - } - - /** - * @deprecated use {@link ForgeEventFactory#getItemBurnTime(ItemStack)} - */ - @Deprecated - public static int getFuelValueLegacy(@Nonnull ItemStack itemStack) - { - int fuelValue = 0; - for (IFuelHandler handler : fuelHandlers) - { - fuelValue = Math.max(fuelValue, handler.getBurnTime(itemStack)); - } - return fuelValue; - } - - /** - * ObjectHolder can be used to automatically populate public static final fields with entries - * from the registry. These values can then be referred within mod code directly. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.TYPE, ElementType.FIELD}) - public @interface ObjectHolder - { - /** - * If used on a class, this represents a modid only. - * If used on a field, it represents a name, which can be abbreviated or complete. - * Abbreviated names derive their modid from an enclosing ObjectHolder at the class level. - * - * @return either a modid or a name based on the rules above - */ - String value(); - } - - /** - * ItemStackHolder can be used to automatically populate public static final fields with - * {@link ItemStack} instances, referring a specific item, potentially configured with NBT. - * These values can then be used in things like recipes and other places where ItemStacks - * might be required. - *

- * If the item is not found, the field will be populated with null. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface ItemStackHolder - { - /** - * The registry name of the item being looked up. - * - * @return The registry name - */ - String value(); - - /** - * The metadata or damage value for the itemstack, defaults to 0. - * - * @return the metadata value - */ - int meta() default 0; - - /** - * The string serialized nbt value for the itemstack. Defaults to empty for no nbt. - * - * @return a nbt string - */ - String nbt() default ""; - } - - /** - * Makes an {@link ItemStack} based on the itemName reference, with supplied meta, stackSize and nbt, if possible - *

- * Will return null if the item doesn't exist (because it's not from a loaded mod for example) - * Will throw a {@link RuntimeException} if the nbtString is invalid for use in an {@link ItemStack} - * - * @param itemName a registry name reference - * @param meta the meta - * @param stackSize the stack size - * @param nbtString an nbt stack as a string, will be processed by {@link JsonToNBT} - * @return a new itemstack - */ - @Nonnull - public static ItemStack makeItemStack(String itemName, int meta, int stackSize, String nbtString) - { - if (itemName == null) - { - throw new IllegalArgumentException("The itemName cannot be null"); - } - Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemName)); - if (item == null) - { - FMLLog.log.trace("Unable to find item with name {}", itemName); - return ItemStack.EMPTY; - } - ItemStack is = new ItemStack(item, stackSize, meta); - if (!Strings.isNullOrEmpty(nbtString)) - { - try - { - is.setTagCompound(JsonToNBT.getTagFromJson(nbtString)); - } - catch (NBTException e) - { - throw new RuntimeException("Encountered an exception parsing ItemStack NBT string " + nbtString, e); - } - } - return is; - } } diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java b/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java deleted file mode 100644 index da24e6818..000000000 --- a/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.registry; - -import java.lang.reflect.Field; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import net.minecraftforge.fml.common.FMLLog; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -public enum ItemStackHolderInjector -{ - INSTANCE; - - private List itemStackHolders = Lists.newArrayList(); - - public void inject() { - FMLLog.log.info("Injecting itemstacks"); - for (ItemStackHolderRef ishr: itemStackHolders) { - ishr.apply(); - } - FMLLog.log.info("Itemstack injection complete"); - } - - public void findHolders(ASMDataTable table) { - FMLLog.log.info("Identifying ItemStackHolder annotations"); - Set allItemStackHolders = table.getAll(GameRegistry.ItemStackHolder.class.getName()); - Map> classCache = Maps.newHashMap(); - for (ASMData data : allItemStackHolders) - { - String className = data.getClassName(); - String annotationTarget = data.getObjectName(); - String value = (String) data.getAnnotationInfo().get("value"); - int meta = data.getAnnotationInfo().containsKey("meta") ? (Integer) data.getAnnotationInfo().get("meta") : 0; - String nbt = data.getAnnotationInfo().containsKey("nbt") ? (String) data.getAnnotationInfo().get("nbt") : ""; - addHolder(classCache, className, annotationTarget, value, meta, nbt); - } - FMLLog.log.info("Found {} ItemStackHolder annotations", allItemStackHolders.size()); - - } - - private void addHolder(Map> classCache, String className, String annotationTarget, String value, Integer meta, String nbt) - { - Class clazz; - if (classCache.containsKey(className)) - { - clazz = classCache.get(className); - } - else - { - try - { - clazz = Class.forName(className, true, getClass().getClassLoader()); - classCache.put(className, clazz); - } - catch (ClassNotFoundException ex) - { - // unpossible? - throw new RuntimeException(ex); - } - } - try - { - Field f = clazz.getField(annotationTarget); - itemStackHolders.add(new ItemStackHolderRef(f, value, meta, nbt)); - } - catch (NoSuchFieldException ex) - { - // unpossible? - throw new RuntimeException(ex); - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java b/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java deleted file mode 100644 index bfc0600fb..000000000 --- a/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.registry; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.FMLLog; - -/** - * Internal class used in tracking {@link GameRegistry.ItemStackHolder} references - * - * @author cpw - * - */ -class ItemStackHolderRef { - private Field field; - private String itemName; - private int meta; - private String serializednbt; - - - ItemStackHolderRef(Field field, String itemName, int meta, String serializednbt) - { - this.field = field; - this.itemName = itemName; - this.meta = meta; - this.serializednbt = serializednbt; - makeWritable(field); - } - - private static Field modifiersField; - private static Object reflectionFactory; - private static Method newFieldAccessor; - private static Method fieldAccessorSet; - private static void makeWritable(Field f) - { - try - { - if (modifiersField == null) - { - Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory"); - reflectionFactory = getReflectionFactory.invoke(null); - newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class); - fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class); - modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - } - modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL); - } - catch (ReflectiveOperationException e) - { - throw new RuntimeException(e); - } - } - - public void apply() - { - ItemStack is; - try - { - is = GameRegistry.makeItemStack(itemName, meta, 1, serializednbt); - } catch (RuntimeException e) - { - FMLLog.log.error("Caught exception processing itemstack {},{},{} in annotation at {}.{}", itemName, meta, serializednbt,field.getClass().getName(),field.getName()); - throw e; - } - try - { - Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false); - fieldAccessorSet.invoke(fieldAccessor, null, is); - } - catch (Exception e) - { - FMLLog.log.warn("Unable to set {} with value {},{},{}", this.field, this.itemName, this.meta, this.serializednbt); - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java index 7d4705a57..08c17dc14 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java @@ -26,18 +26,13 @@ import java.util.Random; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import net.minecraft.entity.monster.EntityZombieVillager; +import net.minecraftforge.fml.RegistryObject; import org.apache.commons.lang3.Validate; import net.minecraft.entity.passive.EntityVillager; -import net.minecraft.entity.passive.EntityVillager.ITradeList; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.registry.RegistryNamespaced; -import net.minecraft.world.gen.structure.StructureComponent; -import net.minecraft.world.gen.structure.StructureVillagePieces; -import net.minecraft.world.gen.structure.StructureVillagePieces.PieceWeight; -import net.minecraft.world.gen.structure.StructureVillagePieces.Village; -import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import net.minecraftforge.registries.GameData; import net.minecraftforge.registries.IForgeRegistryEntry; @@ -48,8 +43,7 @@ import javax.annotation.Nullable; */ public class VillagerRegistry { - @ObjectHolder("minecraft:farmer") - public static final VillagerProfession FARMER = null; + public static final RegistryObject FARMER = RegistryObject.of("minecraft:farmer", ()->VillagerProfession.class); private static final VillagerRegistry INSTANCE = new VillagerRegistry(); private Map, IVillageCreationHandler> villageCreationHandlers = Maps.newHashMap(); diff --git a/src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java b/src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java deleted file mode 100644 index 5c22296d7..000000000 --- a/src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.toposort; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.Sets; -import net.minecraftforge.fml.common.DummyModContainer; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.ModAPIManager; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.common.toposort.TopologicalSort.DirectedGraph; -import net.minecraftforge.fml.common.versioning.ArtifactVersion; - -import com.google.common.collect.Maps; - -/** - * @author cpw - * - */ -public class ModSorter -{ - private DirectedGraph modGraph; - - private ModContainer beforeAll = new DummyModContainer("BeforeAll"); - private ModContainer afterAll = new DummyModContainer("AfterAll"); - private ModContainer before = new DummyModContainer("Before"); - private ModContainer after = new DummyModContainer("After"); - - public ModSorter(List modList, Map nameLookup) - { - HashMap sortingNameLookup = Maps.newHashMap(nameLookup); - ModAPIManager.INSTANCE.injectAPIModContainers(modList, sortingNameLookup); - buildGraph(modList, sortingNameLookup); - } - - private void buildGraph(List modList, Map nameLookup) - { - modGraph = new DirectedGraph(); - modGraph.addNode(beforeAll); - modGraph.addNode(before); - modGraph.addNode(afterAll); - modGraph.addNode(after); - modGraph.addEdge(before, after); - modGraph.addEdge(beforeAll, before); - modGraph.addEdge(after, afterAll); - - for (ModContainer mod : modList) - { - modGraph.addNode(mod); - } - - for (ModContainer mod : modList) - { - if (mod.isImmutable()) - { - // Immutable mods are always before everything - modGraph.addEdge(beforeAll, mod); - modGraph.addEdge(mod, before); - continue; - } - boolean preDepAdded = false; - boolean postDepAdded = false; - - for (ArtifactVersion dep : mod.getDependencies()) - { - preDepAdded = true; - - String modid = dep.getLabel(); - if (modid.equals("*")) - { - // We are "after" everything - modGraph.addEdge(mod, afterAll); - modGraph.addEdge(after, mod); - postDepAdded = true; - } - else - { - modGraph.addEdge(before, mod); - if (nameLookup.containsKey(modid) || Loader.isModLoaded(modid)) { - modGraph.addEdge(nameLookup.get(modid), mod); - } - } - } - - for (ArtifactVersion dep : mod.getDependants()) - { - postDepAdded = true; - - String modid = dep.getLabel(); - if (modid.equals("*")) - { - // We are "before" everything - modGraph.addEdge(beforeAll, mod); - modGraph.addEdge(mod, before); - preDepAdded = true; - } - else - { - modGraph.addEdge(mod, after); - if (Loader.isModLoaded(modid)) { - modGraph.addEdge(mod, nameLookup.get(modid)); - } - } - } - - if (!preDepAdded) - { - modGraph.addEdge(before, mod); - } - - if (!postDepAdded) - { - modGraph.addEdge(mod, after); - } - } - } - - public List sort() - { - List sortedList; - try - { - sortedList = TopologicalSort.topologicalSort(modGraph); - } - catch (TopologicalSort.TopoSortException tse) - { - FMLLog.log.fatal("Mod Sorting failed."); - FMLLog.log.fatal("Visiting node {}", tse.getNode()); - FMLLog.log.fatal("Current sorted list : {}", tse.getSortedResult()); - FMLLog.log.fatal("Visited set for this node : {}", tse.getVisitedNodes()); - FMLLog.log.fatal("Explored node set : {}", tse.getExpandedNodes()); - Sets.SetView cycleList = Sets.difference(tse.getVisitedNodes(), tse.getExpandedNodes()); - FMLLog.log.fatal("Likely cycle is in : {}", cycleList); - - throw new ModSortingException("There was a cycle detected in the input graph, sorting is not possible", tse.getNode(), cycleList); - } - sortedList.removeAll(Arrays.asList(new ModContainer[] {beforeAll, before, after, afterAll})); - return sortedList; - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java b/src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java index 4f9df80d6..15517e0ff 100644 --- a/src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java +++ b/src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java @@ -26,8 +26,6 @@ package net.minecraftforge.fml.common.versioning; public interface ArtifactVersion extends Comparable { - String getLabel(); - String getVersionString(); boolean containsVersion(ArtifactVersion source); diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java b/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java deleted file mode 100644 index 79fcfb098..000000000 --- a/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.versioning; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; - -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.LoaderException; -import net.minecraftforge.fml.javafmlmod.FMLModContainer; -import net.minecraftforge.api.distmarker.Dist; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public final class DependencyParser -{ - public static class DependencyInfo - { - public final Set requirements = new HashSet<>(); - public final List dependencies = new ArrayList<>(); - public final List dependants = new ArrayList<>(); - } - - private static final ImmutableList DEPENDENCY_INSTRUCTIONS = ImmutableList.of("client", "server", "required", "before", "after"); - private static final Splitter DEPENDENCY_INSTRUCTIONS_SPLITTER = Splitter.on("-").omitEmptyStrings().trimResults(); - private static final Splitter DEPENDENCY_PART_SPLITTER = Splitter.on(":").omitEmptyStrings().trimResults(); - private static final Splitter DEPENDENCY_SPLITTER = Splitter.on(";").omitEmptyStrings().trimResults(); - - private final String modId; - private final Side side; - - public DependencyParser(String modId, Side side) - { - this.modId = modId; - this.side = side; - } - - public DependencyInfo parseDependencies(String dependencyString) - { - DependencyInfo info = new DependencyInfo(); - if (dependencyString == null || dependencyString.length() == 0) - { - return info; - } - - for (String dep : DEPENDENCY_SPLITTER.split(dependencyString)) - { - final List depParts = DEPENDENCY_PART_SPLITTER.splitToList(dep); - if (depParts.size() != 2) - { - throw new DependencyParserException(modId, dep, "Dependency string needs 2 parts."); - } - - final List instructions = DEPENDENCY_INSTRUCTIONS_SPLITTER.splitToList(depParts.get(0)); - final String target = depParts.get(1); - parseDependency(dep, instructions, target, info); - } - return info; - } - - private void parseDependency(String dep, List instructions, String target, DependencyInfo info) - { - final boolean targetIsAll = target.startsWith("*"); - final boolean targetIsBounded = target.contains("@"); - if (targetIsAll) - { - if (target.length() > 1) - { - throw new DependencyParserException(modId, dep, "Cannot have an \"all\" (*) relationship with anything except pure *"); - } - else if (targetIsBounded) - { - throw new DependencyParserException(modId, dep, "You cannot have a versioned dependency on everything (*)"); - } - } - - Side depSide = null; - String depOrder = null; - boolean depRequired = false; - - for (String instruction : instructions) - { - if ("client".equals(instruction)) - { - if (depSide != null) - { - throw new DependencyParserException(modId, dep, "Up to one side (client or server) can be specified."); - } - depSide = Side.CLIENT; - } - else if ("server".equals(instruction)) - { - if (depSide != null) - { - throw new DependencyParserException(modId, dep, "Up to one side (client or server) can be specified."); - } - depSide = Side.SERVER; - } - else if ("required".equals(instruction)) - { - if (depRequired) - { - throw new DependencyParserException(modId, dep, "'required' can only be specified once."); - } - if (targetIsAll) - { - throw new DependencyParserException(modId, dep, "You can't 'require' everything (*)"); - } - depRequired = true; - } - else if ("before".equals(instruction) || "after".equals(instruction)) - { - if (depOrder != null) - { - throw new DependencyParserException(modId, dep, "'before' or 'after' can only be specified once."); - } - depOrder = instruction; - } - else - { - throw new DependencyParserException(modId, dep, String.format("Found invalid instruction '%s'. Only %s are allowed.", instruction, DEPENDENCY_INSTRUCTIONS)); - } - } - - ArtifactVersion artifactVersion; - try - { - artifactVersion = VersionParser.parseVersionReference(target); - } - catch (RuntimeException e) - { - throw new DependencyParserException(modId, dep, "Could not parse version string.", e); - } - - if (!targetIsAll) - { - String depModId = artifactVersion.getLabel(); - sanityCheckModId(modId, dep, depModId); - } - - if (!depRequired && depOrder == null) - { - throw new DependencyParserException(modId, dep, "'required', 'client', or 'server' must be specified."); - } - - if (depSide == null || depSide == this.side) - { - if (depRequired) - { - info.requirements.add(artifactVersion); - } - - if ("before".equals(depOrder)) - { - info.dependants.add(artifactVersion); - } - else if ("after".equals(depOrder)) - { - info.dependencies.add(artifactVersion); - } - } - } - - // TODO 1.13: throw these exceptions instead of logging them - /** Based on {@link FMLModContainer#sanityCheckModId()} */ - private static void sanityCheckModId(String modId, String dep, String depModId) - { - if (Strings.isNullOrEmpty(depModId)) - { - LOGGER.error(new DependencyParserException(modId, dep, "The modId is null or empty").getMessage()); - } - else if (depModId.length() > 64) - { - LOGGER.error(new DependencyParserException(modId, dep, String.format("The modId '%s' is longer than the maximum of 64 characters.", depModId)).getMessage()); - } - else if (!depModId.equals(depModId.toLowerCase(Locale.ENGLISH))) - { - LOGGER.error(new DependencyParserException(modId, dep, String.format("The modId '%s' must be all lowercase.", depModId)).getMessage()); - } - } - - private static class DependencyParserException extends LoaderException - { - public DependencyParserException(String modId, String dependencyString, String explanation) - { - super(formatMessage(modId, dependencyString, explanation)); - } - - public DependencyParserException(String modId, String dependencyString, String explanation, Throwable cause) - { - super(formatMessage(modId, dependencyString, explanation), cause); - } - - public static String formatMessage(String modId, String dependencyString, String explanation) - { - return String.format("Unable to parse dependency for mod '%s' with dependency string '%s'. %s", modId, dependencyString, explanation); - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java b/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java index 7ab25c15d..438559a86 100644 --- a/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java +++ b/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java @@ -22,7 +22,6 @@ package net.minecraftforge.fml.common.versioning; * under the License. */ -import net.minecraft.util.text.translation.I18n; //Forge: Added imports import javax.annotation.Nullable; /** @@ -206,6 +205,7 @@ public class Restriction return buf.toString(); } + /* //Forge: Added toStringFriendly, uses Minecraft's localization engine to create user friendly localized message. public String toStringFriendly() { @@ -262,4 +262,5 @@ public class Restriction } } } + */ } diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java b/src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java deleted file mode 100644 index 9b7792fcb..000000000 --- a/src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.versioning; - -import java.util.List; - -import net.minecraftforge.fml.common.LoaderException; - -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.Lists; - -/** - * Parses version strings according to the specification here: - * http://docs.codehaus.org/display/MAVEN/Versioning - * and allows for comparison of versions based on that document. - * Bounded version specifications are defined as - * https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html - * - * Borrows heavily from maven version range management code - * - * @author cpw - * - */ -public class VersionParser -{ - private static final Splitter SEPARATOR = Splitter.on('@').omitEmptyStrings().trimResults(); - public static ArtifactVersion parseVersionReference(String labelledRef) - { - if (Strings.isNullOrEmpty(labelledRef)) - { - throw new RuntimeException(String.format("Empty reference %s", labelledRef)); - } - List parts = Lists.newArrayList(SEPARATOR.split(labelledRef)); - if (parts.size()>2) - { - throw new RuntimeException(String.format("Invalid versioned reference %s", labelledRef)); - } - if (parts.size()==1) - { - return new DefaultArtifactVersion(parts.get(0), true); - } - return new DefaultArtifactVersion(parts.get(0),parseRange(parts.get(1))); - } - - public static boolean satisfies(ArtifactVersion target, ArtifactVersion source) - { - return target.containsVersion(source); - } - - public static VersionRange parseRange(String range) - { - try - { - return VersionRange.createFromVersionSpec(range); - } - catch (InvalidVersionSpecificationException e) - { - throw new LoaderException("Unable to parse a version range specification successfully " + range, e); - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java b/src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java index a9e42e650..989c6598b 100644 --- a/src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java +++ b/src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java @@ -469,8 +469,7 @@ public class VersionRange return restrictions; } - - + //Forge: Removed getSelectedVersion and isSelectedVersion @Override //Forge: Added @Override @@ -486,6 +485,7 @@ public class VersionRange } } + /* //Forge: Added friendly {localized} toString public String toStringFriendly() { @@ -503,6 +503,7 @@ public class VersionRange return Joiner.on(", ").join(friendlyRestrictions); } } + */ public ArtifactVersion matchVersion( List versions ) { diff --git a/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java b/src/main/java/net/minecraftforge/fml/config/ModConfig.java similarity index 82% rename from src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java rename to src/main/java/net/minecraftforge/fml/config/ModConfig.java index 980511e3e..e4dc13d92 100644 --- a/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java +++ b/src/main/java/net/minecraftforge/fml/config/ModConfig.java @@ -17,11 +17,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.common; +package net.minecraftforge.fml.config; -import net.minecraftforge.fml.ModContainer; - -public interface FMLContainerHolder +public class ModConfig { - ModContainer getFMLContainer(); } diff --git a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java index 2763f6d06..8ef6b298e 100644 --- a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java +++ b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java @@ -19,7 +19,6 @@ package net.minecraftforge.fml.javafmlmod; -import net.minecraftforge.fml.DeferredWorkQueue; import net.minecraftforge.fml.LifecycleEventProvider; import net.minecraftforge.fml.language.IModLanguageProvider; import net.minecraftforge.fml.language.IModInfo; @@ -31,19 +30,20 @@ import org.objectweb.asm.Type; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Map; -import java.util.concurrent.FutureTask; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; import static net.minecraftforge.fml.Logging.LOADING; import static net.minecraftforge.fml.Logging.SCAN; -import static net.minecraftforge.fml.Logging.fmlLog; public class FMLJavaModLanguageProvider implements IModLanguageProvider { + + private static final Logger LOGGER = LogManager.getLogger(); + private static class FMLModTarget implements IModLanguageProvider.IModLanguageLoader { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = FMLJavaModLanguageProvider.LOGGER; private final String className; private final String modId; @@ -92,7 +92,7 @@ public class FMLJavaModLanguageProvider implements IModLanguageProvider return scanResult -> { final Map modTargetMap = scanResult.getAnnotations().stream() .filter(ad -> ad.getAnnotationType().equals(MODANNOTATION)) - .peek(ad -> fmlLog.debug(SCAN, "Found @Mod class {} with id {}", ad.getClassType().getClassName(), ad.getAnnotationData().get("value"))) + .peek(ad -> LOGGER.debug(SCAN, "Found @Mod class {} with id {}", ad.getClassType().getClassName(), ad.getAnnotationData().get("value"))) .map(ad -> new FMLModTarget(ad.getClassType().getClassName(), (String)ad.getAnnotationData().get("value"))) .collect(Collectors.toMap(FMLModTarget::getModId, Function.identity())); scanResult.addLanguageLoader(modTargetMap); diff --git a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java index bf4c1aefc..5adf73813 100644 --- a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java +++ b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java @@ -40,7 +40,7 @@ import static net.minecraftforge.fml.Logging.LOADING; public class FMLModContainer extends ModContainer { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private final ModFileScanData scanResults; private final IEventBus eventBus; private Object modInstance; @@ -89,7 +89,7 @@ public class FMLModContainer extends ModContainer } private void beforeEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) { - ModLoadingContext.get().setActiveContainer(this); + FMLModLoadingContext.get().setActiveContainer(this); ModThreadContext.get().setActiveContainer(this); } @@ -111,7 +111,7 @@ public class FMLModContainer extends ModContainer private void afterEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) { ModThreadContext.get().setActiveContainer(null); - ModLoadingContext.get().setActiveContainer(null); + FMLModLoadingContext.get().setActiveContainer(null); if (getCurrentState() == ModLoadingStage.ERROR) { LOGGER.error(LOADING,"An error occurred while dispatching event {} to {}", lifecycleEvent.fromStage(), getModId()); } diff --git a/src/main/java/net/minecraftforge/fml/javafmlmod/ModLoadingContext.java b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModLoadingContext.java similarity index 88% rename from src/main/java/net/minecraftforge/fml/javafmlmod/ModLoadingContext.java rename to src/main/java/net/minecraftforge/fml/javafmlmod/FMLModLoadingContext.java index 11a3a61a8..a43c0df3f 100644 --- a/src/main/java/net/minecraftforge/fml/javafmlmod/ModLoadingContext.java +++ b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModLoadingContext.java @@ -24,11 +24,11 @@ import net.minecraftforge.fml.ExtensionPoint; import java.util.function.Supplier; -public class ModLoadingContext +public class FMLModLoadingContext { - private static ThreadLocal context = ThreadLocal.withInitial(ModLoadingContext::new); + private static ThreadLocal context = ThreadLocal.withInitial(FMLModLoadingContext::new); private FMLModContainer activeContainer; - public static ModLoadingContext get() { + public static FMLModLoadingContext get() { return context.get(); } diff --git a/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java b/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java index 48dc3cd36..387a0703a 100644 --- a/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java +++ b/src/main/java/net/minecraftforge/fml/loading/FMLConfig.java @@ -19,68 +19,61 @@ package net.minecraftforge.fml.loading; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; +import com.electronwill.nightconfig.core.ConfigSpec; +import com.electronwill.nightconfig.core.file.CommentedFileConfig; +import com.electronwill.nightconfig.core.io.WritingMode; +import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.common.FMLPaths; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; -import java.io.BufferedWriter; -import java.io.IOException; -import java.lang.reflect.Type; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; +import java.util.Arrays; +import java.util.stream.Collectors; import static net.minecraftforge.fml.Logging.CORE; -import static net.minecraftforge.fml.Logging.fmlLog; public class FMLConfig { - private static FMLConfig INSTANCE; - private final Map configData = new HashMap<>(); - - private FMLConfig() { - configData.putAll(defaultValues()); + private static FMLConfig INSTANCE = new FMLConfig(); + private static ConfigSpec configSpec = new ConfigSpec(); + static { + configSpec.define("splashscreen", Boolean.TRUE); + configSpec.defineInList("side", Dist.CLIENT.name(), Arrays.stream(Dist.values()).map(Enum::name).collect(Collectors.toList())); + configSpec.defineInRange("maxframerate", 60, 10, 120); + configSpec.defineInRange("minframerate", 60, 10, 120); + configSpec.defineInList(Arrays.asList("tasty","flavour"), Dist.CLIENT.name(), Arrays.stream(Dist.values()).map(Enum::name).collect(Collectors.toList())); + configSpec.defineInList(Arrays.asList("tasty","teaser"), Dist.CLIENT.name(), Arrays.stream(Dist.values()).map(Enum::name).collect(Collectors.toList())); + configSpec.define("longstring", StringUtils.repeat("AAAA", 10000), s->s!=null && ((String)s).length()>0); } - private Map defaultValues() { - final Map result = new HashMap<>(); - result.put("splashscreen", "true"); - return result; - } + private CommentedFileConfig configData; - private void loadFrom(final Path configFile) throws IOException + private void loadFrom(final Path configFile) { - final Type type = new TypeToken>() {}.getType(); - final Gson gson = new Gson(); - final Map loadedConfig = gson.fromJson(Files.newBufferedReader(configFile), type); - if (loadedConfig != null) - configData.putAll(loadedConfig); + configData = CommentedFileConfig.builder(configFile).sync(). + defaultResource("/META-INF/defaultfmlconfig.toml"). + autosave().autoreload(). + writingMode(WritingMode.REPLACE). + build(); + configData.load(); + if (!configSpec.isCorrect(configData)) { + LogManager.getLogger().warn(CORE, "Configuration file {} is not correct. Correcting", configFile); + configSpec.correct(configData, (action, path, incorrectValue, correctedValue) -> + LogManager.getLogger().warn(CORE, "Incorrect key {} was corrected from {} to {}", path, incorrectValue, correctedValue)); + } + configData.save(); } - private void saveConfigIfNecessary(final Path configFile) throws IOException { - final Type type = new TypeToken>() {}.getType(); - final Gson gson = new Gson(); - final BufferedWriter writer = Files.newBufferedWriter(configFile); - gson.toJson(configData, type, writer); - writer.flush(); - } public static void load() { final Path configFile = FMLPaths.FMLCONFIG.get(); - INSTANCE = new FMLConfig(); - try - { - if (Files.exists(configFile)) - { - INSTANCE.loadFrom(configFile); - } - INSTANCE.saveConfigIfNecessary(configFile); - } - catch (IOException ioe) - { - fmlLog.error(CORE,"Unable to read FML config at {}", configFile, ioe); - throw new RuntimeException("Unable to read FML config", ioe); - } + INSTANCE.loadFrom(configFile); + LogManager.getLogger().debug(CORE, "Loaded FML config from {}", FMLPaths.FMLCONFIG.get()); + LogManager.getLogger().debug(CORE, "Splash screen is {}", INSTANCE.splashScreenEnabled()); + } + + public boolean splashScreenEnabled() { + return configData.getOptional("splashscreen").orElse(Boolean.FALSE); } } diff --git a/src/main/java/net/minecraftforge/fml/loading/FMLDevClientLaunchProvider.java b/src/main/java/net/minecraftforge/fml/loading/FMLDevClientLaunchProvider.java index 6234ce373..e45e1e912 100644 --- a/src/main/java/net/minecraftforge/fml/loading/FMLDevClientLaunchProvider.java +++ b/src/main/java/net/minecraftforge/fml/loading/FMLDevClientLaunchProvider.java @@ -23,6 +23,8 @@ import cpw.mods.modlauncher.api.IEnvironment; import cpw.mods.modlauncher.api.ILaunchHandlerService; import cpw.mods.modlauncher.api.ITransformingClassLoader; import net.minecraftforge.api.distmarker.Dist; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.lang.reflect.Field; import java.net.URISyntaxException; @@ -33,10 +35,12 @@ import java.util.List; import java.util.concurrent.Callable; import static net.minecraftforge.fml.Logging.CORE; -import static net.minecraftforge.fml.Logging.fmlLog; public class FMLDevClientLaunchProvider extends FMLCommonLaunchHandler implements ILaunchHandlerService { + + private static final Logger LOGGER = LogManager.getLogger(); + @Override public String name() { @@ -75,7 +79,7 @@ public class FMLDevClientLaunchProvider extends FMLCommonLaunchHandler implement public Callable launchService(String[] arguments, ITransformingClassLoader launchClassLoader) { return () -> { - fmlLog.debug(CORE, "Launching minecraft in {} with arguments {}", launchClassLoader, arguments); + LOGGER.debug(CORE, "Launching minecraft in {} with arguments {}", launchClassLoader, arguments); super.beforeStart(launchClassLoader, myPath); launchClassLoader.addTargetPackageFilter(cn -> SKIPPACKAGES.stream().noneMatch(cn::startsWith)); Field scl = ClassLoader.class.getDeclaredField("scl"); // Get system class loader @@ -90,7 +94,7 @@ public class FMLDevClientLaunchProvider extends FMLCommonLaunchHandler implement @Override public void setup(IEnvironment environment) { - fmlLog.debug(CORE, "No jar creation necessary. Launch is dev environment"); + LOGGER.debug(CORE, "No jar creation necessary. Launch is dev environment"); } @Override diff --git a/src/main/java/net/minecraftforge/fml/loading/FMLDevServerLaunchProvider.java b/src/main/java/net/minecraftforge/fml/loading/FMLDevServerLaunchProvider.java index ae30b3058..4963b53cf 100644 --- a/src/main/java/net/minecraftforge/fml/loading/FMLDevServerLaunchProvider.java +++ b/src/main/java/net/minecraftforge/fml/loading/FMLDevServerLaunchProvider.java @@ -23,6 +23,8 @@ import cpw.mods.modlauncher.api.IEnvironment; import cpw.mods.modlauncher.api.ILaunchHandlerService; import cpw.mods.modlauncher.api.ITransformingClassLoader; import net.minecraftforge.api.distmarker.Dist; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.lang.reflect.Field; import java.net.URISyntaxException; @@ -33,10 +35,12 @@ import java.util.List; import java.util.concurrent.Callable; import static net.minecraftforge.fml.Logging.CORE; -import static net.minecraftforge.fml.Logging.fmlLog; public class FMLDevServerLaunchProvider extends FMLCommonLaunchHandler implements ILaunchHandlerService { + + private static final Logger LOGGER = LogManager.getLogger(); + @Override public String name() { @@ -75,7 +79,7 @@ public class FMLDevServerLaunchProvider extends FMLCommonLaunchHandler implement public Callable launchService(String[] arguments, ITransformingClassLoader launchClassLoader) { return () -> { - fmlLog.debug(CORE, "Launching minecraft in {} with arguments {}", launchClassLoader, arguments); + LOGGER.debug(CORE, "Launching minecraft in {} with arguments {}", launchClassLoader, arguments); super.beforeStart(launchClassLoader, myPath); launchClassLoader.addTargetPackageFilter(cn -> SKIPPACKAGES.stream().noneMatch(cn::startsWith)); Field scl = ClassLoader.class.getDeclaredField("scl"); // Get system class loader @@ -90,7 +94,7 @@ public class FMLDevServerLaunchProvider extends FMLCommonLaunchHandler implement @Override public void setup(IEnvironment environment) { - fmlLog.debug(CORE, "No jar creation necessary. Launch is dev environment"); + LOGGER.debug(CORE, "No jar creation necessary. Launch is dev environment"); } @Override diff --git a/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java b/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java index 396201bae..f5b13599e 100644 --- a/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java +++ b/src/main/java/net/minecraftforge/fml/loading/FMLLoader.java @@ -31,6 +31,8 @@ import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler; import net.minecraftforge.fml.loading.moddiscovery.ModDiscoverer; import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.forgespi.ICoreModProvider; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.net.URISyntaxException; import java.net.URL; @@ -44,10 +46,10 @@ import java.util.stream.Collectors; import static net.minecraftforge.fml.Logging.CORE; import static net.minecraftforge.fml.Logging.SCAN; -import static net.minecraftforge.fml.Logging.fmlLog; public class FMLLoader { + private static final Logger LOGGER = LogManager.getLogger(); private static ILaunchPluginService accessTransformer; private static ModDiscoverer modDiscoverer; private static ICoreModProvider coreModProvider; @@ -63,51 +65,51 @@ public class FMLLoader static void onInitialLoad(IEnvironment environment, Set otherServices) throws IncompatibleEnvironmentException { final String version = ForgeVersion.getVersion(); - fmlLog.debug(CORE,"FML {} loading", version); + LOGGER.debug(CORE,"FML {} loading", version); final Package modLauncherPackage = ITransformationService.class.getPackage(); - fmlLog.debug(CORE,"FML found ModLauncher version : {}", modLauncherPackage.getImplementationVersion()); + LOGGER.debug(CORE,"FML found ModLauncher version : {}", modLauncherPackage.getImplementationVersion()); if (!modLauncherPackage.isCompatibleWith("1.0")) { - fmlLog.error(CORE,"Found incompatible ModLauncher specification : {}, version {} from {}", modLauncherPackage.getSpecificationVersion(), modLauncherPackage.getImplementationVersion(), modLauncherPackage.getImplementationVendor()); + LOGGER.error(CORE,"Found incompatible ModLauncher specification : {}, version {} from {}", modLauncherPackage.getSpecificationVersion(), modLauncherPackage.getImplementationVersion(), modLauncherPackage.getImplementationVendor()); throw new IncompatibleEnvironmentException("Incompatible modlauncher found "+modLauncherPackage.getSpecificationVersion()); } - fmlLog.debug(CORE, "Initializing modjar URL handler"); + LOGGER.debug(CORE, "Initializing modjar URL handler"); URL.setURLStreamHandlerFactory(p->p.equals("modjar") ? new ModJarURLHandler() : null); accessTransformer = environment.findLaunchPlugin("accesstransformer").orElseThrow(()-> new IncompatibleEnvironmentException("Missing AccessTransformer, cannot run")); final Package atPackage = accessTransformer.getClass().getPackage(); - fmlLog.debug(CORE,"FML found AccessTransformer version : {}", atPackage.getImplementationVersion()); + LOGGER.debug(CORE,"FML found AccessTransformer version : {}", atPackage.getImplementationVersion()); if (!atPackage.isCompatibleWith("1.0")) { - fmlLog.error(CORE,"Found incompatible AccessTransformer specification : {}, version {} from {}", atPackage.getSpecificationVersion(), atPackage.getImplementationVersion(), atPackage.getImplementationVendor()); + LOGGER.error(CORE,"Found incompatible AccessTransformer specification : {}, version {} from {}", atPackage.getSpecificationVersion(), atPackage.getImplementationVersion(), atPackage.getImplementationVendor()); throw new IncompatibleEnvironmentException("Incompatible accesstransformer found "+atPackage.getSpecificationVersion()); } eventBus = environment.findLaunchPlugin("eventbus").orElseThrow(()-> new IncompatibleEnvironmentException("Missing EventBus, cannot run")); final Package eventBusPackage = eventBus.getClass().getPackage(); - fmlLog.debug(CORE,"FML found EventBus version : {}", eventBusPackage.getImplementationVersion()); + LOGGER.debug(CORE,"FML found EventBus version : {}", eventBusPackage.getImplementationVersion()); if (!eventBusPackage.isCompatibleWith("1.0")) { - fmlLog.error(CORE,"Found incompatible EventBus specification : {}, version {} from {}", eventBusPackage.getSpecificationVersion(), eventBusPackage.getImplementationVersion(), eventBusPackage.getImplementationVendor()); + LOGGER.error(CORE,"Found incompatible EventBus specification : {}, version {} from {}", eventBusPackage.getSpecificationVersion(), eventBusPackage.getImplementationVersion(), eventBusPackage.getImplementationVendor()); throw new IncompatibleEnvironmentException("Incompatible eventbus found "+eventBusPackage.getSpecificationVersion()); } runtimeDistCleaner = (RuntimeDistCleaner)environment.findLaunchPlugin("runtimedistcleaner").orElseThrow(()->new IncompatibleEnvironmentException("Missing RuntimeDistCleaner, cannot run!")); - fmlLog.debug(CORE, "Found Runtime Dist Cleaner"); + LOGGER.debug(CORE, "Found Runtime Dist Cleaner"); final ArrayList coreModProviders = new ArrayList<>(); ServiceLoader.load(ICoreModProvider.class).forEach(coreModProviders::add); if (coreModProviders.isEmpty()) { - fmlLog.error(CORE, "Found no coremod provider. Cannot run"); + LOGGER.error(CORE, "Found no coremod provider. Cannot run"); throw new IncompatibleEnvironmentException("No coremod library found"); } else if (coreModProviders.size() > 1) { - fmlLog.error(CORE, "Found multiple coremod providers : {}. Cannot run", coreModProviders.stream().map(p -> p.getClass().getName()).collect(Collectors.toList())); + LOGGER.error(CORE, "Found multiple coremod providers : {}. Cannot run", coreModProviders.stream().map(p -> p.getClass().getName()).collect(Collectors.toList())); throw new IncompatibleEnvironmentException("Multiple coremod libraries found"); } coreModProvider = coreModProviders.get(0); final Package coremodPackage = coreModProvider.getClass().getPackage(); - fmlLog.debug(CORE,"FML found CoreMod version : {}", coremodPackage.getImplementationVersion()); + LOGGER.debug(CORE,"FML found CoreMod version : {}", coremodPackage.getImplementationVersion()); languageLoadingProvider = new LanguageLoadingProvider(); } @@ -116,14 +118,14 @@ public class FMLLoader { final String launchTarget = environment.getProperty(IEnvironment.Keys.LAUNCHTARGET.get()).orElse("MISSING"); final Optional launchHandler = environment.findLaunchHandler(launchTarget); - fmlLog.debug(CORE, "Using {} as launch service", launchTarget); + LOGGER.debug(CORE, "Using {} as launch service", launchTarget); if (!launchHandler.isPresent()) { - fmlLog.error(CORE,"Missing LaunchHandler {}, cannot continue", launchTarget); + LOGGER.error(CORE,"Missing LaunchHandler {}, cannot continue", launchTarget); throw new RuntimeException("Missing launch handler"); } if (!(launchHandler.get() instanceof FMLCommonLaunchHandler)) { - fmlLog.error(CORE, "Incompatible Launch handler found - type {}, cannot continue", launchHandler.get().getClass().getName()); + LOGGER.error(CORE, "Incompatible Launch handler found - type {}, cannot continue", launchHandler.get().getClass().getName()); throw new RuntimeException("Incompatible launch handler found"); } gamePath = environment.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElse(Paths.get(".").toAbsolutePath()); @@ -135,7 +137,7 @@ public class FMLLoader } public static void beginModScan() { - fmlLog.debug(SCAN,"Scanning for Mod Locators"); + LOGGER.debug(SCAN,"Scanning for Mod Locators"); modDiscoverer = new ModDiscoverer(); final BackgroundScanHandler backgroundScanHandler = modDiscoverer.discoverMods(); loadingModList = backgroundScanHandler.getLoadingModList(); @@ -158,19 +160,19 @@ public class FMLLoader } try { - fmlLog.debug(CORE, "Loading forge_at.cfg into access transformer"); + LOGGER.debug(CORE, "Loading forge_at.cfg into access transformer"); accessTransformer.addResource(Paths.get(resource.toURI()), "forge_at.cfg"); } catch (URISyntaxException e) { - fmlLog.error("Error loading forge_at.cfg file", e); + LOGGER.error("Error loading forge_at.cfg file", e); throw new RuntimeException(e); } } public static void addAccessTransformer(Path atPath, ModFile modName) { - fmlLog.debug(SCAN, "Adding Access Transformer in {}", modName.getFilePath()); + LOGGER.debug(SCAN, "Adding Access Transformer in {}", modName.getFilePath()); accessTransformer.addResource(atPath, modName.getFileName()); } diff --git a/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java b/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java index 309623722..7134aa0a8 100644 --- a/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java +++ b/src/main/java/net/minecraftforge/fml/loading/FMLServiceProvider.java @@ -26,6 +26,8 @@ import cpw.mods.modlauncher.api.IncompatibleEnvironmentException; import joptsimple.ArgumentAcceptingOptionSpec; import joptsimple.OptionSpecBuilder; import net.minecraftforge.fml.common.FMLPaths; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import javax.annotation.Nonnull; import java.util.ArrayList; @@ -34,11 +36,11 @@ import java.util.Set; import java.util.function.BiFunction; import static net.minecraftforge.fml.Logging.CORE; -import static net.minecraftforge.fml.Logging.fmlLog; public class FMLServiceProvider implements ITransformationService { + private static final Logger LOGGER = LogManager.getLogger(); private ArgumentAcceptingOptionSpec modsOption; private ArgumentAcceptingOptionSpec modListsOption; private List modsArgumentList; @@ -53,15 +55,15 @@ public class FMLServiceProvider implements ITransformationService @Override public void initialize(IEnvironment environment) { - fmlLog.debug(CORE,"Setting up basic FML game directories"); + LOGGER.debug(CORE,"Setting up basic FML game directories"); FMLPaths.setup(environment); - fmlLog.debug(CORE,"Loading configuration"); + LOGGER.debug(CORE,"Loading configuration"); FMLConfig.load(); - fmlLog.debug(CORE, "Preparing launch handler"); + LOGGER.debug(CORE, "Preparing launch handler"); FMLLoader.setupLaunchHandler(environment); - fmlLog.debug(CORE,"Initiating mod scan"); + LOGGER.debug(CORE,"Initiating mod scan"); FMLLoader.beginModScan(); - fmlLog.debug(CORE, "Loading access transformers"); + LOGGER.debug(CORE, "Loading access transformers"); FMLLoader.loadAccessTransformer(); } @@ -89,7 +91,7 @@ public class FMLServiceProvider implements ITransformationService @Override public List transformers() { - fmlLog.debug(CORE, "Loading coremod transformers"); + LOGGER.debug(CORE, "Loading coremod transformers"); return new ArrayList<>(FMLLoader.getCoreModProvider().getCoreModTransformers()); } diff --git a/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java b/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java index e134f13be..f78ba5d84 100644 --- a/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java +++ b/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java @@ -25,6 +25,8 @@ import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion; import net.minecraftforge.fml.common.versioning.VersionRange; import net.minecraftforge.fml.language.IModLanguageProvider; import net.minecraftforge.fml.loading.moddiscovery.ModFile; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.nio.file.Path; import java.util.ArrayList; @@ -36,10 +38,10 @@ import java.util.function.Consumer; import java.util.stream.Stream; import static net.minecraftforge.fml.Logging.CORE; -import static net.minecraftforge.fml.Logging.fmlLog; public class LanguageLoadingProvider { + private static final Logger LOGGER = LogManager.getLogger(); private final List languageProviders = new ArrayList<>(); private final ServiceLoader serviceLoader; private final Map languageProviderMap = new HashMap<>(); @@ -79,7 +81,7 @@ public class LanguageLoadingProvider if (implementationVersion == null) { implementationVersion = ForgeVersion.getVersion(); } - fmlLog.debug(CORE, "Found system classpath language provider {}, version {}", lp.name(), implementationVersion); + LOGGER.debug(CORE, "Found system classpath language provider {}, version {}", lp.name(), implementationVersion); languageProviderMap.put(lp.name(), new ModLanguageWrapper(lp, new DefaultArtifactVersion(implementationVersion))); }); } diff --git a/src/main/java/net/minecraftforge/fml/loading/ModSorter.java b/src/main/java/net/minecraftforge/fml/loading/ModSorter.java index 472e0757c..71a210f2a 100644 --- a/src/main/java/net/minecraftforge/fml/loading/ModSorter.java +++ b/src/main/java/net/minecraftforge/fml/loading/ModSorter.java @@ -21,7 +21,6 @@ package net.minecraftforge.fml.loading; import net.minecraftforge.fml.Java9BackportUtils; import net.minecraftforge.fml.common.DuplicateModsFoundException; -import net.minecraftforge.fml.common.MissingModsException; import net.minecraftforge.fml.common.toposort.TopologicalSort; import net.minecraftforge.fml.common.versioning.ArtifactVersion; import net.minecraftforge.fml.language.IModInfo; @@ -44,7 +43,7 @@ import static net.minecraftforge.fml.Logging.LOADING; public class ModSorter { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private List modFiles; private List sortedList; private Map modIdNameLookup; @@ -123,12 +122,12 @@ public class ModSorter collect(Collectors.groupingBy(Function.identity(), Java9BackportUtils.flatMapping(e -> e.getDependencies().stream(), Collectors.toList()))); final Set mandatoryModVersions = modVersionDependencies.values().stream().flatMap(Collection::stream). filter(mv -> mv.isMandatory() && mv.getSide().isCorrectSide()).collect(Collectors.toSet()); - LogManager.getLogger("FML").debug(LOADING, "Found {} mandatory requirements", mandatoryModVersions.size()); + LOGGER.debug(LOADING, "Found {} mandatory requirements", mandatoryModVersions.size()); final Set missingVersions = mandatoryModVersions.stream().filter(mv->this.modVersionMatches(mv, modVersions)).collect(Collectors.toSet()); - LogManager.getLogger("FML").debug(LOADING, "Found {} mandatory mod requirements missing", missingVersions.size()); + LOGGER.debug(LOADING, "Found {} mandatory mod requirements missing", missingVersions.size()); if (!missingVersions.isEmpty()) { - throw new MissingModsException(null,null,null); + throw new RuntimeException("Missing mods"); } } diff --git a/src/main/java/net/minecraftforge/fml/loading/RuntimeDistCleaner.java b/src/main/java/net/minecraftforge/fml/loading/RuntimeDistCleaner.java index a628123f7..16c58de2a 100644 --- a/src/main/java/net/minecraftforge/fml/loading/RuntimeDistCleaner.java +++ b/src/main/java/net/minecraftforge/fml/loading/RuntimeDistCleaner.java @@ -46,7 +46,7 @@ import org.objectweb.asm.tree.MethodNode; public class RuntimeDistCleaner implements ILaunchPluginService { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker DISTXFORM = MarkerManager.getMarker("DISTXFORM"); private static String DIST; private static final String ONLYIN = Type.getDescriptor(OnlyIn.class); diff --git a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/BackgroundScanHandler.java b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/BackgroundScanHandler.java index fc99a6416..091d04393 100644 --- a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/BackgroundScanHandler.java +++ b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/BackgroundScanHandler.java @@ -21,6 +21,8 @@ package net.minecraftforge.fml.loading.moddiscovery; import net.minecraftforge.fml.language.ModFileScanData; import net.minecraftforge.fml.loading.LoadingModList; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.ArrayList; import java.util.List; @@ -30,10 +32,10 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import static net.minecraftforge.fml.Logging.SCAN; -import static net.minecraftforge.fml.Logging.fmlLog; public class BackgroundScanHandler { + private static final Logger LOGGER = LogManager.getLogger(); private final ExecutorService modContentScanner; private final List pendingFiles; private final List scannedFiles; @@ -65,7 +67,7 @@ public class BackgroundScanHandler private void addCompletedFile(final ModFile file, final ModFileScanData modFileScanData, final Throwable throwable) { if (throwable != null) { - fmlLog.error(SCAN,"An error occurred scanning file {}", file, throwable); + LOGGER.error(SCAN,"An error occurred scanning file {}", file, throwable); } pendingFiles.remove(file); scannedFiles.add(file); diff --git a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ExplodedDirectoryLocator.java b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ExplodedDirectoryLocator.java index 80fc54aad..b6ff994a4 100644 --- a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ExplodedDirectoryLocator.java +++ b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ExplodedDirectoryLocator.java @@ -19,6 +19,9 @@ package net.minecraftforge.fml.loading.moddiscovery; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Files; @@ -33,23 +36,23 @@ import java.util.stream.Stream; import static net.minecraftforge.fml.Logging.LOADING; import static net.minecraftforge.fml.Logging.SCAN; -import static net.minecraftforge.fml.Logging.fmlLog; public class ExplodedDirectoryLocator implements IModLocator { private static final String DIR = System.getProperty("fml.explodedDir", "modclasses"); + private static final Logger LOGGER = LogManager.getLogger(); private final Path rootDir; public ExplodedDirectoryLocator() { this.rootDir = FileSystems.getDefault().getPath(DIR); if (!Files.exists(this.rootDir)) { - fmlLog.debug(LOADING,"Creating directory {}" + this.rootDir); + LOGGER.debug(LOADING,"Creating directory {}" + this.rootDir); try { Files.createDirectory(this.rootDir); } catch (IOException e) { - fmlLog.error(LOADING,"Error creating {}", this.rootDir, e); + LOGGER.error(LOADING,"Error creating {}", this.rootDir, e); throw new RuntimeException(e); } } @@ -75,13 +78,13 @@ public class ExplodedDirectoryLocator implements IModLocator { @Override public void scanFile(final ModFile modFile, final Consumer pathConsumer) { - fmlLog.debug(SCAN,"Scanning directory {}", rootDir); + LOGGER.debug(SCAN,"Scanning directory {}", rootDir); try (Stream files = Files.find(rootDir, Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) { files.forEach(pathConsumer); } catch (IOException e) { e.printStackTrace(); } - fmlLog.debug(SCAN,"Directory scan complete {}", rootDir); + LOGGER.debug(SCAN,"Directory scan complete {}", rootDir); } @Override diff --git a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java index ca96debd7..dedcaf868 100644 --- a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java +++ b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java @@ -23,6 +23,8 @@ import cpw.mods.modlauncher.ServiceLoaderStreamUtils; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.LoadingModList; import net.minecraftforge.fml.loading.ModSorter; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.Collection; import java.util.Iterator; @@ -32,16 +34,16 @@ import java.util.ServiceLoader; import java.util.stream.Collectors; import static net.minecraftforge.fml.Logging.SCAN; -import static net.minecraftforge.fml.Logging.fmlLog; public class ModDiscoverer { + private static final Logger LOGGER = LogManager.getLogger(); private final ServiceLoader locators; private final List locatorList; public ModDiscoverer() { locators = ServiceLoader.load(IModLocator.class); locatorList = ServiceLoaderStreamUtils.toList(this.locators); - fmlLog.debug(SCAN,"Found Mod Locators : {}", ()->locatorList.stream().map(iModLocator -> "("+iModLocator.name() + ":" + iModLocator.getClass().getPackage().getImplementationVersion()+")").collect(Collectors.joining(","))); + LOGGER.debug(SCAN,"Found Mod Locators : {}", ()->locatorList.stream().map(iModLocator -> "("+iModLocator.name() + ":" + iModLocator.getClass().getPackage().getImplementationVersion()+")").collect(Collectors.joining(","))); } ModDiscoverer(List locatorList) { @@ -50,12 +52,12 @@ public class ModDiscoverer { } public BackgroundScanHandler discoverMods() { - fmlLog.debug(SCAN,"Scanning for mods and other resources to load. We know {} ways to find mods", locatorList.size()); + LOGGER.debug(SCAN,"Scanning for mods and other resources to load. We know {} ways to find mods", locatorList.size()); final Map> modFiles = locatorList.stream() - .peek(loc -> fmlLog.debug(SCAN,"Trying locator {}", loc)) + .peek(loc -> LOGGER.debug(SCAN,"Trying locator {}", loc)) .map(IModLocator::scanMods) .flatMap(Collection::stream) - .peek(mf -> fmlLog.debug(SCAN,"Found mod file {} of type {} with locator {}", mf.getFileName(), mf.getType(), mf.getLocator())) + .peek(mf -> LOGGER.debug(SCAN,"Found mod file {} of type {} with locator {}", mf.getFileName(), mf.getType(), mf.getLocator())) .collect(Collectors.groupingBy(ModFile::getType)); FMLLoader.getLanguageLoadingProvider().addAdditionalLanguages(modFiles.get(ModFile.Type.LANGPROVIDER)); @@ -65,11 +67,11 @@ public class ModDiscoverer { { ModFile mod = iterator.next(); if (!mod.identifyMods()) { - fmlLog.debug(SCAN, "Removing file {} from further analysis - it is invalid", mod); + LOGGER.debug(SCAN, "Removing file {} from further analysis - it is invalid", mod); iterator.remove(); } } - fmlLog.debug(SCAN,"Found {} mod files with {} mods", mods::size, ()->mods.stream().mapToInt(mf -> mf.getModInfos().size()).sum()); + LOGGER.debug(SCAN,"Found {} mod files with {} mods", mods::size, ()->mods.stream().mapToInt(mf -> mf.getModInfos().size()).sum()); final LoadingModList loadingModList = ModSorter.sort(mods); loadingModList.addCoreMods(); loadingModList.addAccessTransformers(); diff --git a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java index a36f405b4..241e5d538 100644 --- a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java +++ b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java @@ -25,6 +25,8 @@ import net.minecraftforge.fml.language.IModInfo; import net.minecraftforge.fml.language.ModFileScanData; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.language.IModLanguageProvider; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.nio.file.Files; import java.nio.file.Path; @@ -41,11 +43,12 @@ import java.util.jar.Manifest; import static net.minecraftforge.fml.Logging.LOADING; import static net.minecraftforge.fml.Logging.SCAN; -import static net.minecraftforge.fml.Logging.fmlLog; public class ModFile { private static final Manifest DEFAULTMANIFEST; + private static final Logger LOGGER = LogManager.getLogger(); + static { DEFAULTMANIFEST = new Manifest(); DEFAULTMANIFEST.getMainAttributes().putValue("FMLModType", "MOD"); @@ -89,8 +92,8 @@ public class ModFile this.locator = locator; this.filePath = file; manifest = locator.findManifest(file).orElse(DEFAULTMANIFEST); - if (manifest != DEFAULTMANIFEST) fmlLog.debug(SCAN,"Mod file {} has a manifest", file); - else fmlLog.debug(SCAN,"Mod file {} is missing a manifest", file); + if (manifest != DEFAULTMANIFEST) LOGGER.debug(SCAN,"Mod file {} has a manifest", file); + else LOGGER.debug(SCAN,"Mod file {} is missing a manifest", file); final Optional value = Optional.ofNullable(manifest.getMainAttributes().getValue(TYPE)); modFileType = Type.valueOf(value.orElse("MOD")); jarVersion = Optional.ofNullable(manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION)).orElse("NONE"); @@ -117,9 +120,9 @@ public class ModFile public boolean identifyMods() { this.modFileInfo = ModFileParser.readModList(this); if (this.modFileInfo == null) return false; - fmlLog.debug(LOADING,"Loading mod file {} with language {}", this.getFilePath(), this.modFileInfo.getModLoader()); + LOGGER.debug(LOADING,"Loading mod file {} with language {}", this.getFilePath(), this.modFileInfo.getModLoader()); this.coreMods = ModFileParser.getCoreMods(this); - this.coreMods.forEach(mi-> fmlLog.debug(LOADING,"Found coremod {}", mi.getPath())); + this.coreMods.forEach(mi-> LOGGER.debug(LOADING,"Found coremod {}", mi.getPath())); this.accessTransformer = locator.findPath(this, "META-INF", "accesstransformer.cfg"); this.loader = FMLLoader.getLanguageLoadingProvider().findLanguage(this.modFileInfo.getModLoader(), this.modFileInfo.getModLoaderVersion()); return true; diff --git a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java index c894a490d..4bed96139 100644 --- a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java +++ b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java @@ -23,6 +23,8 @@ import com.electronwill.nightconfig.core.file.FileConfig; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import net.minecraftforge.fml.language.IModFileInfo; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.io.IOException; import java.lang.reflect.Type; @@ -34,14 +36,16 @@ import java.util.Map; import java.util.stream.Collectors; import static net.minecraftforge.fml.Logging.LOADING; -import static net.minecraftforge.fml.Logging.fmlLog; public class ModFileParser { + + private static final Logger LOGGER = LogManager.getLogger(); + public static IModFileInfo readModList(final ModFile modFile) { - fmlLog.debug(LOADING,"Parsing mod file candidate {}", modFile.getFilePath()); + LOGGER.debug(LOADING,"Parsing mod file candidate {}", modFile.getFilePath()); final Path modsjson = modFile.getLocator().findPath(modFile, "META-INF", "mods.toml"); if (!Files.exists(modsjson)) { - fmlLog.warn(LOADING, "Mod file {} is missing mods.toml file", modFile); + LOGGER.warn(LOADING, "Mod file {} is missing mods.toml file", modFile); return null; } return loadModFile(modFile, modsjson); @@ -66,12 +70,12 @@ public class ModFileParser { final Gson gson = new Gson(); coreModPaths = gson.fromJson(Files.newBufferedReader(coremodsjson), type); } catch (IOException e) { - fmlLog.debug(LOADING,"Failed to read coremod list coremods.json", e); + LOGGER.debug(LOADING,"Failed to read coremod list coremods.json", e); return Collections.emptyList(); } return coreModPaths.entrySet().stream(). - peek(e-> fmlLog.debug(LOADING,"Found coremod {} with Javascript path {}", e.getKey(), e.getValue())). + peek(e-> LOGGER.debug(LOADING,"Found coremod {} with Javascript path {}", e.getKey(), e.getValue())). map(e -> new CoreModFile(e.getKey(), modFile.getLocator().findPath(modFile, e.getValue()),modFile)). collect(Collectors.toList()); } diff --git a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModsFolderLocator.java b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModsFolderLocator.java index 144bcc9cc..feabc29b3 100644 --- a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModsFolderLocator.java +++ b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModsFolderLocator.java @@ -21,6 +21,8 @@ package net.minecraftforge.fml.loading.moddiscovery; import net.minecraftforge.fml.loading.StringUtils; import net.minecraftforge.fml.common.FMLPaths; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.io.IOException; import java.nio.file.FileSystem; @@ -42,13 +44,13 @@ import java.util.zip.ZipError; import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.uncheck; import static net.minecraftforge.fml.Logging.SCAN; -import static net.minecraftforge.fml.Logging.fmlLog; /** * Support loading mods located in JAR files in the mods folder */ public class ModsFolderLocator implements IModLocator { private static final String SUFFIX = ".jar"; + private static final Logger LOGGER = LogManager.getLogger(); private final Path modFolder; private final Map modJars; public ModsFolderLocator() { @@ -62,7 +64,7 @@ public class ModsFolderLocator implements IModLocator { @Override public List scanMods() { - fmlLog.debug(SCAN,"Scanning mods dir {} for mods", this.modFolder); + LOGGER.debug(SCAN,"Scanning mods dir {} for mods", this.modFolder); return uncheck(()-> Files.list(this.modFolder)). sorted(Comparator.comparing(path-> StringUtils.toLowerCase(path.getFileName().toString()))). filter(p->StringUtils.toLowerCase(p.getFileName().toString()).endsWith(SUFFIX)). @@ -80,7 +82,7 @@ public class ModsFolderLocator implements IModLocator { try { return FileSystems.newFileSystem(modFile.getFilePath(), modFile.getClass().getClassLoader()); } catch (ZipError | IOException e) { - fmlLog.debug(SCAN,"Ignoring invalid JAR file {}", modFile.getFilePath()); + LOGGER.debug(SCAN,"Ignoring invalid JAR file {}", modFile.getFilePath()); return null; } } @@ -95,7 +97,7 @@ public class ModsFolderLocator implements IModLocator { @Override public void scanFile(final ModFile file, final Consumer pathConsumer) { - fmlLog.debug(SCAN,"Scan started: {}", file); + LOGGER.debug(SCAN,"Scan started: {}", file); FileSystem fs = modJars.get(file); fs.getRootDirectories().forEach(path -> { try (Stream files = Files.find(path, Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) { @@ -104,7 +106,7 @@ public class ModsFolderLocator implements IModLocator { e.printStackTrace(); } }); - fmlLog.debug(SCAN,"Scan finished: {}", file); + LOGGER.debug(SCAN,"Scan finished: {}", file); } @Override diff --git a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/Scanner.java b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/Scanner.java index 3230bbc0e..60e385927 100644 --- a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/Scanner.java +++ b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/Scanner.java @@ -21,6 +21,8 @@ package net.minecraftforge.fml.loading.moddiscovery; import net.minecraftforge.fml.language.IModLanguageProvider; import net.minecraftforge.fml.language.ModFileScanData; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.objectweb.asm.ClassReader; import java.io.IOException; @@ -28,9 +30,9 @@ import java.nio.file.Files; import java.nio.file.Path; import static net.minecraftforge.fml.Logging.SCAN; -import static net.minecraftforge.fml.Logging.fmlLog; public class Scanner { + private static final Logger LOGGER = LogManager.getLogger(); private final ModFile fileToScan; public Scanner(final ModFile fileToScan) { @@ -41,14 +43,14 @@ public class Scanner { ModFileScanData result = new ModFileScanData(); fileToScan.scanFile(p -> fileVisitor(p, result)); final IModLanguageProvider loader = fileToScan.getLoader(); - fmlLog.debug(SCAN, "Scanning {} with language loader {}", fileToScan.getFilePath(), loader.name()); + LOGGER.debug(SCAN, "Scanning {} with language loader {}", fileToScan.getFilePath(), loader.name()); loader.getFileVisitor().accept(result); return result; } private void fileVisitor(final Path path, final ModFileScanData result) { try { - fmlLog.debug(SCAN,"Scanning {} path {}", fileToScan, path); + LOGGER.debug(SCAN,"Scanning {} path {}", fileToScan, path); ModClassVisitor mcv = new ModClassVisitor(); ClassReader cr = new ClassReader(Files.newInputStream(path)); cr.accept(mcv, 0); diff --git a/src/main/java/net/minecraftforge/fml/network/ICustomPacket.java b/src/main/java/net/minecraftforge/fml/network/ICustomPacket.java new file mode 100644 index 000000000..8a8ad09d2 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/network/ICustomPacket.java @@ -0,0 +1,29 @@ +package net.minecraftforge.fml.network; + +import net.minecraft.network.Packet; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ResourceLocation; + +import java.util.function.Supplier; + +public interface ICustomPacket> { + default PacketBuffer getData() { + return getBufferDataSupplier().get(); + } + + default ResourceLocation getName() { + return getChannelNameSupplier().get(); + } + + default NetworkDirection getDirection() { + return NetworkDirection.directionFor(this.getClass()); + } + + @SuppressWarnings("unchecked") + default T getThis() { + return (T)this; + } + + Supplier getChannelNameSupplier(); + Supplier getBufferDataSupplier(); +} diff --git a/src/main/java/net/minecraftforge/fml/network/NetworkDirection.java b/src/main/java/net/minecraftforge/fml/network/NetworkDirection.java index 972837163..abfc760ac 100644 --- a/src/main/java/net/minecraftforge/fml/network/NetworkDirection.java +++ b/src/main/java/net/minecraftforge/fml/network/NetworkDirection.java @@ -19,26 +19,52 @@ package net.minecraftforge.fml.network; +import it.unimi.dsi.fastutil.objects.Reference2ReferenceArrayMap; +import net.minecraft.network.Packet; import net.minecraft.network.PacketBuffer; +import net.minecraft.network.login.client.CPacketCustomPayloadLogin; +import net.minecraft.network.login.server.SPacketCustomPayloadLogin; +import net.minecraft.network.play.client.CPacketCustomPayload; +import net.minecraft.network.play.server.SPacketCustomPayload; import net.minecraftforge.fml.LogicalSide; import java.util.function.BiFunction; +import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; public enum NetworkDirection { - PLAY_TO_SERVER(NetworkEvent.ClientCustomPayloadEvent::new, LogicalSide.CLIENT), - PLAY_TO_CLIENT(NetworkEvent.ServerCustomPayloadEvent::new, LogicalSide.SERVER), - LOGIN_TO_SERVER(NetworkEvent.ClientCustomPayloadEvent::new, LogicalSide.CLIENT), - LOGIN_TO_CLIENT(NetworkEvent.ServerCustomPayloadEvent::new, LogicalSide.SERVER); + PLAY_TO_SERVER(NetworkEvent.ClientCustomPayloadEvent::new, LogicalSide.CLIENT, CPacketCustomPayload.class), + PLAY_TO_CLIENT(NetworkEvent.ServerCustomPayloadEvent::new, LogicalSide.SERVER, SPacketCustomPayload.class), + LOGIN_TO_SERVER(NetworkEvent.ClientCustomPayloadEvent::new, LogicalSide.CLIENT, CPacketCustomPayloadLogin.class), + LOGIN_TO_CLIENT(NetworkEvent.ServerCustomPayloadEvent::new, LogicalSide.SERVER, SPacketCustomPayloadLogin.class); private final BiFunction, NetworkEvent> eventSupplier; private final LogicalSide logicalSide; + private final Class packetClass; - NetworkDirection(BiFunction, NetworkEvent> eventSupplier, LogicalSide logicalSide) + private static final Reference2ReferenceArrayMap, NetworkDirection> packetLookup; + + static { + packetLookup = Stream.of(values()). + collect(Collectors.toMap(NetworkDirection::getPacketClass, Function.identity(), (m1,m2)->m1, Reference2ReferenceArrayMap::new)); + } + + NetworkDirection(BiFunction, NetworkEvent> eventSupplier, LogicalSide logicalSide, Class clazz) { this.eventSupplier = eventSupplier; this.logicalSide = logicalSide; + this.packetClass = clazz; + } + + private Class getPacketClass() { + return packetClass; + } + public static > NetworkDirection directionFor(Class customPacket) + { + return packetLookup.get(customPacket); } public NetworkEvent getEvent(final PacketBuffer buffer, final Supplier manager) { diff --git a/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java b/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java index 70fa3e688..7941be159 100644 --- a/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java +++ b/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java @@ -23,11 +23,7 @@ import net.minecraft.entity.Entity; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; -import net.minecraft.network.handshake.client.C00Handshake; -import net.minecraft.network.play.client.CPacketCustomPayload; -import net.minecraft.network.play.server.SPacketCustomPayload; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.registry.EntityRegistry; +import net.minecraft.network.handshake.client.CPacketHandshake; import java.util.Objects; @@ -40,7 +36,7 @@ public class NetworkHooks return ip.contains("\0") ? Objects.equals(ip.split("\0")[1], NETVERSION) ? NETVERSION : ip.split("\0")[1] : NOVERSION; } - public static boolean accepts(final C00Handshake packet) + public static boolean accepts(final CPacketHandshake packet) { return Objects.equals(packet.getFMLVersion(), NETVERSION); } @@ -52,36 +48,18 @@ public class NetworkHooks public static Packet getEntitySpawningPacket(Entity entity) { - EntityRegistry.EntityRegistration er = EntityRegistry.instance().lookupModSpawn(entity.getClass(), false); - if (er == null || er.usesVanillaSpawning()) - { - return null; - } return null; } - public static void onServerCustomPayload(final SPacketCustomPayload packet, final NetworkManager manager) { - NetworkRegistry.findTarget(new ResourceLocation(packet.getChannelName())). - ifPresent(ni->ni.dispatch(NetworkDirection.PLAY_TO_SERVER, packet.getBufferData(), manager)); + public static void onCustomPayload(final ICustomPacket packet, final NetworkManager manager) { + NetworkRegistry.findTarget(packet.getName()). + ifPresent(ni->ni.dispatch(packet.getDirection(), packet.getData(), manager)); } - public static void onClientCustomPayload(final CPacketCustomPayload packet, final NetworkManager manager) { - NetworkRegistry.findTarget(new ResourceLocation(packet.getChannelName())). - ifPresent(ni->ni.dispatch(NetworkDirection.PLAY_TO_CLIENT, packet.getBufferData(), manager)); - } - - public static void onServerLoginCustomPayload(final SPacketCustomPayload packet, final NetworkManager manager) { - NetworkRegistry.findTarget(new ResourceLocation(packet.getChannelName())). - ifPresent(ni->ni.dispatch(NetworkDirection.LOGIN_TO_SERVER, packet.getBufferData(), manager)); - } - - public static void onClientLoginCustomPayload(final CPacketCustomPayload packet, final NetworkManager manager) { - NetworkRegistry.findTarget(new ResourceLocation(packet.getChannelName())). - ifPresent(ni->ni.dispatch(NetworkDirection.LOGIN_TO_CLIENT, packet.getBufferData(), manager)); - } - - public static void registerServerChannel(NetworkManager manager, C00Handshake packet) + public static void registerServerChannel(NetworkManager manager, CPacketHandshake packet) { manager.channel().attr(NetworkRegistry.FML_MARKER).set(packet.getFMLVersion()); } + + } diff --git a/src/main/java/net/minecraftforge/fml/network/NetworkInstance.java b/src/main/java/net/minecraftforge/fml/network/NetworkInstance.java index b6e372906..70efcf124 100644 --- a/src/main/java/net/minecraftforge/fml/network/NetworkInstance.java +++ b/src/main/java/net/minecraftforge/fml/network/NetworkInstance.java @@ -32,9 +32,9 @@ import java.util.function.Supplier; public class NetworkInstance { - public String getChannelName() + public ResourceLocation getChannelName() { - return channelName.toString(); + return channelName; } private final ResourceLocation channelName; diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLSecurityManager.java b/src/main/java/net/minecraftforge/fml/relauncher/FMLSecurityManager.java deleted file mode 100644 index 2aaf5fa97..000000000 --- a/src/main/java/net/minecraftforge/fml/relauncher/FMLSecurityManager.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.relauncher; - -import java.security.Permission; - -/** - * A custom security manager stopping certain events from happening - * unexpectedly. - * - * @author cpw - * - */ -public class FMLSecurityManager extends SecurityManager { - @Override - public void checkPermission(Permission perm) - { - String permName = perm.getName() != null ? perm.getName() : "missing"; - if (permName.startsWith("exitVM")) - { - Class[] classContexts = getClassContext(); - String callingClass = classContexts.length > 4 ? classContexts[4].getName() : "none"; - String callingParent = classContexts.length > 5 ? classContexts[5].getName() : "none"; - // FML is allowed to call system exit and the Minecraft applet (from the quit button) - if (!(callingClass.startsWith("net.minecraftforge.fml.") - || "net.minecraft.server.dedicated.ServerHangWatchdog$1".equals(callingClass) - || "net.minecraft.server.dedicated.ServerHangWatchdog".equals(callingClass) - || ( "net.minecraft.client.Minecraft".equals(callingClass) && "net.minecraft.client.Minecraft".equals(callingParent)) - || ("net.minecraft.server.dedicated.DedicatedServer".equals(callingClass) && "net.minecraft.server.MinecraftServer".equals(callingParent))) - ) - { - throw new ExitTrappedException(); - } - } - else if ("setSecurityManager".equals(permName)) - { - throw new SecurityException("Cannot replace the FML security manager"); - } - return; - } - - @Override - public void checkPermission(Permission perm, Object context) - { - this.checkPermission(perm); - } - - public static class ExitTrappedException extends SecurityException { - private static final long serialVersionUID = 1L; - } -} diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java b/src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java deleted file mode 100644 index ebb596eb2..000000000 --- a/src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.relauncher; - -import javax.annotation.Nullable; -import java.io.File; -import java.io.FilenameFilter; -import java.util.Arrays; -import java.util.Comparator; - -public final class FileListHelper { - private enum CaseInsensitiveFileComparator implements Comparator - { - INSTANCE; - @Override - public int compare(File o1, File o2) - { - return o1 != null && o2 != null ? o1.getName().compareToIgnoreCase(o2.getName()) : o1 == null ? -1 : 1; - } - - } - public static File[] sortFileList(File[] files) - { - Arrays.sort(files, CaseInsensitiveFileComparator.INSTANCE); - return files; - } - public static File[] sortFileList(File dir, @Nullable FilenameFilter filter) - { - File[] files = dir.listFiles(filter); - return sortFileList(files); - } -} diff --git a/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java b/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java deleted file mode 100644 index 908a622ac..000000000 --- a/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.relauncher; - -import com.google.common.base.Preconditions; -import net.minecraft.launchwrapper.Launch; -import org.apache.commons.lang3.StringUtils; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -/** - * Some reflection helper code. - * - * @author cpw - * - */ -public class ReflectionHelper -{ - public static class UnableToFindMethodException extends RuntimeException - { - private static final long serialVersionUID = 1L; - //private String[] methodNames; - - public UnableToFindMethodException(String[] methodNames, Exception failed) - { - super(failed); - //this.methodNames = methodNames; - } - - public UnableToFindMethodException(Throwable failed) - { - super(failed); - } - - } - - public static class UnableToFindClassException extends RuntimeException - { - private static final long serialVersionUID = 1L; - //private String[] classNames; - - public UnableToFindClassException(String[] classNames, @Nullable Exception err) - { - super(err); - //this.classNames = classNames; - } - - } - - public static class UnableToAccessFieldException extends RuntimeException - { - private static final long serialVersionUID = 1L; - //private String[] fieldNameList; - - public UnableToAccessFieldException(String[] fieldNames, Exception e) - { - super(e); - //this.fieldNameList = fieldNames; - } - } - - public static class UnableToFindFieldException extends RuntimeException - { - private static final long serialVersionUID = 1L; - //private String[] fieldNameList; - public UnableToFindFieldException(String[] fieldNameList, Exception e) - { - super(e); - //this.fieldNameList = fieldNameList; - } - } - - public static class UnknownConstructorException extends RuntimeException - { - public UnknownConstructorException(final String message) - { - super(message); - } - } - - public static Field findField(Class clazz, String... fieldNames) - { - Exception failed = null; - for (String fieldName : fieldNames) - { - try - { - Field f = clazz.getDeclaredField(fieldName); - f.setAccessible(true); - return f; - } - catch (Exception e) - { - failed = e; - } - } - throw new UnableToFindFieldException(fieldNames, failed); - } - - @SuppressWarnings("unchecked") - public static T getPrivateValue(Class classToAccess, @Nullable E instance, int fieldIndex) - { - try - { - Field f = classToAccess.getDeclaredFields()[fieldIndex]; - f.setAccessible(true); - return (T) f.get(instance); - } - catch (Exception e) - { - throw new UnableToAccessFieldException(new String[0], e); - } - } - - @SuppressWarnings("unchecked") - public static T getPrivateValue(Class classToAccess, E instance, String... fieldNames) - { - try - { - return (T) findField(classToAccess, fieldNames).get(instance); - } - catch (Exception e) - { - throw new UnableToAccessFieldException(fieldNames, e); - } - } - - public static void setPrivateValue(Class classToAccess, T instance, E value, int fieldIndex) - { - try - { - Field f = classToAccess.getDeclaredFields()[fieldIndex]; - f.setAccessible(true); - f.set(instance, value); - } - catch (Exception e) - { - throw new UnableToAccessFieldException(new String[0] , e); - } - } - - public static void setPrivateValue(Class classToAccess, T instance, E value, String... fieldNames) - { - try - { - findField(classToAccess, fieldNames).set(instance, value); - } - catch (Exception e) - { - throw new UnableToAccessFieldException(fieldNames, e); - } - } - - @SuppressWarnings("unchecked") - public static Class getClass(ClassLoader loader, String... classNames) - { - Exception err = null; - for (String className : classNames) - { - try - { - return (Class) Class.forName(className, false, loader); - } - catch (Exception e) - { - err = e; - } - } - - throw new UnableToFindClassException(classNames, err); - } - - /** - * Finds a method with the specified name and parameters in the given class and makes it accessible. - * Note: for performance, store the returned value and avoid calling this repeatedly. - *

- * Throws an exception if the method is not found. - * - * @param clazz The class to find the method on. - * @param methodName The name of the method to find (used in developer environments, i.e. "getWorldTime"). - * @param methodObfName The obfuscated name of the method to find (used in obfuscated environments, i.e. "func_72820_D"). - * If the name you are looking for is on a class that is never obfuscated, this should be null. - * @param parameterTypes The parameter types of the method to find. - * @return The method with the specified name and parameters in the given class. - */ - @Nonnull - public static Method findMethod(@Nonnull Class clazz, @Nonnull String methodName, @Nullable String methodObfName, Class... parameterTypes) - { - Preconditions.checkNotNull(clazz); - Preconditions.checkArgument(StringUtils.isNotEmpty(methodName), "Method name cannot be empty"); - - String nameToFind; - if (methodObfName == null || (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment")) - { - nameToFind = methodName; - } - else - { - nameToFind = methodObfName; - } - - try - { - Method m = clazz.getDeclaredMethod(nameToFind, parameterTypes); - m.setAccessible(true); - return m; - } - catch (Exception e) - { - throw new UnableToFindMethodException(e); - } - } - - /** - * Finds a constructor in the specified class that has matching parameter types. - * - * @param klass The class to find the constructor in - * @param parameterTypes The parameter types of the constructor. - * @param The type - * @return The constructor - * @throws NullPointerException if {@code klass} is null - * @throws NullPointerException if {@code parameterTypes} is null - * @throws UnknownConstructorException if the constructor could not be found - */ - @Nonnull - public static Constructor findConstructor(@Nonnull final Class klass, @Nonnull final Class... parameterTypes) - { - Preconditions.checkNotNull(klass, "class"); - Preconditions.checkNotNull(parameterTypes, "parameter types"); - - final Constructor constructor; - try - { - constructor = klass.getDeclaredConstructor(parameterTypes); - constructor.setAccessible(true); - } - catch (final NoSuchMethodException e) - { - final StringBuilder desc = new StringBuilder(); - desc.append(klass.getSimpleName()).append('('); - for (int i = 0, length = parameterTypes.length; i < length; i++) - { - desc.append(parameterTypes[i].getName()); - if (i > length) - { - desc.append(',').append(' '); - } - } - desc.append(')'); - throw new UnknownConstructorException("Could not find constructor '" + desc.toString() + "' in " + klass); - } - return constructor; - } -} diff --git a/src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java b/src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java deleted file mode 100644 index 56ae209fc..000000000 --- a/src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.relauncher; - -import java.lang.reflect.Method; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.core.LoggerContext; - -public class ServerLaunchWrapper { - - /** - * @param args - */ - public static void main(String[] args) - { - new ServerLaunchWrapper().run(args); - } - - private ServerLaunchWrapper() - { - - } - - private void run(String[] args) - { - if (System.getProperty("log4j.configurationFile") == null) - { - // Set this early so we don't need to reconfigure later - System.setProperty("log4j.configurationFile", "log4j2_server.xml"); - } - Class launchwrapper = null; - try - { - launchwrapper = Class.forName("net.minecraft.launchwrapper.Launch",true,getClass().getClassLoader()); - Class.forName("org.objectweb.asm.Type",true,getClass().getClassLoader()); - } - catch (Exception e) - { - System.err.printf("We appear to be missing one or more essential library files.\n" + - "You will need to add them to your server before FML and Forge will run successfully."); - e.printStackTrace(System.err); - System.exit(1); - } - - try - { - Method main = launchwrapper.getMethod("main", String[].class); - String[] allArgs = new String[args.length + 2]; - allArgs[0] = "--tweakClass"; - allArgs[1] = "net.minecraftforge.fml.common.launcher.FMLServerTweaker"; - System.arraycopy(args, 0, allArgs, 2, args.length); - main.invoke(null,(Object)allArgs); - } - catch (Exception e) - { - System.err.printf("A problem occurred running the Server launcher."); - e.printStackTrace(System.err); - System.exit(1); - } - } - -} diff --git a/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java b/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java deleted file mode 100644 index fa5bcdd9e..000000000 --- a/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.server; - -import java.io.*; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import net.minecraft.launchwrapper.Launch; -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetHandlerPlayServer; -import net.minecraft.network.NetworkManager; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.dedicated.PendingCommand; -import net.minecraft.util.IThreadListener; -import net.minecraft.util.text.translation.LanguageMap; -import net.minecraft.world.storage.SaveFormatOld; -import net.minecraftforge.common.util.CompoundDataFixer; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.IFMLSidedHandler; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.StartupQuery; -import net.minecraftforge.fml.common.network.FMLNetworkEvent; - -import com.google.common.collect.ImmutableList; -import org.apache.commons.io.IOUtils; - -/** - * Handles primary communication from hooked code into the system - * - * The FML entry point is {@link #beginServerLoading(MinecraftServer)} called from - * {@link net.minecraft.server.dedicated.DedicatedServer} - * - * Obfuscated code should focus on this class and other members of the "server" - * (or "client") code - * - * The actual mod loading is handled at arms length by {@link Loader} - * - * It is expected that a similar class will exist for each target environment: - * Bukkit and Client side. - * - * It should not be directly modified. - * - * @author cpw - * - */ -public class FMLServerHandler implements IFMLSidedHandler -{ - /** - * The singleton - */ - private static final FMLServerHandler INSTANCE = new FMLServerHandler(); - - /** - * A reference to the server itself - */ - private MinecraftServer server; - private List injectedModContainers; - private FMLServerHandler() - { - injectedModContainers = FMLCommonHandler.instance().beginLoading(this); - } - /** - * Called to start the whole game off from - * {@link MinecraftServer#startServer} - * - * @param minecraftServer server - */ - @Override - public void beginServerLoading(MinecraftServer minecraftServer) - { - server = minecraftServer; - Loader.instance().loadMods(injectedModContainers); - Loader.instance().preinitializeMods(); - } - - /** - * Called a bit later on during server initialization to finish loading mods - */ - @Override - public void finishServerLoading() - { - Loader.instance().initializeMods(); - } - - @Override - public void haltGame(String message, Throwable exception) - { - throw new RuntimeException(message, exception); - } - - @Override - public File getSavesDirectory() - { - return ((SaveFormatOld) server.getActiveAnvilConverter()).savesDirectory; - } - - /** - * Get the server instance - */ - @Override - public MinecraftServer getServer() - { - return server; - } - - /** - * @return the instance - */ - public static FMLServerHandler instance() - { - return INSTANCE; - } - - /* (non-Javadoc) - * @see net.minecraftforge.fml.common.IFMLSidedHandler#getAdditionalBrandingInformation() - */ - @Override - public List getAdditionalBrandingInformation() - { - return ImmutableList.of(); - } - - /* (non-Javadoc) - * @see net.minecraftforge.fml.common.IFMLSidedHandler#getDist() - */ - @Override - public Side getSide() - { - return Side.SERVER; - } - - @Override - public void showGuiScreen(Object clientGuiElement) - { - - } - - @Override - public void queryUser(StartupQuery query) throws InterruptedException - { - if (query.getResult() == null) - { - FMLLog.log.warn(query.getText()); - query.finish(); - } - else - { - String text = query.getText() + - "\n\nRun the command /fml confirm or or /fml cancel to proceed." + - "\nAlternatively start the server with -Dfml.queryResult=confirm or -Dfml.queryResult=cancel to preselect the answer."; - FMLLog.log.warn(text); - - if (!query.isSynchronous()) return; // no-op until mc does commands in another thread (if ever) - - boolean done = false; - - while (!done && server.isServerRunning()) - { - if (Thread.interrupted()) throw new InterruptedException(); - - DedicatedServer dedServer = (DedicatedServer) server; - - // rudimentary command processing, check for fml confirm/cancel and stop commands - synchronized (dedServer.pendingCommandList) - { - for (Iterator it = dedServer.pendingCommandList.iterator(); it.hasNext(); ) - { - String cmd = it.next().command.trim().toLowerCase(); - - if (cmd.equals("/fml confirm")) - { - FMLLog.log.info("confirmed"); - query.setResult(true); - done = true; - it.remove(); - } - else if (cmd.equals("/fml cancel")) - { - FMLLog.log.info("cancelled"); - query.setResult(false); - done = true; - it.remove(); - } - else if (cmd.equals("/stop")) - { - StartupQuery.abort(); - } - } - } - - Thread.sleep(10L); - } - - query.finish(); - } - } - - @Override - public boolean isDisplayCloseRequested() - { - return false; - } - - @Override - public boolean shouldServerShouldBeKilledQuietly() - { - return false; - } - - @Override - public void addModAsResource(ModContainer container) - { - String langFile = "assets/" + container.getModId().toLowerCase() + "/lang/en_us.lang"; - String langFile2 = "assets/" + container.getModId().toLowerCase() + "/lang/en_US.lang"; - File source = container.getSource(); - InputStream stream = null; - ZipFile zip = null; - try - { - if (source.isDirectory() && (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment")) - { - File f = new File(source.toURI().resolve(langFile).getPath()); - if (!f.exists()) - f = new File(source.toURI().resolve(langFile2).getPath()); - if (!f.exists()) - throw new FileNotFoundException(source.toURI().resolve(langFile).getPath()); - stream = new FileInputStream(f); - } - else if (source.exists()) //Fake sources.. Yay coremods -.- - { - zip = new ZipFile(source); - ZipEntry entry = zip.getEntry(langFile); - if (entry == null) entry = zip.getEntry(langFile2); - if (entry == null) throw new FileNotFoundException(langFile); - stream = zip.getInputStream(entry); - } - if (stream != null) - LanguageMap.inject(stream); - } - catch (FileNotFoundException e) - { - FMLLog.log.warn("Missing English translation for {}: {}", container.getModId(), e.getMessage()); - } - catch (IOException e) - { - // hush - } - catch(Exception e) - { - FMLLog.log.error(e); - } - finally - { - IOUtils.closeQuietly(stream); - IOUtils.closeQuietly(zip); - } - } - - @Override - public String getCurrentLanguage() - { - return "en_US"; - } - - @Override - public void serverStopped() - { - // NOOP - } - @Override - public NetworkManager getClientToServerNetworkManager() - { - throw new RuntimeException("Missing"); - } - @Override - public INetHandler getClientPlayHandler() - { - return null; - } - - @Override - public void fireNetRegistrationEvent(IEventBus bus, NetworkManager manager, Set channelSet, String channel, Side side) - { - bus.post(new FMLNetworkEvent.CustomPacketRegistrationEvent(manager, channelSet, channel, side, NetHandlerPlayServer.class)); - } - - @Override - public boolean shouldAllowPlayerLogins() - { - return DedicatedServer.allowPlayerLogins; - } - - @Override - public void allowLogins() { - DedicatedServer.allowPlayerLogins = true; - } - - @Override - public IThreadListener getWorldThread(INetHandler net) - { - // Always the server on the dedicated server, eventually add Per-World if Mojang adds world stuff. - return getServer(); - } - - @Override - public void processWindowMessages() - { - // NOOP - } - - @Override - public String stripSpecialChars(String message) - { - return message; - } - - @Override - public void reloadRenderers() { - // NOOP - } - - @Override - public void fireSidedRegistryEvents() - { - // NOOP - } - @Override - public CompoundDataFixer getDataFixer() - { - return (CompoundDataFixer)this.server.getDataFixer(); - } - - @Override - public boolean isDisplayVSyncForced() - { - return false; - } -} diff --git a/src/main/java/net/minecraftforge/fml/ServerLifecycleHooks.java b/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java similarity index 89% rename from src/main/java/net/minecraftforge/fml/ServerLifecycleHooks.java rename to src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java index e137ed701..0e1520b1b 100644 --- a/src/main/java/net/minecraftforge/fml/ServerLifecycleHooks.java +++ b/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java @@ -17,18 +17,19 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml; +package net.minecraftforge.fml.server; import net.minecraft.network.EnumConnectionState; import net.minecraft.network.NetworkManager; -import net.minecraft.network.handshake.client.C00Handshake; -import net.minecraft.network.login.server.SPacketDisconnect; +import net.minecraft.network.handshake.client.CPacketHandshake; +import net.minecraft.network.login.server.SPacketDisconnectLogin; import net.minecraft.server.MinecraftServer; import net.minecraft.util.text.TextComponentString; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.LogicalSidedProvider; import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent; -import net.minecraftforge.fml.common.event.FMLServerStartedEvent; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; +import net.minecraftforge.fml.common.event.FMLServerStartedEvent; import net.minecraftforge.fml.common.event.FMLServerStoppedEvent; import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; import net.minecraftforge.fml.network.NetworkHooks; @@ -43,7 +44,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public class ServerLifecycleHooks { - private static final Logger LOGGER = LogManager.getLogger("FML"); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker SERVERHOOKS = MarkerManager.getMarker("SERVERHOOKS"); private static volatile CountDownLatch exitLatch = null; private static MinecraftServer currentServer; @@ -97,12 +98,12 @@ public class ServerLifecycleHooks } private static AtomicBoolean allowLogins = new AtomicBoolean(false); - public static boolean handleServerLogin(final C00Handshake packet, final NetworkManager manager) { + public static boolean handleServerLogin(final CPacketHandshake packet, final NetworkManager manager) { if (!allowLogins.get()) { TextComponentString text = new TextComponentString("Server is still starting! Please wait before reconnecting."); - LOGGER.info(SERVERHOOKS,"Disconnecting Player (server is still starting): {}", text.getUnformattedText()); - manager.sendPacket(new SPacketDisconnect(text)); + LOGGER.info(SERVERHOOKS,"Disconnecting Player (server is still starting): {}", text.getUnformattedComponentText()); + manager.sendPacket(new SPacketDisconnectLogin(text)); manager.closeChannel(text); return false; } @@ -113,7 +114,7 @@ public class ServerLifecycleHooks TextComponentString text = new TextComponentString("This server has mods that require Forge to be installed on the client. Contact your server admin for more details."); List modNames = net.minecraftforge.fml.network.NetworkRegistry.getNonVanillaNetworkMods(); LOGGER.info(SERVERHOOKS,"Disconnecting vanilla connection attempt. Required mods {}", modNames); - manager.sendPacket(new SPacketDisconnect(text)); + manager.sendPacket(new SPacketDisconnectLogin(text)); manager.closeChannel(text); return false; } diff --git a/src/main/java/net/minecraftforge/items/CapabilityItemHandler.java b/src/main/java/net/minecraftforge/items/CapabilityItemHandler.java index f390a5cd8..f957d466c 100644 --- a/src/main/java/net/minecraftforge/items/CapabilityItemHandler.java +++ b/src/main/java/net/minecraftforge/items/CapabilityItemHandler.java @@ -20,7 +20,7 @@ package net.minecraftforge.items; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.INBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.EnumFacing; @@ -40,7 +40,7 @@ public class CapabilityItemHandler CapabilityManager.INSTANCE.register(IItemHandler.class, new Capability.IStorage() { @Override - public NBTBase writeNBT(Capability capability, IItemHandler instance, EnumFacing side) + public INBTBase writeNBT(Capability capability, IItemHandler instance, EnumFacing side) { NBTTagList nbtTagList = new NBTTagList(); int size = instance.getSlots(); @@ -52,27 +52,27 @@ public class CapabilityItemHandler NBTTagCompound itemTag = new NBTTagCompound(); itemTag.setInteger("Slot", i); stack.writeToNBT(itemTag); - nbtTagList.appendTag(itemTag); + nbtTagList.add(itemTag); } } return nbtTagList; } @Override - public void readNBT(Capability capability, IItemHandler instance, EnumFacing side, NBTBase base) + public void readNBT(Capability capability, IItemHandler instance, EnumFacing side, INBTBase base) { if (!(instance instanceof IItemHandlerModifiable)) throw new RuntimeException("IItemHandler instance does not implement IItemHandlerModifiable"); IItemHandlerModifiable itemHandlerModifiable = (IItemHandlerModifiable) instance; NBTTagList tagList = (NBTTagList) base; - for (int i = 0; i < tagList.tagCount(); i++) + for (int i = 0; i < tagList.size(); i++) { NBTTagCompound itemTags = tagList.getCompoundTagAt(i); int j = itemTags.getInteger("Slot"); if (j >= 0 && j < instance.getSlots()) { - itemHandlerModifiable.setStackInSlot(j, new ItemStack(itemTags)); + itemHandlerModifiable.setStackInSlot(j, ItemStack.func_199557_a(itemTags)); } } } diff --git a/src/main/java/net/minecraftforge/items/ItemStackHandler.java b/src/main/java/net/minecraftforge/items/ItemStackHandler.java index 307f95907..eb07f42a5 100644 --- a/src/main/java/net/minecraftforge/items/ItemStackHandler.java +++ b/src/main/java/net/minecraftforge/items/ItemStackHandler.java @@ -181,7 +181,7 @@ public class ItemStackHandler implements IItemHandler, IItemHandlerModifiable, I NBTTagCompound itemTag = new NBTTagCompound(); itemTag.setInteger("Slot", i); stacks.get(i).writeToNBT(itemTag); - nbtTagList.appendTag(itemTag); + nbtTagList.add(itemTag); } } NBTTagCompound nbt = new NBTTagCompound(); @@ -195,14 +195,14 @@ public class ItemStackHandler implements IItemHandler, IItemHandlerModifiable, I { setSize(nbt.hasKey("Size", Constants.NBT.TAG_INT) ? nbt.getInteger("Size") : stacks.size()); NBTTagList tagList = nbt.getTagList("Items", Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < tagList.tagCount(); i++) + for (int i = 0; i < tagList.size(); i++) { NBTTagCompound itemTags = tagList.getCompoundTagAt(i); int slot = itemTags.getInteger("Slot"); if (slot >= 0 && slot < stacks.size()) { - stacks.set(slot, new ItemStack(itemTags)); + stacks.set(slot, ItemStack.func_199557_a(itemTags)); } } onLoad(); diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java index 72a006b40..646ae08b5 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java @@ -59,7 +59,7 @@ import org.apache.logging.log4j.MarkerManager; public class ForgeRegistry> implements IForgeRegistryInternal, IForgeRegistryModifiable { public static Marker REGISTRIES = MarkerManager.getMarker("REGISTRIES"); - private static Logger LOGGER = LogManager.getLogger("FML"); + private static Logger LOGGER = LogManager.getLogger(); private final RegistryManager stage; private final BiMap ids = HashBiMap.create(); private final BiMap names = HashBiMap.create(); @@ -329,7 +329,7 @@ public class ForgeRegistry> implements IForgeRe this.names.put(key, value); this.ids.put(idToUse, value); this.availabilityMap.set(idToUse); - this.owners.put(new OverrideOwner(owner == null ? key.getResourceDomain() : owner, key), value); + this.owners.put(new OverrideOwner(owner == null ? key.getPath() : owner, key), value); if (isDelegated) { @@ -683,7 +683,7 @@ public class ForgeRegistry> implements IForgeRe LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), newId, realId); } - int realId = add(newId, obj, primaryName == null ? itemName.getResourceDomain() : primaryName); + int realId = add(newId, obj, primaryName == null ? itemName.getPath() : primaryName); if (realId != newId) LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), newId, realId); ovs.remove(itemName); @@ -936,7 +936,7 @@ public class ForgeRegistry> implements IForgeRe if (m == null) defaulted.add(remap.key); else - this.add(remap.id, m, remap.key.getResourceDomain()); + this.add(remap.id, m, remap.key.getPath()); } else if (action == MissingMappings.Action.IGNORE) { diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java index 8bb681549..0d80f60eb 100644 --- a/src/main/java/net/minecraftforge/registries/GameData.java +++ b/src/main/java/net/minecraftforge/registries/GameData.java @@ -20,7 +20,6 @@ package net.minecraftforge.registries; import com.google.common.collect.HashBiMap; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; @@ -54,7 +53,6 @@ import net.minecraftforge.fml.StartupQuery; import net.minecraftforge.fml.common.ZipperUtil; import net.minecraftforge.fml.common.registry.EntityEntry; import net.minecraftforge.fml.common.registry.EntityEntryBuilder; -import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession; import com.google.common.collect.ArrayListMultimap; @@ -76,20 +74,20 @@ import javax.annotation.Nullable; import net.minecraftforge.fml.common.thread.EffectiveSide; import org.apache.commons.lang3.Validate; -import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; -import static net.minecraftforge.fml.Logging.fmlLog; - /** * INTERNAL ONLY * MODDERS SHOULD HAVE NO REASON TO USE THIS CLASS */ public class GameData { + private static final Logger LOGGER = LogManager.getLogger(); + private static final Marker GD = MarkerManager.getMarker("GAMEDATA"); + public static final ResourceLocation BLOCKS = new ResourceLocation("minecraft:blocks"); public static final ResourceLocation ITEMS = new ResourceLocation("minecraft:items"); public static final ResourceLocation POTIONS = new ResourceLocation("minecraft:potions"); @@ -114,8 +112,6 @@ public class GameData private static final ResourceLocation BLOCK_TO_ITEM = new ResourceLocation("minecraft:blocktoitemmap"); private static final ResourceLocation BLOCKSTATE_TO_ID = new ResourceLocation("minecraft:blockstatetoid"); - private static final Logger LOGGER = LogManager.getLogger("FML"); - private static final Marker GD = MarkerManager.getMarker("GAMEDATA"); private static boolean hasInit = false; private static final boolean DISABLE_VANILLA_REGISTRIES = Boolean.parseBoolean(System.getProperty("forge.disableVanillaGameData", "false")); // Use for unit tests/debugging private static final BiConsumer> LOCK_VANILLA = (name, reg) -> reg.slaves.values().stream().filter(o -> o instanceof ILockableRegistry).forEach(o -> ((ILockableRegistry)o).lock()); @@ -161,7 +157,7 @@ public class GameData public static > RegistryNamespacedDefaultedByKey getWrapperDefaulted(Class cls) { - IForgeRegistry reg = GameRegistry.findRegistry(cls); + IForgeRegistry reg = RegistryManager.ACTIVE.getRegistry(cls); Validate.notNull(reg, "Attempted to get vanilla wrapper for unknown registry: " + cls.toString()); @SuppressWarnings("unchecked") RegistryNamespacedDefaultedByKey ret = reg.getSlaveMap(NamespacedDefaultedWrapper.Factory.ID, NamespacedDefaultedWrapper.class); @@ -171,7 +167,7 @@ public class GameData public static > RegistryNamespaced getWrapper(Class cls) { - IForgeRegistry reg = GameRegistry.findRegistry(cls); + IForgeRegistry reg = RegistryManager.ACTIVE.getRegistry(cls); Validate.notNull(reg, "Attempted to get vanilla wrapper for unknown registry: " + cls.toString()); @SuppressWarnings("unchecked") RegistryNamespaced ret = reg.getSlaveMap(NamespacedWrapper.Factory.ID, NamespacedWrapper.class); @@ -182,20 +178,20 @@ public class GameData @SuppressWarnings("unchecked") public static BiMap getBlockItemMap() { - return GameRegistry.findRegistry(Item.class).getSlaveMap(BLOCK_TO_ITEM, BiMap.class); + return RegistryManager.ACTIVE.getRegistry((Class)Item.class).getSlaveMap(BLOCK_TO_ITEM, BiMap.class); } @SuppressWarnings("unchecked") public static ObjectIntIdentityMap getBlockStateIDMap() { - return GameRegistry.findRegistry(Block.class).getSlaveMap(BLOCKSTATE_TO_ID, ObjectIntIdentityMap.class); + return RegistryManager.ACTIVE.getRegistry((Class)Block.class).getSlaveMap(BLOCKSTATE_TO_ID, ObjectIntIdentityMap.class); } public static > K register_impl(K value) { Validate.notNull(value, "Attempted to register a null object"); Validate.notNull(value.getRegistryName(), String.format("Attempt to register object without having set a registry name %s (type %s)", value, value.getClass().getName())); - final IForgeRegistry registry = GameRegistry.findRegistry(value.getRegistryType()); + final IForgeRegistry registry = RegistryManager.ACTIVE.getRegistry(value.getRegistryType()); Validate.notNull(registry, "Attempted to registry object without creating registry first: " + value.getRegistryType().getName()); registry.register(value); return value; @@ -204,7 +200,7 @@ public class GameData @SuppressWarnings({ "unchecked", "rawtypes" }) public static void vanillaSnapshot() { - fmlLog.debug("Creating vanilla freeze snapshot"); + LOGGER.debug("Creating vanilla freeze snapshot"); for (Map.Entry>> r : RegistryManager.ACTIVE.registries.entrySet()) { final Class clazz = RegistryManager.ACTIVE.getSuperType(r.getKey()); @@ -217,7 +213,7 @@ public class GameData }); RegistryManager.VANILLA.registries.forEach(LOCK_VANILLA); RegistryManager.ACTIVE.registries.forEach(LOCK_VANILLA); - fmlLog.debug("Vanilla freeze snapshot created"); + LOGGER.debug("Vanilla freeze snapshot created"); } @SuppressWarnings({ "rawtypes", "unchecked" }) diff --git a/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java b/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java index 6f3cea44a..4a903de36 100644 --- a/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java +++ b/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java @@ -29,7 +29,6 @@ import java.util.Queue; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import javax.annotation.Nullable; @@ -108,7 +107,7 @@ class ObjectHolderRef Collections.addAll(typesToExamine, type.getInterfaces()); if (IForgeRegistryEntry.class.isAssignableFrom(type)) { - registry = (ForgeRegistry)GameRegistry.findRegistry((Class)type); + registry = (ForgeRegistry)RegistryManager.ACTIVE.getRegistry((Class)type); final Class parentType = type.getSuperclass(); if (parentType != null) { diff --git a/src/main/resources/META-INF/defaultfmlconfig.toml b/src/main/resources/META-INF/defaultfmlconfig.toml new file mode 100644 index 000000000..bddded498 --- /dev/null +++ b/src/main/resources/META-INF/defaultfmlconfig.toml @@ -0,0 +1,2 @@ +# does the splashscreen run +splashscreen = true diff --git a/src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java b/src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java index 9a7d98c6e..ae6abb4c4 100644 --- a/src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java +++ b/src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java @@ -27,7 +27,8 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.item.EntityArmorStand; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; -import net.minecraftforge.fml.client.registry.IRenderFactory; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.client.registry.RenderingRegistry; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; @@ -41,29 +42,11 @@ public class VertexBufferNormalTest @Instance("wrnormal") public static VertexBufferNormalTest instance; - public static ServerProxy proxy; - @EventHandler public void init(FMLPreInitializationEvent event) { EntityRegistry.registerModEntity(new ResourceLocation("wrnormal", "scale_test"), EntityScaleTest.class, "scale_test", 0, instance, 60, 3, true); - proxy.registerRenders(); - } - - public static class ServerProxy - { - public void registerRenders() - { - } - } - - public static class ClientProxy extends ServerProxy - { - @Override - public void registerRenders() - { - RenderingRegistry.registerEntityRenderingHandler(EntityScaleTest.class, new RenderScaleTestFactory()); - } + DistExecutor.runWhenOn(Dist.CLIENT, ()-> () -> RenderingRegistry.registerEntityRenderingHandler(EntityScaleTest.class, RenderScaleTest::new)); } public static class RenderScaleTestFactory implements IRenderFactory