package net.minecraftforkage.instsetup.cmdline;
import java.io.File;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraftforkage.instsetup.InstallationArguments;
import net.minecraftforkage.instsetup.SetupEntryPoint;
public class CommandLineInstanceSetup {
public static void main(String[] args) throws Exception {
InstallationArguments instArgs = new InstallationArguments();
String[] runArgs = null;
argloop: for(int k = 0; k < args.length;) {
switch(args[k++]) {
case "--instanceBaseDir":
if(k == args.length) throw new Exception("--instanceBaseDir requires argument");
instArgs.instanceBaseDir = new File(args[k++]);
break;
case "--outputLocation":
if(k == args.length) throw new Exception("--outputLocation requires argument");
instArgs.outputLocation = new File(args[k++]);
break;
case "--coreLocation":
if(k == args.length) throw new Exception("--coreLocation requires argument");
instArgs.coreLocation = new File(args[k++]).toURI().toURL();
break;
case "--standalone":
instArgs.standalone = true;
break;
case "--libraryDir":
if(k == args.length) throw new Exception("--libraryDir requires argument");
instArgs.libraryDir = new File(args[k++]);
break;
case "--nativesDir":
if(k == args.length) throw new Exception("--nativesDir requires argument");
instArgs.nativesDir = new File(args[k++]);
break;
case "--run":
// All arguments after --run are passed to Minecraft
runArgs = Arrays.copyOfRange(args, k, args.length);
break argloop;
default:
throw new Exception("Unknown argument: " + args[k-1]);
}
}
if(runArgs != null && instArgs.libraryDir == null)
throw new Exception("--run requires --libraryDir");
SetupEntryPoint.setupInstance(instArgs);
if(runArgs != null) {
List<URL> urls = new ArrayList<URL>();
// If the modpack JAR is standalone, then the libraries
// are included in it and don't need to be added to the classpath.
if(!instArgs.standalone) {
JsonObject json;
try (Reader in = new InputStreamReader(getLauncherJsonURL(instArgs.coreLocation).openStream(), StandardCharsets.UTF_8)) {
json = new GsonBuilder().create().fromJson(in, JsonObject.class);
}
for(JsonElement library : json.get("libraries").getAsJsonArray()) {
String name = library.getAsJsonObject().get("name").getAsString();
String[] parts = name.split(":");
File libfile = new File(instArgs.libraryDir, parts[1]+"-"+parts[2]+".jar");
if(libfile.exists()) {
urls.add(libfile.toURI().toURL());
continue;
}
libfile = new File(instArgs.libraryDir, parts[0].replace(".",File.separator)+File.separator+parts[1]+File.separator+parts[2]+File.separator+parts[1]+"-"+parts[2]+".jar");
if(libfile.exists()) {
urls.add(libfile.toURI().toURL());
continue;
}
System.err.println("Couldn't find library "+name+" in "+instArgs.libraryDir);
}
}
urls.add(instArgs.outputLocation.toURI().toURL());
@SuppressWarnings("resource")
URLClassLoader mcLoader = new URLClassLoader(urls.toArray(new URL[0]));
List<String> allRunArgs = new ArrayList<>();
allRunArgs.addAll(Arrays.asList(runArgs));
allRunArgs.add("--gameDir");
allRunArgs.add(instArgs.instanceBaseDir.getAbsolutePath());
Class<?> mcMain = mcLoader.loadClass("net.minecraft.launchwrapper.Launch");
Method mainMethod = mcMain.getMethod("main", String[].class);
//System.in.read();
mainMethod.invoke(null, (Object)allRunArgs.toArray(new String[0]));
}
}
private static URL getLauncherJsonURL(URL coreLoc) throws MalformedURLException {
return new URL("jar:" + coreLoc.toString() + "!/mcforkage-launcher-info.json");
}
}