From 29f53d574c16a0ee9b00cbf4fcdf96bcfe4352ef Mon Sep 17 00:00:00 2001 From: huangyuhui Date: Sat, 1 Jul 2017 21:31:24 +0800 Subject: [PATCH] add log lines limitation --- HMCL/log4j.xml | 23 +++ .../org/jackhuang/hmcl/setting/Config.java | 15 ++ .../java/org/jackhuang/hmcl/ui/LogWindow.form | 124 ++++++++---- .../java/org/jackhuang/hmcl/ui/LogWindow.java | 188 +++++++++++------- .../hmcl/ui/LogWindowOutputStream.java | 8 +- .../main/java/org/jackhuang/hmcl/util/C.java | 4 +- .../org/jackhuang/hmcl/util/log/Level.java | 22 +- .../org/jackhuang/hmcl/util/net/WebFrame.java | 2 +- .../hmcl/util/sys/ProcessMonitor.java | 18 +- .../hmcl/util/sys/ProcessThread.java | 2 +- .../hmcl/util/sys/WaitForThread.java | 47 +++++ .../wizard/modules/InstructionsPanelImpl.java | 7 +- .../org/jackhuang/hmcl/lang/I18N.properties | 1 + 13 files changed, 322 insertions(+), 139 deletions(-) create mode 100644 HMCL/log4j.xml create mode 100644 HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/WaitForThread.java diff --git a/HMCL/log4j.xml b/HMCL/log4j.xml new file mode 100644 index 000000000..ef67b60ad --- /dev/null +++ b/HMCL/log4j.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java index 3037a7621..e63f1de67 100755 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java @@ -86,10 +86,13 @@ public final class Config implements Cloneable { private String fontFamily; @SerializedName("fontSize") private int fontSize; + @SerializedName("logLines") + private int logLines; public Config() { clientToken = UUID.randomUUID().toString(); logintype = downloadtype = 0; + logLines = 100; enableAnimation = enableBlur = true; if (OS.os() == OS.WINDOWS) enableShadow = true; @@ -315,6 +318,18 @@ public final class Config implements Cloneable { Settings.save(); } + public int getLogLines() { + if (logLines == 100 || logLines == 1000 || logLines == 5000) + return logLines; + else + return logLines = 100; + } + + public void setLogLines(int logLines) { + this.logLines = logLines; + Settings.save(); + } + @Override public Object clone() { try { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.form b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.form index 2d954fb7d..3b02342c2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.form +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.form @@ -29,18 +29,12 @@ - + - - + + - - - - - - - + @@ -51,6 +45,21 @@ + + + + + + + + + + + + + + + @@ -59,20 +68,27 @@ + + + + + + + + + + - + - - - + - @@ -117,30 +133,14 @@ - - - - - - - - - + - + - - - - - - - - - + @@ -153,14 +153,6 @@ - - - - - - - - @@ -172,5 +164,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.java index e1969efec..b49a86c3a 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindow.java @@ -18,6 +18,8 @@ package org.jackhuang.hmcl.ui; import java.io.PrintStream; +import java.util.Deque; +import java.util.LinkedList; import javax.swing.SwingUtilities; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; @@ -73,13 +75,17 @@ public class LogWindow extends javax.swing.JFrame { btnClose = new javax.swing.JButton(); btnCopy = new javax.swing.JButton(); lblCrash = new javax.swing.JLabel(); - btnMCBBS = new javax.swing.JButton(); - btnTieBa = new javax.swing.JButton(); - btnMCF = new javax.swing.JButton(); + btnContact = new javax.swing.JButton(); btnTerminateGame = new javax.swing.JButton(); - btnGitHub = new javax.swing.JButton(); pnlLog = new javax.swing.JScrollPane(); txtLog = new javax.swing.JTextPane(); + jLabel1 = new javax.swing.JLabel(); + cboShowLines = new javax.swing.JComboBox<>(); + btnDebug = new javax.swing.JToggleButton(); + btnInfo = new javax.swing.JToggleButton(); + btnWarn = new javax.swing.JToggleButton(); + btnError = new javax.swing.JButton(); + btnFatal = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle(C.i18n("logwindow.title")); // NOI18N @@ -112,24 +118,10 @@ public class LogWindow extends javax.swing.JFrame { lblCrash.setText(C.i18n("ui.label.crashing")); // NOI18N - btnMCBBS.setText("MCBBS"); - btnMCBBS.addActionListener(new java.awt.event.ActionListener() { + btnContact.setText(C.i18n("logwindow.contact")); // NOI18N + btnContact.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - btnMCBBSActionPerformed(evt); - } - }); - - btnTieBa.setText(C.i18n("logwindow.tieba")); // NOI18N - btnTieBa.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnTieBaActionPerformed(evt); - } - }); - - btnMCF.setText("Minecraft Forum"); - btnMCF.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnMCFActionPerformed(evt); + btnContactActionPerformed(evt); } }); @@ -140,31 +132,38 @@ public class LogWindow extends javax.swing.JFrame { } }); - btnGitHub.setText("GitHub"); - btnGitHub.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnGitHubActionPerformed(evt); + pnlLog.setViewportView(txtLog); + + jLabel1.setText("显示行数"); + jLabel1.setToolTipText(""); + + cboShowLines.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "100", "1000", "5000" })); + cboShowLines.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + cboShowLinesItemStateChanged(evt); } }); - pnlLog.setViewportView(txtLog); + btnDebug.setText("debugs"); + + btnInfo.setText("infos"); + + btnWarn.setText("warns"); + + btnError.setText("errors"); + + btnFatal.setText("fatals"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGroup(layout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(pnlLog) - .addGroup(layout.createSequentialGroup() - .addComponent(btnTieBa) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnMCBBS) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnMCF) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnGitHub) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pnlLog, javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(btnContact) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnTerminateGame) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -173,26 +172,46 @@ public class LogWindow extends javax.swing.JFrame { .addComponent(btnClear) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnClose)) - .addComponent(lblCrash, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(lblCrash, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cboShowLines, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnFatal) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnError) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnWarn) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnInfo) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnDebug))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(cboShowLines, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnDebug) + .addComponent(btnInfo) + .addComponent(btnWarn) + .addComponent(btnError) + .addComponent(btnFatal)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblCrash) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pnlLog, javax.swing.GroupLayout.DEFAULT_SIZE, 356, Short.MAX_VALUE) + .addComponent(pnlLog, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnClear) .addComponent(btnClose) .addComponent(btnCopy) - .addComponent(btnMCBBS) - .addComponent(btnTieBa) - .addComponent(btnMCF) - .addComponent(btnTerminateGame) - .addComponent(btnGitHub)) + .addComponent(btnContact) + .addComponent(btnTerminateGame)) .addContainerGap()) ); @@ -213,44 +232,43 @@ public class LogWindow extends javax.swing.JFrame { Utils.setClipborad(this.txtLog.getText()); }//GEN-LAST:event_btnCopyActionPerformed - private void btnMCBBSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCBBSActionPerformed - SwingUtils.openLink(C.URL_PUBLISH); - }//GEN-LAST:event_btnMCBBSActionPerformed - - private void btnTieBaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTieBaActionPerformed - SwingUtils.openLink(C.URL_TIEBA); - }//GEN-LAST:event_btnTieBaActionPerformed - - private void btnMCFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCFActionPerformed - SwingUtils.openLink(C.URL_MINECRAFTFORUM); - }//GEN-LAST:event_btnMCFActionPerformed + private void btnContactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnContactActionPerformed + SwingUtils.openLink(C.URL_CONTACT); + }//GEN-LAST:event_btnContactActionPerformed private void btnTerminateGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTerminateGameActionPerformed terminateGames(); }//GEN-LAST:event_btnTerminateGameActionPerformed - private void btnGitHubActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGitHubActionPerformed - SwingUtils.openLink(C.URL_GITHUB); - }//GEN-LAST:event_btnGitHubActionPerformed - private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing if (listener != null && listener.apply()) terminateGames(); SwingUtils.exitIfNoWindow(this); }//GEN-LAST:event_formWindowClosing + private void cboShowLinesItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboShowLinesItemStateChanged + Settings.getInstance().setLogLines(Integer.parseInt(cboShowLines.getSelectedItem().toString())); + }//GEN-LAST:event_cboShowLinesItemStateChanged + void terminateGames() { ProcessMonitor.stopAll(); } + + int removedLength = 0; + Deque offsets = new LinkedList<>(); + int fatals = 0, errors = 0, warns = 0, infos = 0, debugs = 0; public void log(final String status, final Level c) { - if (isVisible()) + if (!isVisible()) return; SwingUtilities.invokeLater(() -> { Document d = txtLog.getStyledDocument(); try { // prevent too much memory used. - if (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() > 1l * 1024 * 1024 * 256) + if (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() > 1l * 1024 * 1024 * 256) { d.remove(0, d.getLength()); + offsets.clear(); + removedLength = 0; + } } catch (Exception ex) { HMCLog.err("Failed to clear the text component", ex); } @@ -258,10 +276,30 @@ public class LogWindow extends javax.swing.JFrame { SimpleAttributeSet sas = new SimpleAttributeSet(); StyleConstants.setForeground(sas, c.COLOR); try { + offsets.add(d.getLength() + removedLength); d.insertString(d.getLength(), newStatus, sas); } catch (Exception ex) { HMCLog.err("Failed to insert \"" + newStatus + "\" to " + d.getLength(), ex); } + + switch (c) { + case FATAL: btnFatal.setText(++fatals + " fatals"); break; + case ERROR: btnError.setText(++errors + " errors"); break; + case WARN: btnWarn.setText(++warns + " warns"); break; + case INFO: btnInfo.setText(++infos + " infos"); break; + case DEBUG: btnDebug.setText(++debugs + " debugs"); break; + } + + int maxLines = Integer.parseInt(cboShowLines.getSelectedItem().toString()); + while (offsets.size() > maxLines) { + int start = offsets.pollFirst(); + int end = offsets.peekFirst(); + try { + d.remove(start - removedLength, end - start); // start - removedLength must become 0 + removedLength = end; + } catch(Exception ignore) { + } + } }); } @@ -275,27 +313,25 @@ public class LogWindow extends javax.swing.JFrame { @Override public void setVisible(boolean b) { + cboShowLines.setSelectedItem(Settings.getInstance().getLogLines()); + txtLog.setFont(Settings.getInstance().getConsoleFont()); lblCrash.setVisible(false); - btnMCBBS.setVisible(false); - btnTieBa.setVisible(false); - btnMCF.setVisible(false); + btnContact.setVisible(false); super.setVisible(b); } public void showAsCrashWindow(boolean out_date) { + cboShowLines.setSelectedItem(Settings.getInstance().getLogLines()); + txtLog.setFont(Settings.getInstance().getConsoleFont()); if (out_date) { lblCrash.setVisible(false); - btnMCBBS.setVisible(false); - btnTieBa.setVisible(false); - btnMCF.setVisible(false); + btnContact.setVisible(false); lblCrash.setText(C.i18n("ui.label.crashing_out_dated")); } else { lblCrash.setVisible(true); - btnMCBBS.setVisible(true); - btnTieBa.setVisible(true); - btnMCF.setVisible(true); + btnContact.setVisible(true); lblCrash.setText(C.i18n("ui.label.crashing")); } @@ -305,12 +341,16 @@ public class LogWindow extends javax.swing.JFrame { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnClear; private javax.swing.JButton btnClose; + private javax.swing.JButton btnContact; private javax.swing.JButton btnCopy; - private javax.swing.JButton btnGitHub; - private javax.swing.JButton btnMCBBS; - private javax.swing.JButton btnMCF; + private javax.swing.JToggleButton btnDebug; + private javax.swing.JButton btnError; + private javax.swing.JButton btnFatal; + private javax.swing.JToggleButton btnInfo; private javax.swing.JButton btnTerminateGame; - private javax.swing.JButton btnTieBa; + private javax.swing.JToggleButton btnWarn; + private javax.swing.JComboBox cboShowLines; + private javax.swing.JLabel jLabel1; private javax.swing.JLabel lblCrash; private javax.swing.JScrollPane pnlLog; private javax.swing.JTextPane txtLog; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindowOutputStream.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindowOutputStream.java index 6b9c789fd..b9d8dd901 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindowOutputStream.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LogWindowOutputStream.java @@ -45,10 +45,16 @@ public class LogWindowOutputStream extends OutputStream { public final void write(byte[] arr, int off, int len) { append(new String(arr, off, len)); } + + final Object obj = new Object(); + Level lastLevel = null; private void append(final String str) { SwingUtilities.invokeLater(() -> { - txt.log(str, Level.guessLevel(str, sas)); + Level level = Level.guessLevel(str); + if (level == null) level = lastLevel; + else lastLevel = level; + txt.log(str, Level.mergeLevel(sas, level)); }); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/C.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/C.java index 69876b010..e9c3924cd 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/C.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/C.java @@ -31,9 +31,7 @@ public final class C { //http://repo1.maven.org/maven2 public static final String URL_PUBLISH = "http://www.mcbbs.net/thread-142335-1-1.html"; - public static final String URL_TIEBA = "http://tieba.baidu.com/f?kw=hellominecraftlauncher"; - public static final String URL_GITHUB = "https://github.com/huanghongxun/HMCL/issues"; - public static final String URL_MINECRAFTFORUM = "http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-tools/1265720-hello-minecraft-launcher-1-9-3-mc-1-7-4-auto"; + public static final String URL_CONTACT = "http://huangyuhui.duapp.com/hmcl.php"; public static final String URL_FORGE_LIST = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/json"; public static final String URL_LITELOADER_LIST = "http://dl.liteloader.com/versions/versions.json"; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/log/Level.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/log/Level.java index 907435bc5..1ad696266 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/log/Level.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/log/Level.java @@ -51,10 +51,8 @@ public enum Level { public static final Pattern MINECRAFT_LOGGER_CATEGORY = Pattern.compile("\\[(?[0-9:]+)\\] \\[[^/]+/(?[^\\]]+)\\] \\[(?[^\\]]+)\\]"); 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 preLevel) { - if (line.startsWith("MC:")) - line = line.substring("MC:".length()); - Level level = preLevel; + public static Level guessLevel(String line) { + Level level = null; Matcher m = MINECRAFT_LOGGER.matcher(line); if (m.find()) { // New style logs from log4j @@ -109,13 +107,23 @@ public enum Level { if (line.contains("overwriting existing")) return FATAL; - if (line.contains("Exception in thread") + /*if (line.contains("Exception in thread") || line.matches("\\s+at " + JAVA_SYMBOL) || line.matches("Caused by: " + JAVA_SYMBOL) || 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 preLevel.level < level.level ? preLevel : level; + return ERROR;*/ + return level; + } + + public static boolean isError(Level a) { + return a == null ? false : a.lessOrEqual(Level.ERROR); + } + + public static Level mergeLevel(Level a, Level b) { + if (a == null) return b; + else if (b == null) return a; + else return a.level < b.level ? a : b; } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/net/WebFrame.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/net/WebFrame.java index f86ffc39d..b2bd606a7 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/net/WebFrame.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/net/WebFrame.java @@ -32,7 +32,7 @@ import org.jackhuang.hmcl.util.ui.SwingUtils; public class WebFrame extends JDialog { public WebFrame(String... strs) { - this(("" + StrUtils.parseParams(t -> (""), strs, t -> "
") + "") + this(("" + StrUtils.parseParams(t -> (""), strs, t -> "
") + "") .replace(" ", " ").replace("\t", "    ")); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/ProcessMonitor.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/ProcessMonitor.java index 27dcbcc9d..2da07097a 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/ProcessMonitor.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/ProcessMonitor.java @@ -41,7 +41,9 @@ public class ProcessMonitor { public static final HashSet MONITORS = new HashSet<>(); private final CountDownLatch latch = new CountDownLatch(2); - ProcessThread inputThread, errorThread; + ProcessThread inputThread; + ProcessThread errorThread; + WaitForThread waitForThread; private final IProcess p; public ProcessMonitor(IProcess p) { @@ -83,10 +85,15 @@ public class ProcessMonitor { private void threadStopped(SimpleEvent event) { latch.countDown(); ProcessThread t = (ProcessThread) event.getSource(); - HMCLog.log("Process exit code: " + p.getExitCode()); + int exitCode = Integer.MAX_VALUE; + try { + exitCode = p.getExitCode(); + } catch(IllegalThreadStateException e) { + HMCLog.err("Failed to "); + } if (p.getExitCode() != 0 || StrUtils.containsOne(t.getLines(), - Arrays.asList("Unable to launch"), - x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR))) + Arrays.asList("Unable to launch"), // LaunchWrapper will terminate the application returning exit code 0, but this is an error state. + x -> Level.isError(Level.guessLevel(x)))) synchronized (this) { if (!hasFired) { hasFired = true; @@ -98,7 +105,7 @@ public class ProcessMonitor { "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))) + x -> Level.isError(Level.guessLevel(x)))) synchronized (this) { if (!hasFired) { hasFired = true; @@ -127,7 +134,6 @@ public class ProcessMonitor { try { latch.await(); } catch (InterruptedException ignore) { - HMCLog.warn("Thread has been interrupted.", ignore); } } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/ProcessThread.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/ProcessThread.java index ae9cb1608..c990eeb69 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/ProcessThread.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/ProcessThread.java @@ -86,7 +86,7 @@ public class ProcessThread extends Thread { protected void println(String line) { printlnEvent.fire(new PrintlnEvent(monitor, line, readError)); - (readError ? System.err : System.out).println("MC: " + line); + (readError ? System.err : System.out).println(line); lines.add(line); p.getStdOutLines().add(line); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/WaitForThread.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/WaitForThread.java new file mode 100644 index 000000000..05f05af95 --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/sys/WaitForThread.java @@ -0,0 +1,47 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2013 huangyuhui + * + * 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.hmcl.util.sys; + +import java.util.concurrent.CountDownLatch; +import org.jackhuang.hmcl.api.HMCLog; + +/** + * + * @author huang + */ +public class WaitForThread extends Thread { + + CountDownLatch latch; + Runnable done; + + public WaitForThread(CountDownLatch latch, Runnable done) { + this.latch = latch; + } + + @Override + public void run() { + try { + latch.await(); + } catch (InterruptedException ex) { + HMCLog.err("Interrupted latch waiting"); + } + done.run(); + } + + +} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ui/wizard/modules/InstructionsPanelImpl.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ui/wizard/modules/InstructionsPanelImpl.java index 99275a3d0..a7b81d728 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ui/wizard/modules/InstructionsPanelImpl.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/ui/wizard/modules/InstructionsPanelImpl.java @@ -123,10 +123,9 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, public InstructionsPanelImpl(BufferedImage img, Wizard wizard) { if (img == null) try { - img = ImageIO.read(InstructionsPanelImpl.class.getResourceAsStream( - "/org/jackhuang/hmcl/wizard.jpg")); - } catch (IOException ioe) { - HMCLog.err("Failed to load wizard.jpg, maybe you fucking modified the launcher", ioe); + img = ImageIO.read(InstructionsPanelImpl.class.getResourceAsStream("/org/jackhuang/hmcl/wizard.jpg")); + } catch (IOException | NullPointerException ioe) { + HMCLog.err("Failed to load wizard.jpg, maybe you have fuckingly modified the launcher file", ioe); } this.img = img; this.wizard = wizard; diff --git a/HMCLCore/src/main/resources/org/jackhuang/hmcl/lang/I18N.properties b/HMCLCore/src/main/resources/org/jackhuang/hmcl/lang/I18N.properties index f24f039d2..d0eb913a8 100644 --- a/HMCLCore/src/main/resources/org/jackhuang/hmcl/lang/I18N.properties +++ b/HMCLCore/src/main/resources/org/jackhuang/hmcl/lang/I18N.properties @@ -433,3 +433,4 @@ wizard.steps=Steps lang=English lang.default=Belong to OS language. +logwindow.contact=Contact Us