mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-02-23 17:19:44 +08:00
Might fix game log watcher?
This commit is contained in:
parent
cb125b83cb
commit
afecb87c6d
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher
HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util
MetroLookAndFeel/src/main
java/org/jackhuang/hellominecraft/lookandfeel
comp
painter
ui
resources/org/jackhuang/hellominecraft/lookandfeel
@ -26,16 +26,11 @@ import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.ui.LogWindow;
|
||||
import org.jackhuang.hellominecraft.launcher.util.MinecraftCrashAdvicer;
|
||||
import org.jackhuang.hellominecraft.util.DoubleOutputStream;
|
||||
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;
|
||||
|
||||
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 {
|
||||
File logFile = new File("hmclmc.log");
|
||||
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, "Main Class: {0}", mainClass);
|
||||
LOGGER.log(Level.INFO, "Class Path: '{'\n{0}\n'}'", StrUtils.parseParams(" ", tokenized, "\n"));
|
||||
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.setVisible(true));
|
||||
}
|
||||
|
||||
URL[] urls = new URL[len];
|
||||
@ -104,7 +90,6 @@ public final class Launcher {
|
||||
for (int j = 0; j < len; j++)
|
||||
urls[j] = new File(tokenized[j]).toURI().toURL();
|
||||
} catch (Throwable e) {
|
||||
MessageBox.Show(C.i18n("crash.main_class_not_found"));
|
||||
LOGGER.log(Level.SEVERE, "Failed to get classpath.", e);
|
||||
return;
|
||||
}
|
||||
@ -115,48 +100,21 @@ public final class Launcher {
|
||||
try {
|
||||
minecraftMain = ucl.loadClass(mainClass).getMethod("main", String[].class);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException t) {
|
||||
MessageBox.Show(C.i18n("crash.main_class_not_found"));
|
||||
LOGGER.log(Level.SEVERE, "Minecraft main class not found.", t);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("*** Launching Game ***");
|
||||
|
||||
int flag = 0;
|
||||
try {
|
||||
minecraftMain.invoke(null, new Object[] { (String[]) cmdList.toArray(new String[cmdList.size()]) });
|
||||
} catch (Throwable 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(advice);
|
||||
System.err.println(MinecraftCrashAdvicer.getAdvice(trace));
|
||||
System.err.println(trace);
|
||||
LogWindow.INSTANCE.setExit(() -> true);
|
||||
LogWindow.INSTANCE.setVisible(true);
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
LOGGER.info("*** Game exited ***");
|
||||
}
|
||||
/*
|
||||
* 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();
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
|
||||
/**
|
||||
@ -26,12 +27,13 @@ import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
*/
|
||||
public class DownloadLibraryJob {
|
||||
|
||||
public String url, name;
|
||||
public IMinecraftLibrary lib;
|
||||
public String url;
|
||||
public File path;
|
||||
|
||||
public DownloadLibraryJob(String n, String u, File p) {
|
||||
public DownloadLibraryJob(IMinecraftLibrary n, String u, File p) {
|
||||
url = u;
|
||||
name = n;
|
||||
lib = n;
|
||||
path = IOUtils.tryGetCanonicalFile(p);
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
|
||||
String libURL = service.getDownloadType().getProvider().getLibraryDownloadURL() + "/";
|
||||
libURL = service.getDownloadType().getProvider().getParsedLibraryDownloadURL(l.getDownloadURL(libURL, service.getDownloadType()));
|
||||
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;
|
||||
}
|
||||
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");
|
||||
if (gdi != null) {
|
||||
if (gdi.url != null)
|
||||
|
@ -17,7 +17,9 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import java.util.Locale;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.util.lang.SupportedLocales;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -72,7 +74,15 @@ public class MojangDownloadProvider extends IDownloadProvider {
|
||||
|
||||
@Override
|
||||
public String getParsedLibraryDownloadURL(String str) {
|
||||
return 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,9 +43,9 @@ public class DefaultGameLauncher extends GameLauncher {
|
||||
ParallelTask parallelTask = new ParallelTask();
|
||||
HashSet<String> names = new HashSet<>();
|
||||
for (DownloadLibraryJob s : t) {
|
||||
if (names.contains(s.name))
|
||||
if (names.contains(s.lib.name))
|
||||
continue;
|
||||
names.add(s.name);
|
||||
names.add(s.lib.name);
|
||||
parallelTask.addDependsTask(new LibraryDownloadTask(s));
|
||||
}
|
||||
dw.append(parallelTask);
|
||||
|
@ -128,7 +128,7 @@ public class GameLauncher {
|
||||
ProcessBuilder builder = new ProcessBuilder(str);
|
||||
if (options.getLaunchVersion() == null || service.baseDirectory() == null)
|
||||
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());
|
||||
JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER);
|
||||
HMCLog.log("The game process have been started");
|
||||
|
@ -38,13 +38,14 @@ public class LibraryDownloadTask extends FileDownloadTask {
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
if (job.name.startsWith("net.minecraftforge:forge:")) {
|
||||
String[] s = job.name.split(":");
|
||||
String name = job.lib.name;
|
||||
if (name.startsWith("net.minecraftforge:forge:")) {
|
||||
String[] s = name.split(":");
|
||||
if (s.length == 3)
|
||||
job.url = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" + s[2] + "/forge-" + s[2] + "-universal.jar";
|
||||
}
|
||||
if (job.name.startsWith("com.mumfrey:liteloader:")) {
|
||||
String[] s = job.name.split(":");
|
||||
if (name.startsWith("com.mumfrey:liteloader:")) {
|
||||
String[] s = name.split(":");
|
||||
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";
|
||||
}
|
||||
@ -59,7 +60,7 @@ public class LibraryDownloadTask extends FileDownloadTask {
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("download") + ": " + job.name;
|
||||
return C.i18n("download") + ": " + job.lib.name;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,9 +21,17 @@ package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class GameDownloadInfo {
|
||||
public class GameDownloadInfo implements Cloneable {
|
||||
|
||||
public String sha1, url;
|
||||
public int size;
|
||||
|
||||
@Override
|
||||
protected Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new Error(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -40,7 +40,7 @@ public class MinecraftLibrary extends IMinecraftLibrary {
|
||||
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);
|
||||
this.rules = rules == null ? null : (ArrayList<Rules>) rules.clone();
|
||||
this.url = url;
|
||||
|
@ -60,7 +60,8 @@ public class VersionSetting {
|
||||
|
||||
public VersionSetting() {
|
||||
debug = fullscreen = canceledWrapper = false;
|
||||
launcherVisibility = gameDirType = 0;
|
||||
launcherVisibility = 1;
|
||||
gameDirType = 0;
|
||||
javaDir = java = minecraftArgs = serverIp = precalledCommand = "";
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ import org.jackhuang.hellominecraft.util.MessageBox;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.system.JavaProcessMonitor;
|
||||
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);
|
||||
jpm.applicationExitedAbnormallyEvent.register(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 -> {
|
||||
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(() -> {
|
||||
if ((LauncherVisibility) obj.getTag() != LauncherVisibility.KEEP && !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\".");
|
||||
if ((LauncherVisibility) obj.getTag() == LauncherVisibility.CLOSE && !LogWindow.INSTANCE.isVisible()) {
|
||||
HMCLog.log("With the option of closing the launcher anyway, the launcher will exit and will NOT catch game logs.");
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
|
@ -48,7 +48,7 @@ import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
||||
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.util.MessageBox;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
|
@ -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.service.IMinecraftService;
|
||||
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.lookandfeel.comp.ConstomButton;
|
||||
import org.jackhuang.hellominecraft.util.func.Consumer;
|
||||
|
@ -25,6 +25,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
int res = 0;
|
||||
for (int i = 0; i < s.length(); i++)
|
||||
@ -141,33 +151,37 @@ public final class StrUtils {
|
||||
return parseParams(addBefore, paramArrayOfObject.toArray(), paramString);
|
||||
}
|
||||
|
||||
public static String parseParams(String addBefore, Object[] paramArrayOfObject, String paramString) {
|
||||
if (paramArrayOfObject == null)
|
||||
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("[");
|
||||
public static String parseParams(String addBefore, Object[] params, String addAfter) {
|
||||
return parseParams(t -> addBefore, params, t -> addAfter);
|
||||
}
|
||||
|
||||
if ((localObject instanceof Object[])) {
|
||||
Object[] arrayOfObject = (Object[]) localObject;
|
||||
localStringBuffer.append(parseParams(addBefore, arrayOfObject, paramString));
|
||||
public static String parseParams(Function<Object, String> beforeFunc, Object[] params, Function<Object, String> afterFunc) {
|
||||
if (params == null)
|
||||
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
|
||||
for (int j = 0; j < Array.getLength(localObject); j++) {
|
||||
for (int j = 0; j < Array.getLength(param); j++) {
|
||||
if (j > 0)
|
||||
localStringBuffer.append(paramString);
|
||||
localStringBuffer.append(addBefore).append(Array.get(localObject, j));
|
||||
sb.append(addAfter);
|
||||
sb.append(addBefore).append(Array.get(param, j));
|
||||
}
|
||||
localStringBuffer.append("]");
|
||||
sb.append("]");
|
||||
} 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) {
|
||||
|
@ -30,7 +30,6 @@ public class JavaProcess {
|
||||
private final List<String> commands;
|
||||
private final Process process;
|
||||
private final ArrayList<String> stdOutLines = new ArrayList<>();
|
||||
private final ArrayList<String> stdErrLines = new ArrayList<>();
|
||||
|
||||
public JavaProcess(List<String> commands, Process process, ProcessManager pm) {
|
||||
this.commands = commands;
|
||||
@ -59,10 +58,6 @@ public class JavaProcess {
|
||||
return this.stdOutLines;
|
||||
}
|
||||
|
||||
public ArrayList<String> getStdErrLines() {
|
||||
return this.stdErrLines;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
try {
|
||||
this.process.exitValue();
|
||||
|
@ -20,9 +20,10 @@ package org.jackhuang.hellominecraft.util.system;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import org.jackhuang.hellominecraft.util.CollectionUtils;
|
||||
import org.jackhuang.hellominecraft.util.Event;
|
||||
import org.jackhuang.hellominecraft.util.EventHandler;
|
||||
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;
|
||||
}
|
||||
|
||||
public JavaProcess getJavaProcess() {
|
||||
return p;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
Event<JavaProcess> event = (sender2, t) -> {
|
||||
if (t.getExitCode() != 0)
|
||||
ProcessThread a = new ProcessThread(p);
|
||||
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());
|
||||
processThreadStopped((ProcessThread) sender2, false);
|
||||
if (t.getExitCode() != 0 && StrUtils.containsOne(t.getStdOutLines(),
|
||||
Arrays.asList("Could not create the Java Virtual Machine.",
|
||||
"Error occurred during initialization of VM",
|
||||
"A fatal exception has occurred. Program will exit.",
|
||||
"Unable to launch"),
|
||||
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
|
||||
jvmLaunchFailedEvent.execute(t.getExitCode());
|
||||
processThreadStopped((ProcessThread) sender, false);
|
||||
return true;
|
||||
};
|
||||
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",
|
||||
"A fatal exception has occurred. Program will exit.")))
|
||||
jvmLaunchFailedEvent.execute(p1.getExitCode());
|
||||
processThreadStopped((ProcessThread) sender3, false);
|
||||
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();
|
||||
al.add(a);
|
||||
}
|
||||
|
@ -30,15 +30,12 @@ import org.jackhuang.hellominecraft.util.EventHandler;
|
||||
public class ProcessThread extends Thread {
|
||||
|
||||
JavaProcess p;
|
||||
boolean readError = false, enableReading = true;
|
||||
|
||||
public final EventHandler<String> printlnEvent = 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;
|
||||
this.readError = readError;
|
||||
this.enableReading = enableReading;
|
||||
}
|
||||
|
||||
public JavaProcess getProcess() {
|
||||
@ -47,58 +44,33 @@ public class ProcessThread extends Thread {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setName("ProcessMonitor");
|
||||
InputStreamReader br = null;
|
||||
try {
|
||||
InputStreamReader br;
|
||||
if (enableReading) {
|
||||
InputStream in = readError ? p.getRawProcess().getErrorStream() : p.getRawProcess().getInputStream();
|
||||
try {
|
||||
br = new InputStreamReader(in, System.getProperty("sun.jnu.encoding", "UTF-8"));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
HMCLog.warn("Unsupported encoding: " + System.getProperty("sun.jnu.encoding", "UTF-8"), ex);
|
||||
br = new InputStreamReader(in);
|
||||
}
|
||||
} else
|
||||
br = null;
|
||||
InputStream in = p.getRawProcess().getInputStream();
|
||||
try {
|
||||
br = new InputStreamReader(in, System.getProperty("sun.jnu.encoding", "UTF-8"));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
HMCLog.warn("Unsupported encoding: " + System.getProperty("sun.jnu.encoding", "UTF-8"), ex);
|
||||
br = new InputStreamReader(in);
|
||||
}
|
||||
|
||||
int ch;
|
||||
String line = "";
|
||||
while (p.isRunning())
|
||||
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 = "";
|
||||
} 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);
|
||||
}
|
||||
System.out.println("Minecraft: " + line);
|
||||
p.getStdOutLines().add(line);
|
||||
line = "";
|
||||
} else
|
||||
line += (char) ch;
|
||||
stopEvent.execute(p);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
HMCLog.err("An error occured when reading process stdout/stderr.", e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(br);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package org.jackhuang.hellominecraft.lookandfeel;
|
||||
package org.jackhuang.hellominecraft.util.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
@ -28,23 +28,23 @@ public class GraphicsUtils extends SynthGraphicsUtils {
|
||||
* value of that hint is obtained from the Graphics and stored as the value
|
||||
* for the key in savedHints.
|
||||
*
|
||||
* @param g2d the graphics surface
|
||||
* @param g2d the graphics surface
|
||||
* @param hintsToSave the list of rendering hints to set on the graphics
|
||||
* @param savedHints a set where to save the previous rendering hints, might
|
||||
* be null
|
||||
* @param savedHints a set where to save the previous rendering hints,
|
||||
* might
|
||||
* be null
|
||||
*
|
||||
* @return the previous set of rendering hints
|
||||
*/
|
||||
public static RenderingHints getRenderingHints(Graphics2D g2d,
|
||||
Map<?, ?> hintsToSave,
|
||||
RenderingHints savedHints) {
|
||||
if (savedHints == null) {
|
||||
Map<?, ?> hintsToSave,
|
||||
RenderingHints savedHints) {
|
||||
if (savedHints == null)
|
||||
savedHints = new RenderingHints(null);
|
||||
} else {
|
||||
else
|
||||
savedHints.clear();
|
||||
}
|
||||
if (hintsToSave.isEmpty()) {
|
||||
if (hintsToSave.isEmpty())
|
||||
return savedHints;
|
||||
}
|
||||
/* RenderingHints.keySet() returns Set */
|
||||
for (Object o : hintsToSave.keySet()) {
|
||||
RenderingHints.Key key = (RenderingHints.Key) o;
|
||||
@ -77,17 +77,16 @@ public class GraphicsUtils extends SynthGraphicsUtils {
|
||||
} else {
|
||||
oldAA = g2.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
|
||||
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
}
|
||||
|
||||
super.paintText(ss, g, text, x, y, mnemonicIndex);
|
||||
|
||||
if (oldHints != null) {
|
||||
if (oldHints != null)
|
||||
g2.addRenderingHints(oldHints);
|
||||
} else if (oldAA != null) {
|
||||
else if (oldAA != null)
|
||||
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
oldAA);
|
||||
}
|
||||
oldAA);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,6 +95,7 @@ public class GraphicsUtils extends SynthGraphicsUtils {
|
||||
* so that it can safely be used in a static context.
|
||||
*
|
||||
* @param imgName The name of the image to load, eg. "border.png"
|
||||
*
|
||||
* @return The loaded image
|
||||
*/
|
||||
public static BufferedImage loadImage(String imgName) {
|
||||
@ -108,21 +108,25 @@ public class GraphicsUtils extends SynthGraphicsUtils {
|
||||
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
|
||||
* "#FF00AB".
|
||||
*
|
||||
* @param c The color string
|
||||
*
|
||||
* @return The Color described
|
||||
*/
|
||||
public static Color getWebColor(String c) {
|
||||
if (c.startsWith("#")) {
|
||||
if (c.startsWith("#"))
|
||||
c = c.substring(1);
|
||||
}
|
||||
return new Color(
|
||||
Integer.parseInt(c.substring(0, 2), 16),
|
||||
Integer.parseInt(c.substring(2, 4), 16),
|
||||
Integer.parseInt(c.substring(4, 6), 16)
|
||||
Integer.parseInt(c.substring(0, 2), 16),
|
||||
Integer.parseInt(c.substring(2, 4), 16),
|
||||
Integer.parseInt(c.substring(4, 6), 16)
|
||||
);
|
||||
}
|
||||
|
||||
@ -131,17 +135,17 @@ public class GraphicsUtils extends SynthGraphicsUtils {
|
||||
* "#FF00AB".
|
||||
*
|
||||
* @param c The color string
|
||||
*
|
||||
* @return The Color described
|
||||
*/
|
||||
public static Color getWebColorWithAlpha(String c) {
|
||||
if (c.startsWith("#")) {
|
||||
if (c.startsWith("#"))
|
||||
c = c.substring(1);
|
||||
}
|
||||
return new Color(
|
||||
Integer.parseInt(c.substring(0, 2), 16),
|
||||
Integer.parseInt(c.substring(2, 4), 16),
|
||||
Integer.parseInt(c.substring(4, 6), 16),
|
||||
Integer.parseInt(c.substring(6, 8), 16)
|
||||
Integer.parseInt(c.substring(0, 2), 16),
|
||||
Integer.parseInt(c.substring(2, 4), 16),
|
||||
Integer.parseInt(c.substring(4, 6), 16),
|
||||
Integer.parseInt(c.substring(6, 8), 16)
|
||||
);
|
||||
}
|
||||
|
||||
@ -151,6 +155,7 @@ public class GraphicsUtils extends SynthGraphicsUtils {
|
||||
*
|
||||
* @param c1 The first color string
|
||||
* @param c2 The second color string
|
||||
*
|
||||
* @return The Color middle color
|
||||
*/
|
||||
public static Color getMidWebColor(String c1, String c2) {
|
||||
@ -163,15 +168,14 @@ public class GraphicsUtils extends SynthGraphicsUtils {
|
||||
*
|
||||
* @param c1 The first color string
|
||||
* @param c2 The second color string
|
||||
*
|
||||
* @return The Color middle color
|
||||
*/
|
||||
public static Color getMidWebColor(String c1, String c2, int percent) {
|
||||
if (c1.startsWith("#")) {
|
||||
if (c1.startsWith("#"))
|
||||
c1 = c1.substring(1);
|
||||
}
|
||||
if (c2.startsWith("#")) {
|
||||
if (c2.startsWith("#"))
|
||||
c2 = c2.substring(1);
|
||||
}
|
||||
int rTop = Integer.parseInt(c1.substring(0, 2), 16);
|
||||
int gTop = Integer.parseInt(c1.substring(2, 4), 16);
|
||||
int bTop = Integer.parseInt(c1.substring(4, 6), 16);
|
@ -33,31 +33,6 @@ public class LogWindowOutputStream extends OutputStream {
|
||||
private final LogWindow txt;
|
||||
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) {
|
||||
txt = logWindow;
|
||||
this.sas = l;
|
||||
|
@ -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(" ", " ").replace("\t", " "));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
package org.jackhuang.hellominecraft.lookandfeel.comp;
|
||||
|
||||
import java.awt.Color;
|
||||
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils;
|
||||
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -30,7 +30,7 @@ import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.synth.SynthConstants;
|
||||
import javax.swing.plaf.synth.SynthContext;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
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.SynthPainter;
|
||||
|
@ -25,7 +25,7 @@ import javax.swing.plaf.synth.SynthPainter;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.plaf.synth.SynthConstants;
|
||||
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils;
|
||||
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
|
||||
|
||||
/**
|
||||
* TextFieldPainter
|
||||
|
@ -1,6 +1,6 @@
|
||||
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.basic.BasicComboBoxUI;
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
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.JComponent;
|
||||
|
@ -26,7 +26,7 @@
|
||||
<color value="#9CC5D8" type="TEXT_BACKGROUND"/>
|
||||
<font name="微软雅黑" size="12" />
|
||||
</state>
|
||||
<object id="GraphicsUtils" class="org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils"/>
|
||||
<object id="GraphicsUtils" class="org.jackhuang.hellominecraft.util.ui.GraphicsUtils"/>
|
||||
<graphicsUtils idref="GraphicsUtils"/>
|
||||
</style>
|
||||
<bind style="default" type="region" key=".*"/>
|
||||
|
@ -26,7 +26,7 @@
|
||||
<color value="#9CC5D8" type="TEXT_BACKGROUND"/>
|
||||
<font name="微软雅黑" size="12" />
|
||||
</state>
|
||||
<object id="GraphicsUtils" class="org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils"/>
|
||||
<object id="GraphicsUtils" class="org.jackhuang.hellominecraft.util.ui.GraphicsUtils"/>
|
||||
<graphicsUtils idref="GraphicsUtils"/>
|
||||
</style>
|
||||
<bind style="default" type="region" key=".*"/>
|
||||
|
Loading…
Reference in New Issue
Block a user