Goodbye @Mod, it was lovely knowing you!
This commit is contained in:
parent
d23850ff98
commit
14ac77e444
37 changed files with 1541 additions and 176 deletions
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
#Mon Sep 14 12:28:28 PDT 2015
|
#Sat Mar 10 11:15:39 EST 2018
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip
|
||||||
|
|
52
gradlew
vendored
52
gradlew
vendored
|
@ -6,12 +6,30 @@
|
||||||
##
|
##
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Attempt to set APP_HOME
|
||||||
DEFAULT_JVM_OPTS=""
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
APP_NAME="Gradle"
|
||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
@ -30,6 +48,7 @@ die ( ) {
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
case "`uname`" in
|
case "`uname`" in
|
||||||
CYGWIN* )
|
CYGWIN* )
|
||||||
cygwin=true
|
cygwin=true
|
||||||
|
@ -40,31 +59,11 @@ case "`uname`" in
|
||||||
MINGW* )
|
MINGW* )
|
||||||
msys=true
|
msys=true
|
||||||
;;
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
|
||||||
if $cygwin ; then
|
|
||||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
|
||||||
# Resolve links: $0 may be a link
|
|
||||||
PRG="$0"
|
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
|
||||||
ls=`ls -ld "$PRG"`
|
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
|
||||||
PRG="$link"
|
|
||||||
else
|
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >&-
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >&-
|
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
|
@ -90,7 +89,7 @@ location of your Java installation."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
if [ $? -eq 0 ] ; then
|
if [ $? -eq 0 ] ; then
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
@ -114,6 +113,7 @@ fi
|
||||||
if $cygwin ; then
|
if $cygwin ; then
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
|
8
gradlew.bat
vendored
8
gradlew.bat
vendored
|
@ -8,14 +8,14 @@
|
||||||
@rem Set local scope for the variables with windows NT shell
|
@rem Set local scope for the variables with windows NT shell
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
set DEFAULT_JVM_OPTS=
|
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
@rem Find java.exe
|
@rem Find java.exe
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ echo location of your Java installation.
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
:init
|
:init
|
||||||
@rem Get command-line arguments, handling Windowz variants
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
|
@ -41,7 +41,7 @@ import net.minecraftforge.fml.common.Loader;
|
||||||
import net.minecraftforge.fml.common.LoaderException;
|
import net.minecraftforge.fml.common.LoaderException;
|
||||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||||
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
|
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
|
||||||
import net.minecraftforge.fml.common.discovery.asm.ModAnnotation.EnumHolder;
|
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation.EnumHolder;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
|
85
src/main/java/net/minecraftforge/fml/FMLConfig.java
Normal file
85
src/main/java/net/minecraftforge/fml/FMLConfig.java
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import net.minecraftforge.fml.common.FMLPaths;
|
||||||
|
|
||||||
|
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 static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class FMLConfig
|
||||||
|
{
|
||||||
|
private static FMLConfig INSTANCE;
|
||||||
|
private final Map<String, String> configData = new HashMap<>();
|
||||||
|
|
||||||
|
private FMLConfig() {
|
||||||
|
configData.putAll(defaultValues());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String,String> defaultValues() {
|
||||||
|
final Map<String,String> result = new HashMap<>();
|
||||||
|
result.put("splashscreen", "true");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadFrom(final Path configFile) throws IOException
|
||||||
|
{
|
||||||
|
final Type type = new TypeToken<Map<String, String>>() {}.getType();
|
||||||
|
final Gson gson = new Gson();
|
||||||
|
final Map<String,String> loadedConfig = gson.fromJson(Files.newBufferedReader(configFile), type);
|
||||||
|
if (loadedConfig != null)
|
||||||
|
configData.putAll(loadedConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveConfigIfNecessary(final Path configFile) throws IOException {
|
||||||
|
final Type type = new TypeToken<Map<String, String>>() {}.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("Unable to read FML config at {}", configFile, ioe);
|
||||||
|
throw new RuntimeException("Unable to read FML config", ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
src/main/java/net/minecraftforge/fml/FileUtils.java
Normal file
51
src/main/java/net/minecraftforge/fml/FileUtils.java
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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;
|
||||||
|
|
||||||
|
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.fmlLog;
|
||||||
|
|
||||||
|
public class FileUtils
|
||||||
|
{
|
||||||
|
public static Path getOrCreateDirectory(Path dirPath, String dirLabel) {
|
||||||
|
if (!Files.isDirectory(dirPath))
|
||||||
|
{
|
||||||
|
fmlLog.debug("Making {} directory : {}", dirLabel, dirPath);
|
||||||
|
try {
|
||||||
|
Files.createDirectory(dirPath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (e instanceof FileAlreadyExistsException) {
|
||||||
|
fmlLog.error("Failed to create {} directory - there is a file in the way", dirLabel);
|
||||||
|
} else {
|
||||||
|
fmlLog.error("Problem with creating {} directory (Permissions?)", dirLabel, e);
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Problem creating directory", e);
|
||||||
|
}
|
||||||
|
fmlLog.debug("Created {} directory : {}", dirLabel, dirPath);
|
||||||
|
} else {
|
||||||
|
fmlLog.debug("Found existing {} directory : {}", dirLabel, dirPath);
|
||||||
|
}
|
||||||
|
return dirPath;
|
||||||
|
}
|
||||||
|
}
|
33
src/main/java/net/minecraftforge/fml/LaunchTesting.java
Normal file
33
src/main/java/net/minecraftforge/fml/LaunchTesting.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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;
|
||||||
|
|
||||||
|
import cpw.mods.modlauncher.Launcher;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
import org.apache.logging.log4j.core.config.Configurator;
|
||||||
|
|
||||||
|
public class LaunchTesting
|
||||||
|
{
|
||||||
|
public static void main(String... args)
|
||||||
|
{
|
||||||
|
Configurator.setRootLevel(Level.DEBUG);
|
||||||
|
Launcher.main("--launchTarget", "fml","--gameDir", "projects/run");
|
||||||
|
}
|
||||||
|
}
|
30
src/main/java/net/minecraftforge/fml/Logging.java
Normal file
30
src/main/java/net/minecraftforge/fml/Logging.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.logging.log4j.core.config.Configurator;
|
||||||
|
|
||||||
|
public class Logging
|
||||||
|
{
|
||||||
|
public static final Logger fmlLog = LogManager.getLogger("FML");
|
||||||
|
}
|
|
@ -25,9 +25,8 @@ import com.google.common.collect.SetMultimap;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||||
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
|
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
|
||||||
import net.minecraftforge.fml.common.discovery.asm.ModAnnotation;
|
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import org.apache.logging.log4j.Level;
|
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
84
src/main/java/net/minecraftforge/fml/common/FMLPaths.java
Normal file
84
src/main/java/net/minecraftforge/fml/common/FMLPaths.java
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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 cpw.mods.modlauncher.api.IEnvironment;
|
||||||
|
import net.minecraftforge.fml.FileUtils;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public enum FMLPaths
|
||||||
|
{
|
||||||
|
GAMEDIR(),
|
||||||
|
MODSDIR("mods"),
|
||||||
|
CONFIGDIR("config"),
|
||||||
|
FMLCONFIG(false, CONFIGDIR, "fml.cfg");
|
||||||
|
|
||||||
|
private final Path relativePath;
|
||||||
|
private final boolean isDirectory;
|
||||||
|
private Path absolutePath;
|
||||||
|
|
||||||
|
FMLPaths() {
|
||||||
|
this("");
|
||||||
|
}
|
||||||
|
|
||||||
|
FMLPaths(String... path) {
|
||||||
|
relativePath = computePath(path);
|
||||||
|
this.isDirectory = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path computePath(String... path)
|
||||||
|
{
|
||||||
|
return Paths.get(path[0], Arrays.copyOfRange(path, 1, path.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
FMLPaths(boolean isDir, FMLPaths parent, String... path) {
|
||||||
|
this.relativePath = parent.relativePath.resolve(computePath(path));
|
||||||
|
this.isDirectory = isDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setup(IEnvironment env) {
|
||||||
|
final Path rootPath = env.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElseThrow(() -> new RuntimeException("No game path found"));
|
||||||
|
|
||||||
|
loadAbsolutePaths(rootPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadAbsolutePaths(Path rootPath)
|
||||||
|
{
|
||||||
|
for (FMLPaths path : FMLPaths.values())
|
||||||
|
{
|
||||||
|
path.absolutePath = rootPath.resolve(path.relativePath).toAbsolutePath();
|
||||||
|
fmlLog.debug("Path {} is {}", ()-> path, ()-> path.absolutePath);
|
||||||
|
if (path.isDirectory)
|
||||||
|
{
|
||||||
|
FileUtils.getOrCreateDirectory(path.absolutePath, path.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Path get() {
|
||||||
|
return absolutePath;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,11 +22,10 @@ package net.minecraftforge.fml.common;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import net.minecraftforge.fml.common.discovery.ModCandidate;
|
import net.minecraftforge.fml.common.discovery.ModCandidate;
|
||||||
import net.minecraftforge.fml.common.discovery.asm.ASMModParser;
|
import net.minecraftforge.fml.common.discovery.asm.ASMModParser;
|
||||||
import net.minecraftforge.fml.common.discovery.asm.ModAnnotation;
|
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation;
|
||||||
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ import net.minecraftforge.fml.common.LoaderException;
|
||||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||||
import net.minecraftforge.fml.common.discovery.ModCandidate;
|
import net.minecraftforge.fml.common.discovery.ModCandidate;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation;
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ModClassVisitor;
|
||||||
import org.objectweb.asm.ClassReader;
|
import org.objectweb.asm.ClassReader;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
|
|
@ -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.discovery.asm;
|
|
||||||
|
|
||||||
import org.objectweb.asm.AnnotationVisitor;
|
|
||||||
import org.objectweb.asm.ClassVisitor;
|
|
||||||
import org.objectweb.asm.FieldVisitor;
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
|
|
||||||
public class ModClassVisitor extends ClassVisitor
|
|
||||||
{
|
|
||||||
private ASMModParser discoverer;
|
|
||||||
|
|
||||||
public ModClassVisitor(ASMModParser discoverer)
|
|
||||||
{
|
|
||||||
super(Opcodes.ASM5);
|
|
||||||
this.discoverer = discoverer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
|
||||||
{
|
|
||||||
discoverer.beginNewTypeName(name, version, superName, interfaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
|
|
||||||
{
|
|
||||||
discoverer.startClassAnnotation(annotationName);
|
|
||||||
return new ModAnnotationVisitor(discoverer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
|
|
||||||
{
|
|
||||||
return new ModFieldVisitor(name, discoverer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
|
|
||||||
{
|
|
||||||
return new ModMethodVisitor(name, desc, discoverer);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,7 +23,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.apache.commons.lang3.Validate;
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
|
@ -31,7 +30,7 @@ import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import net.minecraftforge.fml.common.FMLLog;
|
import net.minecraftforge.fml.common.FMLLog;
|
||||||
import net.minecraftforge.fml.common.discovery.asm.ModAnnotation.EnumHolder;
|
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation.EnumHolder;
|
||||||
|
|
||||||
//Package private, modders shouldn't access this. Do it through ASMDataTable.
|
//Package private, modders shouldn't access this. Do it through ASMDataTable.
|
||||||
class ASMInfo
|
class ASMInfo
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading;
|
||||||
|
|
||||||
|
import cpw.mods.modlauncher.api.ILaunchHandlerService;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class FMLLaunchProvider implements ILaunchHandlerService
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String name()
|
||||||
|
{
|
||||||
|
return "fml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path[] identifyTransformationTargets()
|
||||||
|
{
|
||||||
|
return new Path[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Callable<Void> launchService(String[] arguments, ClassLoader launchClassLoader)
|
||||||
|
{
|
||||||
|
return () -> { return null; };
|
||||||
|
}
|
||||||
|
}
|
62
src/main/java/net/minecraftforge/fml/loading/FMLLoader.java
Normal file
62
src/main/java/net/minecraftforge/fml/loading/FMLLoader.java
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading;
|
||||||
|
|
||||||
|
import cpw.mods.modlauncher.api.IEnvironment;
|
||||||
|
import cpw.mods.modlauncher.api.ITransformationService;
|
||||||
|
import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
|
||||||
|
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
|
||||||
|
import net.minecraftforge.common.ForgeVersion;
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ModDiscoverer;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class FMLLoader
|
||||||
|
{
|
||||||
|
|
||||||
|
private static ILaunchPluginService accessTransformer;
|
||||||
|
private static ModDiscoverer modDiscoverer;
|
||||||
|
|
||||||
|
static void initialize(IEnvironment environment, Set<String> otherServices) throws IncompatibleEnvironmentException
|
||||||
|
{
|
||||||
|
final String version = ForgeVersion.getVersion();
|
||||||
|
fmlLog.debug("FML {} loading", version);
|
||||||
|
final Package modLauncherPackage = ITransformationService.class.getPackage();
|
||||||
|
fmlLog.debug("FML found ModLauncher version : {}", modLauncherPackage.getImplementationVersion());
|
||||||
|
if (!modLauncherPackage.isCompatibleWith("1.0")) {
|
||||||
|
fmlLog.error("Found incompatible ModLauncher specification : {}, version {} from {}", modLauncherPackage.getSpecificationVersion(), modLauncherPackage.getImplementationVersion(), modLauncherPackage.getImplementationVendor());
|
||||||
|
throw new IncompatibleEnvironmentException("Incompatible modlauncher found "+modLauncherPackage.getSpecificationVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
accessTransformer = environment.findLaunchPlugin("accesstransformer").orElseThrow(()-> new IncompatibleEnvironmentException("Missing AccessTransformer, cannot run"));
|
||||||
|
|
||||||
|
final Package atPackage = accessTransformer.getClass().getPackage();
|
||||||
|
fmlLog.debug("FML found AccessTransformer version : {}", atPackage.getImplementationVersion());
|
||||||
|
if (!atPackage.isCompatibleWith("1.0")) {
|
||||||
|
fmlLog.error("Found incompatible AccessTransformer specification : {}, version {} from {}", atPackage.getSpecificationVersion(), atPackage.getImplementationVersion(), atPackage.getImplementationVendor());
|
||||||
|
}
|
||||||
|
// final ILaunchPluginService coreMod = environment.findLaunchPlugin("coremod").orElseThrow(()-> new IncompatibleEnvironmentException("Missing CoreMod, cannot run"));
|
||||||
|
|
||||||
|
fmlLog.debug("Scanning for Mod Locators");
|
||||||
|
modDiscoverer = new ModDiscoverer();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading;
|
||||||
|
|
||||||
|
import cpw.mods.modlauncher.api.IEnvironment;
|
||||||
|
import cpw.mods.modlauncher.api.ITransformationService;
|
||||||
|
import cpw.mods.modlauncher.api.ITransformer;
|
||||||
|
import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
|
||||||
|
import joptsimple.ArgumentAcceptingOptionSpec;
|
||||||
|
import joptsimple.OptionSpecBuilder;
|
||||||
|
import net.minecraftforge.fml.FMLConfig;
|
||||||
|
import net.minecraftforge.fml.common.FMLPaths;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class FMLServiceProvider implements ITransformationService
|
||||||
|
{
|
||||||
|
|
||||||
|
private ArgumentAcceptingOptionSpec<String> modsOption;
|
||||||
|
private ArgumentAcceptingOptionSpec<String> modListsOption;
|
||||||
|
private List<String> modsArgumentList;
|
||||||
|
private List<String> modListsArgumentList;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name()
|
||||||
|
{
|
||||||
|
return "fml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(IEnvironment environment)
|
||||||
|
{
|
||||||
|
fmlLog.debug("Setting up basic FML game directories");
|
||||||
|
FMLPaths.setup(environment);
|
||||||
|
fmlLog.debug("Loading configuration");
|
||||||
|
FMLConfig.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad(IEnvironment environment, Set<String> otherServices) throws IncompatibleEnvironmentException
|
||||||
|
{
|
||||||
|
FMLLoader.initialize(environment, otherServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void arguments(BiFunction<String, String, OptionSpecBuilder> argumentBuilder)
|
||||||
|
{
|
||||||
|
modsOption = argumentBuilder.apply("mods", "List of mods to add").withRequiredArg().ofType(String.class).withValuesSeparatedBy(",");
|
||||||
|
modListsOption = argumentBuilder.apply("modLists", "JSON modlists").withRequiredArg().ofType(String.class).withValuesSeparatedBy(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void argumentValues(OptionResult option)
|
||||||
|
{
|
||||||
|
modsArgumentList = option.values(modsOption);
|
||||||
|
modListsArgumentList = option.values(modListsOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public List<ITransformer> transformers()
|
||||||
|
{
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class BackgroundScanHandler
|
||||||
|
{
|
||||||
|
private final ExecutorService modContentScanner;
|
||||||
|
private final List<ModFile> pendingFiles;
|
||||||
|
private final List<ModFile> scannedFiles;
|
||||||
|
private final List<ModFile> allFiles;
|
||||||
|
|
||||||
|
public BackgroundScanHandler() {
|
||||||
|
modContentScanner = Executors.newCachedThreadPool();
|
||||||
|
scannedFiles = new ArrayList<>();
|
||||||
|
pendingFiles = new ArrayList<>();
|
||||||
|
allFiles = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void submitForScanning(final ModFile file) {
|
||||||
|
if (modContentScanner.isShutdown()) {
|
||||||
|
throw new IllegalStateException("Scanner has shutdown");
|
||||||
|
}
|
||||||
|
allFiles.add(file);
|
||||||
|
pendingFiles.add(file);
|
||||||
|
final CompletableFuture<ScanResult> future = CompletableFuture.supplyAsync(file::compileContent, modContentScanner)
|
||||||
|
.whenComplete(file::setScanResult)
|
||||||
|
.whenComplete((r,t)-> this.addCompletedFile(file,r,t));
|
||||||
|
file.setFutureScanResult(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCompletedFile(final ModFile file, final ScanResult scanResult, final Throwable throwable) {
|
||||||
|
if (throwable != null) {
|
||||||
|
fmlLog.error("An error occurred scanning file {}", file, throwable);
|
||||||
|
}
|
||||||
|
pendingFiles.remove(file);
|
||||||
|
scannedFiles.add(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ModFile> getScannedFiles() {
|
||||||
|
if (!pendingFiles.isEmpty()) {
|
||||||
|
modContentScanner.shutdown();
|
||||||
|
try {
|
||||||
|
modContentScanner.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scannedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ModFile> getAllFiles() {
|
||||||
|
return allFiles;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
public class CoreModFile implements net.minecraftforge.forgespi.ICoreModFile {
|
||||||
|
private final java.nio.file.Path internalPath;
|
||||||
|
private final ModFile file;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
CoreModFile(final String name, final java.nio.file.Path path, final ModFile file) {
|
||||||
|
this.name = name;
|
||||||
|
this.internalPath = path;
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.io.Reader readCoreMod() throws java.io.IOException {
|
||||||
|
return java.nio.file.Files.newBufferedReader(this.internalPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.nio.file.Path getPath() {
|
||||||
|
return this.internalPath;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class ExplodedDirectoryLocator implements IModLocator {
|
||||||
|
private static final String DIR = System.getProperty("fml.explodedDir", "modclasses");
|
||||||
|
private final Path rootDir;
|
||||||
|
|
||||||
|
ExplodedDirectoryLocator() {
|
||||||
|
this.rootDir = FileSystems.getDefault().getPath(DIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ModFile> scanMods() {
|
||||||
|
return Collections.singletonList(new ModFile(rootDir, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "exploded directory";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path findPath(final ModFile modFile, final String... path) {
|
||||||
|
if (path.length < 1) {
|
||||||
|
throw new IllegalArgumentException("Missing path");
|
||||||
|
}
|
||||||
|
return rootDir.resolve(FileSystems.getDefault().getPath(path[0], Arrays.copyOfRange(path, 1, path.length)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanFile(final ModFile modFile, final Consumer<Path> pathConsumer) {
|
||||||
|
fmlLog.debug("Scanning directory {}", rootDir);
|
||||||
|
try (Stream<Path> 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("Directory scan complete {}", rootDir);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.jar.Manifest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loaded as a ServiceLoader. Takes mechanisms for locating candidate "mods"
|
||||||
|
* and transforms them into {@link ModFile} objects.
|
||||||
|
*/
|
||||||
|
public interface IModLocator {
|
||||||
|
List<ModFile> scanMods();
|
||||||
|
|
||||||
|
String name();
|
||||||
|
|
||||||
|
Path findPath(ModFile modFile, String... path);
|
||||||
|
|
||||||
|
void scanFile(final ModFile modFile, Consumer<Path> pathConsumer);
|
||||||
|
|
||||||
|
Optional<Manifest> findManifest(Path file);
|
||||||
|
}
|
|
@ -17,13 +17,12 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.minecraftforge.fml.common.discovery.asm;
|
package net.minecraftforge.fml.loading.moddiscovery;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.minecraftforge.fml.common.discovery.asm.ASMModParser.AnnotationType;
|
|
||||||
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
|
@ -53,20 +52,21 @@ public class ModAnnotation
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AnnotationType type;
|
ElementType type;
|
||||||
Type asmType;
|
Type asmType;
|
||||||
String member;
|
String member;
|
||||||
Map<String,Object> values = Maps.newHashMap();
|
Map<String,Object> values = Maps.newHashMap();
|
||||||
|
|
||||||
private ArrayList<Object> arrayList;
|
private ArrayList<Object> arrayList;
|
||||||
private String arrayName;
|
private String arrayName;
|
||||||
public ModAnnotation(AnnotationType type, Type asmType, String member)
|
public ModAnnotation(ElementType type, Type asmType, String member)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.asmType = asmType;
|
this.asmType = asmType;
|
||||||
this.member = member;
|
this.member = member;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModAnnotation(AnnotationType type, Type asmType, ModAnnotation parent)
|
public ModAnnotation(ElementType type, Type asmType, ModAnnotation parent)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.asmType = asmType;
|
this.asmType = asmType;
|
||||||
|
@ -81,7 +81,8 @@ public class ModAnnotation
|
||||||
.add("values", values)
|
.add("values", values)
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
public AnnotationType getType()
|
|
||||||
|
public ElementType getType()
|
||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -126,7 +127,7 @@ public class ModAnnotation
|
||||||
}
|
}
|
||||||
public ModAnnotation addChildAnnotation(String name, String desc)
|
public ModAnnotation addChildAnnotation(String name, String desc)
|
||||||
{
|
{
|
||||||
ModAnnotation child = new ModAnnotation(AnnotationType.SUBTYPE, Type.getType(desc), this);
|
ModAnnotation child = new ModAnnotation(ElementType.PARAMETER, Type.getType(desc), this);
|
||||||
addProperty(name, child.getValues());
|
addProperty(name, child.getValues());
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
|
@ -17,72 +17,79 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.minecraftforge.fml.common.discovery.asm;
|
package net.minecraftforge.fml.loading.moddiscovery;
|
||||||
|
|
||||||
import org.objectweb.asm.AnnotationVisitor;
|
import org.objectweb.asm.AnnotationVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
public class ModAnnotationVisitor extends AnnotationVisitor
|
public class ModAnnotationVisitor extends AnnotationVisitor
|
||||||
{
|
{
|
||||||
private ASMModParser discoverer;
|
private final ModAnnotation annotation;
|
||||||
|
private LinkedList<ModAnnotation> annotations;
|
||||||
private boolean array;
|
private boolean array;
|
||||||
private String name;
|
private String name;
|
||||||
private boolean isSubAnnotation;
|
private boolean isSubAnnotation;
|
||||||
|
|
||||||
public ModAnnotationVisitor(ASMModParser discoverer)
|
public ModAnnotationVisitor(LinkedList<ModAnnotation> annotations, ModAnnotation annotation)
|
||||||
{
|
{
|
||||||
super(Opcodes.ASM5);
|
super(Opcodes.ASM5);
|
||||||
this.discoverer = discoverer;
|
this.annotations = annotations;
|
||||||
|
this.annotation = annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModAnnotationVisitor(ASMModParser discoverer, String name)
|
public ModAnnotationVisitor(LinkedList<ModAnnotation> annotations, ModAnnotation annotation, String name)
|
||||||
{
|
{
|
||||||
this(discoverer);
|
this(annotations, annotation);
|
||||||
this.array = true;
|
this.array = true;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
discoverer.addAnnotationArray(name);
|
annotation.addArray(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModAnnotationVisitor(ASMModParser discoverer, boolean isSubAnnotation)
|
public ModAnnotationVisitor(LinkedList<ModAnnotation> annotations, ModAnnotation annotation, boolean isSubAnnotation)
|
||||||
{
|
{
|
||||||
this(discoverer);
|
this(annotations, annotation);
|
||||||
this.isSubAnnotation = true;
|
this.isSubAnnotation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(String key, Object value)
|
public void visit(String key, Object value)
|
||||||
{
|
{
|
||||||
discoverer.addAnnotationProperty(key, value);
|
annotation.addProperty(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitEnum(String name, String desc, String value)
|
public void visitEnum(String name, String desc, String value)
|
||||||
{
|
{
|
||||||
discoverer.addAnnotationEnumProperty(name, desc, value);
|
annotation.addEnumProperty(name, desc, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnnotationVisitor visitArray(String name)
|
public AnnotationVisitor visitArray(String name)
|
||||||
{
|
{
|
||||||
return new ModAnnotationVisitor(discoverer, name);
|
return new ModAnnotationVisitor(annotations, annotation, name);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public AnnotationVisitor visitAnnotation(String name, String desc)
|
public AnnotationVisitor visitAnnotation(String name, String desc)
|
||||||
{
|
{
|
||||||
discoverer.addSubAnnotation(name, desc);
|
ModAnnotation ma = annotations.getFirst();
|
||||||
return new ModAnnotationVisitor(discoverer, true);
|
final ModAnnotation childAnnotation = ma.addChildAnnotation(name, desc);
|
||||||
|
annotations.addFirst(childAnnotation);
|
||||||
|
return new ModAnnotationVisitor(annotations, childAnnotation,true);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void visitEnd()
|
public void visitEnd()
|
||||||
{
|
{
|
||||||
if (array)
|
if (array)
|
||||||
{
|
{
|
||||||
discoverer.endArray();
|
annotation.endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSubAnnotation)
|
if (isSubAnnotation)
|
||||||
{
|
{
|
||||||
discoverer.endSubAnnotation();
|
ModAnnotation child = annotations.removeFirst();
|
||||||
|
annotations.addLast(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
import org.objectweb.asm.AnnotationVisitor;
|
||||||
|
import org.objectweb.asm.ClassVisitor;
|
||||||
|
import org.objectweb.asm.FieldVisitor;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class ModClassVisitor extends ClassVisitor
|
||||||
|
{
|
||||||
|
private Type asmType;
|
||||||
|
private Type asmSuperType;
|
||||||
|
private Set<Type> interfaces;
|
||||||
|
private final LinkedList<ModAnnotation> annotations = new LinkedList<>();
|
||||||
|
public ModClassVisitor()
|
||||||
|
{
|
||||||
|
super(Opcodes.ASM5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||||
|
{
|
||||||
|
this.asmType = Type.getObjectType(name);
|
||||||
|
this.asmSuperType = superName != null && superName.length() > 0 ? Type.getObjectType(superName) : null;
|
||||||
|
this.interfaces = Stream.of(interfaces).map(Type::getObjectType).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnnotationVisitor visitAnnotation(final String annotationName, final boolean runtimeVisible)
|
||||||
|
{
|
||||||
|
ModAnnotation ann = new ModAnnotation(ElementType.TYPE, Type.getType(annotationName), this.asmType.getClassName());
|
||||||
|
annotations.addFirst(ann);
|
||||||
|
return new ModAnnotationVisitor(annotations, ann);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
|
||||||
|
{
|
||||||
|
return new ModFieldVisitor(name, annotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
|
||||||
|
{
|
||||||
|
return new ModMethodVisitor(name, desc, annotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void buildData(final List<ScanResult.ClassData> classes, final List<ScanResult.AnnotationData> annotations) {
|
||||||
|
classes.add(new ScanResult.ClassData(this.asmType, this.asmSuperType, this.interfaces));
|
||||||
|
final List<ScanResult.AnnotationData> collect = this.annotations.stream().filter(ScanResult::interestingAnnotations).
|
||||||
|
map(a -> ScanResult.AnnotationData.fromModAnnotation(this.asmType, a)).collect(Collectors.toList());
|
||||||
|
annotations.addAll(collect);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
import cpw.mods.modlauncher.ServiceLoaderStreamUtils;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class ModDiscoverer {
|
||||||
|
private final ServiceLoader<IModLocator> locators;
|
||||||
|
private final List<IModLocator> locatorList;
|
||||||
|
|
||||||
|
public ModDiscoverer() {
|
||||||
|
locators = ServiceLoader.load(IModLocator.class);
|
||||||
|
locatorList = ServiceLoaderStreamUtils.toList(this.locators);
|
||||||
|
fmlLog.debug("Found Mod Locators : {}", ()->locatorList.stream().map(IModLocator::name).collect(Collectors.joining(",")));
|
||||||
|
}
|
||||||
|
|
||||||
|
ModDiscoverer(List<IModLocator> locatorList) {
|
||||||
|
this.locatorList = locatorList;
|
||||||
|
this.locators = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BackgroundScanHandler discoverMods() {
|
||||||
|
fmlLog.debug("Scanning for mods and other resources to load. We know {} ways to find mods", locatorList.size());
|
||||||
|
final Map<ModFile.Type, List<ModFile>> modFiles = locatorList.stream()
|
||||||
|
.peek(loc -> fmlLog.debug("Trying locator {}", loc))
|
||||||
|
.map(IModLocator::scanMods)
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.peek(mf -> fmlLog.debug("Found mod file {} of type {} with locator {}", mf.getFileName(), mf.getType(), mf.getLocator()))
|
||||||
|
.collect(Collectors.groupingBy(ModFile::getType));
|
||||||
|
|
||||||
|
ModLanguageProvider.loadAdditionalLanguages(modFiles.get(ModFile.Type.LANGPROVIDER));
|
||||||
|
BackgroundScanHandler backgroundScanHandler = new BackgroundScanHandler();
|
||||||
|
final List<ModFile> mods = modFiles.get(ModFile.Type.MOD);
|
||||||
|
mods.forEach(ModFile::identifyMods);
|
||||||
|
fmlLog.debug("Found {} mod files with {} mods", mods::size, ()->mods.stream().mapToInt(mf -> mf.getModInfos().size()).sum());
|
||||||
|
mods.stream().map(ModFile::getCoreMods).flatMap(List::stream).forEach(ServiceProviders.getCoreModProvider()::addCoreMod);
|
||||||
|
mods.forEach(backgroundScanHandler::submitForScanning);
|
||||||
|
return backgroundScanHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,29 +17,33 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.minecraftforge.fml.common.discovery.asm;
|
package net.minecraftforge.fml.loading.moddiscovery;
|
||||||
|
|
||||||
import org.objectweb.asm.AnnotationVisitor;
|
import org.objectweb.asm.AnnotationVisitor;
|
||||||
import org.objectweb.asm.FieldVisitor;
|
import org.objectweb.asm.FieldVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
public class ModFieldVisitor extends FieldVisitor
|
public class ModFieldVisitor extends FieldVisitor
|
||||||
{
|
{
|
||||||
|
private final LinkedList<ModAnnotation> annotations;
|
||||||
|
private final String fieldName;
|
||||||
|
|
||||||
private String fieldName;
|
public ModFieldVisitor(String name, final LinkedList<ModAnnotation> annotations)
|
||||||
private ASMModParser discoverer;
|
|
||||||
|
|
||||||
public ModFieldVisitor(String name, ASMModParser discoverer)
|
|
||||||
{
|
{
|
||||||
super(Opcodes.ASM5);
|
super(Opcodes.ASM5);
|
||||||
this.fieldName = name;
|
this.fieldName = name;
|
||||||
this.discoverer = discoverer;
|
this.annotations = annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
|
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
|
||||||
{
|
{
|
||||||
discoverer.startFieldAnnotation(fieldName, annotationName);
|
ModAnnotation ann = new ModAnnotation(ElementType.FIELD, Type.getType(annotationName), fieldName);
|
||||||
return new ModAnnotationVisitor(discoverer);
|
annotations.addFirst(ann);
|
||||||
|
return new ModAnnotationVisitor(annotations, ann);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.jar.Attributes;
|
||||||
|
import java.util.jar.Manifest;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class ModFile
|
||||||
|
{
|
||||||
|
private static final Manifest DEFAULTMANIFEST;
|
||||||
|
static {
|
||||||
|
DEFAULTMANIFEST = new Manifest();
|
||||||
|
DEFAULTMANIFEST.getMainAttributes().putValue("FMLModType", "MOD");
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
MOD, LIBRARY, LANGPROVIDER
|
||||||
|
}
|
||||||
|
private final Path filePath;
|
||||||
|
private final Type modFileType;
|
||||||
|
private final Manifest manifest;
|
||||||
|
private List<ModInfo> modInfos;
|
||||||
|
private final IModLocator locator;
|
||||||
|
private ScanResult fileScanResult;
|
||||||
|
private CompletableFuture<ScanResult> futureScanResult;
|
||||||
|
private List<CoreModFile> coreMods;
|
||||||
|
|
||||||
|
private static final Attributes.Name TYPE = new Attributes.Name("FMLModType");
|
||||||
|
|
||||||
|
public ModFile(final Path file, final IModLocator locator) {
|
||||||
|
this.locator = locator;
|
||||||
|
this.filePath = file;
|
||||||
|
manifest = locator.findManifest(file).orElse(DEFAULTMANIFEST);
|
||||||
|
if (manifest != DEFAULTMANIFEST) fmlLog.debug("Mod file {} has a manifest", file);
|
||||||
|
else fmlLog.debug("Mod file {} is missing a manifest", file);
|
||||||
|
modFileType = Type.valueOf(manifest.getMainAttributes().getValue(TYPE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return modFileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Path getFilePath() {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ModInfo> getModInfos() {
|
||||||
|
return modInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void identifyMods() {
|
||||||
|
this.modInfos = ModFileParser.readModList(this);
|
||||||
|
this.modInfos.forEach(mi-> fmlLog.debug("Found mod {} for language {}", mi.getModId(), mi.getModLoader()));
|
||||||
|
this.coreMods = ModFileParser.getCoreMods(this);
|
||||||
|
this.coreMods.forEach(mi-> fmlLog.debug("Found coremod {}", mi.getPath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<CoreModFile> getCoreMods() {
|
||||||
|
return coreMods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run in an executor thread to harvest the class and annotation list
|
||||||
|
*/
|
||||||
|
public ScanResult compileContent() {
|
||||||
|
return new Scanner(this).scan();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scanFile(Consumer<Path> pathConsumer) {
|
||||||
|
locator.scanFile(this, pathConsumer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFutureScanResult(CompletableFuture<ScanResult> future)
|
||||||
|
{
|
||||||
|
this.futureScanResult = future;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanResult getScanResult() {
|
||||||
|
if (this.futureScanResult != null) {
|
||||||
|
try {
|
||||||
|
this.futureScanResult.get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.fileScanResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScanResult(final ScanResult scanResult, final Throwable throwable) {
|
||||||
|
this.futureScanResult = null;
|
||||||
|
this.fileScanResult = scanResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Mod File: " + Objects.toString(this.filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return getFilePath().getFileName().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IModLocator getLocator() {
|
||||||
|
return locator;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.InstanceCreator;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import net.minecraftforge.fml.common.versioning.ArtifactVersion;
|
||||||
|
import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class ModFileParser {
|
||||||
|
protected static java.util.List<net.minecraftforge.fml.loading.moddiscovery.ModInfo> readModList(final ModFile modFile) {
|
||||||
|
fmlLog.debug("Parsing mod file candidate {}", modFile.getFilePath());
|
||||||
|
try {
|
||||||
|
final java.nio.file.Path modsjson = modFile.getLocator().findPath(modFile, "META-INF", "mods.json");
|
||||||
|
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||||
|
gsonBuilder.registerTypeAdapter(ModInfo.class, (InstanceCreator<ModInfo>)ic -> new ModInfo(modFile, null, null, null, null, null, null, null));
|
||||||
|
gsonBuilder.registerTypeAdapter(ArtifactVersion.class, (JsonDeserializer<ArtifactVersion>) (element, type, context) -> new DefaultArtifactVersion(element.getAsString()));
|
||||||
|
Gson gson = gsonBuilder.create();
|
||||||
|
final ModInfo[] modInfos = gson.fromJson(java.nio.file.Files.newBufferedReader(modsjson), ModInfo[].class);
|
||||||
|
return java.util.stream.Stream.of(modInfos).collect(java.util.stream.Collectors.toList());
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
fmlLog.debug("Ignoring invalid JAR file {}", modFile.getFilePath());
|
||||||
|
return java.util.Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static java.util.List<CoreModFile> getCoreMods(final ModFile modFile) {
|
||||||
|
java.util.Map<String,String> coreModPaths;
|
||||||
|
try {
|
||||||
|
final java.nio.file.Path coremodsjson = modFile.getLocator().findPath(modFile, "META-INF", "coremods.json");
|
||||||
|
if (!java.nio.file.Files.exists(coremodsjson)) {
|
||||||
|
return java.util.Collections.emptyList();
|
||||||
|
}
|
||||||
|
final java.lang.reflect.Type type = new TypeToken<Map<String, String>>() {}.getType();
|
||||||
|
final Gson gson = new Gson();
|
||||||
|
coreModPaths = gson.fromJson(java.nio.file.Files.newBufferedReader(coremodsjson), type);
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
fmlLog.debug("Failed to read coremod list coremods.json", e);
|
||||||
|
return java.util.Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return coreModPaths.entrySet().stream().
|
||||||
|
peek(e-> fmlLog.debug("Found coremod {} with Javascript path {}", e.getKey(), e.getValue())).
|
||||||
|
map(e -> new CoreModFile(e.getKey(), modFile.getLocator().findPath(modFile, e.getValue()),modFile)).
|
||||||
|
collect(java.util.stream.Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.common.versioning.ArtifactVersion;
|
||||||
|
|
||||||
|
public class ModInfo {
|
||||||
|
private final ModFile owningFile;
|
||||||
|
private final String modId;
|
||||||
|
private final ArtifactVersion version;
|
||||||
|
private final String displayName;
|
||||||
|
private final String description;
|
||||||
|
private final java.net.URL updateJSONURL;
|
||||||
|
private final String modLoader;
|
||||||
|
private final java.util.List<net.minecraftforge.fml.loading.moddiscovery.ModInfo.ModVersion> dependencies;
|
||||||
|
|
||||||
|
public ModInfo(final ModFile owningFile, final String modLoader, final String modId, final String displayName, final ArtifactVersion version, final String description, final java.net.URL updateJSONURL, final java.util.List<net.minecraftforge.fml.loading.moddiscovery.ModInfo.ModVersion> dependencies) {
|
||||||
|
this.owningFile = owningFile;
|
||||||
|
this.modLoader = modLoader;
|
||||||
|
this.modId = modId;
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.version = version;
|
||||||
|
this.description = description;
|
||||||
|
this.updateJSONURL = updateJSONURL;
|
||||||
|
this.dependencies = dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModFile getOwningFile() {
|
||||||
|
return owningFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModLoader() {
|
||||||
|
return modLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModId() {
|
||||||
|
return modId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArtifactVersion getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Ordering {
|
||||||
|
BEFORE, AFTER, NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DependencySide {
|
||||||
|
CLIENT, SERVER, BOTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ModVersion {
|
||||||
|
private final String modId;
|
||||||
|
private final ArtifactVersion version;
|
||||||
|
private final boolean mandatory;
|
||||||
|
private final Ordering ordering;
|
||||||
|
private final DependencySide side;
|
||||||
|
|
||||||
|
public ModVersion(final String modId, final ArtifactVersion version, final boolean mandatory, final Ordering ordering, final DependencySide side) {
|
||||||
|
this.modId = modId;
|
||||||
|
this.version = version;
|
||||||
|
this.mandatory = mandatory;
|
||||||
|
this.ordering = ordering;
|
||||||
|
this.side = side;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,31 +17,36 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.minecraftforge.fml.common.discovery.asm;
|
package net.minecraftforge.fml.loading.moddiscovery;
|
||||||
|
|
||||||
import org.objectweb.asm.AnnotationVisitor;
|
import org.objectweb.asm.AnnotationVisitor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
public class ModMethodVisitor extends MethodVisitor {
|
public class ModMethodVisitor extends MethodVisitor {
|
||||||
|
|
||||||
|
private final LinkedList<ModAnnotation> annotations;
|
||||||
private String methodName;
|
private String methodName;
|
||||||
private String methodDescriptor;
|
private String methodDescriptor;
|
||||||
private ASMModParser discoverer;
|
|
||||||
|
|
||||||
public ModMethodVisitor(String name, String desc, ASMModParser discoverer)
|
public ModMethodVisitor(String name, String desc, final LinkedList<ModAnnotation> annotations)
|
||||||
{
|
{
|
||||||
super(Opcodes.ASM5);
|
super(Opcodes.ASM5);
|
||||||
this.methodName = name;
|
this.methodName = name;
|
||||||
this.methodDescriptor = desc;
|
this.methodDescriptor = desc;
|
||||||
this.discoverer = discoverer;
|
this.annotations = annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
|
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
|
||||||
{
|
{
|
||||||
discoverer.startMethodAnnotation(methodName, methodDescriptor, annotationName);
|
ModAnnotation ann = new ModAnnotation(ElementType.METHOD, Type.getType(annotationName), methodName+methodDescriptor);
|
||||||
return new ModAnnotationVisitor(discoverer);
|
annotations.addFirst(ann);
|
||||||
|
return new ModAnnotationVisitor(annotations, ann);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.common.FMLPaths;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import java.util.zip.ZipError;
|
||||||
|
|
||||||
|
import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.uncheck;
|
||||||
|
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 final Path modFolder;
|
||||||
|
private final Map<ModFile, FileSystem> modJars;
|
||||||
|
public ModsFolderLocator() {
|
||||||
|
this(FMLPaths.MODSDIR.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
ModsFolderLocator(Path modFolder) {
|
||||||
|
this.modFolder = modFolder;
|
||||||
|
this.modJars = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ModFile> scanMods() {
|
||||||
|
return uncheck(()-> Files.list(this.modFolder)).
|
||||||
|
sorted(Comparator.comparing(path-> StringUtils.toLowerCase(path.getFileName().toString()))).
|
||||||
|
filter(p->StringUtils.toLowerCase(p.getFileName().toString()).endsWith(SUFFIX)).
|
||||||
|
map(p->new ModFile(p, this)).
|
||||||
|
peek(f->modJars.compute(f, (mf, fs)->createFileSystem(mf))).
|
||||||
|
collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "mods folder";
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileSystem createFileSystem(ModFile modFile) {
|
||||||
|
try {
|
||||||
|
return FileSystems.newFileSystem(modFile.getFilePath(), modFile.getClass().getClassLoader());
|
||||||
|
} catch (ZipError | IOException e) {
|
||||||
|
fmlLog.debug("Ignoring invalid JAR file {}", modFile.getFilePath());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path findPath(final ModFile modFile, final String... path) {
|
||||||
|
if (path.length < 1) {
|
||||||
|
throw new IllegalArgumentException("Missing path");
|
||||||
|
}
|
||||||
|
return modJars.get(modFile).getPath(path[0], Arrays.copyOfRange(path, 1, path.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scanFile(final ModFile file, final Consumer<Path> pathConsumer) {
|
||||||
|
fmlLog.debug("Scan started: {}", file);
|
||||||
|
FileSystem fs = modJars.get(file);
|
||||||
|
fs.getRootDirectories().forEach(path -> {
|
||||||
|
try (Stream<Path> files = Files.find(path, Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) {
|
||||||
|
files.forEach(pathConsumer);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fmlLog.debug("Scan finished: {}", file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{FolderJar locator at "+this.modFolder+"}";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ScanResult {
|
||||||
|
private final ModFile file;
|
||||||
|
private final java.util.List<net.minecraftforge.fml.loading.moddiscovery.ScanResult.AnnotationData> annotations = new java.util.ArrayList<>();
|
||||||
|
private final java.util.List<net.minecraftforge.fml.loading.moddiscovery.ScanResult.ClassData> classes = new java.util.ArrayList<>();
|
||||||
|
|
||||||
|
public ScanResult(final ModFile file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean interestingAnnotations(final ModAnnotation annotation) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.util.List<net.minecraftforge.fml.loading.moddiscovery.ScanResult.ClassData> getClasses() {
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.util.List<net.minecraftforge.fml.loading.moddiscovery.ScanResult.AnnotationData> getAnnotations() {
|
||||||
|
return annotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ClassData {
|
||||||
|
private final Type clazz;
|
||||||
|
private final Type parent;
|
||||||
|
private final Set<Type> interfaces;
|
||||||
|
|
||||||
|
public ClassData(final Type clazz, final Type parent, final Set<Type> interfaces) {
|
||||||
|
this.clazz = clazz;
|
||||||
|
this.parent = parent;
|
||||||
|
this.interfaces = interfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public static class AnnotationData {
|
||||||
|
private final Type annotationType;
|
||||||
|
private final Type clazz;
|
||||||
|
private final String memberName;
|
||||||
|
private final Map<String,Object> annotationData;
|
||||||
|
|
||||||
|
|
||||||
|
public AnnotationData(final Type annotationType, final Type clazz, final String memberName, final Map<String, Object> annotationData) {
|
||||||
|
this.annotationType = annotationType;
|
||||||
|
this.clazz = clazz;
|
||||||
|
this.memberName = memberName;
|
||||||
|
this.annotationData = annotationData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getAnnotationType() {
|
||||||
|
return annotationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getClassType() {
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMemberName() {
|
||||||
|
return memberName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getAnnotationData() {
|
||||||
|
return annotationData;
|
||||||
|
}
|
||||||
|
public static ScanResult.AnnotationData fromModAnnotation(final Type clazz, final ModAnnotation annotation) {
|
||||||
|
return new AnnotationData(annotation.asmType, clazz, annotation.member, annotation.values);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 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.loading.moddiscovery;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||||
|
|
||||||
|
public class Scanner {
|
||||||
|
private final ModFile fileToScan;
|
||||||
|
|
||||||
|
public Scanner(final ModFile fileToScan) {
|
||||||
|
this.fileToScan = fileToScan;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanResult scan() {
|
||||||
|
ScanResult result = new ScanResult(fileToScan);
|
||||||
|
fileToScan.scanFile(p -> fileVisitor(p, result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fileVisitor(final java.nio.file.Path path, final ScanResult result) {
|
||||||
|
try {
|
||||||
|
fmlLog.debug("Scanning {} path {}", fileToScan, path);
|
||||||
|
ModClassVisitor mcv = new ModClassVisitor();
|
||||||
|
org.objectweb.asm.ClassReader cr = new ClassReader(java.nio.file.Files.newInputStream(path));
|
||||||
|
cr.accept(mcv, 0);
|
||||||
|
mcv.buildData(result.getClasses(), result.getAnnotations());
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
// mark path bad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
net.minecraftforge.fml.loading.FMLLaunchProvider
|
|
@ -0,0 +1 @@
|
||||||
|
net.minecraftforge.fml.loading.FMLServiceProvider
|
|
@ -1,52 +1,59 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Configuration status="warn" packages="net.minecraftforge.server.terminalconsole.util">
|
<Configuration status="WARN" packages="com.mojang.util">
|
||||||
<Appenders>
|
<Appenders>
|
||||||
|
<Console name="FmlSysOut" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n" />
|
||||||
|
</Console>
|
||||||
<Console name="SysOut" target="SYSTEM_OUT">
|
<Console name="SysOut" target="SYSTEM_OUT">
|
||||||
<PatternLayout>
|
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||||
<LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n">
|
|
||||||
<!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
|
|
||||||
<PatternMatch key="net.minecraft." pattern="[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %msg%n"/>
|
|
||||||
<PatternMatch key="com.mojang." pattern="[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %msg%n"/>
|
|
||||||
</LoggerNamePatternSelector>
|
|
||||||
</PatternLayout>
|
|
||||||
</Console>
|
</Console>
|
||||||
<Queue name="ServerGuiConsole" ignoreExceptions="true">
|
<Queue name="ServerGuiConsole" ignoreExceptions="true">
|
||||||
<PatternLayout>
|
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n" />
|
||||||
<LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n">
|
|
||||||
<!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
|
|
||||||
<PatternMatch key="net.minecraft." pattern="[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %msg%n"/>
|
|
||||||
<PatternMatch key="com.mojang." pattern="[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %msg%n"/>
|
|
||||||
</LoggerNamePatternSelector>
|
|
||||||
</PatternLayout>
|
|
||||||
</Queue>
|
</Queue>
|
||||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||||
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n"/>
|
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||||
<Policies>
|
<Policies>
|
||||||
<TimeBasedTriggeringPolicy />
|
<TimeBasedTriggeringPolicy />
|
||||||
<OnStartupTriggeringPolicy />
|
<OnStartupTriggeringPolicy />
|
||||||
</Policies>
|
</Policies>
|
||||||
</RollingRandomAccessFile>
|
</RollingRandomAccessFile>
|
||||||
<RollingRandomAccessFile name="DebugFile" fileName="logs/debug.log" filePattern="logs/debug-%i.log.gz">
|
<Routing name="FmlFile">
|
||||||
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n"/>
|
<Routes pattern="$${ctx:side}">
|
||||||
|
<Route>
|
||||||
|
<RollingRandomAccessFile name="FmlFile" fileName="logs/fml-${ctx:side}-latest.log" filePattern="logs/fml-${ctx:side}-%i.log">
|
||||||
|
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger/%X{mod}]: %msg%n" />
|
||||||
|
<DefaultRolloverStrategy max="3" fileIndex="max" />
|
||||||
<Policies>
|
<Policies>
|
||||||
<OnStartupTriggeringPolicy />
|
<OnStartupTriggeringPolicy />
|
||||||
<SizeBasedTriggeringPolicy size="200MB"/>
|
|
||||||
</Policies>
|
</Policies>
|
||||||
<DefaultRolloverStrategy max="5" fileIndex="min"/>
|
|
||||||
</RollingRandomAccessFile>
|
</RollingRandomAccessFile>
|
||||||
|
</Route>
|
||||||
|
<Route key="$${ctx:side}">
|
||||||
|
<RandomAccessFile name="FmlFile" fileName="logs/fml-junk-earlystartup.log" >
|
||||||
|
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n" />
|
||||||
|
</RandomAccessFile>
|
||||||
|
</Route>
|
||||||
|
</Routes>
|
||||||
|
</Routing>
|
||||||
</Appenders>
|
</Appenders>
|
||||||
<Loggers>
|
<Loggers>
|
||||||
<!-- make sure mojang's logging is set to 'info' so that their LOGGER.isDebugEnabled() behavior isn't active -->
|
<Logger level="info" name="com.mojang" additivity="false">
|
||||||
<Logger level="${sys:forge.logging.mojang.level:-info}" name="com.mojang"/>
|
<AppenderRef ref="SysOut" level="INFO" />
|
||||||
<Logger level="${sys:forge.logging.mojang.level:-info}" name="net.minecraft"/>
|
<AppenderRef ref="File" />
|
||||||
<Root level="all">
|
<AppenderRef ref="ServerGuiConsole" level="INFO" />
|
||||||
|
</Logger>
|
||||||
|
<Logger level="info" name="net.minecraft" additivity="false">
|
||||||
<filters>
|
<filters>
|
||||||
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
|
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
|
||||||
</filters>
|
</filters>
|
||||||
<AppenderRef ref="SysOut" level="${sys:forge.logging.console.level:-info}"/>
|
<AppenderRef ref="SysOut" level="INFO" />
|
||||||
<AppenderRef ref="ServerGuiConsole" level="${sys:forge.logging.console.level:-info}"/>
|
<AppenderRef ref="File" />
|
||||||
<AppenderRef ref="File" level="${sys:forge.logging.file.level:-info}"/>
|
<AppenderRef ref="ServerGuiConsole" level="INFO" />
|
||||||
<AppenderRef ref="DebugFile" level="${sys:forge.logging.debugFile.level:-trace}"/>
|
</Logger>
|
||||||
|
<Root level="INFO">
|
||||||
|
<AppenderRef ref="FmlSysOut"/>
|
||||||
|
<AppenderRef ref="ServerGuiConsole" level="INFO" />
|
||||||
|
<AppenderRef ref="FmlFile"/>
|
||||||
</Root>
|
</Root>
|
||||||
</Loggers>
|
</Loggers>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
|
|
Loading…
Reference in a new issue