mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-14 06:17:47 -04:00
Optimization HMCLProcessListener::onLog (#1867)
This commit is contained in:
parent
2e532be34c
commit
e1eb40c129
@ -685,7 +685,7 @@ public final class LauncherHelper {
|
||||
* Guarantee that one [JavaProcess], one [HMCLProcessListener].
|
||||
* Because every time we launched a game, we generates a new [HMCLProcessListener]
|
||||
*/
|
||||
class HMCLProcessListener implements ProcessListener {
|
||||
private final class HMCLProcessListener implements ProcessListener {
|
||||
|
||||
private final HMCLGameRepository repository;
|
||||
private final Version version;
|
||||
@ -694,9 +694,11 @@ public final class LauncherHelper {
|
||||
private boolean lwjgl;
|
||||
private LogWindow logWindow;
|
||||
private final boolean detectWindow;
|
||||
private final ArrayDeque<Pair<String, Log4jLevel>> logs;
|
||||
private final ArrayDeque<String> logs;
|
||||
private final ArrayDeque</*Log4jLevel*/Object> levels;
|
||||
private final CountDownLatch logWindowLatch = new CountDownLatch(1);
|
||||
private final CountDownLatch launchingLatch;
|
||||
private final String forbiddenAccessToken;
|
||||
|
||||
public HMCLProcessListener(HMCLGameRepository repository, Version version, AuthInfo authInfo, LaunchOptions launchOptions, CountDownLatch launchingLatch, boolean detectWindow) {
|
||||
this.repository = repository;
|
||||
@ -704,8 +706,11 @@ public final class LauncherHelper {
|
||||
this.launchOptions = launchOptions;
|
||||
this.launchingLatch = launchingLatch;
|
||||
this.detectWindow = detectWindow;
|
||||
this.forbiddenAccessToken = authInfo != null ? authInfo.getAccessToken() : null;
|
||||
|
||||
this.logs = new ArrayDeque<>(config().getLogLines() + 1);
|
||||
final int numLogs = config().getLogLines() + 1;
|
||||
this.logs = new ArrayDeque<>(numLogs);
|
||||
this.levels = new ArrayDeque<>(numLogs);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -764,17 +769,24 @@ public final class LauncherHelper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onLog(String log, Log4jLevel level) {
|
||||
String filteredLog = Logging.filterForbiddenToken(log);
|
||||
public void onLog(String log, boolean isErrorStream) {
|
||||
String filteredLog = forbiddenAccessToken == null ? log : log.replace(forbiddenAccessToken, "<access token>");
|
||||
|
||||
if (level.lessOrEqual(Log4jLevel.ERROR))
|
||||
if (isErrorStream)
|
||||
System.err.println(filteredLog);
|
||||
else
|
||||
System.out.println(filteredLog);
|
||||
|
||||
logs.add(pair(filteredLog, level));
|
||||
if (logs.size() > config().getLogLines())
|
||||
logs.removeFirst();
|
||||
Log4jLevel level = isErrorStream ? Log4jLevel.ERROR : (showLogs ? Log4jLevel.guessLevel(filteredLog) : null);
|
||||
|
||||
synchronized (this) {
|
||||
logs.add(filteredLog);
|
||||
levels.add(level != null ? level : Optional.empty()); // Use 'Optional.empty()' as hole
|
||||
if (logs.size() > config().getLogLines()) {
|
||||
logs.removeFirst();
|
||||
levels.removeFirst();
|
||||
}
|
||||
}
|
||||
|
||||
if (showLogs) {
|
||||
try {
|
||||
@ -787,7 +799,7 @@ public final class LauncherHelper {
|
||||
Platform.runLater(() -> logWindow.logLine(filteredLog, level));
|
||||
}
|
||||
|
||||
if (!lwjgl && (filteredLog.toLowerCase().contains("lwjgl version") || filteredLog.toLowerCase().contains("lwjgl openal") || !detectWindow)) {
|
||||
if (!lwjgl && (!detectWindow || filteredLog.toLowerCase().contains("lwjgl version") || filteredLog.toLowerCase().contains("lwjgl openal"))) {
|
||||
lwjgl = true;
|
||||
finishLaunch();
|
||||
}
|
||||
@ -804,8 +816,11 @@ public final class LauncherHelper {
|
||||
if (!lwjgl) finishLaunch();
|
||||
|
||||
if (exitType != ExitType.NORMAL) {
|
||||
ArrayList<Pair<String, Log4jLevel>> pairs = new ArrayList<>(logs.size());
|
||||
Lang.forEachZipped(logs, levels,
|
||||
(log, l) -> pairs.add(pair(log, l instanceof Log4jLevel ? ((Log4jLevel) l) : Log4jLevel.guessLevel(log))));
|
||||
repository.markVersionLaunchedAbnormally(version.getId());
|
||||
Platform.runLater(() -> new GameCrashWindow(process, exitType, repository, version, launchOptions, logs).show());
|
||||
Platform.runLater(() -> new GameCrashWindow(process, exitType, repository, version, launchOptions, pairs).show());
|
||||
}
|
||||
|
||||
checkExit();
|
||||
|
@ -42,6 +42,7 @@ import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.Log4jLevel;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
import org.jackhuang.hmcl.util.platform.Architecture;
|
||||
import org.jackhuang.hmcl.util.platform.CommandBuilder;
|
||||
@ -222,7 +223,7 @@ public class GameCrashWindow extends Stage {
|
||||
private void showLogWindow() {
|
||||
LogWindow logWindow = new LogWindow();
|
||||
|
||||
logWindow.logLine("Command: " + new CommandBuilder().addAll(managedProcess.getCommands()).toString(), Log4jLevel.INFO);
|
||||
logWindow.logLine(Logging.filterForbiddenToken("Command: " + new CommandBuilder().addAll(managedProcess.getCommands())), Log4jLevel.INFO);
|
||||
if (managedProcess.getClasspath() != null) logWindow.logLine("ClassPath: " + managedProcess.getClasspath(), Log4jLevel.INFO);
|
||||
for (Map.Entry<String, Log4jLevel> entry : logs)
|
||||
logWindow.logLine(entry.getKey(), entry.getValue());
|
||||
|
@ -37,7 +37,6 @@ import javafx.stage.Stage;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
import org.jackhuang.hmcl.game.LauncherHelper;
|
||||
import org.jackhuang.hmcl.util.Log4jLevel;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -95,8 +94,8 @@ public final class LogWindow extends Stage {
|
||||
levelShownMap.values().forEach(property -> property.addListener((a, b, newValue) -> shakeLogs()));
|
||||
}
|
||||
|
||||
public void logLine(String line, Log4jLevel level) {
|
||||
Log log = new Log(Logging.filterForbiddenToken(parseEscapeSequence(line)), level);
|
||||
public void logLine(String filteredLine, Log4jLevel level) {
|
||||
Log log = new Log(parseEscapeSequence(filteredLine), level);
|
||||
logs.add(log);
|
||||
if (levelShownMap.get(level).get())
|
||||
impl.listView.getItems().add(log);
|
||||
|
@ -21,7 +21,6 @@ import org.jackhuang.hmcl.auth.AuthInfo;
|
||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.game.*;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.Log4jLevel;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
@ -646,15 +645,15 @@ public class DefaultLauncher extends Launcher {
|
||||
throw new ExecutionPolicyLimitException();
|
||||
}
|
||||
|
||||
private void startMonitors(ManagedProcess managedProcess, ProcessListener processListener, Charset encoding, boolean isDaemon) {
|
||||
private static void startMonitors(ManagedProcess managedProcess, ProcessListener processListener, Charset encoding, boolean isDaemon) {
|
||||
processListener.setProcess(managedProcess);
|
||||
Thread stdout = Lang.thread(new StreamPump(managedProcess.getProcess().getInputStream(), it -> {
|
||||
processListener.onLog(it, Optional.ofNullable(Log4jLevel.guessLevel(it)).orElse(Log4jLevel.INFO));
|
||||
processListener.onLog(it, false);
|
||||
managedProcess.addLine(it);
|
||||
}, encoding), "stdout-pump", isDaemon);
|
||||
managedProcess.addRelatedThread(stdout);
|
||||
Thread stderr = Lang.thread(new StreamPump(managedProcess.getProcess().getErrorStream(), it -> {
|
||||
processListener.onLog(it, Log4jLevel.ERROR);
|
||||
processListener.onLog(it, true);
|
||||
managedProcess.addLine(it);
|
||||
}, encoding), "stderr-pump", isDaemon);
|
||||
managedProcess.addRelatedThread(stderr);
|
||||
|
@ -17,7 +17,6 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.launch;
|
||||
|
||||
import org.jackhuang.hmcl.util.Log4jLevel;
|
||||
import org.jackhuang.hmcl.util.platform.ManagedProcess;
|
||||
|
||||
/**
|
||||
@ -40,7 +39,7 @@ public interface ProcessListener {
|
||||
*
|
||||
* @param log the log
|
||||
*/
|
||||
void onLog(String log, Log4jLevel level);
|
||||
void onLog(String log, boolean isErrorStream);
|
||||
|
||||
/**
|
||||
* Called when the game process stops.
|
||||
|
@ -366,6 +366,13 @@ public final class Lang {
|
||||
return () -> iterator;
|
||||
}
|
||||
|
||||
public static <T, U> void forEachZipped(Iterable<T> i1, Iterable<U> i2, BiConsumer<T, U> action) {
|
||||
Iterator<T> it1 = i1.iterator();
|
||||
Iterator<U> it2 = i2.iterator();
|
||||
while (it1.hasNext() && it2.hasNext())
|
||||
action.accept(it1.next(), it2.next());
|
||||
}
|
||||
|
||||
private static Timer timer;
|
||||
|
||||
public static synchronized Timer getTimer() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user