Might fix game log watcher?

This commit is contained in:
huangyuhui 2016-02-16 18:57:26 +08:00
parent cb125b83cb
commit afecb87c6d
29 changed files with 280 additions and 223 deletions

View File

@ -26,16 +26,11 @@ import java.net.URLClassLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.ui.LogWindow;
import org.jackhuang.hellominecraft.launcher.util.MinecraftCrashAdvicer; import org.jackhuang.hellominecraft.launcher.util.MinecraftCrashAdvicer;
import org.jackhuang.hellominecraft.util.DoubleOutputStream; import org.jackhuang.hellominecraft.util.DoubleOutputStream;
import org.jackhuang.hellominecraft.util.LauncherPrintStream; import org.jackhuang.hellominecraft.util.LauncherPrintStream;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.Utils;
/** /**
* *
@ -69,14 +64,6 @@ public final class Launcher {
int len = tokenized.length; int len = tokenized.length;
if (showInfo) { if (showInfo) {
LogWindow.INSTANCE.setTerminateGame(() -> {
try {
Utils.shutdownForcely(1);
} catch (Exception e) {
MessageBox.Show(C.i18n("launcher.exit_failed"));
HMCLog.err("Failed to shutdown forcely", e);
}
});
try { try {
File logFile = new File("hmclmc.log"); File logFile = new File("hmclmc.log");
if (!logFile.exists() && !logFile.createNewFile()) if (!logFile.exists() && !logFile.createNewFile())
@ -95,7 +82,6 @@ public final class Launcher {
LOGGER.log(Level.INFO, "Arguments: '{'\n{0}\n'}'", StrUtils.parseParams(" ", args, "\n")); LOGGER.log(Level.INFO, "Arguments: '{'\n{0}\n'}'", StrUtils.parseParams(" ", args, "\n"));
LOGGER.log(Level.INFO, "Main Class: {0}", mainClass); LOGGER.log(Level.INFO, "Main Class: {0}", mainClass);
LOGGER.log(Level.INFO, "Class Path: '{'\n{0}\n'}'", StrUtils.parseParams(" ", tokenized, "\n")); LOGGER.log(Level.INFO, "Class Path: '{'\n{0}\n'}'", StrUtils.parseParams(" ", tokenized, "\n"));
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.setVisible(true));
} }
URL[] urls = new URL[len]; URL[] urls = new URL[len];
@ -104,7 +90,6 @@ public final class Launcher {
for (int j = 0; j < len; j++) for (int j = 0; j < len; j++)
urls[j] = new File(tokenized[j]).toURI().toURL(); urls[j] = new File(tokenized[j]).toURI().toURL();
} catch (Throwable e) { } catch (Throwable e) {
MessageBox.Show(C.i18n("crash.main_class_not_found"));
LOGGER.log(Level.SEVERE, "Failed to get classpath.", e); LOGGER.log(Level.SEVERE, "Failed to get classpath.", e);
return; return;
} }
@ -115,48 +100,21 @@ public final class Launcher {
try { try {
minecraftMain = ucl.loadClass(mainClass).getMethod("main", String[].class); minecraftMain = ucl.loadClass(mainClass).getMethod("main", String[].class);
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException t) { } catch (ClassNotFoundException | NoSuchMethodException | SecurityException t) {
MessageBox.Show(C.i18n("crash.main_class_not_found"));
LOGGER.log(Level.SEVERE, "Minecraft main class not found.", t); LOGGER.log(Level.SEVERE, "Minecraft main class not found.", t);
return; return;
} }
LOGGER.info("*** Launching Game ***"); LOGGER.info("*** Launching Game ***");
int flag = 0;
try { try {
minecraftMain.invoke(null, new Object[] { (String[]) cmdList.toArray(new String[cmdList.size()]) }); minecraftMain.invoke(null, new Object[] { (String[]) cmdList.toArray(new String[cmdList.size()]) });
} catch (Throwable throwable) { } catch (Throwable throwable) {
String trace = StrUtils.getStackTrace(throwable); String trace = StrUtils.getStackTrace(throwable);
final String advice = MinecraftCrashAdvicer.getAdvice(trace);
MessageBox.Show(C.i18n("crash.minecraft") + ": " + advice);
System.err.println(C.i18n("crash.minecraft")); System.err.println(C.i18n("crash.minecraft"));
System.err.println(advice); System.err.println(MinecraftCrashAdvicer.getAdvice(trace));
System.err.println(trace); System.err.println(trace);
LogWindow.INSTANCE.setExit(() -> true);
LogWindow.INSTANCE.setVisible(true);
flag = 1;
} }
LOGGER.info("*** Game Exited ***"); LOGGER.info("*** Game exited ***");
try {
Utils.shutdownForcely(flag);
} catch (Exception e) {
MessageBox.Show(C.i18n("launcher.exit_failed"));
HMCLog.err("Failed to shutdown forcely", e);
} }
} }
/*
* static Object getShutdownHaltLock() {
* try {
* Class z = Class.forName("java.lang.Shutdown");
* Field haltLock = z.getDeclaredField("haltLock");
* haltLock.setAccessible(true);
* return haltLock.get(null);
* } catch (Throwable ex) {
* ex.printStackTrace();
* return new Object();
* }
* }
*/
}

