Modify logging system
This commit is contained in:
@@ -167,7 +167,7 @@ public abstract class GameLauncher {
|
||||
ProcessBuilder builder = new ProcessBuilder(str);
|
||||
if (options.getLaunchVersion() == null || service.baseDirectory() == null)
|
||||
throw new Error("Fucking bug!");
|
||||
builder.redirectErrorStream(true).directory(service.version().getRunDirectory(options.getLaunchVersion()))
|
||||
builder.directory(service.version().getRunDirectory(options.getLaunchVersion()))
|
||||
.environment().put("APPDATA", service.baseDirectory().getAbsolutePath());
|
||||
JavaProcess jp = new JavaProcess(str, builder.start());
|
||||
HMCLog.log("Have started the process");
|
||||
|
||||
@@ -50,7 +50,8 @@ public enum Level {
|
||||
public static final Pattern MINECRAFT_LOGGER = Pattern.compile("\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]");
|
||||
public static final String JAVA_SYMBOL = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*";
|
||||
|
||||
public static Level guessLevel(String line, Level level) {
|
||||
public static Level guessLevel(String line, Level preLevel) {
|
||||
Level level = preLevel;
|
||||
Matcher m = MINECRAFT_LOGGER.matcher(line);
|
||||
if (m.find()) {
|
||||
// New style logs from log4j
|
||||
@@ -98,7 +99,7 @@ public enum Level {
|
||||
|| line.matches("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)")
|
||||
|| line.matches("... \\d+ more$"))
|
||||
return ERROR;
|
||||
return level;
|
||||
return preLevel.level < level.level ? preLevel : level;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ package org.jackhuang.hmcl.util.sys;
|
||||
import org.jackhuang.hmcl.api.IProcess;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -28,7 +27,6 @@ import java.util.List;
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class JavaProcess implements IProcess {
|
||||
public static HashSet<Process> processes = new HashSet<>();
|
||||
|
||||
private final List<String> commands;
|
||||
private final Process process;
|
||||
@@ -37,7 +35,6 @@ public class JavaProcess implements IProcess {
|
||||
public JavaProcess(List<String> commands, Process process) {
|
||||
this.commands = commands;
|
||||
this.process = process;
|
||||
processes.add(process);
|
||||
}
|
||||
|
||||
public JavaProcess(String[] commands, Process process) {
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.jackhuang.hmcl.util.sys;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import org.jackhuang.hmcl.util.CollectionUtils;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.process.JVMLaunchFailedEvent;
|
||||
import org.jackhuang.hmcl.api.event.process.JavaProcessExitedAbnormallyEvent;
|
||||
@@ -36,7 +35,9 @@ import org.jackhuang.hmcl.api.IProcess;
|
||||
*/
|
||||
public class ProcessMonitor {
|
||||
|
||||
private final HashSet<Thread> al = new HashSet<>();
|
||||
public static final HashSet<ProcessMonitor> MONITORS = new HashSet<>();
|
||||
|
||||
ProcessThread inputThread, errorThread;
|
||||
private final IProcess p;
|
||||
|
||||
public ProcessMonitor(IProcess p) {
|
||||
@@ -46,7 +47,7 @@ public class ProcessMonitor {
|
||||
public IProcess getProcess() {
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
private Object tag;
|
||||
|
||||
public Object getTag() {
|
||||
@@ -56,36 +57,44 @@ public class ProcessMonitor {
|
||||
public void setTag(Object tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
|
||||
public void start() {
|
||||
MONITORS.add(this);
|
||||
HMCLApi.EVENT_BUS.fireChannel(new JavaProcessStartingEvent(this, p));
|
||||
ProcessThread a = new ProcessThread(p);
|
||||
a.stopEvent.register(event -> {
|
||||
HMCLog.log("Process exit code: " + p.getExitCode());
|
||||
if (p.getExitCode() != 0 || StrUtils.containsOne(p.getStdOutLines(),
|
||||
Arrays.asList("Unable to launch"),
|
||||
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
|
||||
HMCLApi.EVENT_BUS.fireChannel(new JavaProcessExitedAbnormallyEvent(ProcessMonitor.this, p));
|
||||
if (p.getExitCode() != 0 && StrUtils.containsOne(p.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)))
|
||||
HMCLApi.EVENT_BUS.fireChannel(new JVMLaunchFailedEvent(ProcessMonitor.this, p));
|
||||
processThreadStopped((ProcessThread) event.getSource(), false);
|
||||
});
|
||||
a.start();
|
||||
al.add(a);
|
||||
inputThread = new ProcessThread(p, false);
|
||||
errorThread = new ProcessThread(p, true);
|
||||
inputThread.stopEvent.register(this::threadStopped);
|
||||
inputThread.stopEvent.register(event -> processThreadStopped((ProcessThread) event.getSource()));
|
||||
errorThread.stopEvent.register(this::threadStopped);
|
||||
inputThread.start();
|
||||
}
|
||||
|
||||
void processThreadStopped(ProcessThread t1, boolean forceTermintate) {
|
||||
CollectionUtils.removeIf(al, t -> t == t1 || !t.isAlive());
|
||||
if (al.isEmpty() || forceTermintate) {
|
||||
for (Thread a : al)
|
||||
a.interrupt();
|
||||
al.clear();
|
||||
HMCLApi.EVENT_BUS.fireChannel(new JavaProcessStoppedEvent(this, p));
|
||||
private void threadStopped() {
|
||||
HMCLog.log("Process exit code: " + p.getExitCode());
|
||||
if (p.getExitCode() != 0 || StrUtils.containsOne(p.getStdOutLines(),
|
||||
Arrays.asList("Unable to launch"),
|
||||
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
|
||||
HMCLApi.EVENT_BUS.fireChannel(new JavaProcessExitedAbnormallyEvent(ProcessMonitor.this, p));
|
||||
if (p.getExitCode() != 0 && StrUtils.containsOne(p.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)))
|
||||
HMCLApi.EVENT_BUS.fireChannel(new JVMLaunchFailedEvent(ProcessMonitor.this, p));
|
||||
}
|
||||
|
||||
private void processThreadStopped(ProcessThread t1) {
|
||||
MONITORS.remove(this);
|
||||
errorThread.interrupt();
|
||||
HMCLApi.EVENT_BUS.fireChannel(new JavaProcessStoppedEvent(this, p));
|
||||
}
|
||||
|
||||
public static void stopAll() {
|
||||
for (ProcessMonitor monitor : MONITORS) {
|
||||
monitor.getProcess().getRawProcess().destroy();
|
||||
monitor.inputThread.interrupt();
|
||||
monitor.errorThread.interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,12 +34,14 @@ import org.jackhuang.hmcl.api.IProcess;
|
||||
public class ProcessThread extends Thread {
|
||||
|
||||
IProcess p;
|
||||
|
||||
boolean readError;
|
||||
public final EventHandler<SimpleEvent<String>> printlnEvent = new EventHandler<>();
|
||||
public final EventHandler<SimpleEvent<IProcess>> stopEvent = new EventHandler<>();
|
||||
|
||||
public ProcessThread(IProcess process) {
|
||||
public ProcessThread(IProcess process, boolean readError) {
|
||||
p = process;
|
||||
this.readError = readError;
|
||||
setDaemon(readError);
|
||||
}
|
||||
|
||||
public IProcess getProcess() {
|
||||
@@ -51,7 +53,7 @@ public class ProcessThread extends Thread {
|
||||
setName("ProcessMonitor");
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
InputStream in = p.getRawProcess().getInputStream();
|
||||
InputStream in = readError ? p.getRawProcess().getErrorStream() : p.getRawProcess().getInputStream();
|
||||
br = new BufferedReader(new InputStreamReader(in, Charsets.toCharset()));
|
||||
|
||||
String line;
|
||||
@@ -66,7 +68,6 @@ public class ProcessThread extends Thread {
|
||||
System.out.println("MC: " + line);
|
||||
p.getStdOutLines().add(line);
|
||||
}
|
||||
JavaProcess.processes.remove(p.getRawProcess());
|
||||
stopEvent.fire(new SimpleEvent<>(this, p));
|
||||
} catch (IOException e) {
|
||||
HMCLog.err("An error occured when reading process stdout/stderr.", e);
|
||||
|
||||
Reference in New Issue
Block a user