-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
293 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.gradle/ | ||
build/ | ||
|
||
bin/ | ||
.settings/ | ||
.project | ||
.classpath | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
apply plugin: 'java' | ||
apply plugin: 'eclipse' | ||
|
||
sourceCompatibility = '1.6' | ||
targetCompatibility = '1.6' | ||
|
||
version = '0.0.1' | ||
|
||
repositories { | ||
mavenCentral() | ||
maven { | ||
name = 'minecraft' | ||
url = 'https://libraries.minecraft.net/' | ||
} | ||
} | ||
|
||
configurations { | ||
buildOnly | ||
} | ||
|
||
dependencies { | ||
compile 'net.minecraft:launchwrapper:1.12' | ||
compile 'org.apache.logging.log4j:log4j-core:2.0-beta9' | ||
// TODO Fix this | ||
buildOnly files('C:/Users/Simon/.gradle/caches/minecraft/net/minecraftforge/forge/1.8.9-11.15.1.1808/stable/22/forgeBin-1.8.9-11.15.1.1808.jar') | ||
compile files('C:/Users/Simon/.gradle/caches/minecraft/net/minecraftforge/forge/1.8.9-11.15.1.1808/start') | ||
} | ||
|
||
sourceSets.main.compileClasspath += [ configurations.buildOnly ] | ||
|
||
jar { | ||
manifest { | ||
attributes( | ||
"Main-Class": "com.simon816.sponge.bootstrap.Bootstrap", | ||
"Class-Path": "libraries/net/minecraft/launchwrapper/1.12/launchwrapper-1.12.jar" | ||
+ " libraries/net/sf/jopt-simple/jopt-simple/4.6/jopt-simple-4.6.jar" | ||
+ " minecraft_server.1.8.9.jar" | ||
) | ||
} | ||
} |
243 changes: 243 additions & 0 deletions
243
src/main/java/com/simon816/sponge/bootstrap/Bootstrap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,243 @@ | ||
package com.simon816.sponge.bootstrap; | ||
|
||
import net.minecraft.launchwrapper.ITweaker; | ||
import net.minecraft.launchwrapper.Launch; | ||
import net.minecraft.launchwrapper.LaunchClassLoader; | ||
import net.minecraftforge.fml.relauncher.CoreModManager; | ||
import net.minecraftforge.gradle.GradleStartCommon; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
||
import java.io.File; | ||
import java.io.FileFilter; | ||
import java.lang.reflect.Field; | ||
import java.lang.reflect.Method; | ||
import java.net.URISyntaxException; | ||
import java.net.URL; | ||
import java.net.URLClassLoader; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Scanner; | ||
|
||
public class Bootstrap { | ||
|
||
private static final String COREMOD = "org.spongepowered.mod.SpongeCoremod"; | ||
private static final String PRE_TWEAKER = "com.simon816.sponge.bootstrap.Bootstrap$PreFMLTweaker"; | ||
private static final String POST_TWEAKER = "com.simon816.sponge.bootstrap.Bootstrap$PostFMLTweaker"; | ||
public static final String FML_TWEAKER = "net.minecraftforge.fml.common.launcher.FMLServerTweaker"; | ||
|
||
private static final Logger logger = LogManager.getLogger("SpongeBootstrap"); | ||
|
||
public static void main(String[] args) { | ||
logger.info("Detecting environment..."); | ||
try { | ||
Class.forName("GradleStartServer"); | ||
logger.info("Detected gradle development environment, continuing"); | ||
loadGradle(args); | ||
} catch (ClassNotFoundException e) { | ||
try { | ||
Class.forName("net.minecraft.launchwrapper.Launch"); | ||
logger.info("Found launch wrapper, continuing"); | ||
findAndLoadJars(); | ||
load(args); | ||
} catch (ClassNotFoundException e1) { | ||
System.err.println("Failed to load Launch class"); | ||
System.exit(1); | ||
} catch (NoClassDefFoundError e2) { | ||
System.err.println("Failed to load Launch class"); | ||
System.exit(1); | ||
} | ||
} | ||
} | ||
|
||
private static void removeFromSysArgs() { | ||
// Remove SpongeCoremod from args as we load it ourselves | ||
List<String> coreModsArgs = new ArrayList<String>(Arrays.asList(System.getProperty("fml.coreMods.load", "").split(","))); | ||
while (coreModsArgs.contains(COREMOD)) { | ||
coreModsArgs.remove(COREMOD); | ||
} | ||
StringBuilder coreMods = new StringBuilder(); | ||
for (String cm : coreModsArgs) { | ||
coreMods.append(cm).append(','); | ||
} | ||
System.setProperty("fml.coreMods.load", coreMods.toString()); | ||
} | ||
|
||
private static void findAndLoadJars() { | ||
File rootDir; | ||
try { | ||
rootDir = new File(Bootstrap.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile(); | ||
} catch (URISyntaxException e) { | ||
System.err.println("Could not get jar directory"); | ||
e.printStackTrace(); | ||
System.exit(1); | ||
return; | ||
} | ||
findJar(rootDir, "forge", new FileFilter() { | ||
|
||
@Override | ||
public boolean accept(File pathname) { | ||
String fn = pathname.getName().toLowerCase(); | ||
return fn.endsWith(".jar") && fn.contains("forge") && fn.contains("-universal") && fn.contains("1.8.9"); | ||
} | ||
}); | ||
findJar(new File(rootDir, "mods"), "sponge", new FileFilter() { | ||
|
||
@Override | ||
public boolean accept(File pathname) { | ||
String fn = pathname.getName().toLowerCase(); | ||
return fn.endsWith(".jar") && fn.contains("sponge") && fn.contains("1.8.9"); | ||
} | ||
}); | ||
} | ||
|
||
private static void findJar(File directory, String jarName, FileFilter filter) { | ||
File[] files = directory.listFiles(filter); | ||
if (files == null) { | ||
System.err.println("An error occured when listing directory contents"); | ||
System.exit(1); | ||
return; | ||
} | ||
if (files.length == 0) { | ||
System.err.println("Could not find " + jarName + " jar. Please make sure a" + jarName + " jar exists."); | ||
System.exit(1); | ||
} | ||
int idx = 0; | ||
if (files.length > 1) { | ||
System.out.println("Multiple " + jarName + " jars have been detected, please choose"); | ||
for (int i = 0; i < files.length; i++) { | ||
System.out.println(String.format("%d: %s", i, files[i])); | ||
} | ||
@SuppressWarnings("resource") | ||
Scanner scanner = new Scanner(System.in); | ||
do { | ||
idx = scanner.nextInt(); | ||
} while (idx < 0 || idx > files.length - 1); | ||
// scanner.close(); Don't close - this kills command handling | ||
} | ||
File jarFile = files[idx]; | ||
URLClassLoader classLoader = (URLClassLoader) Bootstrap.class.getClassLoader(); | ||
try { | ||
Method addUrl = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); | ||
addUrl.setAccessible(true); | ||
addUrl.invoke(classLoader, jarFile.toURI().toURL()); | ||
} catch (Exception e) { | ||
System.err.println("Failed to add " + jarName + " jar to classpath"); | ||
e.printStackTrace(); | ||
System.exit(1); | ||
} | ||
} | ||
|
||
private static void load(String[] args) { | ||
removeFromSysArgs(); | ||
String[] newArgs = new String[args.length + 6]; | ||
System.arraycopy(args, 0, newArgs, 6, args.length); | ||
newArgs[0] = "--tweakClass"; | ||
newArgs[1] = PRE_TWEAKER; | ||
newArgs[2] = "--tweakClass"; | ||
newArgs[3] = FML_TWEAKER; | ||
newArgs[4] = "--tweakClass"; | ||
newArgs[5] = POST_TWEAKER; | ||
Launch.main(newArgs); | ||
} | ||
|
||
private static void loadGradle(String[] args) { | ||
removeFromSysArgs(); | ||
try { | ||
GradleHackServer.main(args); | ||
} catch (Throwable e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
} | ||
|
||
public static class PreFMLTweaker extends SimpleTweaker { | ||
|
||
@Override | ||
public void injectIntoClassLoader(LaunchClassLoader classLoader) { | ||
// Adds SpongeCoremod to FML's 'root plugins' so it always loads | ||
// before other coremods | ||
// Add to end of array so FML plugins are first | ||
try { | ||
logger.info("Performing SpongeCoremod injection"); | ||
Field rootPluginsField = CoreModManager.class.getDeclaredField("rootPlugins"); | ||
rootPluginsField.setAccessible(true); | ||
String[] rootPlugins = (String[]) rootPluginsField.get(null); | ||
String[] rootPlugins2 = new String[rootPlugins.length + 1]; | ||
System.arraycopy(rootPlugins, 0, rootPlugins2, 0, rootPlugins.length); | ||
rootPlugins2[rootPlugins.length] = COREMOD; | ||
rootPluginsField.set(null, rootPlugins2); | ||
logger.info("SpongeCoremod successfully injected into FML"); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
|
||
public static class PostFMLTweaker extends SimpleTweaker { | ||
|
||
@Override | ||
public void injectIntoClassLoader(LaunchClassLoader classLoader) { | ||
// Mixin system already loaded early so don't load twice | ||
List<?> tweakClasses = (List<?>) Launch.blackboard.get("TweakClasses"); | ||
while (tweakClasses.remove("org.spongepowered.asm.launch.MixinTweaker")) { | ||
} | ||
System.out.println(Launch.blackboard); | ||
} | ||
} | ||
|
||
private static class SimpleTweaker implements ITweaker { | ||
|
||
@Override | ||
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) { | ||
} | ||
|
||
@Override | ||
public void injectIntoClassLoader(LaunchClassLoader classLoader) { | ||
} | ||
|
||
@Override | ||
public String getLaunchTarget() { | ||
return "net.minecraft.server.MinecraftServer"; | ||
} | ||
|
||
@Override | ||
public String[] getLaunchArguments() { | ||
return new String[0]; | ||
} | ||
|
||
} | ||
|
||
public static class GradleHackServer extends GradleStartCommon { | ||
|
||
public static void main(String[] args) throws Throwable { | ||
(new GradleHackServer()).launch(args); | ||
} | ||
|
||
@Override | ||
protected String getTweakClass() { | ||
return PRE_TWEAKER; | ||
} | ||
|
||
@Override | ||
protected String getBounceClass() { | ||
return "net.minecraft.launchwrapper.Launch"; | ||
} | ||
|
||
@Override | ||
protected void preLaunch(Map<String, String> argMap, List<String> extras) { | ||
// Add the tweak class from GradleStartServer AFTER our tweaker | ||
extras.add("--tweakClass"); | ||
extras.add(FML_TWEAKER); | ||
extras.add("--tweakClass"); | ||
extras.add(POST_TWEAKER); | ||
} | ||
|
||
@Override | ||
protected void setDefaultArguments(Map<String, String> argMap) { | ||
} | ||
} | ||
|
||
} |