View File

@ -18,6 +18,7 @@
package org.jackhuang.hellominecraft.launcher.core.download; package org.jackhuang.hellominecraft.launcher.core.download;
import java.io.File; import java.io.File;
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
import org.jackhuang.hellominecraft.util.system.IOUtils; import org.jackhuang.hellominecraft.util.system.IOUtils;
/** /**
@ -26,12 +27,13 @@ import org.jackhuang.hellominecraft.util.system.IOUtils;
*/ */
public class DownloadLibraryJob { public class DownloadLibraryJob {
public String url, name; public IMinecraftLibrary lib;
public String url;
public File path; public File path;
public DownloadLibraryJob(String n, String u, File p) { public DownloadLibraryJob(IMinecraftLibrary n, String u, File p) {
url = u; url = u;
name = n; lib = n;
path = IOUtils.tryGetCanonicalFile(p); path = IOUtils.tryGetCanonicalFile(p);
} }
} }

View File

@ -65,7 +65,7 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
String libURL = service.getDownloadType().getProvider().getLibraryDownloadURL() + "/"; String libURL = service.getDownloadType().getProvider().getLibraryDownloadURL() + "/";
libURL = service.getDownloadType().getProvider().getParsedLibraryDownloadURL(l.getDownloadURL(libURL, service.getDownloadType())); libURL = service.getDownloadType().getProvider().getParsedLibraryDownloadURL(l.getDownloadURL(libURL, service.getDownloadType()));
if (libURL != null) if (libURL != null)
downloadLibraries.add(new DownloadLibraryJob(l.name, libURL, ff)); downloadLibraries.add(new DownloadLibraryJob(l, libURL, ff));
} }
} }
} }
@ -100,7 +100,7 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
return; return;
} }
String jarURL = vurl + id + ".jar", hash = null; String jarURL = vurl + id + ".jar", hash = null;
if (mv != null && mv.downloads != null && service.getDownloadType().getProvider().isAllowedToUseSelfURL()) { if (mv.downloads != null && service.getDownloadType().getProvider().isAllowedToUseSelfURL()) {
GameDownloadInfo gdi = mv.downloads.get("client"); GameDownloadInfo gdi = mv.downloads.get("client");
if (gdi != null) { if (gdi != null) {
if (gdi.url != null) if (gdi.url != null)

View File

@ -17,7 +17,9 @@
*/ */
package org.jackhuang.hellominecraft.launcher.core.download; package org.jackhuang.hellominecraft.launcher.core.download;
import java.util.Locale;
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
import org.jackhuang.hellominecraft.util.lang.SupportedLocales;
/** /**
* *
@ -72,6 +74,14 @@ public class MojangDownloadProvider extends IDownloadProvider {
@Override @Override
public String getParsedLibraryDownloadURL(String str) { public String getParsedLibraryDownloadURL(String str) {
if (str == null)
return null;
else if (str.contains("typesafe"))
if (SupportedLocales.NOW_LOCALE.self == Locale.CHINA)
return str.replace("http://files.minecraftforge.net/maven", "http://maven.oschina.net/content/groups/public");
else
return str.replace("http://files.minecraftforge.net/maven", "http://repo1.maven.org/maven2");
else
return str; return str;
} }

View File

@ -43,9 +43,9 @@ public class DefaultGameLauncher extends GameLauncher {
ParallelTask parallelTask = new ParallelTask(); ParallelTask parallelTask = new ParallelTask();
HashSet<String> names = new HashSet<>(); HashSet<String> names = new HashSet<>();
for (DownloadLibraryJob s : t) { for (DownloadLibraryJob s : t) {
if (names.contains(s.name)) if (names.contains(s.lib.name))
continue; continue;
names.add(s.name); names.add(s.lib.name);
parallelTask.addDependsTask(new LibraryDownloadTask(s)); parallelTask.addDependsTask(new LibraryDownloadTask(s));
} }
dw.append(parallelTask); dw.append(parallelTask);

View File

@ -128,7 +128,7 @@ public class GameLauncher {
ProcessBuilder builder = new ProcessBuilder(str); ProcessBuilder builder = new ProcessBuilder(str);
if (options.getLaunchVersion() == null || service.baseDirectory() == null) if (options.getLaunchVersion() == null || service.baseDirectory() == null)
throw new Error("Fucking bug!"); throw new Error("Fucking bug!");
builder.directory(service.version().getRunDirectory(options.getLaunchVersion())) builder.redirectErrorStream(true).directory(service.version().getRunDirectory(options.getLaunchVersion()))
.environment().put("APPDATA", service.baseDirectory().getAbsolutePath()); .environment().put("APPDATA", service.baseDirectory().getAbsolutePath());
JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER); JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER);
HMCLog.log("The game process have been started"); HMCLog.log("The game process have been started");

View File

@ -38,13 +38,14 @@ public class LibraryDownloadTask extends FileDownloadTask {
@Override @Override
public void executeTask() throws Throwable { public void executeTask() throws Throwable {
if (job.name.startsWith("net.minecraftforge:forge:")) { String name = job.lib.name;
String[] s = job.name.split(":"); if (name.startsWith("net.minecraftforge:forge:")) {
String[] s = name.split(":");
if (s.length == 3) if (s.length == 3)
job.url = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" + s[2] + "/forge-" + s[2] + "-universal.jar"; job.url = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" + s[2] + "/forge-" + s[2] + "-universal.jar";
} }
if (job.name.startsWith("com.mumfrey:liteloader:")) { if (name.startsWith("com.mumfrey:liteloader:")) {
String[] s = job.name.split(":"); String[] s = name.split(":");
if (s.length == 3 && s[2].length() > 3) if (s.length == 3 && s[2].length() > 3)
job.url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + s[2].substring(0, s[2].length() - 3) + "/liteloader-" + s[2] + ".jar"; job.url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + s[2].substring(0, s[2].length() - 3) + "/liteloader-" + s[2] + ".jar";
} }
@ -59,7 +60,7 @@ public class LibraryDownloadTask extends FileDownloadTask {
@Override @Override
public String getInfo() { public String getInfo() {
return C.i18n("download") + ": " + job.name; return C.i18n("download") + ": " + job.lib.name;
} }
} }

View File

@ -21,9 +21,17 @@ package org.jackhuang.hellominecraft.launcher.core.version;
* *
* @author huangyuhui * @author huangyuhui
*/ */
public class GameDownloadInfo { public class GameDownloadInfo implements Cloneable {
public String sha1, url; public String sha1, url;
public int size; public int size;
@Override
protected Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException ex) {
throw new Error(ex);
}
}
} }

View File

@ -0,0 +1,27 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.core.version;
/**
*
* @author huangyuhui
*/
public class LibraryDownloadInfo extends GameDownloadInfo {
public String path;
}

View File

@ -40,7 +40,7 @@ public class MinecraftLibrary extends IMinecraftLibrary {
super(name); super(name);
} }
public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract) { public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract, LibraryDownloadInfo downloads) {
super(name); super(name);
this.rules = rules == null ? null : (ArrayList<Rules>) rules.clone(); this.rules = rules == null ? null : (ArrayList<Rules>) rules.clone();
this.url = url; this.url = url;

View File

@ -60,7 +60,8 @@ public class VersionSetting {
public VersionSetting() { public VersionSetting() {
debug = fullscreen = canceledWrapper = false; debug = fullscreen = canceledWrapper = false;
launcherVisibility = gameDirType = 0; launcherVisibility = 1;
gameDirType = 0;
javaDir = java = minecraftArgs = serverIp = precalledCommand = ""; javaDir = java = minecraftArgs = serverIp = precalledCommand = "";
} }

View File

@ -30,6 +30,7 @@ import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.logging.HMCLog; import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.system.JavaProcessMonitor; import org.jackhuang.hellominecraft.util.system.JavaProcessMonitor;
import org.jackhuang.hellominecraft.util.ui.LogWindow; import org.jackhuang.hellominecraft.util.ui.LogWindow;
import org.jackhuang.hellominecraft.util.ui.WebFrame;
/** /**
* *
@ -71,15 +72,21 @@ public class LaunchingUIDaemon {
JavaProcessMonitor jpm = new JavaProcessMonitor(p); JavaProcessMonitor jpm = new JavaProcessMonitor(p);
jpm.applicationExitedAbnormallyEvent.register(t -> { jpm.applicationExitedAbnormallyEvent.register(t -> {
HMCLog.err("The game exited abnormally, exit code: " + t); HMCLog.err("The game exited abnormally, exit code: " + t);
MessageBox.Show(C.i18n("launch.exited_abnormally") + ", exit code: " + t); MessageBox.Show(C.i18n("launch.exited_abnormally") + " exit code: " + t);
WebFrame f = new WebFrame(jpm.getJavaProcess().getStdOutLines().toArray(new String[0]));
f.setTitle("Game output");
f.setVisible(true);
}); });
jpm.jvmLaunchFailedEvent.register(t -> { jpm.jvmLaunchFailedEvent.register(t -> {
HMCLog.err("Cannot create jvm, exit code: " + t); HMCLog.err("Cannot create jvm, exit code: " + t);
MessageBox.Show(C.i18n("launch.cannot_create_jvm") + ", exit code: " + t); MessageBox.Show(C.i18n("launch.cannot_create_jvm") + " exit code: " + t);
WebFrame f = new WebFrame(jpm.getJavaProcess().getStdOutLines().toArray(new String[0]));
f.setTitle("Game output");
f.setVisible(true);
}); });
jpm.stoppedEvent.register(() -> { jpm.stoppedEvent.register(() -> {
if ((LauncherVisibility) obj.getTag() != LauncherVisibility.KEEP && !LogWindow.INSTANCE.isVisible()) { if ((LauncherVisibility) obj.getTag() == LauncherVisibility.CLOSE && !LogWindow.INSTANCE.isVisible()) {
HMCLog.log("Without the option of keeping the launcher visible, this application will exit and will NOT catch game logs, but you can turn on \"Debug Mode\"."); HMCLog.log("With the option of closing the launcher anyway, the launcher will exit and will NOT catch game logs.");
System.exit(0); System.exit(0);
} }
}); });

View File

@ -48,7 +48,7 @@ import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.launcher.Main; import org.jackhuang.hellominecraft.launcher.Main;
import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils; import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
import org.jackhuang.hellominecraft.lookandfeel.Theme; import org.jackhuang.hellominecraft.lookandfeel.Theme;
import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;

View File

@ -37,7 +37,7 @@ import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.launcher.core.mod.ModpackManager; import org.jackhuang.hellominecraft.launcher.core.mod.ModpackManager;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.ui.modpack.ModpackWizard; import org.jackhuang.hellominecraft.launcher.ui.modpack.ModpackWizard;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils; import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
import org.jackhuang.hellominecraft.util.Event; import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton; import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton;
import org.jackhuang.hellominecraft.util.func.Consumer; import org.jackhuang.hellominecraft.util.func.Consumer;

View File

@ -25,6 +25,8 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.jackhuang.hellominecraft.util.func.Function;
import org.jackhuang.hellominecraft.util.func.Predicate;
/** /**
* *
@ -115,6 +117,14 @@ public final class StrUtils {
return false; return false;
} }
public static boolean containsOne(List<String> base, List<String> match, Predicate<String> pred) {
for (String a : base)
for (String b : match)
if (pred.apply(a) && a.toLowerCase().contains(b.toLowerCase()))
return true;
return false;
}
public static int getCharShowTime(String s, char c) { public static int getCharShowTime(String s, char c) {
int res = 0; int res = 0;
for (int i = 0; i < s.length(); i++) for (int i = 0; i < s.length(); i++)
@ -141,33 +151,37 @@ public final class StrUtils {
return parseParams(addBefore, paramArrayOfObject.toArray(), paramString); return parseParams(addBefore, paramArrayOfObject.toArray(), paramString);
} }
public static String parseParams(String addBefore, Object[] paramArrayOfObject, String paramString) { public static String parseParams(String addBefore, Object[] params, String addAfter) {
if (paramArrayOfObject == null) return parseParams(t -> addBefore, params, t -> addAfter);
return ""; }
StringBuilder localStringBuffer = new StringBuilder();
for (int i = 0; i < paramArrayOfObject.length; i++) {
Object localObject = paramArrayOfObject[i];
if (i > 0)
localStringBuffer.append(addBefore).append(paramString);
if (localObject == null)
localStringBuffer.append("null");
else if (localObject.getClass().isArray()) {
localStringBuffer.append("[");
if ((localObject instanceof Object[])) { public static String parseParams(Function<Object, String> beforeFunc, Object[] params, Function<Object, String> afterFunc) {
Object[] arrayOfObject = (Object[]) localObject; if (params == null)
localStringBuffer.append(parseParams(addBefore, arrayOfObject, paramString)); return "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < params.length; i++) {
Object param = params[i];
String addBefore = beforeFunc.apply(param), addAfter = afterFunc.apply(param);
if (i > 0)
sb.append(addAfter).append(addBefore);
if (param == null)
sb.append("null");
else if (param.getClass().isArray()) {
sb.append("[");
if ((param instanceof Object[])) {
Object[] objs = (Object[]) param;
sb.append(parseParams(beforeFunc, objs, afterFunc));
} else } else
for (int j = 0; j < Array.getLength(localObject); j++) { for (int j = 0; j < Array.getLength(param); j++) {
if (j > 0) if (j > 0)
localStringBuffer.append(paramString); sb.append(addAfter);
localStringBuffer.append(addBefore).append(Array.get(localObject, j)); sb.append(addBefore).append(Array.get(param, j));
} }
localStringBuffer.append("]"); sb.append("]");
} else } else
localStringBuffer.append(addBefore).append(paramArrayOfObject[i]); sb.append(addBefore).append(params[i]);
} }
return localStringBuffer.toString(); return sb.toString();
} }
public static boolean isEquals(String base, String to) { public static boolean isEquals(String base, String to) {

View File

@ -30,7 +30,6 @@ public class JavaProcess {
private final List<String> commands; private final List<String> commands;
private final Process process; private final Process process;
private final ArrayList<String> stdOutLines = new ArrayList<>(); private final ArrayList<String> stdOutLines = new ArrayList<>();
private final ArrayList<String> stdErrLines = new ArrayList<>();
public JavaProcess(List<String> commands, Process process, ProcessManager pm) { public JavaProcess(List<String> commands, Process process, ProcessManager pm) {
this.commands = commands; this.commands = commands;
@ -59,10 +58,6 @@ public class JavaProcess {
return this.stdOutLines; return this.stdOutLines;
} }
public ArrayList<String> getStdErrLines() {
return this.stdErrLines;
}
public boolean isRunning() { public boolean isRunning() {
try { try {
this.process.exitValue(); this.process.exitValue();

View File

@ -20,9 +20,10 @@ package org.jackhuang.hellominecraft.util.system;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.jackhuang.hellominecraft.util.CollectionUtils; import org.jackhuang.hellominecraft.util.CollectionUtils;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.util.EventHandler;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.logging.Level;
/** /**
* *
@ -51,31 +52,28 @@ public class JavaProcessMonitor {
this.p = p; this.p = p;
} }
public JavaProcess getJavaProcess() {
return p;
}
public void start() { public void start() {
Event<JavaProcess> event = (sender2, t) -> { ProcessThread a = new ProcessThread(p);
if (t.getExitCode() != 0) a.stopEvent.register((sender, t) -> {
HMCLog.log("Process exit code: " + t.getExitCode());
if (t.getExitCode() != 0 || StrUtils.containsOne(t.getStdOutLines(),
Arrays.asList("Unable to launch"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
applicationExitedAbnormallyEvent.execute(t.getExitCode()); applicationExitedAbnormallyEvent.execute(t.getExitCode());
processThreadStopped((ProcessThread) sender2, false); if (t.getExitCode() != 0 && StrUtils.containsOne(t.getStdOutLines(),
return true; Arrays.asList("Could not create the Java Virtual Machine.",
};
Event<JavaProcess> event2 = (sender3, p1) -> {
if (p1.getExitCode() != 0 && p1.getStdErrLines().size() > 0 && StrUtils.containsOne(p1.getStdErrLines(), Arrays.asList("Could not create the Java Virtual Machine.",
"Error occurred during initialization of VM", "Error occurred during initialization of VM",
"A fatal exception has occurred. Program will exit."))) "A fatal exception has occurred. Program will exit.",
jvmLaunchFailedEvent.execute(p1.getExitCode()); "Unable to launch"),
processThreadStopped((ProcessThread) sender3, false); x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
jvmLaunchFailedEvent.execute(t.getExitCode());
processThreadStopped((ProcessThread) sender, false);
return true; return true;
}; });
ProcessThread a = new ProcessThread(p, true, true);
a.stopEvent.register(event2);
a.start();
al.add(a);
a = new ProcessThread(p, false, true);
a.stopEvent.register(event2);
a.start();
al.add(a);
a = new ProcessThread(p, false, false);
a.stopEvent.register(event);
a.start(); a.start();
al.add(a); al.add(a);
} }

View File

@ -30,15 +30,12 @@ import org.jackhuang.hellominecraft.util.EventHandler;
public class ProcessThread extends Thread { public class ProcessThread extends Thread {
JavaProcess p; JavaProcess p;
boolean readError = false, enableReading = true;
public final EventHandler<String> printlnEvent = new EventHandler<>(this); public final EventHandler<String> printlnEvent = new EventHandler<>(this);
public final EventHandler<JavaProcess> stopEvent = new EventHandler<>(this); public final EventHandler<JavaProcess> stopEvent = new EventHandler<>(this);
public ProcessThread(JavaProcess process, boolean readError, boolean enableReading) { public ProcessThread(JavaProcess process) {
p = process; p = process;
this.readError = readError;
this.enableReading = enableReading;
} }
public JavaProcess getProcess() { public JavaProcess getProcess() {
@ -47,58 +44,33 @@ public class ProcessThread extends Thread {
@Override @Override
public void run() { public void run() {
setName("ProcessMonitor");
InputStreamReader br = null;
try { try {
InputStreamReader br; InputStream in = p.getRawProcess().getInputStream();
if (enableReading) {
InputStream in = readError ? p.getRawProcess().getErrorStream() : p.getRawProcess().getInputStream();
try { try {
br = new InputStreamReader(in, System.getProperty("sun.jnu.encoding", "UTF-8")); br = new InputStreamReader(in, System.getProperty("sun.jnu.encoding", "UTF-8"));
} catch (UnsupportedEncodingException ex) { } catch (UnsupportedEncodingException ex) {
HMCLog.warn("Unsupported encoding: " + System.getProperty("sun.jnu.encoding", "UTF-8"), ex); HMCLog.warn("Unsupported encoding: " + System.getProperty("sun.jnu.encoding", "UTF-8"), ex);
br = new InputStreamReader(in); br = new InputStreamReader(in);
} }
} else
br = null;
int ch; int ch;
String line = ""; String line = "";
while (p.isRunning()) while (p.isRunning())
if (br != null)
while ((ch = br.read()) != -1) while ((ch = br.read()) != -1)
if (ch == '\n') { if (ch == '\n') {
printlnEvent.execute(line); printlnEvent.execute(line);
if (readError) { System.out.println("Minecraft: " + line);
System.err.println(line);
p.getStdErrLines().add(line);
} else {
System.out.println(line);
p.getStdOutLines().add(line); p.getStdOutLines().add(line);
}
line = "";
} else
line += (char) ch;
else
try {
Thread.sleep(1);
} catch (Exception e) {
}
if (br != null)
while ((ch = br.read()) != -1)
if (ch == '\n') {
printlnEvent.execute(line);
if (readError) {
System.err.println(line);
p.getStdErrLines().add(line);
} else {
System.out.println(line);
p.getStdOutLines().add(line);
}
line = ""; line = "";
} else } else
line += (char) ch; line += (char) ch;
stopEvent.execute(p); stopEvent.execute(p);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); HMCLog.err("An error occured when reading process stdout/stderr.", e);
} finally {
IOUtils.closeQuietly(br);
} }
} }
} }

View File

@ -1,4 +1,4 @@
package org.jackhuang.hellominecraft.lookandfeel; package org.jackhuang.hellominecraft.util.ui;
import java.awt.Color; import java.awt.Color;
import java.awt.Graphics; import java.awt.Graphics;
@ -30,21 +30,21 @@ public class GraphicsUtils extends SynthGraphicsUtils {
* *
* @param g2d the graphics surface * @param g2d the graphics surface
* @param hintsToSave the list of rendering hints to set on the graphics * @param hintsToSave the list of rendering hints to set on the graphics
* @param savedHints a set where to save the previous rendering hints, might * @param savedHints a set where to save the previous rendering hints,
* might
* be null * be null
*
* @return the previous set of rendering hints * @return the previous set of rendering hints
*/ */
public static RenderingHints getRenderingHints(Graphics2D g2d, public static RenderingHints getRenderingHints(Graphics2D g2d,
Map<?, ?> hintsToSave, Map<?, ?> hintsToSave,
RenderingHints savedHints) { RenderingHints savedHints) {
if (savedHints == null) { if (savedHints == null)
savedHints = new RenderingHints(null); savedHints = new RenderingHints(null);
} else { else
savedHints.clear(); savedHints.clear();
} if (hintsToSave.isEmpty())
if (hintsToSave.isEmpty()) {
return savedHints; return savedHints;
}
/* RenderingHints.keySet() returns Set */ /* RenderingHints.keySet() returns Set */
for (Object o : hintsToSave.keySet()) { for (Object o : hintsToSave.keySet()) {
RenderingHints.Key key = (RenderingHints.Key) o; RenderingHints.Key key = (RenderingHints.Key) o;
@ -82,13 +82,12 @@ public class GraphicsUtils extends SynthGraphicsUtils {
super.paintText(ss, g, text, x, y, mnemonicIndex); super.paintText(ss, g, text, x, y, mnemonicIndex);
if (oldHints != null) { if (oldHints != null)
g2.addRenderingHints(oldHints); g2.addRenderingHints(oldHints);
} else if (oldAA != null) { else if (oldAA != null)
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
oldAA); oldAA);
} }
}
/** /**
* Load an image using ImageIO from resource in * Load an image using ImageIO from resource in
@ -96,6 +95,7 @@ public class GraphicsUtils extends SynthGraphicsUtils {
* so that it can safely be used in a static context. * so that it can safely be used in a static context.
* *
* @param imgName The name of the image to load, eg. "border.png" * @param imgName The name of the image to load, eg. "border.png"
*
* @return The loaded image * @return The loaded image
*/ */
public static BufferedImage loadImage(String imgName) { public static BufferedImage loadImage(String imgName) {
@ -108,17 +108,21 @@ public class GraphicsUtils extends SynthGraphicsUtils {
return null; return null;
} }
public static String getColor(Color c) {
return Integer.toHexString(c.getRGB() & 0xFFFFFF);
}
/** /**
* Get a Color object from a web color string of the form "FF00AB" or * Get a Color object from a web color string of the form "FF00AB" or
* "#FF00AB". * "#FF00AB".
* *
* @param c The color string * @param c The color string
*
* @return The Color described * @return The Color described
*/ */
public static Color getWebColor(String c) { public static Color getWebColor(String c) {
if (c.startsWith("#")) { if (c.startsWith("#"))
c = c.substring(1); c = c.substring(1);
}
return new Color( return new Color(
Integer.parseInt(c.substring(0, 2), 16), Integer.parseInt(c.substring(0, 2), 16),
Integer.parseInt(c.substring(2, 4), 16), Integer.parseInt(c.substring(2, 4), 16),
@ -131,12 +135,12 @@ public class GraphicsUtils extends SynthGraphicsUtils {
* "#FF00AB". * "#FF00AB".
* *
* @param c The color string * @param c The color string
*
* @return The Color described * @return The Color described
*/ */
public static Color getWebColorWithAlpha(String c) { public static Color getWebColorWithAlpha(String c) {
if (c.startsWith("#")) { if (c.startsWith("#"))
c = c.substring(1); c = c.substring(1);
}
return new Color( return new Color(
Integer.parseInt(c.substring(0, 2), 16), Integer.parseInt(c.substring(0, 2), 16),
Integer.parseInt(c.substring(2, 4), 16), Integer.parseInt(c.substring(2, 4), 16),
@ -151,6 +155,7 @@ public class GraphicsUtils extends SynthGraphicsUtils {
* *
* @param c1 The first color string * @param c1 The first color string
* @param c2 The second color string * @param c2 The second color string
*
* @return The Color middle color * @return The Color middle color
*/ */
public static Color getMidWebColor(String c1, String c2) { public static Color getMidWebColor(String c1, String c2) {
@ -163,15 +168,14 @@ public class GraphicsUtils extends SynthGraphicsUtils {
* *
* @param c1 The first color string * @param c1 The first color string
* @param c2 The second color string * @param c2 The second color string
*
* @return The Color middle color * @return The Color middle color
*/ */
public static Color getMidWebColor(String c1, String c2, int percent) { public static Color getMidWebColor(String c1, String c2, int percent) {
if (c1.startsWith("#")) { if (c1.startsWith("#"))
c1 = c1.substring(1); c1 = c1.substring(1);
} if (c2.startsWith("#"))
if (c2.startsWith("#")) {
c2 = c2.substring(1); c2 = c2.substring(1);
}
int rTop = Integer.parseInt(c1.substring(0, 2), 16); int rTop = Integer.parseInt(c1.substring(0, 2), 16);
int gTop = Integer.parseInt(c1.substring(2, 4), 16); int gTop = Integer.parseInt(c1.substring(2, 4), 16);
int bTop = Integer.parseInt(c1.substring(4, 6), 16); int bTop = Integer.parseInt(c1.substring(4, 6), 16);

View File

@ -33,31 +33,6 @@ public class LogWindowOutputStream extends OutputStream {
private final LogWindow txt; private final LogWindow txt;
private final Level sas; private final Level sas;
/*
* private final CacheTask t = new CacheTask();
* private class CacheTask extends TimerTask {
* private final Object lock = new Object();
* private StringBuilder cachedString = new StringBuilder();
*
* @Override
* public void run() {
* synchronized(lock) {
* SwingUtilities.invokeLater(() -> {
* String t = txt.getText() + cachedString.toString().replace("\t", " ");
* txt.setText(t);
* txt.setCaretPosition(t.length());
* cachedString = new StringBuilder();
* });
* }
* }
*
* void cache(String s) {
* synchronized(lock) {
* cachedString.append(s);
* }
* }
* }
*/
public LogWindowOutputStream(LogWindow logWindow, Level l) { public LogWindowOutputStream(LogWindow logWindow, Level l) {
txt = logWindow; txt = logWindow;
this.sas = l; this.sas = l;

View File

@ -0,0 +1,85 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.ui;
import java.awt.Frame;
import java.awt.HeadlessException;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.List;
import javax.swing.JFrame;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.logging.Level;
/**
*
* @author huangyuhui
*/
public class WebFrame extends JFrame {
public WebFrame(String... strs) {
this(("<html>" + StrUtils.parseParams(t -> ("<font color='#" + GraphicsUtils.getColor(Level.guessLevel((String) t, Level.INFO).COLOR) + "'>"), strs, t -> "</font><br />") + "</html>")
.replace(" ", "&nbsp;").replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;"));
}
public WebFrame(String content) throws HeadlessException {
addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
boolean flag = false;
for (Frame f : Frame.getFrames()) {
if (f == WebFrame.this)
continue;
if (f.isVisible())
flag = true;
}
if (!flag)
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
add(new WebPage(content));
pack();
setLocationRelativeTo(null);
}
}

View File

@ -17,7 +17,7 @@
package org.jackhuang.hellominecraft.lookandfeel.comp; package org.jackhuang.hellominecraft.lookandfeel.comp;
import java.awt.Color; import java.awt.Color;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils; import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
/** /**
* *

View File

@ -30,7 +30,7 @@ import javax.swing.SwingUtilities;
import javax.swing.plaf.synth.SynthConstants; import javax.swing.plaf.synth.SynthConstants;
import javax.swing.plaf.synth.SynthContext; import javax.swing.plaf.synth.SynthContext;
import javax.swing.plaf.synth.SynthPainter; import javax.swing.plaf.synth.SynthPainter;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils; import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton; import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton;
/** /**

View File

@ -20,7 +20,7 @@
*/ */
package org.jackhuang.hellominecraft.lookandfeel.painter; package org.jackhuang.hellominecraft.lookandfeel.painter;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils; import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
import javax.swing.plaf.synth.SynthContext; import javax.swing.plaf.synth.SynthContext;
import javax.swing.plaf.synth.SynthPainter; import javax.swing.plaf.synth.SynthPainter;

View File

@ -25,7 +25,7 @@ import javax.swing.plaf.synth.SynthPainter;
import java.awt.Color; import java.awt.Color;
import java.awt.Graphics; import java.awt.Graphics;
import javax.swing.plaf.synth.SynthConstants; import javax.swing.plaf.synth.SynthConstants;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils; import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
/** /**
* TextFieldPainter * TextFieldPainter

View File

@ -1,6 +1,6 @@
package org.jackhuang.hellominecraft.lookandfeel.ui; package org.jackhuang.hellominecraft.lookandfeel.ui;
import static org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils.loadImage; import static org.jackhuang.hellominecraft.util.ui.GraphicsUtils.loadImage;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicComboBoxUI; import javax.swing.plaf.basic.BasicComboBoxUI;

View File

@ -4,7 +4,7 @@
*/ */
package org.jackhuang.hellominecraft.lookandfeel.ui; package org.jackhuang.hellominecraft.lookandfeel.ui;
import static org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils.loadImage; import static org.jackhuang.hellominecraft.util.ui.GraphicsUtils.loadImage;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JComponent; import javax.swing.JComponent;

View File

@ -26,7 +26,7 @@
<color value="#9CC5D8" type="TEXT_BACKGROUND"/> <color value="#9CC5D8" type="TEXT_BACKGROUND"/>
<font name="微软雅黑" size="12" /> <font name="微软雅黑" size="12" />
</state> </state>
<object id="GraphicsUtils" class="org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils"/> <object id="GraphicsUtils" class="org.jackhuang.hellominecraft.util.ui.GraphicsUtils"/>
<graphicsUtils idref="GraphicsUtils"/> <graphicsUtils idref="GraphicsUtils"/>
</style> </style>
<bind style="default" type="region" key=".*"/> <bind style="default" type="region" key=".*"/>

View File

@ -26,7 +26,7 @@
<color value="#9CC5D8" type="TEXT_BACKGROUND"/> <color value="#9CC5D8" type="TEXT_BACKGROUND"/>
<font name="微软雅黑" size="12" /> <font name="微软雅黑" size="12" />
</state> </state>
<object id="GraphicsUtils" class="org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils"/> <object id="GraphicsUtils" class="org.jackhuang.hellominecraft.util.ui.GraphicsUtils"/>
<graphicsUtils idref="GraphicsUtils"/> <graphicsUtils idref="GraphicsUtils"/>
</style> </style>
<bind style="default" type="region" key=".*"/> <bind style="default" type="region" key=".*"/>