SubServers-2/SubServers.Host/src/net/ME1312/SubServers/Host/Launch.java

285 lines
10 KiB
Java

package net.ME1312.SubServers.Host;
import java.io.*;
import java.lang.management.ManagementFactory;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.xml.parsers.DocumentBuilderFactory;
import jline.console.ConsoleReader;
import jline.console.CursorBuffer;
import net.ME1312.SubServers.Host.Library.Util;
import org.fusesource.jansi.AnsiConsole;
import org.w3c.dom.NodeList;
/**
* SubServers.Host Launcher Class
*/
public final class Launch {
/**
* Prepare and launch SubServers.Host
*
* @param args Args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
String plugins = "";
File rtdir = new File(System.getProperty("user.dir"));
File tmpdir = File.createTempFile("SubServers.Host.", ".jar");
File pldir = new File(rtdir, "Plugins");
tmpdir.delete();
tmpdir.mkdir();
System.out.println(">> Created " + tmpdir.getPath().replace(File.separator, "/"));
extractJar(getCodeSourceLocation(), tmpdir);
System.out.println(">> Extracted ~/" + getCodeSourceLocation().getName());
if (pldir.isDirectory() && pldir.listFiles().length > 0) {
for (File plugin : Arrays.asList(pldir.listFiles())) {
try {
boolean success = false;
if (getFileExtension(plugin.getName()).equalsIgnoreCase("zip")) {
Util.unzip(new FileInputStream(plugin), tmpdir);
success = true;
} else if (getFileExtension(plugin.getName()).equalsIgnoreCase("jar")) {
extractJar(plugin, tmpdir);
success = true;
}
if (new File(tmpdir, "package.xml").exists()) {
NodeList xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(tmpdir, "package.xml")).getElementsByTagName("class");
if (xml.getLength() > 0) {
for (int i = 0; i < xml.getLength(); i++) {
plugins += ((plugins.length() == 0)?"":" ") + xml.item(i).getTextContent().replace(' ', '_');
}
}
new File(tmpdir, "package.xml").delete();
}
if (success) System.out.println(">> Extracted ~/plugins/" + plugin.getName());
} catch (Exception e) {
System.out.println(">> Couldn't extract ~/plugins/" + plugin.getName());
e.printStackTrace();
}
}
}
ArrayList<String> arguments = new ArrayList<String>();
String javaPath = String.valueOf(System.getProperty("java.home")) + File.separator + "bin" + File.separator + "java";
arguments.add(javaPath);
arguments.addAll(getVmArgs());
arguments.add("-Dsubservers.host.runtime=" + URLEncoder.encode(tmpdir.getPath(), "UTF-8"));
if (!plugins.equals(""))
arguments.add("-Dsubservers.host.plugins=" + URLEncoder.encode(plugins, "UTF-8"));
arguments.add("-cp");
arguments.add(tmpdir.getPath());
arguments.add("net.ME1312.SubServers.Host.ExHost");
arguments.addAll(Arrays.asList(args));
ProcessBuilder processBuilder = new ProcessBuilder(arguments);
processBuilder.directory(new File(System.getProperty("user.dir")));
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
syncConsole(process);
System.out.println(">> Cleaning up");
deleteDir(tmpdir);
System.exit(process.exitValue());
}
private static void syncConsole(final Process process) throws Exception {
AnsiConsole.systemInstall();
ConsoleReader console = new ConsoleReader();
console.setExpandEvents(false);
try {
new Thread(() -> {
try {
String line;
BufferedWriter cmd = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
while (process.isAlive() && (line = console.readLine(">")) != null) {
if (line.equals("")) continue;
cmd.write(line);
cmd.newLine();
cmd.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
String line;
BufferedReader obr = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while (process.isAlive() && (line = obr.readLine()) != null) {
stashLine(console);
if (System.getProperty("subservers.host.log.color", "true").equalsIgnoreCase("true")) {
console.println(ConsoleColor.parseColor(line) + ConsoleColor.RESET);
} else {
console.println(ConsoleColor.stripColor(line.replaceAll("\u001B\\[[;\\d]*m", "")));
}
unstashLine(console);
console.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
String line;
BufferedReader obr = new BufferedReader(new InputStreamReader(process.getInputStream()));
while (process.isAlive() && (line = obr.readLine()) != null) {
stashLine(console);
if (System.getProperty("subservers.host.log.color", "true").equalsIgnoreCase("true")) {
console.println(ConsoleColor.parseColor(line) + ConsoleColor.RESET);
} else {
console.println(ConsoleColor.stripColor(line.replaceAll("\u001B\\[[;\\d]*m", "")));
}
unstashLine(console);
console.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
stashLine(console);
AnsiConsole.systemUninstall();
}
private static void extractJar(File jarFile, File dir) throws Exception {
JarFile jar = new JarFile(jarFile);
Enumeration<JarEntry> files = jar.entries();
ArrayList<JarEntry> entries = new ArrayList<JarEntry>();
while (files.hasMoreElements()) {
entries.add(files.nextElement());
}
for (JarEntry file : entries) {
File f = new File(dir, file.getName());
if (f.exists()) {
continue;
}
if (file.isDirectory()) {
f.mkdirs();
continue;
}
if (!f.getParentFile().exists()) {
f.getParentFile().mkdirs();
}
InputStream is = jar.getInputStream(file);
FileOutputStream fos = new FileOutputStream(f);
while (is.available() > 0) {
fos.write(is.read());
}
fos.close();
is.close();
}
}
private static void deleteDir(File f) {
if (f.isDirectory()) {
for (File c : f.listFiles()) {
deleteDir(c);
}
}
f.delete();
}
private static List<String> getVmArgs() {
ArrayList<String> values = new ArrayList<String>();
values.addAll(ManagementFactory.getRuntimeMXBean().getInputArguments());
return values;
}
private static File getCodeSourceLocation() {
try {
return new File(Launch.class.getProtectionDomain().getCodeSource().getLocation().toURI());
}
catch (URISyntaxException e) {
e.printStackTrace();
return null;
}
}
private static String getFileExtension(String fileName) {
String extension = "";
int i = fileName.lastIndexOf(46);
if (i >= 0) {
extension = fileName.substring(i + 1);
}
return extension;
}
private static CursorBuffer stashed;
private static void stashLine(ConsoleReader console) {
stashed = console.getCursorBuffer().copy();
try {
console.getOutput().write("\u001b[1G\u001b[K");
console.flush();
} catch (IOException e) {
// ignore
}
}
private static void unstashLine(ConsoleReader console) {
try {
console.resetPromptLine(console.getPrompt(),
stashed.toString(), stashed.cursor);
} catch (IOException e) {
// ignore
}
}
private enum ConsoleColor {
AQUA('b', "[0;36;1m"),
BLACK('0', "[0;30;22m"),
BLUE('9', "[0;34;1m"),
BOLD('l', "[21m"),
DARK_AQUA('3', "[0;36;22m"),
DARK_BLUE('1', "[0;34;22m"),
DARK_GRAY('8', "[0;30;1m"),
DARK_GREEN('2', "[0;32;22m"),
DARK_PURPLE('5', "[0;35;22m"),
DARK_RED('4', "[0;31;22m"),
GOLD('6', "[0;33;22m"),
GRAY('7', "[0;37;22m"),
GREEN('a', "[0;32;1m"),
ITALIC('o', "[3m"),
LIGHT_PURPLE('d', "[0;35;1m"),
MAGIC('k', "[5m"),
RED('c', "[0;31;1m"),
RESET('r', "[m"),
STRIKETHROUGH('m', "[9m"),
UNDERLINE('n', "[4m"),
WHITE('f', "[0;37;1m"),
YELLOW('e', "[0;33;1m");
private final Character color;
private final String value;
ConsoleColor(Character color, String value) {
this.color = color;
this.value = value;
}
@Override
public String toString() {
return getConsoleString();
}
public String getValue() {
return "\u00A7" + color;
}
public String getConsoleString() {
return "\u001B" + value;
}
public static String parseColor(String str) {
for (ConsoleColor color : Arrays.asList(ConsoleColor.values())) {
str = str.replace(color.getValue(), color.getConsoleString());
}
return str;
}
public static String stripColor(String str) {
for (ConsoleColor color : Arrays.asList(ConsoleColor.values())) {
str = str.replace(color.getValue(), "");
}
return str;
}
}
}