From afecb87c6d0fc855da6a9e18a9d7f048138365f5 Mon Sep 17 00:00:00 2001 From: huangyuhui Date: Tue, 16 Feb 2016 18:57:26 +0800 Subject: [PATCH] Might fix game log watcher? --- .../hellominecraft/launcher/Launcher.java | 46 +--------- .../core/download/DownloadLibraryJob.java | 8 +- .../download/MinecraftDownloadService.java | 4 +- .../core/download/MojangDownloadProvider.java | 12 ++- .../core/launch/DefaultGameLauncher.java | 4 +- .../launcher/core/launch/GameLauncher.java | 2 +- .../core/launch/LibraryDownloadTask.java | 11 +-- .../core/version/GameDownloadInfo.java | 10 ++- .../core/version/LibraryDownloadInfo.java | 27 ++++++ .../core/version/MinecraftLibrary.java | 2 +- .../launcher/setting/VersionSetting.java | 3 +- .../launcher/ui/LaunchingUIDaemon.java | 15 +++- .../hellominecraft/launcher/ui/MainFrame.java | 2 +- .../launcher/ui/MainPagePanel.java | 2 +- .../hellominecraft/util/StrUtils.java | 56 +++++++----- .../util/system/JavaProcess.java | 5 -- .../util/system/JavaProcessMonitor.java | 44 +++++----- .../util/system/ProcessThread.java | 58 ++++--------- .../util/ui}/GraphicsUtils.java | 66 +++++++------- .../util/ui/LogWindowOutputStream.java | 25 ------ .../hellominecraft/util/ui/WebFrame.java | 85 +++++++++++++++++++ .../lookandfeel/comp/ConstomButton.java | 2 +- .../lookandfeel/painter/ButtonPainter.java | 2 +- .../lookandfeel/painter/ProgressPainter.java | 2 +- .../lookandfeel/painter/TextFieldPainter.java | 2 +- .../lookandfeel/ui/ComboBoxUI.java | 2 +- .../lookandfeel/ui/ScrollBarUI.java | 2 +- .../hellominecraft/lookandfeel/synth.xml | 2 +- .../lookandfeel/synth_backup.xml | 2 +- 29 files changed, 280 insertions(+), 223 deletions(-) create mode 100644 HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/LibraryDownloadInfo.java rename {MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel => HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui}/GraphicsUtils.java (82%) create mode 100644 HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/WebFrame.java diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/Launcher.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/Launcher.java index ab93a4efd..76e9624d2 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/Launcher.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/Launcher.java @@ -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(); - * } - * } - */ } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadLibraryJob.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadLibraryJob.java index d2ed929ec..7c5e28592 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadLibraryJob.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadLibraryJob.java @@ -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); } } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftDownloadService.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftDownloadService.java index 477a642b6..397d8ca6e 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftDownloadService.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftDownloadService.java @@ -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) diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/MojangDownloadProvider.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/MojangDownloadProvider.java index f3815e9a4..ab6867da8 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/MojangDownloadProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/download/MojangDownloadProvider.java @@ -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; } } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java index 5120293df..8c0e006e5 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java @@ -43,9 +43,9 @@ public class DefaultGameLauncher extends GameLauncher { ParallelTask parallelTask = new ParallelTask(); HashSet 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); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/GameLauncher.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/GameLauncher.java index dfe5b0f7e..d099a5211 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/GameLauncher.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/GameLauncher.java @@ -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"); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/LibraryDownloadTask.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/LibraryDownloadTask.java index 817ac39d2..3cd1cfbb9 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/LibraryDownloadTask.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/LibraryDownloadTask.java @@ -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; } } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/GameDownloadInfo.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/GameDownloadInfo.java index 62581e598..0f0a0a157 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/GameDownloadInfo.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/GameDownloadInfo.java @@ -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); + } + } } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/LibraryDownloadInfo.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/LibraryDownloadInfo.java new file mode 100644 index 000000000..5e2d9e760 --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/LibraryDownloadInfo.java @@ -0,0 +1,27 @@ +/* + * 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.hellominecraft.launcher.core.version; + +/** + * + * @author huangyuhui + */ +public class LibraryDownloadInfo extends GameDownloadInfo { + + public String path; +} diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftLibrary.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftLibrary.java index 1fd8b7956..77a0c3b93 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftLibrary.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftLibrary.java @@ -40,7 +40,7 @@ public class MinecraftLibrary extends IMinecraftLibrary { super(name); } - public MinecraftLibrary(ArrayList rules, String url, Natives natives, String name, Extract extract) { + public MinecraftLibrary(ArrayList rules, String url, Natives natives, String name, Extract extract, LibraryDownloadInfo downloads) { super(name); this.rules = rules == null ? null : (ArrayList) rules.clone(); this.url = url; diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/VersionSetting.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/VersionSetting.java index adac51a90..361094330 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/VersionSetting.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/VersionSetting.java @@ -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 = ""; } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LaunchingUIDaemon.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LaunchingUIDaemon.java index 87c05698e..4e3adcb92 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LaunchingUIDaemon.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LaunchingUIDaemon.java @@ -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); } }); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainFrame.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainFrame.java index 49e99ab23..678334625 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainFrame.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainFrame.java @@ -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; diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.java index 5bcede7c4..1b0ded4f1 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.java @@ -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; diff --git a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/StrUtils.java b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/StrUtils.java index ad3f90331..d164214da 100755 --- a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/StrUtils.java +++ b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/StrUtils.java @@ -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 base, List match, Predicate 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 beforeFunc, Object[] params, Function 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) { diff --git a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcess.java b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcess.java index 75ecdb696..d4b06d847 100755 --- a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcess.java +++ b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcess.java @@ -30,7 +30,6 @@ public class JavaProcess { private final List commands; private final Process process; private final ArrayList stdOutLines = new ArrayList<>(); - private final ArrayList stdErrLines = new ArrayList<>(); public JavaProcess(List commands, Process process, ProcessManager pm) { this.commands = commands; @@ -59,10 +58,6 @@ public class JavaProcess { return this.stdOutLines; } - public ArrayList getStdErrLines() { - return this.stdErrLines; - } - public boolean isRunning() { try { this.process.exitValue(); diff --git a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcessMonitor.java b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcessMonitor.java index f153774dd..d61a62bef 100755 --- a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcessMonitor.java +++ b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcessMonitor.java @@ -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 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 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); } diff --git a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/ProcessThread.java b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/ProcessThread.java index def777246..b73548c88 100755 --- a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/ProcessThread.java +++ b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/system/ProcessThread.java @@ -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 printlnEvent = new EventHandler<>(this); public final EventHandler 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); } } } diff --git a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/GraphicsUtils.java b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/GraphicsUtils.java similarity index 82% rename from MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/GraphicsUtils.java rename to HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/GraphicsUtils.java index a413163b1..f2b328575 100755 --- a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/GraphicsUtils.java +++ b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/GraphicsUtils.java @@ -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); diff --git a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindowOutputStream.java b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindowOutputStream.java index e3a286fd0..57d884acb 100755 --- a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindowOutputStream.java +++ b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindowOutputStream.java @@ -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; diff --git a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/WebFrame.java b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/WebFrame.java new file mode 100644 index 000000000..2c86c1e61 --- /dev/null +++ b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/ui/WebFrame.java @@ -0,0 +1,85 @@ +/* + * 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.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(("" + StrUtils.parseParams(t -> (""), strs, t -> "
") + "") + .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); + } +} diff --git a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/comp/ConstomButton.java b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/comp/ConstomButton.java index 135fb0851..4ba9f5025 100755 --- a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/comp/ConstomButton.java +++ b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/comp/ConstomButton.java @@ -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; /** * diff --git a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ButtonPainter.java b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ButtonPainter.java index 4d4bde9ce..5d8381c36 100755 --- a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ButtonPainter.java +++ b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ButtonPainter.java @@ -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; /** diff --git a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ProgressPainter.java b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ProgressPainter.java index 718de303e..a7eddcce7 100755 --- a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ProgressPainter.java +++ b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ProgressPainter.java @@ -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; diff --git a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/TextFieldPainter.java b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/TextFieldPainter.java index 9d12eb7f2..560981581 100755 --- a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/TextFieldPainter.java +++ b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/TextFieldPainter.java @@ -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 diff --git a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ComboBoxUI.java b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ComboBoxUI.java index b29a722b2..939865504 100755 --- a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ComboBoxUI.java +++ b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ComboBoxUI.java @@ -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; diff --git a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ScrollBarUI.java b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ScrollBarUI.java index 147364f05..5d63c1e05 100755 --- a/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ScrollBarUI.java +++ b/MetroLookAndFeel/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ScrollBarUI.java @@ -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; diff --git a/MetroLookAndFeel/src/main/resources/org/jackhuang/hellominecraft/lookandfeel/synth.xml b/MetroLookAndFeel/src/main/resources/org/jackhuang/hellominecraft/lookandfeel/synth.xml index 281350303..a0e2a2b04 100755 --- a/MetroLookAndFeel/src/main/resources/org/jackhuang/hellominecraft/lookandfeel/synth.xml +++ b/MetroLookAndFeel/src/main/resources/org/jackhuang/hellominecraft/lookandfeel/synth.xml @@ -26,7 +26,7 @@ - + diff --git a/MetroLookAndFeel/src/main/resources/org/jackhuang/hellominecraft/lookandfeel/synth_backup.xml b/MetroLookAndFeel/src/main/resources/org/jackhuang/hellominecraft/lookandfeel/synth_backup.xml index 08b7dfb13..d92604587 100644 --- a/MetroLookAndFeel/src/main/resources/org/jackhuang/hellominecraft/lookandfeel/synth_backup.xml +++ b/MetroLookAndFeel/src/main/resources/org/jackhuang/hellominecraft/lookandfeel/synth_backup.xml @@ -26,7 +26,7 @@ - +