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
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
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.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
# 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\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
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.
|
||||
MAX_FD="maximum"
|
||||
|
||||
|
@ -30,6 +48,7 @@ die ( ) {
|
|||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
|
@ -40,31 +59,11 @@ case "`uname`" in
|
|||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
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
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
|
@ -90,7 +89,7 @@ location of your Java installation."
|
|||
fi
|
||||
|
||||
# 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`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
|
@ -114,6 +113,7 @@ fi
|
|||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
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
|
||||
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
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
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
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
|
@ -46,7 +46,7 @@ echo location of your Java installation.
|
|||
goto fail
|
||||
|
||||
: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 "%@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.discovery.ASMDataTable;
|
||||
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;
|
||||
|
||||
|
|
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.fml.common.discovery.ASMDataTable;
|
||||
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 org.apache.logging.log4j.Level;
|
||||
|
||||
import java.util.EnumSet;
|
||||
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.lang.reflect.Constructor;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraftforge.fml.common.discovery.ModCandidate;
|
||||
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;
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@ import net.minecraftforge.fml.common.LoaderException;
|
|||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||
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.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.function.Function;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
|
@ -31,7 +30,7 @@ import com.google.common.collect.Lists;
|
|||
import com.google.common.collect.Maps;
|
||||
|
||||
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.
|
||||
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
|
||||
*/
|
||||
|
||||
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.Map;
|
||||
|
||||
import net.minecraftforge.fml.common.discovery.asm.ASMModParser.AnnotationType;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
|
@ -53,20 +52,21 @@ public class ModAnnotation
|
|||
return value;
|
||||
}
|
||||
}
|
||||
AnnotationType type;
|
||||
ElementType type;
|
||||
Type asmType;
|
||||
String member;
|
||||
Map<String,Object> values = Maps.newHashMap();
|
||||
|
||||
private ArrayList<Object> arrayList;
|
||||
private String arrayName;
|
||||
public ModAnnotation(AnnotationType type, Type asmType, String member)
|
||||
public ModAnnotation(ElementType type, Type asmType, String member)
|
||||
{
|
||||
this.type = type;
|
||||
this.asmType = asmType;
|
||||
this.member = member;
|
||||
}
|
||||
|
||||
public ModAnnotation(AnnotationType type, Type asmType, ModAnnotation parent)
|
||||
public ModAnnotation(ElementType type, Type asmType, ModAnnotation parent)
|
||||
{
|
||||
this.type = type;
|
||||
this.asmType = asmType;
|
||||
|
@ -81,7 +81,8 @@ public class ModAnnotation
|
|||
.add("values", values)
|
||||
.toString();
|
||||
}
|
||||
public AnnotationType getType()
|
||||
|
||||
public ElementType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
@ -126,7 +127,7 @@ public class ModAnnotation
|
|||
}
|
||||
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());
|
||||
return child;
|
||||
}
|
|
@ -17,72 +17,79 @@
|
|||
* 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.Opcodes;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class ModAnnotationVisitor extends AnnotationVisitor
|
||||
{
|
||||
private ASMModParser discoverer;
|
||||
private final ModAnnotation annotation;
|
||||
private LinkedList<ModAnnotation> annotations;
|
||||
private boolean array;
|
||||
private String name;
|
||||
private boolean isSubAnnotation;
|
||||
|
||||
public ModAnnotationVisitor(ASMModParser discoverer)
|
||||
public ModAnnotationVisitor(LinkedList<ModAnnotation> annotations, ModAnnotation annotation)
|
||||
{
|
||||
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.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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(String key, Object value)
|
||||
{
|
||||
discoverer.addAnnotationProperty(key, value);
|
||||
annotation.addProperty(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnum(String name, String desc, String value)
|
||||
{
|
||||
discoverer.addAnnotationEnumProperty(name, desc, value);
|
||||
annotation.addEnumProperty(name, desc, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitArray(String name)
|
||||
{
|
||||
return new ModAnnotationVisitor(discoverer, name);
|
||||
return new ModAnnotationVisitor(annotations, annotation, name);
|
||||
}
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String name, String desc)
|
||||
{
|
||||
discoverer.addSubAnnotation(name, desc);
|
||||
return new ModAnnotationVisitor(discoverer, true);
|
||||
ModAnnotation ma = annotations.getFirst();
|
||||
final ModAnnotation childAnnotation = ma.addChildAnnotation(name, desc);
|
||||
annotations.addFirst(childAnnotation);
|
||||
return new ModAnnotationVisitor(annotations, childAnnotation,true);
|
||||
}
|
||||
@Override
|
||||
public void visitEnd()
|
||||
{
|
||||
if (array)
|
||||
{
|
||||
discoverer.endArray();
|
||||
annotation.endArray();
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.common.discovery.asm;
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class ModFieldVisitor extends FieldVisitor
|
||||
{
|
||||
private final LinkedList<ModAnnotation> annotations;
|
||||
private final String fieldName;
|
||||
|
||||
private String fieldName;
|
||||
private ASMModParser discoverer;
|
||||
|
||||
public ModFieldVisitor(String name, ASMModParser discoverer)
|
||||
public ModFieldVisitor(String name, final LinkedList<ModAnnotation> annotations)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
this.fieldName = name;
|
||||
this.discoverer = discoverer;
|
||||
this.annotations = annotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
|
||||
{
|
||||
discoverer.startFieldAnnotation(fieldName, annotationName);
|
||||
return new ModAnnotationVisitor(discoverer);
|
||||
ModAnnotation ann = new ModAnnotation(ElementType.FIELD, Type.getType(annotationName), fieldName);
|
||||
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
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.common.discovery.asm;
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class ModMethodVisitor extends MethodVisitor {
|
||||
|
||||
private final LinkedList<ModAnnotation> annotations;
|
||||
private String methodName;
|
||||
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);
|
||||
this.methodName = name;
|
||||
this.methodDescriptor = desc;
|
||||
this.discoverer = discoverer;
|
||||
this.annotations = annotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
|
||||
{
|
||||
discoverer.startMethodAnnotation(methodName, methodDescriptor, annotationName);
|
||||
return new ModAnnotationVisitor(discoverer);
|
||||
ModAnnotation ann = new ModAnnotation(ElementType.METHOD, Type.getType(annotationName), methodName+methodDescriptor);
|
||||
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"?>
|
||||
<Configuration status="warn" packages="net.minecraftforge.server.terminalconsole.util">
|
||||
<Configuration status="WARN" packages="com.mojang.util">
|
||||
<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">
|
||||
<PatternLayout>
|
||||
<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>
|
||||
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||
</Console>
|
||||
<Queue name="ServerGuiConsole" ignoreExceptions="true">
|
||||
<PatternLayout>
|
||||
<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>
|
||||
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n" />
|
||||
</Queue>
|
||||
<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>
|
||||
<TimeBasedTriggeringPolicy/>
|
||||
<OnStartupTriggeringPolicy/>
|
||||
<TimeBasedTriggeringPolicy />
|
||||
<OnStartupTriggeringPolicy />
|
||||
</Policies>
|
||||
</RollingRandomAccessFile>
|
||||
<RollingRandomAccessFile name="DebugFile" fileName="logs/debug.log" filePattern="logs/debug-%i.log.gz">
|
||||
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n"/>
|
||||
<Policies>
|
||||
<OnStartupTriggeringPolicy/>
|
||||
<SizeBasedTriggeringPolicy size="200MB"/>
|
||||
</Policies>
|
||||
<DefaultRolloverStrategy max="5" fileIndex="min"/>
|
||||
</RollingRandomAccessFile>
|
||||
<Routing name="FmlFile">
|
||||
<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>
|
||||
<OnStartupTriggeringPolicy />
|
||||
</Policies>
|
||||
</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>
|
||||
<Loggers>
|
||||
<!-- make sure mojang's logging is set to 'info' so that their LOGGER.isDebugEnabled() behavior isn't active -->
|
||||
<Logger level="${sys:forge.logging.mojang.level:-info}" name="com.mojang"/>
|
||||
<Logger level="${sys:forge.logging.mojang.level:-info}" name="net.minecraft"/>
|
||||
<Root level="all">
|
||||
<Logger level="info" name="com.mojang" additivity="false">
|
||||
<AppenderRef ref="SysOut" level="INFO" />
|
||||
<AppenderRef ref="File" />
|
||||
<AppenderRef ref="ServerGuiConsole" level="INFO" />
|
||||
</Logger>
|
||||
<Logger level="info" name="net.minecraft" additivity="false">
|
||||
<filters>
|
||||
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL"/>
|
||||
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
|
||||
</filters>
|
||||
<AppenderRef ref="SysOut" level="${sys:forge.logging.console.level:-info}"/>
|
||||
<AppenderRef ref="ServerGuiConsole" level="${sys:forge.logging.console.level:-info}"/>
|
||||
<AppenderRef ref="File" level="${sys:forge.logging.file.level:-info}"/>
|
||||
<AppenderRef ref="DebugFile" level="${sys:forge.logging.debugFile.level:-trace}"/>
|
||||
<AppenderRef ref="SysOut" level="INFO" />
|
||||
<AppenderRef ref="File" />
|
||||
<AppenderRef ref="ServerGuiConsole" level="INFO" />
|
||||
</Logger>
|
||||
<Root level="INFO">
|
||||
<AppenderRef ref="FmlSysOut"/>
|
||||
<AppenderRef ref="ServerGuiConsole" level="INFO" />
|
||||
<AppenderRef ref="FmlFile"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
|
Loading…
Reference in a new issue