diff --git a/.travis.yml b/.travis.yml index 9fce3d616..af71cd894 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,9 +17,6 @@ deploy: - HMCL/build/libs/HMCL-${HMCL_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.jar - HMCL/build/libs/HMCL-${HMCL_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.exe - HMCL/build/libs/HMCL-${HMCL_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}-MacOSApp.zip - - HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.jar - - HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.exe - - HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}-MacOSApp.zip on: repo: huanghongxun/HMCL tags: false @@ -28,7 +25,7 @@ install: echo "skip 'gradle assemble' step" script: gradle build --continue before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock -cache: - directories: - - "$HOME/.gradle/caches/" - - "$HOME/.gradle/wrapper/" +#cache: +# directories: +# - "$HOME/.gradle/caches/" +# - "$HOME/.gradle/wrapper/" diff --git a/HMCL/build.gradle b/HMCL/build.gradle index 6bc999f7d..167cc189c 100755 --- a/HMCL/build.gradle +++ b/HMCL/build.gradle @@ -15,33 +15,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see {http://www.gnu.org/licenses/}. */ -buildscript { - repositories { - mavenCentral(); - - maven { - url "https://libraries.minecraft.net" - } - - dependencies { - classpath 'net.sf.proguard:proguard-gradle:4.10' - classpath 'edu.sc.seis.gradle:launch4j:1.0.6' - classpath 'me.tatarka:gradle-retrolambda:3.1.0' - } - } -} - plugins { id "edu.sc.seis.macAppBundle" version "2.1.6" + id "me.tatarka.retrolambda" version "3.5.0" + id 'edu.sc.seis.launch4j' version '2.3.0' } import java.util.jar.JarOutputStream import java.util.zip.ZipEntry import java.util.zip.ZipFile -apply plugin: 'launch4j' -apply plugin: 'me.tatarka.retrolambda' - if (!hasProperty('mainClass')) { ext.mainClass = 'org.jackhuang.hellominecraft.launcher.Main' } @@ -50,11 +33,11 @@ def buildnumber = System.getenv("TRAVIS_BUILD_NUMBER") if (buildnumber == null) buildnumber = System.getenv("BUILD_NUMBER") if (buildnumber == null) - buildnumber = "233" + buildnumber = "4" def versionroot = System.getenv("VERSION_ROOT") if (versionroot == null) - versionroot = "2.4.1" + versionroot = "2.6.0" String mavenGroupId = 'HMCL' String mavenVersion = versionroot + '.' + buildnumber @@ -146,8 +129,6 @@ jar { } launch4j { - launch4jCmd = 'D:\\Develop\\Java\\Launch4j\\launch4j.exe' - //launch4jCmd = '/home/huangyuhui/softwares/launch4j/launch4j' supportUrl = 'http://www.mcbbs.net/thread-142335-1-1.html' jreMinVersion = '1.6.0' diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/api/PluginManager.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/api/PluginManager.java index 3468dbb22..bb33d229e 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/api/PluginManager.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/api/PluginManager.java @@ -17,7 +17,7 @@ */ package org.jackhuang.hellominecraft.launcher.api; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * @@ -27,18 +27,11 @@ public class PluginManager { private static IPlugin NOW_PLUGIN; - public static void getServerPlugin() { - try { - getPlugin(Thread.currentThread().getContextClassLoader().loadClass("org.jackhuang.hellominecraft.launcher.server.ServerPlugin")); - } catch (ClassNotFoundException ignore) { - } - } - public static void getPlugin(Class cls) { try { IPlugin p = (IPlugin) cls.newInstance(); NOW_PLUGIN = p; - } catch (Exception e) { + } catch (IllegalAccessException | InstantiationException e) { HMCLog.err("Failed to new instance"); } } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/MCUtils.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/MCUtils.java index 9c692f68b..b7d940c3d 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/MCUtils.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/MCUtils.java @@ -19,8 +19,8 @@ package org.jackhuang.hellominecraft.launcher.core; import java.io.File; import java.io.IOException; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.system.OS; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.OS; /** * diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsIndex.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsIndex.java index c1fb867ba..9de6ce609 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsIndex.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsIndex.java @@ -38,7 +38,7 @@ public class AssetsIndex { public boolean virtual; public AssetsIndex() { - this.objects = new LinkedHashMap(); + this.objects = new LinkedHashMap<>(); } public Map getFileMap() { @@ -46,7 +46,7 @@ public class AssetsIndex { } public Set getUniqueObjects() { - return new HashSet(this.objects.values()); + return new HashSet<>(this.objects.values()); } public boolean isVirtual() { diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsMojangLoader.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsMojangLoader.java index ad24a5015..0a10fe205 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsMojangLoader.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsMojangLoader.java @@ -23,18 +23,18 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; -import org.jackhuang.hellominecraft.util.Utils; import org.jackhuang.hellominecraft.util.VersionNumber; -import org.jackhuang.hellominecraft.util.tasks.TaskInfo; +import org.jackhuang.hellominecraft.util.task.TaskInfo; /** * @@ -48,7 +48,7 @@ public class AssetsMojangLoader extends IAssetsHandler { @Override public Task getList(final MinecraftVersion mv, final IMinecraftAssetService mp) { - Utils.requireNonNull(mv); + Objects.requireNonNull(mv); String assetsId = mv.getAssetsIndex().getId(); File assets = mp.getAssets(); HMCLog.log("Gathering asset index: " + assetsId); @@ -63,7 +63,7 @@ public class AssetsMojangLoader extends IAssetsHandler { } @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { if (!areDependTasksSucceeded) throw new IllegalStateException("Failed to get asset index"); String result = FileUtils.read(f); @@ -72,7 +72,6 @@ public class AssetsMojangLoader extends IAssetsHandler { AssetsIndex o = C.GSON.fromJson(result, AssetsIndex.class); assetsDownloadURLs = new ArrayList<>(); assetsLocalNames = new ArrayList<>(); - ArrayList al = new ArrayList<>(); contents = new ArrayList<>(); HashSet loadedHashes = new HashSet<>(); int pgs = 0; @@ -88,7 +87,6 @@ public class AssetsMojangLoader extends IAssetsHandler { contents.add(c); assetsDownloadURLs.add(c.key); assetsLocalNames.add(new File(assets, "objects" + File.separator + c.key.replace("/", File.separator))); - al.add(e.getKey()); if (ppl != null) ppl.setProgress(this, ++pgs, o.getFileMap().size()); } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsObject.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsObject.java index c1fdfb66f..dca3c813b 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsObject.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/AssetsObject.java @@ -26,11 +26,6 @@ public class AssetsObject { private String hash; private long size; - public AssetsObject(String hash, long size) { - this.hash = hash; - this.size = size; - } - public void setHash(String hash) { this.hash = hash; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/Contents.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/Contents.java index 290f4747b..f88a69bc2 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/Contents.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/Contents.java @@ -28,15 +28,6 @@ public class Contents { public Contents() { } - public Contents(String key, String eTag, String lastModified, String storageClass, long size) { - this(); - this.key = key; - this.eTag = eTag; - this.lastModified = lastModified; - this.storageClass = storageClass; - this.size = size; - } - public String getKey() { return key; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/IAssetsHandler.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/IAssetsHandler.java index 7302fba16..e35bd0fe1 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/IAssetsHandler.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/IAssetsHandler.java @@ -24,17 +24,16 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService; import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.net.FileDownloadTask; import org.jackhuang.hellominecraft.util.code.DigestUtils; -import org.jackhuang.hellominecraft.util.system.IOUtils; -import org.jackhuang.hellominecraft.util.NetUtils; -import org.jackhuang.hellominecraft.util.OverridableSwingWorker; -import org.jackhuang.hellominecraft.util.tasks.TaskInfo; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; +import org.jackhuang.hellominecraft.util.task.TaskInfo; /** * Assets @@ -72,7 +71,7 @@ public abstract class IAssetsHandler { * * @param mv The version that needs assets * @param mp Asset Service - * @param x finished event + * @return just run it! */ public abstract Task getList(MinecraftVersion mv, IMinecraftAssetService mp); @@ -98,7 +97,7 @@ public abstract class IAssetsHandler { } @Override - public void executeTask() { + public void executeTask(boolean areDependTasksSucceeded) { if (assetsDownloadURLs == null || assetsLocalNames == null || contents == null) throw new IllegalStateException(C.i18n("assets.not_refreshed")); int max = assetsDownloadURLs.size(); @@ -108,15 +107,15 @@ public abstract class IAssetsHandler { String mark = assetsDownloadURLs.get(i); String url = u + mark; File location = assetsLocalNames.get(i); - if (!location.getParentFile().exists() && !location.getParentFile().mkdirs()) + if (!FileUtils.makeDirectory(location.getParentFile())) HMCLog.warn("Failed to make directories: " + location.getParent()); if (location.isDirectory()) continue; boolean need = true; try { if (location.exists()) { - FileInputStream fis = new FileInputStream(location); - String sha = DigestUtils.sha1Hex(NetUtils.getBytesFromStream(fis)); + FileInputStream fis = FileUtils.openInputStream(location); + String sha = DigestUtils.sha1Hex(IOUtils.toByteArray(fis)); IOUtils.closeQuietly(fis); if (contents.get(i).geteTag().equals(sha)) { ++hasDownloaded; @@ -131,7 +130,7 @@ public abstract class IAssetsHandler { need = !location.exists(); } if (need) - al.add(new FileDownloadTask(url, location).setTag(mark)); + al.add(new FileDownloadTask(url, location).setTag(contents.get(i).geteTag())); } } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/MinecraftAssetService.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/MinecraftAssetService.java index 626dbe7cf..89a751fcb 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/MinecraftAssetService.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/asset/MinecraftAssetService.java @@ -23,20 +23,21 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.Map; +import org.jackhuang.hellominecraft.launcher.core.GameException; +import org.jackhuang.hellominecraft.launcher.core.launch.IAssetProvider; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.core.version.AssetIndexDownloadInfo; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; import org.jackhuang.hellominecraft.util.MessageBox; -import org.jackhuang.hellominecraft.util.func.BiFunction; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; -import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.system.IOUtils; -import org.jackhuang.hellominecraft.util.tasks.TaskInfo; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.TaskWindow; +import org.jackhuang.hellominecraft.util.net.FileDownloadTask; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; +import org.jackhuang.hellominecraft.util.task.TaskInfo; /** * @@ -49,33 +50,33 @@ public class MinecraftAssetService extends IMinecraftAssetService { } @Override - public Task downloadAssets(final String mcVersion) { + public Task downloadAssets(final String mcVersion) throws GameException { return downloadAssets(service.version().getVersionById(mcVersion)); } - public Task downloadAssets(final MinecraftVersion mv) { + public Task downloadAssets(final MinecraftVersion mv) throws GameException { if (mv == null) return null; - return IAssetsHandler.ASSETS_HANDLER.getList(mv, service.asset()).after(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider())); + return IAssetsHandler.ASSETS_HANDLER.getList(mv.resolve(service.version()), service.asset()).with(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider())); } @Override - public boolean refreshAssetsIndex(String id) { + public boolean refreshAssetsIndex(String id) throws GameException { MinecraftVersion mv = service.version().getVersionById(id); if (mv == null) return false; - return downloadMinecraftAssetsIndexAsync(mv.getAssetsIndex()); + return downloadMinecraftAssetsIndexAsync(mv.resolve(service.version()).getAssetsIndex()); } @Override - public Task downloadMinecraftAssetsIndex(AssetIndexDownloadInfo assets) { + public Task downloadMinecraftAssetsIndex(AssetIndexDownloadInfo assetIndex) { File assetsLocation = getAssets(); - if (!assetsLocation.exists() && !assetsLocation.mkdirs()) + if (!FileUtils.makeDirectory(assetsLocation)) HMCLog.warn("Failed to make directories: " + assetsLocation); - File assetsIndex = new File(assetsLocation, "indexes/" + assets.getId() + ".json"); + File assetsIndex = getIndexFile(assetIndex.getId()); File renamed = null; if (assetsIndex.exists()) { - renamed = new File(assetsLocation, "indexes/" + assets.getId() + "-renamed.json"); + renamed = new File(assetsLocation, "indexes/" + assetIndex.getId() + "-renamed.json"); if (assetsIndex.renameTo(renamed)) HMCLog.warn("Failed to rename " + assetsIndex + " to " + renamed); } @@ -83,11 +84,11 @@ public class MinecraftAssetService extends IMinecraftAssetService { return new TaskInfo("Download Asset Index") { @Override public Collection getDependTasks() { - return Arrays.asList(new FileDownloadTask(assets.getUrl(service.getDownloadType()), IOUtils.tryGetCanonicalFile(assetsIndex), assets.sha1).setTag(assets.getId() + ".json")); + return Arrays.asList(new FileDownloadTask(assetIndex.getUrl(service.getDownloadType()), IOUtils.tryGetCanonicalFile(assetsIndex), assetIndex.sha1).setTag(assetIndex.getId() + ".json")); } @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { if (areDependTasksSucceeded) { if (renamedFinal != null && !renamedFinal.delete()) HMCLog.warn("Failed to delete " + renamedFinal + ", maybe you should do it."); @@ -98,20 +99,20 @@ public class MinecraftAssetService extends IMinecraftAssetService { } @Override - public boolean downloadMinecraftAssetsIndexAsync(AssetIndexDownloadInfo assets) { - File assetsLocation = getAssets(); - if (!assetsLocation.exists() && !assetsLocation.mkdirs()) - HMCLog.warn("Failed to make directories: " + assetsLocation); - File assetsIndex = new File(assetsLocation, "indexes/" + assets.getId() + ".json"); + public boolean downloadMinecraftAssetsIndexAsync(AssetIndexDownloadInfo assetIndex) { + File assetsDir = getAssets(); + if (!FileUtils.makeDirectory(assetsDir)) + HMCLog.warn("Failed to make directories: " + assetsDir); + File assetsIndex = getIndexFile(assetIndex.getId()); File renamed = null; if (assetsIndex.exists()) { - renamed = new File(assetsLocation, "indexes/" + assets.getId() + "-renamed.json"); + renamed = new File(assetsDir, "indexes/" + assetIndex.getId() + "-renamed.json"); if (assetsIndex.renameTo(renamed)) HMCLog.warn("Failed to rename " + assetsIndex + " to " + renamed); } if (TaskWindow.factory() - .append(new FileDownloadTask(assets.getUrl(service.getDownloadType()), IOUtils.tryGetCanonicalFile(assetsIndex), assets.sha1).setTag(assets.getId() + ".json")) - .create()) { + .append(new FileDownloadTask(assetIndex.getUrl(service.getDownloadType()), IOUtils.tryGetCanonicalFile(assetsIndex), assetIndex.sha1).setTag(assetIndex.getId() + ".json")) + .execute()) { if (renamed != null && !renamed.delete()) HMCLog.warn("Failed to delete " + renamed + ", maybe you should do it."); return true; @@ -125,30 +126,27 @@ public class MinecraftAssetService extends IMinecraftAssetService { public File getAssets() { return new File(service.baseDirectory(), "assets"); } + + private File getIndexFile(String assetVersion) { + return new File(getAssets(), "indexes/" + assetVersion + ".json"); + } @Override public File getAssetObject(String assetVersion, String name) throws IOException { - File assetsDir = getAssets(); - File indexDir = new File(assetsDir, "indexes"); - File objectsDir = new File(assetsDir, "objects"); - File indexFile = new File(indexDir, assetVersion + ".json"); try { - AssetsIndex index = (AssetsIndex) C.GSON.fromJson(FileUtils.read(indexFile, "UTF-8"), AssetsIndex.class); + AssetsIndex index = (AssetsIndex) C.GSON.fromJson(FileUtils.read(getIndexFile(assetVersion), "UTF-8"), AssetsIndex.class); String hash = ((AssetsObject) index.getFileMap().get(name)).getHash(); - return new File(objectsDir, hash.substring(0, 2) + "/" + hash); + return new File(getAssets(), "objects/" + hash.substring(0, 2) + "/" + hash); } catch (JsonSyntaxException e) { throw new IOException("Assets file format malformed.", e); } } private boolean checkAssetsExistance(AssetIndexDownloadInfo assetIndex) { - File assetsDir = getAssets(); - File indexDir = new File(assetsDir, "indexes"); - File objectDir = new File(assetsDir, "objects"); - File indexFile = new File(indexDir, assetIndex.getId() + ".json"); + File indexFile = getIndexFile(assetIndex.getId()); - if (!assetsDir.exists() || !indexFile.isFile()) + if (!getAssets().exists() || !indexFile.isFile()) return false; try { @@ -157,8 +155,8 @@ public class MinecraftAssetService extends IMinecraftAssetService { if (index == null) return false; - for (Map.Entry entry : index.getFileMap().entrySet()) - if (!new File(new File(objectDir, ((AssetsObject) entry.getValue()).getHash().substring(0, 2)), ((AssetsObject) entry.getValue()).getHash()).exists()) + for (Map.Entry entry : index.getFileMap().entrySet()) + if (!new File(getAssets(), "objects/" + ((AssetsObject) entry.getValue()).getHash().substring(0, 2) + "/" + ((AssetsObject) entry.getValue()).getHash()).exists()) return false; return true; } catch (IOException | JsonSyntaxException e) { @@ -168,10 +166,8 @@ public class MinecraftAssetService extends IMinecraftAssetService { private File reconstructAssets(AssetIndexDownloadInfo assetIndex) { File assetsDir = getAssets(); - File indexDir = new File(assetsDir, "indexes"); - File objectDir = new File(assetsDir, "objects"); String assetVersion = assetIndex.getId(); - File indexFile = new File(indexDir, assetVersion + ".json"); + File indexFile = getIndexFile(assetVersion); File virtualRoot = new File(new File(assetsDir, "virtual"), assetVersion); if (!indexFile.isFile()) { @@ -189,9 +185,9 @@ public class MinecraftAssetService extends IMinecraftAssetService { int cnt = 0; HMCLog.log("Reconstructing virtual assets folder at " + virtualRoot); int tot = index.getFileMap().entrySet().size(); - for (Map.Entry entry : index.getFileMap().entrySet()) { + for (Map.Entry entry : index.getFileMap().entrySet()) { File target = new File(virtualRoot, (String) entry.getKey()); - File original = new File(new File(objectDir, ((AssetsObject) entry.getValue()).getHash().substring(0, 2)), ((AssetsObject) entry.getValue()).getHash()); + File original = new File(assetsDir, "objects/" + ((AssetsObject) entry.getValue()).getHash().substring(0, 2) + "/" + ((AssetsObject) entry.getValue()).getHash()); if (original.exists()) { cnt++; if (!target.isFile()) @@ -209,10 +205,10 @@ public class MinecraftAssetService extends IMinecraftAssetService { return virtualRoot; } - public final BiFunction ASSET_PROVIDER_IMPL = (t, allow) -> { + public final IAssetProvider ASSET_PROVIDER_IMPL = (t, allow) -> { if (allow && !checkAssetsExistance(t.getAssetsIndex())) - if (MessageBox.Show(C.i18n("assets.no_assets"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) - TaskWindow.execute(downloadAssets(t)); + if (MessageBox.show(C.i18n("assets.no_assets"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) + TaskWindow.factory().execute(downloadAssets(t)); return reconstructAssets(t.getAssetsIndex()).getAbsolutePath(); }; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/BestLogin.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/BestLogin.java deleted file mode 100755 index 0a5bc8c52..000000000 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/BestLogin.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.auth; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.nio.charset.Charset; -import org.jackhuang.hellominecraft.util.code.DigestUtils; - -/** - * - * @author huangyuhui - */ -public final class BestLogin extends IAuthenticator { - - public BestLogin(String clientToken) { - super(clientToken); - } - - @Override - public UserProfileProvider login(LoginInfo info) throws AuthenticationException { - try { - String request = "bl:l:" + info.username + ":" + DigestUtils.sha1Hex(info.password); - - Socket socket = new Socket("auth.zhh0000zhh.com", 8); - OutputStream os = socket.getOutputStream(); - os.write(request.length()); - os.write(request.getBytes(Charset.forName("UTF-8"))); - - UserProfileProvider lr = new UserProfileProvider(); - - InputStream is = socket.getInputStream(); - int code = is.read(); - switch (code) { - case -1: - throw new AuthenticationException("internet error."); - case 200: - throw new AuthenticationException("server restarting."); - case 255: - throw new AuthenticationException("unknown error"); - case 3: - throw new AuthenticationException("unregistered."); - case 50: - throw new AuthenticationException("please update your launcher and act your account."); - case 2: - throw new AuthenticationException("wrong password."); - case 100: - throw new AuthenticationException("server reloading."); - case 0: - byte[] b = new byte[64]; - int x = is.read(b, 0, b.length); - if (x != -1) - throw new AuthenticationException("server response does not follow the protocol."); - String[] ss = new String(b, Charset.forName("UTF-8")).split(":"); - lr.setUserName(info.username); - lr.setUserId(ss[1]); - lr.setSession(ss[0]); - lr.setAccessToken(ss[0]); - break; - default: - break; - } - lr.setUserType("Legacy"); - return lr; - } catch (IOException t) { - throw new AuthenticationException(t); - } - } - - @Override - public String id() { - return "best"; - } - - @Override - public String getName() { - return "BestLogin"; - } - - @Override - public UserProfileProvider loginBySettings() { - return null; - } - - @Override - public void logOut() { - } - -} diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/IAuthenticator.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/IAuthenticator.java index f7a3a1133..dcac75f9d 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/IAuthenticator.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/IAuthenticator.java @@ -87,13 +87,13 @@ public abstract class IAuthenticator { public abstract void logOut(); - public Map onSaveSettings() { + public Map onSaveSettings() { HashMap m = new HashMap<>(); m.put("IAuthenticator_UserName", username); return m; } - public void onLoadSettings(Map m) { + public void onLoadSettings(Map m) { if (m == null) return; Object o = m.get("IAuthenticator_UserName"); diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/OfflineAuthenticator.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/OfflineAuthenticator.java index 48cfb00ed..7997d6a07 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/OfflineAuthenticator.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/OfflineAuthenticator.java @@ -29,7 +29,7 @@ import org.jackhuang.hellominecraft.util.code.DigestUtils; */ public final class OfflineAuthenticator extends IAuthenticator { - Map uuidMap = new HashMap<>(); + Map uuidMap = new HashMap<>(); public OfflineAuthenticator(String clientToken) { super(clientToken); @@ -42,7 +42,7 @@ public final class OfflineAuthenticator extends IAuthenticator { return; Object o = m.get("uuidMap"); if (o != null && o instanceof Map) - uuidMap = (Map) o; + uuidMap = (Map) o; } @Override @@ -56,21 +56,21 @@ public final class OfflineAuthenticator extends IAuthenticator { public UserProfileProvider login(LoginInfo info) throws AuthenticationException { if (StrUtils.isBlank(info.username)) throw new AuthenticationException(C.i18n("login.no_Player007")); - UserProfileProvider result = new UserProfileProvider(); - result.setUserName(info.username); String uuid = getUUIDFromUserName(info.username); - if (uuidMap != null && uuidMap.containsKey(uuid)) - uuid = uuidMap.get(info.username); + if (uuidMap != null && uuidMap.containsKey(info.username) && uuidMap.get(info.username) instanceof String) + uuid = (String) uuidMap.get(info.username); else { if (uuidMap == null) uuidMap = new HashMap<>(); uuidMap.put(info.username, uuid); } - result.setSession(uuid); - result.setUserId(uuid); - result.setAccessToken(uuid); - result.setUserType("Legacy"); - return result; + return new UserProfileProvider() + .setUserName(info.username) + .setSession(uuid) + .setUserId(uuid) + .setAccessToken(uuid) + .setUserType("Legacy") + .setClientIdentifier(clientToken); } public static String getUUIDFromUserName(String str) { diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/SkinmeAuthenticator.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/SkinmeAuthenticator.java deleted file mode 100755 index f173bf932..000000000 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/SkinmeAuthenticator.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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.auth; - -import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.code.DigestUtils; -import org.jackhuang.hellominecraft.util.NetUtils; -import org.jackhuang.hellominecraft.util.lang.SupportedLocales; -import org.jackhuang.hellominecraft.util.ui.SwingUtils; - -/** - * - * @author huangyuhui - */ -public final class SkinmeAuthenticator extends IAuthenticator { - - public SkinmeAuthenticator(String clientToken) { - super(clientToken); - } - - public String[] parseType1(String s) { - return s.split(","); - } - - public String getCharacter(String user, String hash, String $char) throws Exception { - return NetUtils.get( - "http://www.skinme.cc/api/login.php?user=" + user + "&hash=" + hash + (($char == null) ? "" : ("&char=" + $char))); - } - - @Override - public UserProfileProvider login(LoginInfo info) throws AuthenticationException { - UserProfileProvider req = new UserProfileProvider(); - if (info.username == null || !info.username.contains("@")) - throw new AuthenticationException(C.i18n("login.not_email")); - try { - String usr = info.username.toLowerCase(SupportedLocales.NOW_LOCALE.self); - String pwd = info.password; - - String str = DigestUtils.sha1Hex(usr); - String hashCode = DigestUtils.sha1Hex(DigestUtils.md5Hex(DigestUtils.sha1Hex(pwd) + pwd) + str); - String data = getCharacter(usr, hashCode, null); - String[] sl = data.split(":"); - if (null != sl[0]) - switch (sl[0]) { - case "0": - if (sl[1].contains("No Valid Character")) - sl[1] = C.i18n("login.no_valid_character"); - throw new AuthenticationException(sl[1]); - case "1": - String[] s = parseType1(sl[1]); - req.setUserName(s[0]); - req.setSession(s[1]); - req.setUserId(s[1]); - req.setAccessToken(s[1]); - break; - case "2": - String[] charators = sl[1].split(";"); - int len = charators.length; - String[] $char = new String[len]; - String[] user = new String[len]; - System.out.println(sl[1]); - for (int i = 0; i < len; i++) { - String[] charator = charators[i].split(","); - $char[i] = charator[0]; - user[i] = charator[1]; - } - int index = SwingUtils.select(user, C.i18n("login.choose_charactor")); - if (index == -1) - throw new AuthenticationException(C.i18n("message.cancelled")); - else { - String character = $char[index]; - sl = getCharacter(usr, hashCode, character).split(":"); - String[] s2 = parseType1(sl[1]); - req.setUserName(s2[0]); - req.setSession(s2[1]); - req.setUserId(s2[1]); - req.setAccessToken(s2[1]); - } - break; - } - - req.setUserType("Legacy"); - return req; - } catch (Exception e) { - throw new AuthenticationException(e); - } - } - - @Override - public String id() { - return "skinme"; - } - - @Override - public String getName() { - return "Skinme"; - } - - @Override - public UserProfileProvider loginBySettings() { - return null; - } - - @Override - public void logOut() { - - } -} diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/UserProfileProvider.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/UserProfileProvider.java index 348bb02c2..9009e5e0c 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/UserProfileProvider.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/UserProfileProvider.java @@ -27,74 +27,83 @@ public final class UserProfileProvider { return username; } - public void setUserName(String username) { + public UserProfileProvider setUserName(String username) { this.username = username; + return this; } public String getUserId() { return userId; } - public void setUserId(String userId) { + public UserProfileProvider setUserId(String userId) { this.userId = userId; + return this; } public String getSession() { return session; } - public void setSession(String session) { + public UserProfileProvider setSession(String session) { this.session = session; + return this; } public String getAccessToken() { return accessToken; } - public void setAccessToken(String accessToken) { + public UserProfileProvider setAccessToken(String accessToken) { if (accessToken == null) accessToken = "0"; this.accessToken = accessToken; + return this; } public String getUserProperties() { return userProperties; } - public void setUserProperties(String userProperties) { + public UserProfileProvider setUserProperties(String userProperties) { this.userProperties = userProperties; + return this; } public String getUserPropertyMap() { return userPropertyMap; } - public void setUserPropertyMap(String userPropertyMap) { + public UserProfileProvider setUserPropertyMap(String userPropertyMap) { this.userPropertyMap = userPropertyMap; + return this; } public String getOtherInfo() { return otherInfo; } - public void setOtherInfo(String otherInfo) { + public UserProfileProvider setOtherInfo(String otherInfo) { this.otherInfo = otherInfo; + return this; } public String getClientIdentifier() { return clientIdentifier; } - public void setClientIdentifier(String clientIdentifier) { + public UserProfileProvider setClientIdentifier(String clientIdentifier) { this.clientIdentifier = clientIdentifier; + return this; } public String getUserType() { return userType; } - public void setUserType(String userType) { + public UserProfileProvider setUserType(String userType) { this.userType = userType; + return this; } private String username = ""; diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/YggdrasilAuthenticator.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/YggdrasilAuthenticator.java index b5db2b902..5a945be88 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/YggdrasilAuthenticator.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/YggdrasilAuthenticator.java @@ -24,9 +24,9 @@ import javax.swing.JOptionPane; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.ArrayUtils; import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.GameProfile; +import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.UUIDTypeAdapter; import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.PropertyMap; import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.YggdrasilAuthentication; -import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.UUIDTypeAdapter; import org.jackhuang.hellominecraft.util.ui.SwingUtils; /** @@ -45,10 +45,9 @@ public final class YggdrasilAuthenticator extends IAuthenticator { @Override public UserProfileProvider login(LoginInfo info) throws AuthenticationException { UserProfileProvider result = new UserProfileProvider(); - result.setUserType("mojang"); if (ua.canPlayOnline()) { - result.setUserName(info.username); - result.setUserId(UUIDTypeAdapter.fromUUID(ua.getSelectedProfile().id)); + result.setUserName(info.username) + .setUserId(UUIDTypeAdapter.fromUUID(ua.getSelectedProfile().id)); } else { String usr = info.username; if (info.username == null || !info.username.contains("@")) @@ -80,14 +79,15 @@ public final class YggdrasilAuthenticator extends IAuthenticator { username = selectedProfile.name; if (username == null) throw new AuthenticationException("No player"); - result.setUserName(username); - result.setUserId(selectedProfile == null ? OfflineAuthenticator.getUUIDFromUserName(username) : UUIDTypeAdapter.fromUUID(selectedProfile.id)); + result.setUserName(username) + .setUserId(selectedProfile == null ? OfflineAuthenticator.getUUIDFromUserName(username) : UUIDTypeAdapter.fromUUID(selectedProfile.id)); } - result.setUserProperties(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new PropertyMap.LegacySerializer()).create().toJson(ua.getUserProperties())); - result.setUserPropertyMap(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create().toJson(ua.getUserProperties())); - result.setAccessToken(ua.getAuthenticatedToken()); - result.setSession(ua.getAuthenticatedToken()); - return result; + return result.setUserType("mojang") + .setUserProperties(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new PropertyMap.LegacySerializer()).create().toJson(ua.getUserProperties())) + .setUserPropertyMap(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create().toJson(ua.getUserProperties())) + .setAccessToken(ua.getAuthenticatedToken()) + .setSession(ua.getAuthenticatedToken()) + .setClientIdentifier(clientToken); } @Override diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/PropertyMap.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/PropertyMap.java index 166fe2cad..b687d5820 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/PropertyMap.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/PropertyMap.java @@ -31,7 +31,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; public class PropertyMap extends HashMap { diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/User.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/User.java index e5e0d111f..48f0e2d4f 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/User.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/User.java @@ -25,11 +25,6 @@ public class User { public User() { } - public User(String id, PropertyMap properties) { - this.id = id; - this.properties = properties; - } - public String getId() { return id; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/YggdrasilAuthentication.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/YggdrasilAuthentication.java index 53d89b54c..17f11de54 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/YggdrasilAuthentication.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/YggdrasilAuthentication.java @@ -29,8 +29,8 @@ import java.util.List; import java.util.Map; import java.util.UUID; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.NetUtils; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.net.NetUtils; import org.jackhuang.hellominecraft.util.StrUtils; public class YggdrasilAuthentication { @@ -140,7 +140,7 @@ public class YggdrasilAuthentication { private void loggedIn(URL url, Object input) throws AuthenticationException { try { - String jsonResult = input == null ? NetUtils.get(url) : NetUtils.post(url, GSON.toJson(input), "application/json", proxy); + String jsonResult = input == null ? NetUtils.get(url, proxy) : NetUtils.post(url, GSON.toJson(input), "application/json", proxy); Response response = (Response) GSON.fromJson(jsonResult, Response.class); if (response == null) @@ -188,24 +188,30 @@ public class YggdrasilAuthentication { public void loadFromStorage(Map credentials) { logOut(); - setUserName((String) credentials.get(STORAGE_KEY_USER_NAME)); + try { + setUserName((String) credentials.get(STORAGE_KEY_USER_NAME)); - if (credentials.containsKey(STORAGE_KEY_USER_ID)) - userid = (String) credentials.get(STORAGE_KEY_USER_ID); - else - userid = username; + if (credentials.containsKey(STORAGE_KEY_USER_ID)) + userid = (String) credentials.get(STORAGE_KEY_USER_ID); + else + userid = username; - if (credentials.containsKey(STORAGE_KEY_USER_PROPERTIES)) - userProperties.fromList((List>) credentials.get(STORAGE_KEY_USER_PROPERTIES)); + if (credentials.containsKey(STORAGE_KEY_USER_PROPERTIES)) + userProperties.fromList((List>) credentials.get(STORAGE_KEY_USER_PROPERTIES)); - if ((credentials.containsKey(STORAGE_KEY_PROFILE_NAME)) && (credentials.containsKey(STORAGE_KEY_PROFILE_ID))) { - GameProfile profile = new GameProfile(UUIDTypeAdapter.fromString((String) credentials.get(STORAGE_KEY_PROFILE_ID)), (String) credentials.get(STORAGE_KEY_PROFILE_NAME)); - if (credentials.containsKey(STORAGE_KEY_PROFILE_PROPERTIES)) - profile.properties.fromList((List>) credentials.get(STORAGE_KEY_PROFILE_PROPERTIES)); - selectedProfile = profile; + if ((credentials.containsKey(STORAGE_KEY_PROFILE_NAME)) && (credentials.containsKey(STORAGE_KEY_PROFILE_ID))) { + GameProfile profile = new GameProfile(UUIDTypeAdapter.fromString((String) credentials.get(STORAGE_KEY_PROFILE_ID)), (String) credentials.get(STORAGE_KEY_PROFILE_NAME)); + if (credentials.containsKey(STORAGE_KEY_PROFILE_PROPERTIES)) + profile.properties.fromList((List>) credentials.get(STORAGE_KEY_PROFILE_PROPERTIES)); + selectedProfile = profile; + } + + this.accessToken = (String) credentials.get(STORAGE_KEY_ACCESS_TOKEN); + } catch(Exception e) { + HMCLog.err("Failed to load yggdrasil authenticator settings, maybe its format is malformed.", e); + + logOut(); } - - this.accessToken = (String) credentials.get(STORAGE_KEY_ACCESS_TOKEN); } public Map saveForStorage() { diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/BMCLAPIDownloadProvider.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/BMCLAPIDownloadProvider.java index 24536b9b3..94e11757d 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/BMCLAPIDownloadProvider.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/BMCLAPIDownloadProvider.java @@ -18,6 +18,7 @@ package org.jackhuang.hellominecraft.launcher.core.download; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList; +import org.jackhuang.hellominecraft.util.C; /** * @@ -71,7 +72,9 @@ public class BMCLAPIDownloadProvider extends IDownloadProvider { : str.replace("https://launchermeta.mojang.com", "http://bmclapi2.bangbang93.com") .replace("https://launcher.mojang.com", "http://bmclapi2.bangbang93.com") .replace("https://libraries.minecraft.net", "http://bmclapi2.bangbang93.com/libraries") - .replace("http://files.minecraftforge.net/maven", "http://bmclapi2.bangbang93.com/maven"); + .replace("http://files.minecraftforge.net/maven", "http://bmclapi2.bangbang93.com/maven") + .replace(C.URL_LITELOADER_LIST, "http://bmclapi2.bangbang93.com/maven/com/mumfrey/liteloader/versions.json") + .replace("http://dl.liteloader.com/versions", "http://bmclapi2.bangbang93.com/maven"); } @Override diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadLibraryJob.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadLibraryJob.java index 7c5e28592..b596c91d2 100644 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadLibraryJob.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadLibraryJob.java @@ -19,7 +19,6 @@ 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; /** * @@ -34,6 +33,21 @@ public class DownloadLibraryJob { public DownloadLibraryJob(IMinecraftLibrary n, String u, File p) { url = u; lib = n; - path = IOUtils.tryGetCanonicalFile(p); + path = p; + } + + public DownloadLibraryJob parse() { + String name = lib.name; + if (name.startsWith("net.minecraftforge:forge:")) { + String[] s = name.split(":"); + if (s.length == 3) + url = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" + s[2] + "/forge-" + s[2] + "-universal.jar"; + } + if (name.startsWith("com.mumfrey:liteloader:")) { + String[] s = name.split(":"); + if (s.length == 3 && s[2].length() > 3) + url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + s[2].substring(0, s[2].length() - 3) + "/liteloader-" + s[2] + ".jar"; + } + return this; } } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadType.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadType.java index 1a7644ef7..d5841de85 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadType.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/DownloadType.java @@ -18,7 +18,7 @@ package org.jackhuang.hellominecraft.launcher.core.download; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; +import org.jackhuang.hellominecraft.util.task.TaskWindow; /** * @@ -28,7 +28,6 @@ public enum DownloadType { Mojang("download.mojang", new MojangDownloadProvider()), BMCL("download.BMCL", new BMCLAPIDownloadProvider()), - //RapidData("download.rapid_data", new RapidDataDownloadProvider()), Curse("Curse CDN", new CurseDownloadProvider()); private final String name; diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftDownloadService.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftDownloadService.java index 478ce10f5..8507570f2 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftDownloadService.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftDownloadService.java @@ -26,17 +26,17 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.core.version.GameDownloadInfo; import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; -import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask; +import org.jackhuang.hellominecraft.util.net.FileDownloadTask; import org.jackhuang.hellominecraft.util.func.Function; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.TaskInfo; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.TaskInfo; /** * @@ -75,7 +75,7 @@ public class MinecraftDownloadService extends IMinecraftDownloadService { } @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { File vpath = new File(service.baseDirectory(), "versions/" + id); if (!areDependTasksSucceeded) { FileUtils.deleteDirectory(vpath); @@ -131,7 +131,7 @@ public class MinecraftDownloadService extends IMinecraftDownloadService { public Task downloadMinecraftVersionJson(String id) { return new TaskInfo("Download Minecraft Json") { @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { List versions = MinecraftRemoteVersions.getRemoteVersions(service.getDownloadType()).justDo(); MinecraftRemoteVersion currentVersion = null; for (MinecraftRemoteVersion v : versions) @@ -144,7 +144,7 @@ public class MinecraftDownloadService extends IMinecraftDownloadService { String jsonURL = currentVersion.getUrl(service.getDownloadType()); File vpath = new File(service.baseDirectory(), "versions/" + id); File mvt = new File(vpath, id + ".json"); - if (!vpath.exists() && !vpath.mkdirs()) + if (!FileUtils.makeDirectory(vpath)) HMCLog.warn("Failed to make directories: " + vpath); if (mvt.exists() && !mvt.delete()) HMCLog.warn("Failed to delete " + mvt); diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteLatestVersion.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteLatestVersion.java index 02973eef6..d707fef92 100644 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteLatestVersion.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteLatestVersion.java @@ -17,12 +17,18 @@ */ package org.jackhuang.hellominecraft.launcher.core.download; +import com.google.gson.annotations.SerializedName; + /** * * @author huangyuhui */ public class MinecraftRemoteLatestVersion { - public String snapshot, release; + @SerializedName("snapshot") + public String snapshot; + + @SerializedName("release") + public String release; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteVersion.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteVersion.java index 04fe13457..64d787c8b 100644 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteVersion.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteVersion.java @@ -17,13 +17,23 @@ */ package org.jackhuang.hellominecraft.launcher.core.download; +import com.google.gson.annotations.SerializedName; + /** * * @author huangyuhui */ public class MinecraftRemoteVersion { - public String id, time, releaseTime, type; + @SerializedName("id") + public String id; + @SerializedName("time") + public String time; + @SerializedName("releaseTime") + public String releaseTime; + @SerializedName("type") + public String type; + @SerializedName("url") private String url; public String getUrl(DownloadType type) { diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteVersions.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteVersions.java index ddee725cd..7b408a01f 100644 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteVersions.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MinecraftRemoteVersions.java @@ -20,8 +20,8 @@ package org.jackhuang.hellominecraft.launcher.core.download; import com.google.gson.annotations.SerializedName; import java.util.ArrayList; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.NetUtils; -import org.jackhuang.hellominecraft.util.OverridableSwingWorker; +import org.jackhuang.hellominecraft.util.net.NetUtils; +import org.jackhuang.hellominecraft.util.AbstractSwingWorker; /** * @@ -55,7 +55,7 @@ public class MinecraftRemoteVersions { return new RemoteVersionsTask(type); } - public static class RemoteVersionsTask extends OverridableSwingWorker { + public static class RemoteVersionsTask extends AbstractSwingWorker { DownloadType type; diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MojangDownloadProvider.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MojangDownloadProvider.java index 6882922dd..815bbe4c9 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MojangDownloadProvider.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/MojangDownloadProvider.java @@ -64,7 +64,7 @@ public class MojangDownloadProvider extends IDownloadProvider { @Override public String getAssetsDownloadURL() { - return "https://resources.download.minecraft.net/"; + return "http://resources.download.minecraft.net/"; } @Override diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/RapidDataDownloadProvider.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/RapidDataDownloadProvider.java deleted file mode 100755 index eb22ccf74..000000000 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/download/RapidDataDownloadProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.download; - -/** - * - * @author huangyuhui - */ -public class RapidDataDownloadProvider extends MojangDownloadProvider { - - @Override - public String getAssetsDownloadURL() { - return "http://mirrors.rapiddata.org/resources.download.minecraft.net/"; - } - - @Override - public String getLibraryDownloadURL() { - return "http://mirrors.rapiddata.org/libraries.minecraft.net"; - } - - @Override - public String getIndexesDownloadURL() { - return "http://mirrors.rapiddata.org/Minecraft.Download/indexes/"; - } - - @Override - public String getVersionsDownloadURL() { - return "http://mirrors.rapiddata.org/Minecraft.Download/versions/"; - } - - @Override - public String getVersionsListDownloadURL() { - return "http://mirrors.rapiddata.org/Minecraft.Download/versions/versions.json"; - } - - @Override - public String getParsedDownloadURL(String str) { - return str == null ? null : str.replace("http://files.minecraftforge.net/maven", "http://mirrors.rapiddata.org/forge/maven"); - } - -} diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/InstallerVersionList.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/InstallerVersionList.java index 2aefcea2c..8aebc7d56 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/InstallerVersionList.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/InstallerVersionList.java @@ -19,16 +19,22 @@ package org.jackhuang.hellominecraft.launcher.core.install; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Objects; -import org.jackhuang.hellominecraft.util.tasks.Task; +import org.jackhuang.hellominecraft.util.StrUtils; +import org.jackhuang.hellominecraft.util.task.Task; /** * * @author huangyuhui */ public abstract class InstallerVersionList { + + public Map> versionMap; + public List versions; /** * Refresh installer versions list from the downloaded content. @@ -53,7 +59,17 @@ public abstract class InstallerVersionList { * * @return cached result. */ - protected abstract List getVersionsImpl(String mcVersion); + public List getVersionsImpl(String mcVersion) { + if (versions == null || versionMap == null) + return null; + if (StrUtils.isBlank(mcVersion)) + return versions; + List c = versionMap.get(mcVersion); + if (c == null) + return versions; + Collections.sort(c, InstallerVersionComparator.INSTANCE); + return c; + } /** * Get installers you want, please cache this method's result to save time. diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/MinecraftInstallerService.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/MinecraftInstallerService.java index cca25c86c..7287ed1b3 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/MinecraftInstallerService.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/MinecraftInstallerService.java @@ -23,13 +23,13 @@ import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList.InstallerVersion; import org.jackhuang.hellominecraft.launcher.core.install.forge.ForgeInstaller; import org.jackhuang.hellominecraft.launcher.core.install.liteloader.LiteLoaderInstaller; -import org.jackhuang.hellominecraft.launcher.core.install.liteloader.LiteLoaderVersionList; +import org.jackhuang.hellominecraft.launcher.core.install.liteloader.LiteLoaderInstallerVersion; import org.jackhuang.hellominecraft.launcher.core.install.optifine.OptiFineInstaller; import org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla.OptiFineDownloadFormatter; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask; -import org.jackhuang.hellominecraft.util.system.IOUtils; -import org.jackhuang.hellominecraft.util.tasks.DeleteFileTask; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.net.FileDownloadTask; +import org.jackhuang.hellominecraft.util.sys.IOUtils; +import org.jackhuang.hellominecraft.util.task.DeleteFileTask; /** * @@ -62,8 +62,8 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService return null; else return new FileDownloadTask(service.getDownloadType().getProvider().getParsedDownloadURL(v.installer), filepath).setTag("forge") - .after(new ForgeInstaller(service, filepath)) - .after(new DeleteFileTask(filepath)); + .with(new ForgeInstaller(service, filepath)) + .with(new DeleteFileTask(filepath)); } @Override @@ -72,16 +72,18 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService if (v.installer == null) return null; OptiFineDownloadFormatter task = new OptiFineDownloadFormatter(v.installer); - return task.after(new FileDownloadTask(filepath).registerPreviousResult(task).setTag("optifine")) - .after(new OptiFineInstaller(service, installId, v, filepath)) - .after(new DeleteFileTask(filepath)); + return task.with(new FileDownloadTask(filepath).registerPreviousResult(task).setTag("optifine")) + .with(new OptiFineInstaller(service, installId, v, filepath)) + .with(new DeleteFileTask(filepath)); } @Override public Task downloadLiteLoader(String installId, InstallerVersion v) { + if (!(v instanceof LiteLoaderInstallerVersion)) + throw new Error("Download lite loader but the version is not ll's."); File filepath = IOUtils.tryGetCanonicalFile("liteloader-universal.jar"); FileDownloadTask task = (FileDownloadTask) new FileDownloadTask(v.universal, filepath).setTag("LiteLoader"); - return task.after(new LiteLoaderInstaller(service, installId, (LiteLoaderVersionList.LiteLoaderInstallerVersion) v).registerPreviousResult(task)) - .after(new DeleteFileTask(filepath)); + return task.with(new LiteLoaderInstaller(service, installId, (LiteLoaderInstallerVersion) v).registerPreviousResult(task)) + .with(new DeleteFileTask(filepath)); } } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/PackMinecraftInstaller.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/PackMinecraftInstaller.java deleted file mode 100755 index 0730b1366..000000000 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/PackMinecraftInstaller.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.install; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.Compressor; -import org.jackhuang.hellominecraft.util.system.FileUtils; - -/** - * - * @author huangyuhui - */ -public class PackMinecraftInstaller { - - File dest; - ArrayList src; - - public PackMinecraftInstaller(ArrayList src, File dest) { - this.dest = dest; - this.src = src; - } - - public void install() throws IOException { - File file = new File("HMCL-MERGE-TEMP"); - if (!file.exists() && !file.mkdirs()) - HMCLog.warn("Failed to make directories: " + file); - for (String src1 : src) - Compressor.unzip(new File(src1), file); - Compressor.zip(file.getAbsolutePath(), dest.getAbsolutePath()); - FileUtils.deleteDirectory(file); - } -} diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/ForgeInstaller.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/ForgeInstaller.java index 7d0d76e11..7b9b6b316 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/ForgeInstaller.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/ForgeInstaller.java @@ -24,14 +24,13 @@ import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.NetUtils; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary; import org.jackhuang.hellominecraft.util.MessageBox; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * @@ -50,36 +49,39 @@ public class ForgeInstaller extends Task { } @Override - public void executeTask() throws Exception { + public void executeTask(boolean areDependTasksSucceeded) throws Exception { HMCLog.log("Extracting install profiles..."); try (ZipFile zipFile = new ZipFile(forgeInstaller)) { ZipEntry entry = zipFile.getEntry("install_profile.json"); - String content = NetUtils.getStreamContent(zipFile.getInputStream(entry)); + String content = IOUtils.toString(zipFile.getInputStream(entry)); InstallProfile profile = C.GSON.fromJson(content, InstallProfile.class); File from = new File(gameDir, "versions" + File.separator + profile.install.getMinecraft()); if (!from.exists()) - if (MessageBox.Show(C.i18n("install.no_version_if_intall")) == MessageBox.YES_OPTION) { + if (MessageBox.show(C.i18n("install.no_version_if_intall")) == MessageBox.YES_OPTION) { if (!mp.version().install(profile.install.getMinecraft(), null)) throw new IllegalStateException(C.i18n("install.no_version")); } else throw new IllegalStateException(C.i18n("install.no_version")); File to = new File(gameDir, "versions" + File.separator + profile.install.getTarget()); - if (!to.exists() && !to.mkdirs()) + if (!FileUtils.makeDirectory(to)) HMCLog.warn("Failed to make new version folder " + to); + HMCLog.log("Copying jar..." + profile.install.getMinecraft() + ".jar to " + profile.install.getTarget() + ".jar"); FileUtils.copyFile(new File(from, profile.install.getMinecraft() + ".jar"), new File(to, profile.install.getTarget() + ".jar")); + HMCLog.log("Creating new version profile..." + profile.install.getTarget() + ".json"); FileUtils.write(new File(to, profile.install.getTarget() + ".json"), C.GSON.toJson(profile.versionInfo)); + HMCLog.log("Extracting universal forge pack..." + profile.install.getFilePath()); entry = zipFile.getEntry(profile.install.getFilePath()); InputStream is = zipFile.getInputStream(entry); MinecraftLibrary forge = new MinecraftLibrary(profile.install.getPath()); File file = new File(gameDir, "libraries/" + forge.getDownloadInfo().path); - if (file.getParentFile().mkdirs()) + if (!FileUtils.makeDirectory(file)) HMCLog.warn("Failed to make library directory " + file.getParent()); - try (FileOutputStream fos = new FileOutputStream(file)) { + try (FileOutputStream fos = FileUtils.openOutputStream(file)) { IOUtils.copyStream(is, fos); } mp.version().refreshVersions(); diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/Install.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/Install.java index eadf7b065..4c8863ef2 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/Install.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/Install.java @@ -47,19 +47,6 @@ public class Install { public Install() { } - public Install(String profileName, String target, String path, String version, String filePath, String welcome, String minecraft, String mirrorList, String logo) { - this(); - this.profileName = profileName; - this.target = target; - this.path = path; - this.version = version; - this.filePath = filePath; - this.welcome = welcome; - this.minecraft = minecraft; - this.mirrorList = mirrorList; - this.logo = logo; - } - public String getProfileName() { return profileName; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/MinecraftForgeVersion.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/MinecraftForgeVersion.java index 349f589eb..f6bd01f03 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/MinecraftForgeVersion.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/MinecraftForgeVersion.java @@ -76,16 +76,4 @@ public class MinecraftForgeVersion { this.modified = modified; } - public MinecraftForgeVersion() { - } - - public MinecraftForgeVersion(String branch, String mcversion, String jobver, String version, int build, double modified) { - this.branch = branch; - this.mcversion = mcversion; - this.jobver = jobver; - this.version = version; - this.build = build; - this.modified = modified; - } - } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/MinecraftForgeVersionList.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/MinecraftForgeVersionList.java index 984425ca1..17d44e4e7 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/MinecraftForgeVersionList.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/MinecraftForgeVersionList.java @@ -22,16 +22,15 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.launcher.core.download.DownloadType; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionNewerComparator; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.TaskInfo; -import org.jackhuang.hellominecraft.util.tasks.download.HTTPGetTask; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.TaskInfo; +import org.jackhuang.hellominecraft.util.net.HTTPGetTask; /** * @@ -48,8 +47,6 @@ public class MinecraftForgeVersionList extends InstallerVersionList { } public MinecraftForgeVersionRoot root; - public Map> versionMap; - public List versions; @Override public Task refresh(String[] needed) { @@ -60,11 +57,11 @@ public class MinecraftForgeVersionList extends InstallerVersionList { @Override public Collection getDependTasks() { - return Arrays.asList(task); + return Arrays.asList(task.setTag("Official Forge Download Site")); } @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { if (!areDependTasksSucceeded) return; String s = task.getResult(); @@ -116,19 +113,6 @@ public class MinecraftForgeVersionList extends InstallerVersionList { }; } - @Override - public List getVersionsImpl(String mcVersion) { - if (versions == null || versionMap == null) - return null; - if (StrUtils.isBlank(mcVersion)) - return versions; - List c = versionMap.get(mcVersion); - if (c == null) - return versions; - Collections.sort(c, InstallerVersionComparator.INSTANCE); - return c; - } - @Override public String getName() { return "Forge - MinecraftForge Offical Site"; diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderInstaller.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderInstaller.java index f41837570..b4e954345 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderInstaller.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderInstaller.java @@ -21,12 +21,12 @@ import java.io.File; import java.util.ArrayList; import java.util.Arrays; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult; -import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResultRegistrar; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.comm.PreviousResult; +import org.jackhuang.hellominecraft.util.task.comm.PreviousResultRegistrar; +import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; @@ -36,16 +36,16 @@ import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; */ public class LiteLoaderInstaller extends Task implements PreviousResultRegistrar { - public LiteLoaderVersionList.LiteLoaderInstallerVersion version; + public LiteLoaderInstallerVersion version; public File installer; public String installId; public IMinecraftService service; - public LiteLoaderInstaller(IMinecraftService service, String installId, LiteLoaderVersionList.LiteLoaderInstallerVersion v) { + public LiteLoaderInstaller(IMinecraftService service, String installId, LiteLoaderInstallerVersion v) { this(service, installId, v, null); } - public LiteLoaderInstaller(IMinecraftService service, String installId, LiteLoaderVersionList.LiteLoaderInstallerVersion v, File installer) { + public LiteLoaderInstaller(IMinecraftService service, String installId, LiteLoaderInstallerVersion v, File installer) { this.service = service; this.installId = installId; this.version = v; @@ -53,7 +53,7 @@ public class LiteLoaderInstaller extends Task implements PreviousResultRegistrar } @Override - public void executeTask() throws Exception { + public void executeTask(boolean areDependTasksSucceeded) throws Exception { if (installId == null) throw new IllegalStateException(C.i18n("install.no_version")); if (pre.size() != 1 && installer == null) @@ -63,7 +63,7 @@ public class LiteLoaderInstaller extends Task implements PreviousResultRegistrar MinecraftVersion mv = (MinecraftVersion) service.version().getVersionById(installId).clone(); mv.inheritsFrom = mv.id; mv.jar = mv.jar == null ? mv.id : mv.jar; - mv.libraries = new ArrayList(Arrays.asList(version.libraries)); + mv.libraries = new ArrayList<>(Arrays.asList(version.libraries)); MinecraftLibrary ml = new MinecraftLibrary("com.mumfrey:liteloader:" + version.selfVersion); //ml.url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + version.mcVersion + "/liteloader-" + version.selfVersion + ".jar"; @@ -75,7 +75,7 @@ public class LiteLoaderInstaller extends Task implements PreviousResultRegistrar mv.mainClass = "net.minecraft.launchwrapper.Launch"; mv.minecraftArguments += " --tweakClass " + version.tweakClass; File folder = new File(service.baseDirectory(), "versions/" + mv.id); - if (!folder.exists() && folder.mkdirs()) + if (!FileUtils.makeDirectory(folder)) HMCLog.warn("Failed to create new liteloader version " + folder); File json = new File(folder, mv.id + ".json"); HMCLog.log("Creating new version profile..." + mv.id + ".json"); @@ -92,7 +92,7 @@ public class LiteLoaderInstaller extends Task implements PreviousResultRegistrar ArrayList> pre = new ArrayList<>(); @Override - public Task registerPreviousResult(PreviousResult pr) { + public Task registerPreviousResult(PreviousResult pr) { pre.add(pr); return this; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderInstallerVersion.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderInstallerVersion.java new file mode 100644 index 000000000..9b5cab2a0 --- /dev/null +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderInstallerVersion.java @@ -0,0 +1,58 @@ +/* + * 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.install.liteloader; + +import java.util.Arrays; +import java.util.Objects; +import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList; +import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary; + +/** + * + * @author huang + */ +public class LiteLoaderInstallerVersion extends InstallerVersionList.InstallerVersion { + + public MinecraftLibrary[] libraries; + public String tweakClass; + + public LiteLoaderInstallerVersion(String selfVersion, String mcVersion) { + super(selfVersion, mcVersion); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 13 * hash + Arrays.deepHashCode(this.libraries); + hash = 13 * hash + Objects.hashCode(this.tweakClass); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof LiteLoaderVersionList)) + return false; + if (this == obj) + return true; + final LiteLoaderInstallerVersion other = (LiteLoaderInstallerVersion) obj; + if (!Objects.equals(this.tweakClass, other.tweakClass)) + return false; + return Arrays.deepEquals(this.libraries, other.libraries); + } + +} diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderVersionList.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderVersionList.java index b8ab21c0b..6040dde55 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderVersionList.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderVersionList.java @@ -22,17 +22,15 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; +import org.jackhuang.hellominecraft.launcher.core.download.DownloadType; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList; -import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList.InstallerVersion; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionNewerComparator; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.TaskInfo; -import org.jackhuang.hellominecraft.util.tasks.download.HTTPGetTask; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.TaskInfo; +import org.jackhuang.hellominecraft.util.net.HTTPGetTask; /** * @@ -49,23 +47,21 @@ public class LiteLoaderVersionList extends InstallerVersionList { } public LiteLoaderVersionsRoot root; - public Map> versionMap; - public List versions; @Override public Task refresh(String[] needed) { if (root != null) return null; return new TaskInfo(C.i18n("install.liteloader.get_list")) { - HTTPGetTask task = new HTTPGetTask(C.URL_LITELOADER_LIST); + HTTPGetTask task = new HTTPGetTask(DownloadType.getSuggestedDownloadType().getProvider().getParsedDownloadURL(C.URL_LITELOADER_LIST)); @Override public Collection getDependTasks() { - return Arrays.asList(task); + return Arrays.asList(task.setTag("Official Liteloader Download Site")); } @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { if (!areDependTasksSucceeded) return; String s = task.getResult(); @@ -85,7 +81,7 @@ public class LiteLoaderVersionList extends InstallerVersionList { continue; LiteLoaderVersion v = entry.getValue(); LiteLoaderInstallerVersion iv = new LiteLoaderInstallerVersion(v.version, StrUtils.formatVersion(arr.getKey())); - iv.universal = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + arr.getKey() + "/" + v.file; + iv.universal = DownloadType.getSuggestedDownloadType().getProvider().getParsedDownloadURL("http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + arr.getKey() + "/" + v.file); iv.tweakClass = v.tweakClass; iv.libraries = Arrays.copyOf(v.libraries, v.libraries.length); iv.installer = "http://dl.liteloader.com/redist/" + iv.mcVersion + "/liteloader-installer-" + iv.selfVersion.replace("_", "-") + ".jar"; @@ -101,33 +97,9 @@ public class LiteLoaderVersionList extends InstallerVersionList { }; } - @Override - public List getVersionsImpl(String mcVersion) { - if (versions == null || versionMap == null) - return null; - if (StrUtils.isBlank(mcVersion)) - return versions; - List c = versionMap.get(mcVersion); - if (c == null) - return versions; - Collections.sort(c, InstallerVersionComparator.INSTANCE); - return c; - } - @Override public String getName() { return "LiteLoader - LiteLoader Official Site(By: Mumfrey)"; } - public static class LiteLoaderInstallerVersion extends InstallerVersion { - - public MinecraftLibrary[] libraries; - public String tweakClass; - - public LiteLoaderInstallerVersion(String selfVersion, String mcVersion) { - super(selfVersion, mcVersion); - } - - } - } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderVersionsMeta.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderVersionsMeta.java index ee7a991e6..078ad9823 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderVersionsMeta.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/liteloader/LiteLoaderVersionsMeta.java @@ -35,13 +35,6 @@ public class LiteLoaderVersionsMeta { public LiteLoaderVersionsMeta() { } - public LiteLoaderVersionsMeta(String description, String authors, String url) { - this(); - this.description = description; - this.authors = authors; - this.url = url; - } - public String getDescription() { return description; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/OptiFineInstaller.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/OptiFineInstaller.java index 4dd27d7a1..499f15446 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/OptiFineInstaller.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/OptiFineInstaller.java @@ -23,13 +23,13 @@ import java.util.zip.ZipFile; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult; -import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResultRegistrar; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.comm.PreviousResult; +import org.jackhuang.hellominecraft.util.task.comm.PreviousResultRegistrar; +import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * @@ -42,10 +42,6 @@ public class OptiFineInstaller extends Task implements PreviousResultRegistrar> pre = new ArrayList(); + ArrayList> pre = new ArrayList<>(); @Override - public Task registerPreviousResult(PreviousResult pr) { + public Task registerPreviousResult(PreviousResult pr) { pre.add(pr); return this; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/OptiFineVersion.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/OptiFineVersion.java index de60439a8..824beee6f 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/OptiFineVersion.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/OptiFineVersion.java @@ -23,7 +23,8 @@ package org.jackhuang.hellominecraft.launcher.core.install.optifine; */ public class OptiFineVersion { - private String dl, ver, date, mirror, mcver; + private String dl, ver, date, mirror, mcversion; + public String patch, type; // For BMCLAPI2. public String getDownloadLink() { return dl; @@ -58,10 +59,10 @@ public class OptiFineVersion { } public String getMCVersion() { - return mcver; + return mcversion; } public void setMCVersion(String mcver) { - this.mcver = mcver; + this.mcversion = mcver; } } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/bmcl/OptiFineBMCLVersionList.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/bmcl/OptiFineBMCLVersionList.java index f0003b91f..c87c64f40 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/bmcl/OptiFineBMCLVersionList.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/bmcl/OptiFineBMCLVersionList.java @@ -24,18 +24,16 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.ArrayUtils; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList; import org.jackhuang.hellominecraft.launcher.core.install.optifine.OptiFineVersion; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.TaskInfo; -import org.jackhuang.hellominecraft.util.tasks.download.HTTPGetTask; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.TaskInfo; +import org.jackhuang.hellominecraft.util.net.HTTPGetTask; /** * @@ -52,8 +50,6 @@ public class OptiFineBMCLVersionList extends InstallerVersionList { } public ArrayList root; - public Map> versionMap; - public List versions; private static final Type TYPE = new TypeToken>() { }.getType(); @@ -65,32 +61,31 @@ public class OptiFineBMCLVersionList extends InstallerVersionList { @Override public Collection getDependTasks() { - return Arrays.asList(task); + return Arrays.asList(task.setTag("BMCL Optifine Download Site")); } @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { String s = task.getResult(); versionMap = new HashMap<>(); versions = new ArrayList<>(); + + HashSet duplicates = new HashSet<>(); if (s == null) return; root = C.GSON.fromJson(s, TYPE); for (OptiFineVersion v : root) { - v.setMirror(v.getMirror().replace("http://optifine.net/http://optifine.net/", "http://optifine.net/")); - - if (StrUtils.isBlank(v.getMCVersion())) { - Pattern p = Pattern.compile("OptiFine (.*) HD"); - Matcher m = p.matcher(v.getVersion()); - while (m.find()) - v.setMCVersion(m.group(1)); - } + v.setVersion(v.type + '_' + v.patch); + v.setMirror(String.format("http://bmclapi2.bangbang93.com/optifine/%s/%s/%s", v.getMCVersion(), v.type, v.patch)); + if (duplicates.contains(v.getMirror())) + continue; + else + duplicates.add(v.getMirror()); InstallerVersion iv = new InstallerVersion(v.getVersion(), StrUtils.formatVersion(v.getMCVersion())); List al = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.getMCVersion())); - //String url = "http://bmclapi.bangbang93.com/optifine/" + iv.selfVersion.replace(" ", "%20"); iv.installer = iv.universal = v.getMirror(); al.add(iv); versions.add(iv); @@ -101,19 +96,6 @@ public class OptiFineBMCLVersionList extends InstallerVersionList { }; } - @Override - public List getVersionsImpl(String mcVersion) { - if (versions == null || versionMap == null) - return null; - if (StrUtils.isBlank(mcVersion)) - return versions; - List c = versionMap.get(mcVersion); - if (c == null) - return versions; - Collections.sort(c, InstallerVersionComparator.INSTANCE); - return c; - } - @Override public String getName() { return "OptiFine - BMCLAPI(By: bangbang93)"; diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/vanilla/OptiFineDownloadFormatter.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/vanilla/OptiFineDownloadFormatter.java index 107bacafc..418a3b522 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/vanilla/OptiFineDownloadFormatter.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/optifine/vanilla/OptiFineDownloadFormatter.java @@ -20,9 +20,9 @@ package org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult; -import org.jackhuang.hellominecraft.util.NetUtils; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.comm.PreviousResult; +import org.jackhuang.hellominecraft.util.net.NetUtils; /** * @@ -37,7 +37,7 @@ public class OptiFineDownloadFormatter extends Task implements PreviousResult root = new ArrayList(); - public Map> versionMap; - public List versions; + public ArrayList root = new ArrayList<>(); @Override public Task refresh(String[] sss) { @@ -72,11 +69,11 @@ public class OptiFineVersionList extends InstallerVersionList { @Override public Collection getDependTasks() { - return Arrays.asList(task); + return Arrays.asList(task.setTag("Optifine Download Site")); } @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { if (!areDependTasksSucceeded) return; String content = task.getResult(); @@ -138,18 +135,4 @@ public class OptiFineVersionList extends InstallerVersionList { public String getName() { return "OptiFine - OptiFine Official Site"; } - - @Override - public List getVersionsImpl(String mcVersion) { - if (versions == null || versionMap == null) - return null; - if (StrUtils.isBlank(mcVersion)) - return versions; - List c = versionMap.get(mcVersion); - if (c == null) - return versions; - Collections.sort(c, InstallerVersionComparator.INSTANCE); - return c; - } - } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/AbstractMinecraftLoader.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/AbstractMinecraftLoader.java index 5e501bb38..740c80773 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/AbstractMinecraftLoader.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/AbstractMinecraftLoader.java @@ -22,12 +22,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.JdkVersion; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.JdkVersion; import org.jackhuang.hellominecraft.util.MathUtils; import org.jackhuang.hellominecraft.util.MessageBox; -import org.jackhuang.hellominecraft.util.system.OS; -import org.jackhuang.hellominecraft.util.system.Platform; +import org.jackhuang.hellominecraft.util.sys.OS; +import org.jackhuang.hellominecraft.util.sys.Platform; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider; @@ -104,17 +104,17 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader { HMCLog.log("System Platform: " + Platform.getPlatform().getBit()); if (jv != null && jv.getPlatform() == Platform.BIT_32 && Platform.getPlatform() == Platform.BIT_64) - MessageBox.Show(C.i18n("advice.os64butjdk32")); + MessageBox.show(C.i18n("advice.os64butjdk32")); if (!StrUtils.isBlank(options.getMaxMemory())) { int mem = MathUtils.parseMemory(options.getMaxMemory(), 2147483647); if (jv != null && jv.getPlatform() == Platform.BIT_32 && mem > 1024) - MessageBox.Show(C.i18n("launch.too_big_memory_alloc_64bit")); + MessageBox.show(C.i18n("launch.too_big_memory_alloc_64bit")); else { long a = OS.getTotalPhysicalMemory() / 1024 / 1024; HMCLog.log("System Physical Memory: " + a); if (a > 0 && a < mem) - MessageBox.Show(C.i18n("launch.too_big_memory_alloc_free_space_too_low", a)); + MessageBox.show(C.i18n("launch.too_big_memory_alloc_free_space_too_low", a)); } String a = "-Xmx" + options.getMaxMemory(); if (MathUtils.canParseInt(options.getMaxMemory())) diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java index 8c0e006e5..562bdba57 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java @@ -20,14 +20,14 @@ package org.jackhuang.hellominecraft.launcher.core.launch; import java.io.IOException; import java.util.HashSet; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.LoginInfo; import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; -import org.jackhuang.hellominecraft.util.tasks.ParallelTask; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; -import org.jackhuang.hellominecraft.util.system.Compressor; +import org.jackhuang.hellominecraft.util.task.ParallelTask; +import org.jackhuang.hellominecraft.util.task.TaskWindow; +import org.jackhuang.hellominecraft.util.sys.CompressingUtils; import org.jackhuang.hellominecraft.util.MessageBox; public class DefaultGameLauncher extends GameLauncher { @@ -46,13 +46,13 @@ public class DefaultGameLauncher extends GameLauncher { if (names.contains(s.lib.name)) continue; names.add(s.lib.name); - parallelTask.addDependsTask(new LibraryDownloadTask(s)); + parallelTask.addTask(new LibraryDownloadTask(s)); } dw.append(parallelTask); boolean flag = true; if (t.size() > 0) - flag = dw.create(); - if (!flag && MessageBox.Show(C.i18n("launch.not_finished_downloading_libraries"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) + flag = dw.execute(); + if (!flag && MessageBox.show(C.i18n("launch.not_finished_downloading_libraries"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) flag = true; return flag; }); @@ -61,7 +61,7 @@ public class DefaultGameLauncher extends GameLauncher { return false; for (int i = 0; i < value.decompressFiles.length; i++) try { - Compressor.unzip(value.decompressFiles[i], value.getDecompressTo(), value.extractRules[i]::allow, false); + CompressingUtils.unzip(value.decompressFiles[i], value.getDecompressTo(), value.extractRules[i]::allow, false); } catch (IOException ex) { HMCLog.err("Unable to decompress library: " + value.decompressFiles[i] + " to " + value.getDecompressTo(), ex); } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/GameLauncher.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/GameLauncher.java index 14e1f0e66..7929359a2 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/GameLauncher.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/GameLauncher.java @@ -17,33 +17,32 @@ */ package org.jackhuang.hellominecraft.launcher.core.launch; -import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader; -import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; import java.util.List; -import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; import org.jackhuang.hellominecraft.launcher.api.PluginManager; import org.jackhuang.hellominecraft.launcher.core.GameException; +import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.LoginInfo; import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider; -import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException; import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob; +import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader; +import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.core.version.DecompressLibraryJob; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.system.IOUtils; -import org.jackhuang.hellominecraft.util.system.JavaProcess; -import org.jackhuang.hellominecraft.util.MessageBox; -import org.jackhuang.hellominecraft.util.system.OS; -import org.jackhuang.hellominecraft.util.StrUtils; +import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.EventHandler; -import org.jackhuang.hellominecraft.util.system.ProcessManager; +import org.jackhuang.hellominecraft.util.StrUtils; +import org.jackhuang.hellominecraft.util.code.Charsets; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; +import org.jackhuang.hellominecraft.util.sys.JavaProcess; +import org.jackhuang.hellominecraft.util.sys.OS; +import org.jackhuang.hellominecraft.util.sys.ProcessManager; public class GameLauncher { @@ -117,7 +116,6 @@ public class GameLauncher { * Launch the game "as soon as possible". * * @param str launch command - * * @throws IOException failed creating process */ public void launch(List str) throws IOException { @@ -138,7 +136,7 @@ public class GameLauncher { if (options.getLaunchVersion() == null || service.baseDirectory() == null) throw new Error("Fucking bug!"); builder.redirectErrorStream(true).directory(service.version().getRunDirectory(options.getLaunchVersion())) - .environment().put("APPDATA", service.baseDirectory().getAbsolutePath()); + .environment().put("APPDATA", service.baseDirectory().getAbsolutePath()); JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER); HMCLog.log("Have started the process"); launchEvent.execute(jp); @@ -148,13 +146,13 @@ public class GameLauncher { * According to the name... * * @param launcherName the name of launch bat/sh - * @param str launch command + * @param str launch command * * @return launcher location * * @throws java.io.IOException write contents failed. */ - public File makeLauncher(String launcherName, List str) throws IOException { + public File makeLauncher(String launcherName, List str) throws IOException { HMCLog.log("Making shell launcher..."); service.version().onLaunch(options.getLaunchVersion()); boolean isWin = OS.os() == OS.WINDOWS; @@ -162,33 +160,28 @@ public class GameLauncher { if (!f.exists() && !f.createNewFile()) HMCLog.warn("Failed to create " + f); BufferedWriter writer; - try { - writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), System.getProperty("sun.jnu.encoding", "UTF-8"))); - } catch (UnsupportedEncodingException ex) { - HMCLog.warn("Failed to create writer, will try again.", ex); - writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f))); - } - if (isWin) { - writer.write("@echo off"); - writer.newLine(); - String appdata = IOUtils.tryGetCanonicalFilePath(service.baseDirectory()); - if (appdata != null) { - writer.write("set appdata=" + appdata); + try (FileOutputStream fos = FileUtils.openOutputStream(f)) { + writer = new BufferedWriter(new OutputStreamWriter(fos, Charsets.toCharset())); + if (isWin) { + writer.write("@echo off"); writer.newLine(); - writer.write("cd /D %appdata%"); + String appdata = IOUtils.tryGetCanonicalFilePath(service.baseDirectory()); + if (appdata != null) { + writer.write("set appdata=" + appdata); + writer.newLine(); + writer.write("cd /D %appdata%"); + writer.newLine(); + } + } + if (StrUtils.isNotBlank(options.getPrecalledCommand())) { + writer.write(options.getPrecalledCommand()); writer.newLine(); } + writer.write(StrUtils.makeCommand(str)); + writer.close(); } - if (StrUtils.isNotBlank(options.getPrecalledCommand())) { - writer.write(options.getPrecalledCommand()); - writer.newLine(); - } - writer.write(StrUtils.makeCommand(str)); - writer.close(); - if (!f.setExecutable(true)) { - HMCLog.warn("Failed to give launcher permission."); - MessageBox.Show(C.i18n("launch.failed_sh_permission")); - } + if (!f.setExecutable(true)) + throw new IOException(C.i18n("launch.failed_sh_permission")); HMCLog.log("Command: " + StrUtils.parseParams("", str, " ")); return f; diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/communication/DefaultPreviousResult.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/IAssetProvider.java old mode 100755 new mode 100644 similarity index 66% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/communication/DefaultPreviousResult.java rename to HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/IAssetProvider.java index ea6d688c0..a21473103 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/communication/DefaultPreviousResult.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/IAssetProvider.java @@ -1,7 +1,7 @@ /* - * Hello Minecraft!. + * 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 @@ -15,24 +15,16 @@ * 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.tasks.communication; +package org.jackhuang.hellominecraft.launcher.core.launch; + +import org.jackhuang.hellominecraft.launcher.core.GameException; +import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; /** * - * @author huangyuhui - * @param the type of result. + * @author huang */ -public class DefaultPreviousResult implements PreviousResult { - - T a; - - public DefaultPreviousResult(T a) { - this.a = a; - } - - @Override - public T getResult() { - return a; - } - +public interface IAssetProvider { + + String provide(MinecraftVersion mv, Boolean allowChecking) throws GameException; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/LaunchOptions.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/LaunchOptions.java index e57ae697c..b70874516 100644 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/LaunchOptions.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/LaunchOptions.java @@ -20,7 +20,7 @@ package org.jackhuang.hellominecraft.launcher.core.launch; import java.io.File; import org.jackhuang.hellominecraft.launcher.core.version.GameDirType; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.system.JdkVersion; +import org.jackhuang.hellominecraft.util.sys.JdkVersion; /** * diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/LibraryDownloadTask.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/LibraryDownloadTask.java index 3cd1cfbb9..9d497eb3d 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/LibraryDownloadTask.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/LibraryDownloadTask.java @@ -17,11 +17,9 @@ */ package org.jackhuang.hellominecraft.launcher.core.launch; -import java.io.File; -import java.net.URL; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob; -import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask; +import org.jackhuang.hellominecraft.util.net.FileDownloadTask; /** * @@ -32,32 +30,10 @@ public class LibraryDownloadTask extends FileDownloadTask { DownloadLibraryJob job; public LibraryDownloadTask(DownloadLibraryJob job) { - super(); + super(job.parse().url, job.path); this.job = job; } - @Override - public void executeTask() throws Throwable { - 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 (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"; - } - download(new URL(job.url), job.path); - } - - void download(URL url, File filePath) throws Throwable { - this.url = url; - this.filePath = filePath; - super.executeTask(); - } - @Override public String getInfo() { return C.i18n("download") + ": " + job.lib.name; diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/MinecraftLoader.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/MinecraftLoader.java index 178cd07bd..268e5984d 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/MinecraftLoader.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/launch/MinecraftLoader.java @@ -21,16 +21,15 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.IOUtils; -import org.jackhuang.hellominecraft.util.system.OS; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.IOUtils; +import org.jackhuang.hellominecraft.util.sys.OS; import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary; -import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; -import org.jackhuang.hellominecraft.util.func.BiFunction; /** * @@ -48,7 +47,7 @@ public class MinecraftLoader extends AbstractMinecraftLoader { ArrayList opt = new ArrayList<>(); for (MinecraftLibrary l : version.libraries) if (l.allow() && !l.isRequiredToUnzip()) { - if (l.name.toLowerCase().contains("optifine")) { + if (l.name.toLowerCase(Locale.US).contains("optifine")) { opt.add(l); continue; } @@ -75,7 +74,7 @@ public class MinecraftLoader extends AbstractMinecraftLoader { throw new GameException(new NullPointerException("Minecraft Arguments can not be null.")); String[] splitted = StrUtils.tokenize(version.minecraftArguments); - String game_assets = assetProvider.apply(version, !options.isNotCheckGame()); + String game_assets = assetProvider.provide(version, !options.isNotCheckGame()); for (String t : splitted) { t = t.replace("${auth_player_name}", lr.getUserName()); @@ -114,13 +113,13 @@ public class MinecraftLoader extends AbstractMinecraftLoader { } } - private final BiFunction DEFAULT_ASSET_PROVIDER = (t, allow) -> { + private final IAssetProvider DEFAULT_ASSET_PROVIDER = (t, allow) -> { return new File(service.baseDirectory(), "assets").getAbsolutePath(); }; - private BiFunction assetProvider = DEFAULT_ASSET_PROVIDER; + private IAssetProvider assetProvider = DEFAULT_ASSET_PROVIDER; - public void setAssetProvider(BiFunction assetProvider) { + public void setAssetProvider(IAssetProvider assetProvider) { if (assetProvider == null) this.assetProvider = DEFAULT_ASSET_PROVIDER; else diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/MinecraftModService.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/MinecraftModService.java index 4235cc6d7..231096434 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/MinecraftModService.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/MinecraftModService.java @@ -18,18 +18,16 @@ package org.jackhuang.hellominecraft.launcher.core.mod; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftModService; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; -import org.jackhuang.hellominecraft.util.code.DigestUtils; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; /** * @@ -80,7 +78,7 @@ public class MinecraftModService extends IMinecraftModService { if (!modCache.containsKey(id)) recacheMods(id); File modsFolder = service.version().getRunDirectory(id, "mods"); - if (!modsFolder.exists() && !modsFolder.mkdirs()) + if (!FileUtils.makeDirectory(modsFolder)) HMCLog.warn("Failed to make directories: " + modsFolder); File newf = new File(modsFolder, f.getName()); FileUtils.copyFile(f, newf); @@ -94,24 +92,23 @@ public class MinecraftModService extends IMinecraftModService { } @Override - public void removeMod(String id, Object[] rows) { + public boolean removeMod(String id, Object[] rows) { if (rows.length == 0) - return; + return true; + boolean flag = true; for (Object r : rows) if (r instanceof ModInfo) { - if (!((ModInfo) r).location.delete()) + if (!((ModInfo) r).location.delete()) { HMCLog.warn("Failed to delete mod" + r); + flag = false; + } } else if (r instanceof Number) - if (!getMods(id).get(((Number) r).intValue()).location.delete()) + if (!getMods(id).get(((Number) r).intValue()).location.delete()) { HMCLog.warn("Failed to delete mod " + r + ", maybe not a file?"); + flag = false; + } recacheMods(id); - } - - public String[] checkMd5s(String id) throws IOException { - String[] res = new String[getMods(id).size()]; - for (int i = 0; i < res.length; i++) - res[i] = DigestUtils.md5Hex(new FileInputStream(getMods(id).get(i).location)); - return res; + return flag; } } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/ModInfo.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/ModInfo.java index f508b2acc..a5a1bfb32 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/ModInfo.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/ModInfo.java @@ -17,20 +17,22 @@ */ package org.jackhuang.hellominecraft.launcher.core.mod; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; -import java.lang.reflect.Type; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; /** * @@ -60,6 +62,8 @@ public class ModInfo implements Comparable { public String credits; @SerializedName("authorList") public String[] authorList; + @SerializedName("authors") + public String[] authors; public boolean isActive() { return !location.getName().endsWith(".disabled"); @@ -87,6 +91,8 @@ public class ModInfo implements Comparable { public String getAuthor() { if (authorList != null && authorList.length > 0) return StrUtils.parseParams("", authorList, ", "); + else if (authors != null && authors.length > 0) + return StrUtils.parseParams("", authors, ", "); else if (StrUtils.isNotBlank(author)) return author; else @@ -123,17 +129,30 @@ public class ModInfo implements Comparable { return name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith("litemod"); } - private static final Type TYPE = new TypeToken>() { - }.getType(); - - private static ModInfo getForgeModInfo(File f, ZipFile jar, ZipEntry entry) throws IOException { + private static ModInfo getForgeModInfo(File f, ZipFile jar, ZipEntry entry) throws IOException, JsonSyntaxException { ModInfo i = new ModInfo(); i.location = f; - List m = C.GSON.fromJson(new InputStreamReader(jar.getInputStream(entry), "UTF-8"), TYPE); + + InputStreamReader streamReader = new InputStreamReader(jar.getInputStream(entry), "UTF-8"); + + JsonParser parser = new JsonParser(); + JsonElement element = parser.parse(streamReader); + List m = null; + if (element.isJsonArray()) + m = C.GSON.fromJson(element, new TypeToken>() { + }.getType()); + else if (element.isJsonObject()) { + JsonObject modInfo = element.getAsJsonObject(); + if (modInfo.has("modList") && modInfo.get("modList").isJsonArray()) + m = C.GSON.fromJson(modInfo.get("modList"), new TypeToken>() { + }.getType()); + } + if (m != null && m.size() > 0) { i = m.get(0); i.location = f; } + return i; } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/ModpackManager.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/ModpackManager.java index cdf103558..fe629aece 100644 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/ModpackManager.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/mod/ModpackManager.java @@ -34,20 +34,21 @@ import java.util.zip.ZipFile; import javax.swing.JFrame; import javax.swing.JOptionPane; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; import org.jackhuang.hellominecraft.util.func.BiFunction; import org.jackhuang.hellominecraft.util.func.CallbackIO; -import org.jackhuang.hellominecraft.util.system.Compressor; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.system.ZipEngine; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.ui.WebPage; +import org.jackhuang.hellominecraft.util.sys.CompressingUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.ZipEngine; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.net.WebPage; import org.jackhuang.hellominecraft.util.MinecraftVersionRequest; -import org.jackhuang.hellominecraft.util.tasks.NoShownTaskException; +import org.jackhuang.hellominecraft.util.sys.IOUtils; +import org.jackhuang.hellominecraft.util.task.NoShownTaskException; /** * A mod pack(*.zip) includes these things: @@ -86,21 +87,21 @@ public final class ModpackManager { Collection c = new ArrayList<>(); @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { String id = idFUCK; String description = C.i18n("modpack.task.install.will"); // Read modpack name and description from `modpack.json` try (ZipFile zip = new ZipFile(input)) { - HashMap map = C.GSON.fromJson(new InputStreamReader(zip.getInputStream(zip.getEntry("modpack.json")), "UTF-8"), HashMap.class); + HashMap map = C.GSON.fromJson(new InputStreamReader(zip.getInputStream(zip.getEntry("modpack.json")), "UTF-8"), HashMap.class); if (map != null) { if (id == null) if (map.containsKey("name") && map.get("name") instanceof String) - id = (String) map.get("name"); + id = map.get("name"); if (id != null) description += id; if (map.containsKey("description") && map.get("description") instanceof String) - description += "\n" + (String) map.get("description"); + description += "\n" + map.get("description"); } if (id == null) throw new IllegalStateException("Illegal modpack id!"); @@ -150,7 +151,7 @@ public final class ModpackManager { try { final AtomicInteger b = new AtomicInteger(0); HMCLog.log("Decompressing modpack"); - Compressor.unzip(input, versions, t -> { + CompressingUtils.unzip(input, versions, t -> { if (t.equals("minecraft/pack.json")) b.incrementAndGet(); return true; @@ -186,8 +187,8 @@ public final class ModpackManager { } } finally { FileUtils.deleteDirectoryQuietly(oldFile); - if (newFile != null) - newFile.renameTo(oldFile); + if (newFile != null && !newFile.renameTo(oldFile)) + HMCLog.warn("Failed to restore version minecraft"); } } @@ -244,7 +245,7 @@ public final class ModpackManager { * * @throws IOException if create tmp directory failed */ - public static void export(File output, IMinecraftProvider provider, String version, List blacklist, Map modpackJson, CallbackIO callback) throws IOException, GameException { + public static void export(File output, IMinecraftProvider provider, String version, List blacklist, Map modpackPreferences, CallbackIO callback) throws IOException, GameException { final ArrayList b = new ArrayList<>(MODPACK_BLACK_LIST); if (blacklist != null) b.addAll(blacklist); @@ -271,12 +272,11 @@ public final class ModpackManager { mv.jar = r.version; mv.runDir = "version"; zip.putTextFile(C.GSON.toJson(mv), "minecraft/pack.json"); - zip.putTextFile(C.GSON.toJson(modpackJson), "modpack.json"); + zip.putTextFile(C.GSON.toJson(modpackPreferences), "modpack.json"); if (callback != null) callback.call(zip); } finally { - if (zip != null) - zip.closeFile(); + IOUtils.closeQuietly(zip); } } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftAssetService.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftAssetService.java index 6ceec9ccb..1801e1bcf 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftAssetService.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftAssetService.java @@ -19,8 +19,9 @@ package org.jackhuang.hellominecraft.launcher.core.service; import java.io.File; import java.io.IOException; +import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.version.AssetIndexDownloadInfo; -import org.jackhuang.hellominecraft.util.tasks.Task; +import org.jackhuang.hellominecraft.util.task.Task; /** * @@ -32,7 +33,7 @@ public abstract class IMinecraftAssetService extends IMinecraftBasicService { super(service); } - public abstract Task downloadAssets(String mcVersion); + public abstract Task downloadAssets(String mcVersion) throws GameException; public abstract File getAssets(); @@ -43,7 +44,7 @@ public abstract class IMinecraftAssetService extends IMinecraftBasicService { * * @return Is the action successful? */ - public abstract boolean refreshAssetsIndex(String a); + public abstract boolean refreshAssetsIndex(String a) throws GameException; public abstract boolean downloadMinecraftAssetsIndexAsync(AssetIndexDownloadInfo assetsId); diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftDownloadService.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftDownloadService.java index 87d65406f..1ef511137 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftDownloadService.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftDownloadService.java @@ -22,7 +22,7 @@ import java.util.List; import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; -import org.jackhuang.hellominecraft.util.tasks.Task; +import org.jackhuang.hellominecraft.util.task.Task; /** * diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftInstallerService.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftInstallerService.java index 133ac59e2..87cef4ec0 100644 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftInstallerService.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftInstallerService.java @@ -19,7 +19,7 @@ package org.jackhuang.hellominecraft.launcher.core.service; import org.jackhuang.hellominecraft.launcher.core.install.InstallerType; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList; -import org.jackhuang.hellominecraft.util.tasks.Task; +import org.jackhuang.hellominecraft.util.task.Task; /** * diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftModService.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftModService.java index d11d84b78..46297f208 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftModService.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/service/IMinecraftModService.java @@ -37,5 +37,5 @@ public abstract class IMinecraftModService extends IMinecraftBasicService { public abstract boolean addMod(String id, File f); - public abstract void removeMod(String id, Object[] mods); + public abstract boolean removeMod(String id, Object[] mods); } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Extract.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Extract.java index 8e6d04580..ca6d914b2 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Extract.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Extract.java @@ -36,7 +36,6 @@ public class Extract implements Cloneable { } @Override - @SuppressWarnings("CloneDeclaresCloneNotSupported") public Object clone() { try { return super.clone(); diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/IMinecraftLibrary.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/IMinecraftLibrary.java index be53ddd18..5de53abe4 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/IMinecraftLibrary.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/IMinecraftLibrary.java @@ -56,7 +56,6 @@ public abstract class IMinecraftLibrary implements Cloneable { } @Override - @SuppressWarnings("CloneDeclaresCloneNotSupported") public Object clone() { try { return super.clone(); diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/LibraryDownloadInfo.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/LibraryDownloadInfo.java index f2cb07a3e..9a5ac015b 100644 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/LibraryDownloadInfo.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/LibraryDownloadInfo.java @@ -20,7 +20,7 @@ package org.jackhuang.hellominecraft.launcher.core.version; import com.google.gson.annotations.SerializedName; import org.jackhuang.hellominecraft.launcher.core.download.DownloadType; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftLibrary.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftLibrary.java index 5c6baede3..b041570ca 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftLibrary.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftLibrary.java @@ -21,8 +21,8 @@ import com.google.gson.annotations.SerializedName; import java.io.File; import java.util.ArrayList; import java.util.HashMap; -import org.jackhuang.hellominecraft.util.system.OS; -import org.jackhuang.hellominecraft.util.system.Platform; +import org.jackhuang.hellominecraft.util.sys.OS; +import org.jackhuang.hellominecraft.util.sys.Platform; import org.jackhuang.hellominecraft.util.StrUtils; /** @@ -46,14 +46,6 @@ public class MinecraftLibrary extends IMinecraftLibrary { super(name); } - 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; - this.natives = natives == null ? null : (Natives) natives.clone(); - this.extract = extract == null ? null : (Extract) extract.clone(); - } - /** * is the library allowed to load. * @@ -79,12 +71,12 @@ public class MinecraftLibrary extends IMinecraftLibrary { private String getNative() { switch (OS.os()) { - case WINDOWS: - return formatArch(natives.windows); - case OSX: - return formatArch(natives.osx); - default: - return formatArch(natives.linux); + case WINDOWS: + return formatArch(natives.windows); + case OSX: + return formatArch(natives.osx); + default: + return formatArch(natives.linux); } } @@ -116,6 +108,7 @@ public class MinecraftLibrary extends IMinecraftLibrary { return extract == null ? new Extract() : extract; } + @Override public LibraryDownloadInfo getDownloadInfo() { if (downloads == null) downloads = new LibrariesDownloadInfo(); @@ -125,12 +118,15 @@ public class MinecraftLibrary extends IMinecraftLibrary { downloads.classifiers = new HashMap<>(); if (!downloads.classifiers.containsKey(getNative())) downloads.classifiers.put(getNative(), info = new LibraryDownloadInfo()); - else + else { info = downloads.classifiers.get(getNative()); - } else if (downloads.artifact == null) - downloads.artifact = info = new LibraryDownloadInfo(); - else + if (info == null) info = new LibraryDownloadInfo(); + } + } else { + if (downloads.artifact == null) + downloads.artifact = new LibraryDownloadInfo(); info = downloads.artifact; + } if (StrUtils.isBlank(info.path)) { info.path = formatName(); if (info.path == null) diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftVersion.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftVersion.java index fb781f84f..16fc0e3e3 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftVersion.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftVersion.java @@ -24,13 +24,13 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider; import org.jackhuang.hellominecraft.launcher.core.asset.AssetsIndex; import org.jackhuang.hellominecraft.util.ArrayUtils; -import org.jackhuang.hellominecraft.util.Utils; /** * @@ -176,9 +176,27 @@ public class MinecraftVersion implements Cloneable, Comparable return id.compareTo(o.id); } + @Override + public int hashCode() { + int hash = 7; + hash = 53 * hash + Objects.hashCode(this.id); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + return Objects.equals(this.id, ((MinecraftVersion) obj).id); + } + + + public AssetIndexDownloadInfo getAssetsIndex() { if (assetIndex == null) - assetIndex = new AssetIndexDownloadInfo((String) Utils.firstNonNull(assets, AssetsIndex.DEFAULT_ASSET_NAME)); + assetIndex = new AssetIndexDownloadInfo(assets == null ? AssetsIndex.DEFAULT_ASSET_NAME : assets); return assetIndex; } @@ -194,6 +212,6 @@ public class MinecraftVersion implements Cloneable, Comparable } public Set getLibraries() { - return libraries == null ? new HashSet() : new HashSet(libraries); + return libraries == null ? new HashSet<>() : new HashSet<>(libraries); } } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftVersionManager.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftVersionManager.java index d4090e91e..8304bd975 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftVersionManager.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/MinecraftVersionManager.java @@ -25,14 +25,14 @@ import java.util.Collection; import java.util.Map; import java.util.TreeMap; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.launcher.core.MCUtils; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.task.TaskWindow; +import org.jackhuang.hellominecraft.util.sys.IOUtils; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.func.Consumer; @@ -45,7 +45,7 @@ import org.jackhuang.hellominecraft.util.ui.SwingUtils; */ public class MinecraftVersionManager extends IMinecraftProvider { - final Map versions = new TreeMap(); + final Map versions = new TreeMap<>(); /** * @@ -100,12 +100,12 @@ public class MinecraftVersionManager extends IMinecraftProvider { } if (ask) { HMCLog.warn("Found not matched filenames version: " + id + ", json: " + jsons[0].getName()); - if (MessageBox.Show(String.format(C.i18n("launcher.versions_json_not_matched"), id, jsons[0].getName()), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) + if (MessageBox.show(String.format(C.i18n("launcher.versions_json_not_matched"), id, jsons[0].getName()), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) if (!jsons[0].renameTo(new File(jsons[0].getParent(), id + ".json"))) HMCLog.warn("Failed to rename version json " + jsons[0]); } if (!jsonFile.exists()) { - if (MessageBox.Show(C.i18n("launcher.versions_json_not_matched_cannot_auto_completion", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) + if (MessageBox.show(C.i18n("launcher.versions_json_not_matched_cannot_auto_completion", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) FileUtils.deleteDirectoryQuietly(dir); continue; } @@ -113,16 +113,16 @@ public class MinecraftVersionManager extends IMinecraftProvider { try { mcVersion = C.GSON.fromJson(FileUtils.read(jsonFile), MinecraftVersion.class); if (mcVersion == null) - throw new GameException("Wrong json format, got null."); - } catch (Exception e) { + throw new JsonSyntaxException("Wrong json format, got null."); + } catch (JsonSyntaxException | IOException e) { HMCLog.warn("Found wrong format json, try to fix it.", e); - if (MessageBox.Show(C.i18n("launcher.versions_json_not_formatted", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) { + if (MessageBox.show(C.i18n("launcher.versions_json_not_formatted", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) { service.download().downloadMinecraftVersionJson(id); try { mcVersion = C.GSON.fromJson(FileUtils.read(jsonFile), MinecraftVersion.class); if (mcVersion == null) - throw new GameException("Wrong json format, got null."); - } catch (IOException | GameException | JsonSyntaxException ex) { + throw new JsonSyntaxException("Wrong json format, got null."); + } catch (IOException | JsonSyntaxException ex) { HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", ex); continue; } @@ -194,7 +194,7 @@ public class MinecraftVersionManager extends IMinecraftProvider { @Override public boolean install(String id, Consumer callback) { - if (!TaskWindow.factory().append(service.download().downloadMinecraft(id)).create()) + if (!TaskWindow.factory().append(service.download().downloadMinecraft(id)).execute()) return false; if (callback != null) { File mvt = new File(versionRoot(id), id + ".json"); @@ -256,7 +256,7 @@ public class MinecraftVersionManager extends IMinecraftProvider { @Override public boolean onLaunch(String id) { File resourcePacks = new File(getRunDirectory(id), "resourcepacks"); - if (!resourcePacks.exists() && !resourcePacks.mkdirs()) + if (!FileUtils.makeDirectory(resourcePacks)) HMCLog.warn("Failed to make resourcePacks: " + resourcePacks); return true; } @@ -278,6 +278,5 @@ public class MinecraftVersionManager extends IMinecraftProvider { @Override public void initializeMiencraft() { - } } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Natives.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Natives.java index c13051e4a..e7f05983c 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Natives.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Natives.java @@ -33,7 +33,6 @@ public class Natives implements Cloneable { public String linux; @Override - @SuppressWarnings("CloneDeclaresCloneNotSupported") protected Object clone() { try { return super.clone(); diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/OSRestriction.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/OSRestriction.java index 2e276adcf..d881ce07b 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/OSRestriction.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/OSRestriction.java @@ -19,7 +19,7 @@ package org.jackhuang.hellominecraft.launcher.core.version; import com.google.gson.annotations.SerializedName; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.system.OS; +import org.jackhuang.hellominecraft.util.sys.OS; /** * diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Rules.java b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Rules.java index 1831a0536..0d792759a 100755 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Rules.java +++ b/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/version/Rules.java @@ -33,14 +33,8 @@ public class Rules { public Rules() { } - public Rules(String action, OSRestriction os) { - this(); - this.action = action; - this.os = os; - } - public String action() { - return os == null || os != null && os.isCurrentOS() ? action : null; + return os == null || os.isCurrentOS() ? action : null; } } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/Main.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/Main.java index a4e8d2689..6af914721 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/Main.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/Main.java @@ -33,19 +33,21 @@ import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; import javax.swing.ImageIcon; +import javax.swing.RepaintManager; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.api.PluginManager; import org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher; import org.jackhuang.hellominecraft.launcher.util.CrashReporter; -import org.jackhuang.hellominecraft.util.logging.Configuration; -import org.jackhuang.hellominecraft.util.logging.appender.ConsoleAppender; -import org.jackhuang.hellominecraft.util.logging.layout.DefaultLayout; +import org.jackhuang.hellominecraft.util.log.Configuration; +import org.jackhuang.hellominecraft.util.log.appender.ConsoleAppender; +import org.jackhuang.hellominecraft.util.log.layout.DefaultLayout; import org.jackhuang.hellominecraft.util.ui.LogWindow; import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.launcher.util.upgrade.IUpgrader; import org.jackhuang.hellominecraft.launcher.ui.MainFrame; +import org.jackhuang.hellominecraft.util.ui.MyRepaintManager; import org.jackhuang.hellominecraft.launcher.util.DefaultPlugin; import org.jackhuang.hellominecraft.lookandfeel.HelloMinecraftLookAndFeel; import org.jackhuang.hellominecraft.util.MathUtils; @@ -75,21 +77,6 @@ public final class Main implements Runnable { }; private static final HostnameVerifier HNV = (hostname, session) -> true; - static { - SSLContext sslContext = null; - - try { - sslContext = SSLContext.getInstance("TLS"); - X509TrustManager[] xtmArray = new X509TrustManager[] { XTM }; - sslContext.init(null, xtmArray, new java.security.SecureRandom()); - } catch (GeneralSecurityException gse) { - } - if (sslContext != null) - HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); - - HttpsURLConnection.setDefaultHostnameVerifier(HNV); - } - public static final String LAUNCHER_NAME = "Hello Minecraft! Launcher"; public static final String LAUNCHER_VERSION = "@HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING@"; public static final int MINIMUM_LAUNCHER_VERSION = 16; @@ -111,7 +98,6 @@ public final class Main implements Runnable { return "HMCL" + ' ' + LAUNCHER_VERSION; } - public static final Main INSTANCE = new Main(); private static HelloMinecraftLookAndFeel LOOK_AND_FEEL; private static final Logger LOGGER = Logger.getLogger(Main.class.getName()); @@ -127,12 +113,22 @@ public final class Main implements Runnable { System.setProperty("swing.aatext", "true"); System.setProperty("sun.java2d.noddraw", "true"); System.setProperty("sun.java2d.dpiaware", "false"); + System.setProperty("https.protocols", "SSLv3,TLSv1"); + + try { + SSLContext c = SSLContext.getInstance("SSL"); + c.init(null, new X509TrustManager[] { XTM }, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(c.getSocketFactory()); + } catch (GeneralSecurityException ignore) { + } + HttpsURLConnection.setDefaultHostnameVerifier(HNV); + Thread.setDefaultUncaughtExceptionHandler(new CrashReporter(true)); try { File file = new File("hmcl.log"); if (!file.exists() && !file.createNewFile()) - HMCLog.warn("Failed to create log file " + file); + LOGGER.log(Level.WARNING, "Failed to create log file {0}", file); Configuration.DEFAULT.appenders.add(new ConsoleAppender("File", new DefaultLayout(), true, new FileOutputStream(file), true)); } catch (IOException ex) { LOGGER.log(Level.SEVERE, "Failed to add log appender File because an error occurred while creating or opening hmcl.log", ex); @@ -147,17 +143,18 @@ public final class Main implements Runnable { Locale.setDefault(sl.self); } - LogWindow.INSTANCE.clean(); - LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses); - try { LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings); UIManager.setLookAndFeel(LOOK_AND_FEEL); + RepaintManager.setCurrentManager(new MyRepaintManager()); } catch (ParseException | UnsupportedLookAndFeelException ex) { HMCLog.warn("Failed to set look and feel...", ex); } + + LogWindow.INSTANCE.clean(); + LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses); - Settings.UPDATE_CHECKER.outdated.register(IUpgrader.NOW_UPGRADER); + Settings.UPDATE_CHECKER.outOfDateEvent.register(IUpgrader.NOW_UPGRADER); Settings.UPDATE_CHECKER.process(false).reg(t -> Main.invokeUpdate()).execute(); if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) { diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Config.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Config.java index 1657642f9..d15b1615e 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Config.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Config.java @@ -28,8 +28,8 @@ import java.util.UUID; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.lookandfeel.Theme; import org.jackhuang.hellominecraft.util.EventHandler; -import org.jackhuang.hellominecraft.util.system.JdkVersion; -import org.jackhuang.hellominecraft.util.system.OS; +import org.jackhuang.hellominecraft.util.sys.JdkVersion; +import org.jackhuang.hellominecraft.util.sys.OS; /** * @@ -53,10 +53,10 @@ public final class Config implements Cloneable { private String proxyPassword; @SerializedName("enableShadow") private boolean enableShadow; + @SerializedName("enableBlur") + private boolean enableBlur; @SerializedName("decorated") private boolean decorated; - @SerializedName("enableAnimation") - private boolean enableAnimation; @SerializedName("theme") private int theme; @SerializedName("java") @@ -110,6 +110,15 @@ public final class Config implements Cloneable { Settings.save(); } + public boolean isEnableBlur() { + return enableBlur; + } + + public void setEnableBlur(boolean enableBlur) { + this.enableBlur = enableBlur; + Settings.save(); + } + public String getLast() { if (last == null) last = Settings.DEFAULT_PROFILE; @@ -131,15 +140,6 @@ public final class Config implements Cloneable { Settings.save(); } - public boolean isEnableAnimation() { - return enableAnimation; - } - - public void setEnableAnimation(boolean enableAnimation) { - this.enableAnimation = enableAnimation; - Settings.save(); - } - public String getClientToken() { return clientToken; } @@ -194,8 +194,7 @@ public final class Config implements Cloneable { public Config() { clientToken = UUID.randomUUID().toString(); logintype = downloadtype = 0; - enableShadow = false; - enableAnimation = true; + enableBlur = enableShadow = true; theme = 4; decorated = OS.os() == OS.LINUX; auth = new HashMap<>(); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Profile.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Profile.java index 344a01a8b..b00532e52 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Profile.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Profile.java @@ -24,10 +24,10 @@ import org.jackhuang.hellominecraft.launcher.api.PluginManager; import org.jackhuang.hellominecraft.launcher.core.MCUtils; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.EventHandler; -import org.jackhuang.hellominecraft.util.system.OS; +import org.jackhuang.hellominecraft.util.sys.OS; /** * diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Settings.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Settings.java index 2dcdbaccf..c1d7ca9ba 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Settings.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Settings.java @@ -23,13 +23,13 @@ import java.io.IOException; import java.util.Collection; import java.util.Map; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.Main; import org.jackhuang.hellominecraft.launcher.core.MCUtils; import org.jackhuang.hellominecraft.launcher.core.download.DownloadType; import org.jackhuang.hellominecraft.util.CollectionUtils; import org.jackhuang.hellominecraft.util.EventHandler; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.UpdateChecker; @@ -126,16 +126,8 @@ public final class Settings { return SETTINGS.getConfigurations(); } - public static void setProfile(Profile ver) { - getProfiles().put(ver.getName(), ver); - } - public static Collection getProfilesFiltered() { - return CollectionUtils.map(getProfiles().values(), t -> t != null && t.getName() != null); - } - - public static Profile getOneProfile() { - return SETTINGS.getConfigurations().firstEntry().getValue(); + return CollectionUtils.filter(getProfiles().values(), t -> t != null && t.getName() != null); } public static boolean putProfile(Profile ver) { @@ -151,7 +143,7 @@ public final class Settings { public static boolean delProfile(String ver) { if (DEFAULT_PROFILE.equals(ver)) { - MessageBox.Show(C.i18n("settings.cannot_remove_default_config")); + MessageBox.show(C.i18n("settings.cannot_remove_default_config")); return false; } boolean notify = false; @@ -163,8 +155,8 @@ public final class Settings { return flag; } - public static final EventHandler profileChangedEvent = new EventHandler(null); - public static final EventHandler profileLoadingEvent = new EventHandler(null); + public static final EventHandler profileChangedEvent = new EventHandler<>(null); + public static final EventHandler profileLoadingEvent = new EventHandler<>(null); static void onProfileChanged() { Profile p = getLastProfile(); 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 e9c69b195..9ba27169e 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 @@ -27,10 +27,10 @@ import org.jackhuang.hellominecraft.launcher.core.version.GameDirType; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.Utils; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.Java; -import org.jackhuang.hellominecraft.util.system.JdkVersion; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.Java; +import org.jackhuang.hellominecraft.util.sys.JdkVersion; +import org.jackhuang.hellominecraft.util.sys.OS; /** * @@ -93,27 +93,6 @@ public class VersionSetting { javaDir = java = minecraftArgs = serverIp = precalledCommand = wrapper = ""; } - public VersionSetting(VersionSetting v) { - this(); - if (v == null) - return; - maxMemory = v.maxMemory; - width = v.width; - height = v.height; - java = v.java; - fullscreen = v.fullscreen; - javaArgs = v.javaArgs; - javaDir = v.javaDir; - minecraftArgs = v.minecraftArgs; - permSize = v.permSize; - gameDirType = v.gameDirType; - noJVMArgs = v.noJVMArgs; - launcherVisibility = v.launcherVisibility; - precalledCommand = v.precalledCommand; - wrapper = v.wrapper; - serverIp = v.serverIp; - } - public String getJavaDir() { Java j = getJava(); if (j.getHome() == null) @@ -173,13 +152,9 @@ public class VersionSetting { propertyChanged.execute("javaArgs"); } - public boolean hasJavaArgs() { - return StrUtils.isNotBlank(getJavaArgs().trim()); - } - public String getMaxMemory() { if (StrUtils.isBlank(maxMemory)) - return String.valueOf(Utils.getSuggestedMemorySize()); + return String.valueOf(OS.getSuggestedMemorySize()); return maxMemory; } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/AnimatedPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/AnimatedPanel.java deleted file mode 100755 index 2cf92cfca..000000000 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/AnimatedPanel.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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.ui; - -import java.awt.AlphaComposite; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import javax.swing.JPanel; -import javax.swing.SwingUtilities; -import javax.swing.Timer; -import org.jackhuang.hellominecraft.launcher.setting.Settings; - -/** - * - * @author huangyuhui - */ -public class AnimatedPanel extends JPanel implements Selectable { - - private static final int ANIMATION_LENGTH = 10; - - public AnimatedPanel() { - timer = new Timer(1, (e) -> { - SwingUtilities.invokeLater(() -> { - AnimatedPanel.this.repaint(); - offsetX += 0.15; - if (offsetX >= ANIMATION_LENGTH) { - timer.stop(); - AnimatedPanel.this.repaint(); - } - }); - }); - } - - double offsetX = ANIMATION_LENGTH; - - Timer timer; - - boolean animationEnabled = true; - - public void animate() { - if (Settings.getInstance().isEnableAnimation() && animationEnabled) { - offsetX = 0; - timer.start(); - } - } - - @Override - public void paint(Graphics g) { - if (!(g instanceof Graphics2D)) { - super.paint(g); - return; - } - double pgs = 1 - Math.sin(Math.PI / 2 / ANIMATION_LENGTH * offsetX); - if (Math.abs(ANIMATION_LENGTH - offsetX) < 0.1) { - super.paint(g); - return; - } - if (pgs > 1) - pgs = 1; - if (pgs < 0) - pgs = 0; - Graphics2D gg = (Graphics2D) g; - int width = this.getWidth(); - int height = this.getHeight(); - if (isOpaque()) { - g.setColor(getBackground()); - g.fillRect(0, 0, width, height); - } - BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - Graphics2D g2d = image.createGraphics(); - g2d.translate((int) (pgs * 50), 0); - super.paint(g2d); - g2d.dispose(); - gg.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (float) (1 - pgs))); - g.drawImage(image, 0, 0, this); - } - - boolean selected = false; - - @Override - public boolean isSelected() { - return selected; - } - - @Override - public void onSelect() { - if (!selected) - animate(); - selected = true; - } - - @Override - public void onLeave() { - selected = false; - } - - boolean created = false; - - @Override - public void onCreate() { - created = true; - } - - @Override - public boolean isCreated() { - return created; - } -} diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameDownloadPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameDownloadPanel.java index f76598cc6..892b22162 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameDownloadPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameDownloadPanel.java @@ -18,20 +18,19 @@ package org.jackhuang.hellominecraft.launcher.ui; import javax.swing.table.DefaultTableModel; -import org.jackhuang.hellominecraft.launcher.core.download.DownloadType; import org.jackhuang.hellominecraft.launcher.core.download.MinecraftRemoteVersions; import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; +import org.jackhuang.hellominecraft.util.task.TaskWindow; import org.jackhuang.hellominecraft.util.ui.SwingUtils; /** * * @author huangyuhui */ -public class GameDownloadPanel extends AnimatedPanel { +public class GameDownloadPanel extends Page { GameSettingsPanel gsp; @@ -108,19 +107,23 @@ public class GameDownloadPanel extends AnimatedPanel { public void refreshDownloads() { DefaultTableModel model = SwingUtils.clearDefaultTable(lstDownloads); + model.addRow(new Object[] { C.i18n("message.loading"), "", "" }); MinecraftRemoteVersions.refreshRomoteVersions(Settings.getLastProfile().service().getDownloadType()) - .reg((ver) -> model.addRow(new Object[] { ver.id, ver.time, - StrUtils.equalsOne(ver.type, "old_beta", "old_alpha", "release", "snapshot") ? C.i18n("versions." + ver.type) : ver.type })) - .regDone(lstDownloads::requestFocus).execute(); + .reg((ver) -> model.addRow(new Object[] { ver.id, ver.time, + StrUtils.equalsOne(ver.type, "old_beta", "old_alpha", "release", "snapshot") ? C.i18n("versions." + ver.type) : ver.type })) + .regDone(SwingUtils.invokeLater(() -> { + lstDownloads.requestFocus(); + model.removeRow(0); + })).execute(); } void downloadMinecraft() { if (lstDownloads.getSelectedRow() < 0) { - MessageBox.Show(C.i18n("gamedownload.not_refreshed")); + MessageBox.show(C.i18n("gamedownload.not_refreshed")); return; } String id = (String) lstDownloads.getModel().getValueAt(lstDownloads.getSelectedRow(), 0); - TaskWindow.execute(Settings.getLastProfile().service().download().downloadMinecraft(id)); + TaskWindow.factory().execute(Settings.getLastProfile().service().download().downloadMinecraft(id)); } // Variables declaration - do not modify//GEN-BEGIN:variables diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.form b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.form index 84a894241..a55e8e82f 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.form +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.form @@ -85,9 +85,6 @@ - - - @@ -372,9 +369,6 @@ - - - @@ -566,9 +560,6 @@ - - - @@ -694,9 +685,6 @@ - - - @@ -788,7 +776,7 @@ - + diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.java index dcd00e1a6..18a111697 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.java @@ -17,9 +17,9 @@ */ package org.jackhuang.hellominecraft.launcher.ui; -import java.awt.Color; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; @@ -34,7 +34,6 @@ import java.io.File; import java.io.IOException; import java.util.List; import javax.swing.DefaultComboBoxModel; -import javax.swing.JFileChooser; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; @@ -42,8 +41,9 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.TableModelEvent; import javax.swing.table.DefaultTableModel; +import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.util.LauncherVisibility; import org.jackhuang.hellominecraft.launcher.setting.Profile; import org.jackhuang.hellominecraft.launcher.setting.Settings; @@ -55,22 +55,24 @@ import org.jackhuang.hellominecraft.launcher.core.version.GameDirType; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; import org.jackhuang.hellominecraft.launcher.setting.VersionSetting; import org.jackhuang.hellominecraft.util.MessageBox; -import org.jackhuang.hellominecraft.util.OverridableSwingWorker; +import org.jackhuang.hellominecraft.util.AbstractSwingWorker; import org.jackhuang.hellominecraft.util.MinecraftVersionRequest; -import org.jackhuang.hellominecraft.util.system.OS; +import org.jackhuang.hellominecraft.util.sys.OS; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.func.Consumer; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.util.ui.SwingUtils; -import org.jackhuang.hellominecraft.util.system.Java; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; +import org.jackhuang.hellominecraft.util.sys.Java; +import org.jackhuang.hellominecraft.util.task.TaskWindow; +import org.jackhuang.hellominecraft.util.ui.GraphicsUtils; +import org.jackhuang.hellominecraft.util.ui.JSystemFileChooser; import org.jackhuang.hellominecraft.util.ui.LogWindow; /** * * @author huangyuhui */ -public final class GameSettingsPanel extends AnimatedPanel implements DropTargetListener { +public final class GameSettingsPanel extends RepaintPage implements DropTargetListener { boolean isLoading = false; public MinecraftVersionRequest minecraftVersion; @@ -78,19 +80,18 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget final InstallerPanel installerPanels[] = new InstallerPanel[InstallerType.values().length]; - /** - * Creates new form GameSettingsPanel - */ public GameSettingsPanel(MainFrame mf) { mf.actions.put("showGameDownloads", () -> { - MainFrame.INSTANCE.selectTab("game"); - showGameDownloads(); - }); + MainFrame.INSTANCE.selectTab("game"); + showGameDownloads(); + }); + + setRepainter(this); } void initGui() { initComponents(); - setBackground(Color.white); + setBackground(GraphicsUtils.getWebColorWithAlpha("FFFFFF7F")); setOpaque(true); for (int i = 0; i < InstallerType.values().length; i++) @@ -163,7 +164,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget ppmManage.add(itm); itm = new JMenuItem(C.i18n("versions.manage.remove")); itm.addActionListener((e) -> { - if (mcVersion != null && MessageBox.Show(C.i18n("versions.manage.remove.confirm") + mcVersion, MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) + if (mcVersion != null && MessageBox.show(C.i18n("versions.manage.remove.confirm") + mcVersion, MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) if (Settings.getLastProfile().service().version().removeVersionFromDisk(mcVersion)) refreshVersions(); }); @@ -177,7 +178,12 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget itm = new JMenuItem(C.i18n("versions.manage.redownload_assets_index")); itm.addActionListener((e) -> { if (mcVersion != null) - Settings.getLastProfile().service().asset().refreshAssetsIndex(mcVersion); + try { + Settings.getLastProfile().service().asset().refreshAssetsIndex(mcVersion); + } catch (GameException ex) { + HMCLog.err("Failed to download assets", ex); + MessageBox.showLocalized("assets.failed_download"); + } }); ppmManage.add(itm); itm = new JMenuItem(C.i18n("versions.mamage.remove_libraries")); @@ -231,13 +237,15 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget public void stateChanged(ChangeEvent e) { if (tabVersionEdit.getSelectedComponent() == pnlAutoInstall && !b) { b = true; - installerPanels[0].refreshVersions(); + TaskWindow.factory().execute(installerPanels[0].refreshVersionsTask()); } } }); + ((NewTabPane) tabVersionEdit).initializing = true; - tabVersionEdit.addTab(C.i18n("settings.tabs.game_download"), pnlGameDownloads); // NOI18N + tabVersionEdit.addTab(C.i18n("settings.tabs.game_download"), pnlGameDownloads); ((NewTabPane) tabVersionEdit).initializing = false; + ((NewTabPane) tabInstallers).initializing = true; for (int i = 0; i < InstallerType.values().length; i++) tabInstallers.addTab(InstallerType.values()[i].getLocalizedName(), installerPanels[i]); @@ -255,7 +263,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget tabVersionEdit = new NewTabPane(); ((NewTabPane)tabVersionEdit).initializing = true; - pnlSettings = new AnimatedPanel(); + pnlSettings = new javax.swing.JPanel(); lblGameDir = new javax.swing.JLabel(); txtGameDir = new javax.swing.JTextField(); lblDimension = new javax.swing.JLabel(); @@ -277,7 +285,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget cboJava = new javax.swing.JComboBox(); btnChoosingGameDir = new javax.swing.JButton(); btnCleanGame = new javax.swing.JButton(); - pnlAdvancedSettings = new AnimatedPanel(); + pnlAdvancedSettings = new javax.swing.JPanel(); lblJavaArgs = new javax.swing.JLabel(); txtJavaArgs = new javax.swing.JTextField(); txtMinecraftArgs = new javax.swing.JTextField(); @@ -292,14 +300,14 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget lblPrecalledCommand1 = new javax.swing.JLabel(); txtWrapperLauncher = new javax.swing.JTextField(); chkDontCheckGame = new javax.swing.JCheckBox(); - pnlModManagement = new AnimatedPanel(); + pnlModManagement = new javax.swing.JPanel(); pnlModManagementContent = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); lstExternalMods = new javax.swing.JTable(); btnAddMod = new javax.swing.JButton(); btnRemoveMod = new javax.swing.JButton(); lblModInfo = new javax.swing.JLabel(); - pnlAutoInstall = new AnimatedPanel(); + pnlAutoInstall = new javax.swing.JPanel(); tabInstallers = new NewTabPane(); pnlTop = new javax.swing.JPanel(); pnlSelection = new javax.swing.JPanel(); @@ -599,9 +607,6 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget .addGroup(pnlAdvancedSettingsLayout.createSequentialGroup() .addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(txtWrapperLauncher) - .addGroup(pnlAdvancedSettingsLayout.createSequentialGroup() - .addComponent(lblPrecalledCommand1) - .addGap(0, 0, Short.MAX_VALUE)) .addGroup(pnlAdvancedSettingsLayout.createSequentialGroup() .addContainerGap() .addComponent(chkNoJVMArgs) @@ -609,6 +614,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget .addComponent(chkDontCheckGame)) .addGroup(pnlAdvancedSettingsLayout.createSequentialGroup() .addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lblPrecalledCommand1) .addComponent(lblPrecalledCommand) .addComponent(lblServerIP)) .addGap(0, 0, Short.MAX_VALUE))) @@ -780,7 +786,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget .addGroup(pnlSelectionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cboVersions, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblVersions)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(11, Short.MAX_VALUE)) ); btnModify.setText(C.i18n("settings.manage")); // NOI18N @@ -946,22 +952,58 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget ((NewTabPane)tabVersionEdit).initializing = false; }// //GEN-END:initComponents - // - private void cboProfilesItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboProfilesItemStateChanged - if (!isLoading) - Settings.getInstance().setLast((String) cboProfiles.getSelectedItem()); - }//GEN-LAST:event_cboProfilesItemStateChanged + + private void btnIncludeMinecraftActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnIncludeMinecraftActionPerformed + JSystemFileChooser fc = new JSystemFileChooser(new File(".")); + fc.setFileSelectionMode(JSystemFileChooser.DIRECTORIES_ONLY); + if (fc.showOpenDialog(this) == JSystemFileChooser.APPROVE_OPTION) { + File newGameDir = fc.getSelectedFile(); + String name = JOptionPane.showInputDialog(C.i18n("setupwindow.give_a_name")); + if (StrUtils.isBlank(name)) { + MessageBox.show(C.i18n("setupwindow.no_empty_name")); + return; + } + Settings.putProfile(new Profile(name).setGameDir(newGameDir.getAbsolutePath())); + MessageBox.show(C.i18n("setupwindow.find_in_configurations")); + loadProfiles(); + } + }//GEN-LAST:event_btnIncludeMinecraftActionPerformed + + private void btnMakeLaunchScriptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMakeLaunchScriptActionPerformed + MainFrame.INSTANCE.daemon.makeLaunchScript(Settings.getLastProfile()); + }//GEN-LAST:event_btnMakeLaunchScriptActionPerformed + + private void btnShowLogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnShowLogActionPerformed + LogWindow.INSTANCE.setVisible(true); + }//GEN-LAST:event_btnShowLogActionPerformed + + private void btnTestGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTestGameActionPerformed + LogWindow.INSTANCE.setVisible(true); + MainFrame.INSTANCE.daemon.runGame(Settings.getLastProfile()); + }//GEN-LAST:event_btnTestGameActionPerformed + + private void btnExploreMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnExploreMouseClicked + ppmExplore.show(evt.getComponent(), evt.getPoint().x, evt.getPoint().y); + }//GEN-LAST:event_btnExploreMouseClicked + + private void btnRemoveProfileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveProfileActionPerformed + if (MessageBox.show(C.i18n("ui.message.sure_remove", Settings.getLastProfile().getName()), MessageBox.YES_NO_OPTION) == MessageBox.NO_OPTION) + return; + Settings.delProfile(Settings.getLastProfile()); + }//GEN-LAST:event_btnRemoveProfileActionPerformed private void btnNewProfileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewProfileActionPerformed new NewProfileWindow(null).setVisible(true); loadProfiles(); }//GEN-LAST:event_btnNewProfileActionPerformed - private void btnRemoveProfileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveProfileActionPerformed - if (MessageBox.Show(C.i18n("ui.message.sure_remove", Settings.getLastProfile().getName()), MessageBox.YES_NO_OPTION) == MessageBox.NO_OPTION) - return; - Settings.delProfile(Settings.getLastProfile()); - }//GEN-LAST:event_btnRemoveProfileActionPerformed + private void btnRefreshVersionsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshVersionsActionPerformed + refreshVersions(); + }//GEN-LAST:event_btnRefreshVersionsActionPerformed + + private void btnModifyMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnModifyMouseClicked + ppmManage.show(evt.getComponent(), evt.getPoint().x, evt.getPoint().y); + }//GEN-LAST:event_btnModifyMouseClicked private void cboVersionsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboVersionsItemStateChanged if (isLoading || evt.getStateChange() != ItemEvent.SELECTED || cboVersions.getSelectedIndex() < 0 || StrUtils.isBlank((String) cboVersions.getSelectedItem())) @@ -969,50 +1011,98 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget Settings.getLastProfile().setSelectedMinecraftVersion((String) cboVersions.getSelectedItem()); }//GEN-LAST:event_cboVersionsItemStateChanged - private void btnRefreshVersionsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshVersionsActionPerformed - refreshVersions(); - }//GEN-LAST:event_btnRefreshVersionsActionPerformed + // + private void cboProfilesItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboProfilesItemStateChanged + if (!isLoading) + Settings.getInstance().setLast((String) cboProfiles.getSelectedItem()); + }//GEN-LAST:event_cboProfilesItemStateChanged - private void btnExploreMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnExploreMouseClicked - ppmExplore.show(evt.getComponent(), evt.getPoint().x, evt.getPoint().y); - }//GEN-LAST:event_btnExploreMouseClicked + private void lblModInfoMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lblModInfoMouseClicked + int idx = lstExternalMods.getSelectedRow(); + if (idx > 0 && idx < Settings.getLastProfile().service().mod().getMods(Settings.getLastProfile().getSelectedVersion()).size()) + SwingUtils.openLink(Settings.getLastProfile().service().mod().getMods(Settings.getLastProfile().getSelectedVersion()).get(idx).url); + }//GEN-LAST:event_lblModInfoMouseClicked - private void btnModifyMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnModifyMouseClicked - ppmManage.show(evt.getComponent(), evt.getPoint().x, evt.getPoint().y); - }//GEN-LAST:event_btnModifyMouseClicked + private void btnRemoveModActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveModActionPerformed + Settings.getLastProfile().service().mod().removeMod(Settings.getLastProfile().getSelectedVersion(), SwingUtils.getValueBySelectedRow(lstExternalMods, lstExternalMods.getSelectedRows(), 1)); + reloadMods(); + }//GEN-LAST:event_btnRemoveModActionPerformed - private void btnDownloadAllAssetsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDownloadAllAssetsActionPerformed - if (mcVersion != null) - TaskWindow.execute(Settings.getLastProfile().service().asset().downloadAssets(mcVersion)); - }//GEN-LAST:event_btnDownloadAllAssetsActionPerformed - - private void txtGameDirFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtGameDirFocusLost - Settings.getLastProfile().setGameDir(txtGameDir.getText()); - loadVersions(); - }//GEN-LAST:event_txtGameDirFocusLost - - private void btnChoosingJavaDirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnChoosingJavaDirActionPerformed - if (cboJava.getSelectedIndex() != 1) + private void btnAddModActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddModActionPerformed + JSystemFileChooser fc = new JSystemFileChooser(); + fc.setFileSelectionMode(JSystemFileChooser.FILES_ONLY); + fc.setDialogTitle(C.i18n("mods.choose_mod")); + fc.setMultiSelectionEnabled(true); + if (fc.showOpenDialog(this) != JSystemFileChooser.APPROVE_OPTION) return; - JFileChooser fc = new JFileChooser(); - fc.setFileSelectionMode(JFileChooser.FILES_ONLY); - fc.setDialogTitle(C.i18n("settings.choose_javapath")); + boolean flag = true; + for (File f : fc.getSelectedFiles()) + flag &= Settings.getLastProfile().service().mod().addMod(Settings.getLastProfile().getSelectedVersion(), f); + reloadMods(); + if (!flag) + MessageBox.show(C.i18n("mods.failed")); + }//GEN-LAST:event_btnAddModActionPerformed + + private void lstExternalModsKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_lstExternalModsKeyPressed + if (evt.getKeyCode() == KeyEvent.VK_DELETE) + btnRemoveModActionPerformed(null); + }//GEN-LAST:event_lstExternalModsKeyPressed + + private void chkDontCheckGameItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkDontCheckGameItemStateChanged + if (!isLoading) + Settings.getLastProfile().getSelectedVersionSetting().setNotCheckGame(chkDontCheckGame.isSelected()); + }//GEN-LAST:event_chkDontCheckGameItemStateChanged + + private void txtWrapperLauncherFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtWrapperLauncherFocusLost + Settings.getLastProfile().getSelectedVersionSetting().setWrapper(txtWrapperLauncher.getText()); + }//GEN-LAST:event_txtWrapperLauncherFocusLost + + private void txtServerIPFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtServerIPFocusLost + Settings.getLastProfile().getSelectedVersionSetting().setServerIp(txtServerIP.getText()); + }//GEN-LAST:event_txtServerIPFocusLost + + private void txtPrecalledCommandFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPrecalledCommandFocusLost + Settings.getLastProfile().getSelectedVersionSetting().setPrecalledCommand(txtPrecalledCommand.getText()); + }//GEN-LAST:event_txtPrecalledCommandFocusLost + + private void chkNoJVMArgsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkNoJVMArgsItemStateChanged + if (!isLoading) + Settings.getLastProfile().getSelectedVersionSetting().setNoJVMArgs(chkNoJVMArgs.isSelected()); + }//GEN-LAST:event_chkNoJVMArgsItemStateChanged + + private void txtPermSizeFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPermSizeFocusLost + Settings.getLastProfile().getSelectedVersionSetting().setPermSize(txtPermSize.getText()); + }//GEN-LAST:event_txtPermSizeFocusLost + + private void txtMinecraftArgsFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtMinecraftArgsFocusLost + Settings.getLastProfile().getSelectedVersionSetting().setMinecraftArgs(txtMinecraftArgs.getText()); + }//GEN-LAST:event_txtMinecraftArgsFocusLost + + private void txtJavaArgsFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtJavaArgsFocusLost + Settings.getLastProfile().getSelectedVersionSetting().setJavaArgs(txtJavaArgs.getText()); + }//GEN-LAST:event_txtJavaArgsFocusLost + + private void btnCleanGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCleanGameActionPerformed + Settings.getLastProfile().service().version().cleanFolder(); + }//GEN-LAST:event_btnCleanGameActionPerformed + + private void btnChoosingGameDirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnChoosingGameDirActionPerformed + JSystemFileChooser fc = new JSystemFileChooser(); + fc.setFileSelectionMode(JSystemFileChooser.DIRECTORIES_ONLY); + fc.setDialogTitle(C.i18n("settings.choose_gamedir")); fc.setMultiSelectionEnabled(false); - fc.setFileFilter(new FileNameFilter("javaw.exe")); - fc.addChoosableFileFilter(new FileNameFilter("java.exe")); - fc.addChoosableFileFilter(new FileNameFilter("java")); fc.showOpenDialog(this); if (fc.getSelectedFile() == null) return; try { String path = fc.getSelectedFile().getCanonicalPath(); - txtJavaDir.setText(path); - Settings.getLastProfile().getSelectedVersionSetting().setJavaDir(txtJavaDir.getText()); + txtGameDir.setText(path); + Settings.getLastProfile().setGameDir(path); } catch (IOException e) { - HMCLog.warn("Failed to set java path.", e); - MessageBox.Show(C.i18n("ui.label.failed_set") + e.getMessage()); + HMCLog.warn("Failed to set game dir.", e); + MessageBox.show(C.i18n("ui.label.failed_set") + e.getMessage()); } - }//GEN-LAST:event_btnChoosingJavaDirActionPerformed + }//GEN-LAST:event_btnChoosingGameDirActionPerformed private void cboJavaItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboJavaItemStateChanged if (evt.getStateChange() != ItemEvent.SELECTED || cboJava.getSelectedIndex() < 0 || StrUtils.isBlank((String) cboJava.getSelectedItem())) @@ -1027,87 +1117,28 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget } }//GEN-LAST:event_cboJavaItemStateChanged - private void btnAddModActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddModActionPerformed - JFileChooser fc = new JFileChooser(); - fc.setFileSelectionMode(JFileChooser.FILES_ONLY); - fc.setDialogTitle(C.i18n("mods.choose_mod")); - fc.setMultiSelectionEnabled(true); - if (fc.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) + private void btnChoosingJavaDirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnChoosingJavaDirActionPerformed + if (cboJava.getSelectedIndex() != 1) return; - boolean flag = true; - for (File f : fc.getSelectedFiles()) - flag &= Settings.getLastProfile().service().mod().addMod(Settings.getLastProfile().getSelectedVersion(), f); - reloadMods(); - if (!flag) - MessageBox.Show(C.i18n("mods.failed")); - }//GEN-LAST:event_btnAddModActionPerformed - - private void btnRemoveModActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveModActionPerformed - Settings.getLastProfile().service().mod().removeMod(Settings.getLastProfile().getSelectedVersion(), SwingUtils.getValueBySelectedRow(lstExternalMods, lstExternalMods.getSelectedRows(), 1)); - reloadMods(); - }//GEN-LAST:event_btnRemoveModActionPerformed - - private void lstExternalModsKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_lstExternalModsKeyPressed - if (evt.getKeyCode() == KeyEvent.VK_DELETE) - btnRemoveModActionPerformed(null); - }//GEN-LAST:event_lstExternalModsKeyPressed - - private void lblModInfoMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lblModInfoMouseClicked - int idx = lstExternalMods.getSelectedRow(); - if (idx > 0 && idx < Settings.getLastProfile().service().mod().getMods(Settings.getLastProfile().getSelectedVersion()).size()) - SwingUtils.openLink(Settings.getLastProfile().service().mod().getMods(Settings.getLastProfile().getSelectedVersion()).get(idx).url); - }//GEN-LAST:event_lblModInfoMouseClicked - - private void btnChoosingGameDirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnChoosingGameDirActionPerformed - JFileChooser fc = new JFileChooser(); - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - fc.setDialogTitle(C.i18n("settings.choose_gamedir")); + JSystemFileChooser fc = new JSystemFileChooser(); + fc.setFileSelectionMode(JSystemFileChooser.FILES_ONLY); + fc.setDialogTitle(C.i18n("settings.choose_javapath")); fc.setMultiSelectionEnabled(false); + fc.setFileFilter(new FileNameFilter("javaw.exe")); + fc.addChoosableFileFilter(new FileNameFilter("java.exe")); + fc.addChoosableFileFilter(new FileNameFilter("java")); fc.showOpenDialog(this); if (fc.getSelectedFile() == null) return; try { String path = fc.getSelectedFile().getCanonicalPath(); - txtGameDir.setText(path); - Settings.getLastProfile().setGameDir(path); + txtJavaDir.setText(path); + Settings.getLastProfile().getSelectedVersionSetting().setJavaDir(txtJavaDir.getText()); } catch (IOException e) { - HMCLog.warn("Failed to set game dir.", e); - MessageBox.Show(C.i18n("ui.label.failed_set") + e.getMessage()); + HMCLog.warn("Failed to set java path.", e); + MessageBox.show(C.i18n("ui.label.failed_set") + e.getMessage()); } - }//GEN-LAST:event_btnChoosingGameDirActionPerformed - - private void btnCleanGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCleanGameActionPerformed - Settings.getLastProfile().service().version().cleanFolder(); - }//GEN-LAST:event_btnCleanGameActionPerformed - - private void btnTestGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTestGameActionPerformed - LogWindow.INSTANCE.setVisible(true); - MainFrame.INSTANCE.daemon.runGame(Settings.getLastProfile()); - }//GEN-LAST:event_btnTestGameActionPerformed - - private void btnShowLogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnShowLogActionPerformed - LogWindow.INSTANCE.setVisible(true); - }//GEN-LAST:event_btnShowLogActionPerformed - - private void btnMakeLaunchScriptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMakeLaunchScriptActionPerformed - MainFrame.INSTANCE.daemon.makeLaunchScript(Settings.getLastProfile()); - }//GEN-LAST:event_btnMakeLaunchScriptActionPerformed - - private void btnIncludeMinecraftActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnIncludeMinecraftActionPerformed - JFileChooser fc = new JFileChooser(new File(".")); - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { - File newGameDir = fc.getSelectedFile(); - String name = JOptionPane.showInputDialog(C.i18n("setupwindow.give_a_name")); - if (StrUtils.isBlank(name)) { - MessageBox.Show(C.i18n("setupwindow.no_empty_name")); - return; - } - Settings.putProfile(new Profile(name).setGameDir(newGameDir.getAbsolutePath())); - MessageBox.Show(C.i18n("setupwindow.find_in_configurations")); - loadProfiles(); - } - }//GEN-LAST:event_btnIncludeMinecraftActionPerformed + }//GEN-LAST:event_btnChoosingJavaDirActionPerformed private void cboRunDirectoryItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboRunDirectoryItemStateChanged if (!isLoading && cboRunDirectory.getSelectedIndex() >= 0) @@ -1119,60 +1150,41 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget Settings.getLastProfile().getSelectedVersionSetting().setLauncherVisibility(LauncherVisibility.values()[cboLauncherVisibility.getSelectedIndex()]); }//GEN-LAST:event_cboLauncherVisibilityItemStateChanged - private void chkFullscreenItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkFullscreenItemStateChanged - if (!isLoading) - Settings.getLastProfile().getSelectedVersionSetting().setFullscreen(chkFullscreen.isSelected()); - }//GEN-LAST:event_chkFullscreenItemStateChanged - - private void chkNoJVMArgsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkNoJVMArgsItemStateChanged - if (!isLoading) - Settings.getLastProfile().getSelectedVersionSetting().setNoJVMArgs(chkNoJVMArgs.isSelected()); - }//GEN-LAST:event_chkNoJVMArgsItemStateChanged + private void btnDownloadAllAssetsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDownloadAllAssetsActionPerformed + if (mcVersion != null) + try { + TaskWindow.factory().execute(Settings.getLastProfile().service().asset().downloadAssets(mcVersion)); + } catch (GameException ex) { + HMCLog.err("Failed to download assets", ex); + MessageBox.showLocalized("assets.failed_download"); + } + }//GEN-LAST:event_btnDownloadAllAssetsActionPerformed private void txtMaxMemoryFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtMaxMemoryFocusLost Settings.getLastProfile().getSelectedVersionSetting().setMaxMemory(txtMaxMemory.getText()); }//GEN-LAST:event_txtMaxMemoryFocusLost - private void txtWidthFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtWidthFocusLost - Settings.getLastProfile().getSelectedVersionSetting().setWidth(txtWidth.getText()); - }//GEN-LAST:event_txtWidthFocusLost + private void txtJavaDirFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtJavaDirFocusLost + Settings.getLastProfile().getSelectedVersionSetting().setJavaDir(txtJavaDir.getText()); + }//GEN-LAST:event_txtJavaDirFocusLost + + private void chkFullscreenItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkFullscreenItemStateChanged + if (!isLoading) + Settings.getLastProfile().getSelectedVersionSetting().setFullscreen(chkFullscreen.isSelected()); + }//GEN-LAST:event_chkFullscreenItemStateChanged private void txtHeightFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtHeightFocusLost Settings.getLastProfile().getSelectedVersionSetting().setHeight(txtHeight.getText()); }//GEN-LAST:event_txtHeightFocusLost - private void txtJavaDirFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtJavaDirFocusLost - Settings.getLastProfile().getSelectedVersionSetting().setJavaDir(txtJavaDir.getText()); - }//GEN-LAST:event_txtJavaDirFocusLost + private void txtWidthFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtWidthFocusLost + Settings.getLastProfile().getSelectedVersionSetting().setWidth(txtWidth.getText()); + }//GEN-LAST:event_txtWidthFocusLost - private void txtJavaArgsFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtJavaArgsFocusLost - Settings.getLastProfile().getSelectedVersionSetting().setJavaArgs(txtJavaArgs.getText()); - }//GEN-LAST:event_txtJavaArgsFocusLost - - private void txtMinecraftArgsFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtMinecraftArgsFocusLost - Settings.getLastProfile().getSelectedVersionSetting().setMinecraftArgs(txtMinecraftArgs.getText()); - }//GEN-LAST:event_txtMinecraftArgsFocusLost - - private void txtPermSizeFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPermSizeFocusLost - Settings.getLastProfile().getSelectedVersionSetting().setPermSize(txtPermSize.getText()); - }//GEN-LAST:event_txtPermSizeFocusLost - - private void txtPrecalledCommandFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPrecalledCommandFocusLost - Settings.getLastProfile().getSelectedVersionSetting().setPrecalledCommand(txtPrecalledCommand.getText()); - }//GEN-LAST:event_txtPrecalledCommandFocusLost - - private void txtServerIPFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtServerIPFocusLost - Settings.getLastProfile().getSelectedVersionSetting().setServerIp(txtServerIP.getText()); - }//GEN-LAST:event_txtServerIPFocusLost - - private void txtWrapperLauncherFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtWrapperLauncherFocusLost - Settings.getLastProfile().getSelectedVersionSetting().setWrapper(txtWrapperLauncher.getText()); - }//GEN-LAST:event_txtWrapperLauncherFocusLost - - private void chkDontCheckGameItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkDontCheckGameItemStateChanged - if (!isLoading) - Settings.getLastProfile().getSelectedVersionSetting().setNotCheckGame(chkDontCheckGame.isSelected()); - }//GEN-LAST:event_chkDontCheckGameItemStateChanged + private void txtGameDirFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtGameDirFocusLost + Settings.getLastProfile().setGameDir(txtGameDir.getText()); + loadVersions(); + }//GEN-LAST:event_txtGameDirFocusLost // // @@ -1224,7 +1236,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget List files = (List) tr.getTransferData(DataFlavor.javaFileListFlavor); for (File file : files) Settings.getLastProfile().service().mod().addMod(Settings.getLastProfile().getSelectedVersion(), file); - } catch (Exception ex) { + } catch (UnsupportedFlavorException | IOException ex) { HMCLog.warn("Failed to drop file.", ex); } } @@ -1260,12 +1272,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget return; reloadingMods = true; DefaultTableModel model = SwingUtils.clearDefaultTable(lstExternalMods); - new OverridableSwingWorker>() { - @Override - protected void work() throws Exception { - publish(Settings.getLastProfile().service().mod().recacheMods(Settings.getLastProfile().getSelectedVersion())); - } - }.reg(t -> { + new OverridableSwingWorkerImpl().reg(t -> { synchronized (modLock) { for (ModInfo x : t) model.addRow(new Object[] { x.isActive(), x, x.version }); @@ -1275,6 +1282,14 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget } } + private static class OverridableSwingWorkerImpl extends AbstractSwingWorker> { + + @Override + protected void work() throws Exception { + publish(Settings.getLastProfile().service().mod().recacheMods(Settings.getLastProfile().getSelectedVersion())); + } + } + // void save() { VersionSetting vs = Settings.getLastProfile().getSelectedVersionSetting(); @@ -1306,6 +1321,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget Settings.onProfileLoading(); } + @Override public void onLeave() { super.onLeave(); save(); @@ -1394,7 +1410,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget private void loadProfiles() { isLoading = true; - DefaultComboBoxModel model = new DefaultComboBoxModel(); + DefaultComboBoxModel model = new DefaultComboBoxModel<>(); for (Profile s : Settings.getProfilesFiltered()) model.addElement(s.getName()); cboProfiles.setModel(model); @@ -1407,7 +1423,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget }; void loadVersions() { - DefaultComboBoxModel model = new DefaultComboBoxModel(); + DefaultComboBoxModel model = new DefaultComboBoxModel<>(); for (MinecraftVersion each : Settings.getLastProfile().service().version().getVersions()) { if (each.hidden) continue; @@ -1422,7 +1438,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget public void versionChanged(String version) { isLoading = true; - DefaultComboBoxModel model = (DefaultComboBoxModel) cboVersions.getModel(); + DefaultComboBoxModel model = (DefaultComboBoxModel) cboVersions.getModel(); for (int i = 0; i < model.getSize(); ++i) if (model.getElementAt(i).equals(version)) { model.setSelectedItem(version); @@ -1446,7 +1462,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget txtGameDir.setText(t.getGameDir()); isLoading = true; - DefaultComboBoxModel model = (DefaultComboBoxModel) cboProfiles.getModel(); + DefaultComboBoxModel model = (DefaultComboBoxModel) cboProfiles.getModel(); for (int i = 0; i < model.getSize(); ++i) if (model.getElementAt(i).equals(t.getName())) { model.setSelectedItem(t.getName()); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/HeaderTab.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/HeaderTab.java index 54cb65370..0a4dc9c3b 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/HeaderTab.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/HeaderTab.java @@ -68,10 +68,6 @@ public class HeaderTab extends JLabel return this.model.getActionListeners(); } - public void removeActionListener(ActionListener listener) { - this.model.removeActionListener(listener); - } - public void setActionCommand(String command) { this.model.setActionCommand(command); } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/InstallerPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/InstallerPanel.java index 26ebaad1b..4f6901cdb 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/InstallerPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/InstallerPanel.java @@ -24,24 +24,25 @@ import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.launcher.core.install.InstallerType; import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList; -import org.jackhuang.hellominecraft.util.tasks.TaskRunnable; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; +import org.jackhuang.hellominecraft.util.task.TaskRunnable; +import org.jackhuang.hellominecraft.util.task.TaskWindow; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.StrUtils; +import org.jackhuang.hellominecraft.util.task.Task; import org.jackhuang.hellominecraft.util.ui.SwingUtils; /** * * @author huangyuhui */ -public class InstallerPanel extends AnimatedPanel { +public class InstallerPanel extends Page { GameSettingsPanel gsp; /** * Creates new form InstallerPanel * - * @param gsp To get the minecraft version + * @param gsp To get the minecraft version * @param installerType load which installer */ public InstallerPanel(GameSettingsPanel gsp, InstallerType installerType) { @@ -113,16 +114,19 @@ public class InstallerPanel extends AnimatedPanel { }//GEN-LAST:event_btnInstallActionPerformed private void btnRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshActionPerformed - refreshVersions(); + TaskWindow.factory().execute(refreshVersionsTask()); }//GEN-LAST:event_btnRefreshActionPerformed transient List versions; - transient InstallerVersionList list; + InstallerVersionList list; InstallerType id; - void refreshVersions() { - if (TaskWindow.execute(list.refresh(new String[] { gsp.getMinecraftVersionFormatted() }))) - loadVersions(); + Task refreshVersionsTask() { + Task t = list.refresh(new String[] { gsp.getMinecraftVersionFormatted() }); + if (t != null) + return t.with(new TaskRunnable(this::loadVersions)); + else + return null; } public synchronized InstallerVersionList.InstallerVersion getVersion(int idx) { @@ -132,11 +136,13 @@ public class InstallerPanel extends AnimatedPanel { synchronized void downloadSelectedRow() { int idx = lstInstallers.getSelectedRow(); if (versions == null || idx < 0 || idx >= versions.size()) { - MessageBox.Show(C.i18n("install.not_refreshed")); + MessageBox.show(C.i18n("install.not_refreshed")); return; } - TaskWindow.execute(Settings.getLastProfile().service().install().download(Settings.getLastProfile().getSelectedVersion(), getVersion(idx), id), - new TaskRunnable(this::refreshVersions)); + TaskWindow.factory() + .append(Settings.getLastProfile().service().install().download(Settings.getLastProfile().getSelectedVersion(), getVersion(idx), id)) + .append(refreshVersionsTask()) + .execute(); } public void loadVersions() { @@ -159,7 +165,7 @@ public class InstallerPanel extends AnimatedPanel { @Override public void onSelect() { if (!refreshed) { - refreshVersions(); + TaskWindow.factory().execute(refreshVersionsTask()); refreshed = true; } } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LauncherSettingsPanel.form b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LauncherSettingsPanel.form index 9eabf0b12..fa1a07eaf 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LauncherSettingsPanel.form +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LauncherSettingsPanel.form @@ -19,18 +19,6 @@ - - - - - - - - - - - - @@ -71,9 +59,20 @@ + + + + + + + + + + + @@ -121,17 +120,18 @@ - + + + - - + - + @@ -157,12 +157,9 @@ - + - - - @@ -291,16 +288,6 @@ - - - - - - - - - - @@ -357,5 +344,15 @@ + + + + + + + + + + diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LauncherSettingsPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LauncherSettingsPanel.java index 29203424f..b2f6fa751 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LauncherSettingsPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/LauncherSettingsPanel.java @@ -17,41 +17,44 @@ */ package org.jackhuang.hellominecraft.launcher.ui; -import java.awt.Color; import java.io.IOException; import javax.swing.DefaultComboBoxModel; -import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.launcher.core.download.DownloadType; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.lang.SupportedLocales; +import org.jackhuang.hellominecraft.util.ui.GraphicsUtils; +import org.jackhuang.hellominecraft.util.ui.JSystemFileChooser; import org.jackhuang.hellominecraft.util.ui.SwingUtils; /** * * @author huangyuhui */ -public class LauncherSettingsPanel extends AnimatedPanel { +public class LauncherSettingsPanel extends RepaintPage { /** * Creates new form LancherSettingsPanel */ public LauncherSettingsPanel() { + setRepainter(this); } void initGui() { initComponents(); + setBackground(GraphicsUtils.getWebColorWithAlpha("FFFFFF7F")); + setOpaque(true); - DefaultComboBoxModel d = new DefaultComboBoxModel(); + DefaultComboBoxModel d = new DefaultComboBoxModel<>(); for (DownloadType type : DownloadType.values()) d.addElement(type.getName()); cboDownloadSource.setModel(d); - d = new DefaultComboBoxModel(); + d = new DefaultComboBoxModel<>(); int id = 0; for (SupportedLocales type : SupportedLocales.values()) { d.addElement(type.showString()); @@ -69,11 +72,8 @@ public class LauncherSettingsPanel extends AnimatedPanel { cboDownloadSource.setSelectedIndex(Settings.getInstance().getDownloadType()); cboTheme.setSelectedIndex(Settings.getInstance().getTheme().ordinal()); chkEnableShadow.setSelected(Settings.getInstance().isEnableShadow()); - chkEnableAnimation.setSelected(Settings.getInstance().isEnableAnimation()); + chkEnableBlur.setSelected(Settings.getInstance().isEnableBlur()); chkDecorated.setSelected(Settings.getInstance().isDecorated()); - - setBackground(Color.white); - setOpaque(true); } @Override @@ -110,13 +110,13 @@ public class LauncherSettingsPanel extends AnimatedPanel { txtProxyUsername = new javax.swing.JTextField(); txtProxyPassword = new javax.swing.JTextField(); lblProxyPassword = new javax.swing.JLabel(); - chkEnableAnimation = new javax.swing.JCheckBox(); chkDecorated = new javax.swing.JCheckBox(); lblModpack = new javax.swing.JLabel(); cboLang = new javax.swing.JComboBox(); lblLang = new javax.swing.JLabel(); lblRestart = new javax.swing.JLabel(); btnMCBBS = new javax.swing.JButton(); + chkEnableBlur = new javax.swing.JCheckBox(); cboDownloadSource.addItemListener(new java.awt.event.ItemListener() { public void itemStateChanged(java.awt.event.ItemEvent evt) { @@ -125,12 +125,7 @@ public class LauncherSettingsPanel extends AnimatedPanel { }); lblAbout.setText(C.i18n("launcher.about")); // NOI18N - lblAbout.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - lblAbout.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseClicked(java.awt.event.MouseEvent evt) { - lblAboutMouseClicked(evt); - } - }); + lblAbout.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); btnSelBackgroundPath.setText(C.i18n("ui.button.explore")); // NOI18N btnSelBackgroundPath.addActionListener(new java.awt.event.ActionListener() { @@ -208,13 +203,6 @@ public class LauncherSettingsPanel extends AnimatedPanel { lblProxyPassword.setText(C.i18n("proxy.password")); // NOI18N - chkEnableAnimation.setText(C.i18n("launcher.enable_animation")); // NOI18N - chkEnableAnimation.addItemListener(new java.awt.event.ItemListener() { - public void itemStateChanged(java.awt.event.ItemEvent evt) { - chkEnableAnimationItemStateChanged(evt); - } - }); - chkDecorated.setText(C.i18n("launcher.decorated")); // NOI18N chkDecorated.addItemListener(new java.awt.event.ItemListener() { public void itemStateChanged(java.awt.event.ItemEvent evt) { @@ -249,6 +237,13 @@ public class LauncherSettingsPanel extends AnimatedPanel { } }); + chkEnableBlur.setText(C.i18n("launcher.enable_blur")); // NOI18N + chkEnableBlur.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + chkEnableBlurItemStateChanged(evt); + } + }); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -256,16 +251,6 @@ public class LauncherSettingsPanel extends AnimatedPanel { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(chkEnableShadow) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(chkEnableAnimation)) - .addGroup(layout.createSequentialGroup() - .addComponent(btnCheckUpdate) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnMCBBS) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(chkDecorated)) .addGroup(layout.createSequentialGroup() .addComponent(lblProxy) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) @@ -301,9 +286,18 @@ public class LauncherSettingsPanel extends AnimatedPanel { .addComponent(cboTheme, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lblAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblModpack, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblRestart)) + .addGroup(layout.createSequentialGroup() + .addComponent(btnCheckUpdate) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnMCBBS)) + .addComponent(lblAbout) + .addComponent(lblModpack) + .addComponent(lblRestart) + .addGroup(layout.createSequentialGroup() + .addComponent(chkEnableShadow) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkEnableBlur)) + .addComponent(chkDecorated)) .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); @@ -341,18 +335,19 @@ public class LauncherSettingsPanel extends AnimatedPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(chkEnableShadow) - .addComponent(chkEnableAnimation)) + .addComponent(chkEnableBlur)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkDecorated) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 6, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnCheckUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(chkDecorated) - .addComponent(btnMCBBS)) + .addComponent(btnMCBBS, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblRestart) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 65, Short.MAX_VALUE) - .addComponent(lblModpack, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblModpack) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblAbout) .addContainerGap()) ); }// //GEN-END:initComponents @@ -362,8 +357,8 @@ public class LauncherSettingsPanel extends AnimatedPanel { }//GEN-LAST:event_cboDownloadSourceItemStateChanged private void btnSelBackgroundPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSelBackgroundPathActionPerformed - JFileChooser fc = new JFileChooser(); - fc.setFileSelectionMode(JFileChooser.FILES_ONLY); + JSystemFileChooser fc = new JSystemFileChooser(); + fc.setFileSelectionMode(JSystemFileChooser.FILES_ONLY); fc.setDialogTitle(C.i18n("launcher.choose_bgpath")); fc.setMultiSelectionEnabled(false); fc.setFileFilter(new FileNameExtensionFilter("*.png", "png")); @@ -379,7 +374,7 @@ public class LauncherSettingsPanel extends AnimatedPanel { MainFrame.INSTANCE.loadBackground(); } catch (IOException e) { HMCLog.warn("Failed to set background path.", e); - MessageBox.Show(C.i18n("ui.label.failed_set") + e.getMessage()); + MessageBox.show(C.i18n("ui.label.failed_set") + e.getMessage()); } }//GEN-LAST:event_btnSelBackgroundPathActionPerformed @@ -413,10 +408,6 @@ public class LauncherSettingsPanel extends AnimatedPanel { Settings.getInstance().setDecorated(chkDecorated.isSelected()); }//GEN-LAST:event_chkDecoratedItemStateChanged - private void chkEnableAnimationItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkEnableAnimationItemStateChanged - Settings.getInstance().setEnableAnimation(chkEnableAnimation.isSelected()); - }//GEN-LAST:event_chkEnableAnimationItemStateChanged - private void txtProxyHostFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtProxyHostFocusLost Settings.getInstance().setProxyHost(txtProxyHost.getText()); }//GEN-LAST:event_txtProxyHostFocusLost @@ -433,14 +424,14 @@ public class LauncherSettingsPanel extends AnimatedPanel { Settings.getInstance().setProxyPassword(txtProxyPassword.getText()); }//GEN-LAST:event_txtProxyPasswordFocusLost - private void lblAboutMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lblAboutMouseClicked - SwingUtils.openLink("http://huangyuhui.duapp.com/link.php?type=sponsor"); - }//GEN-LAST:event_lblAboutMouseClicked - private void btnMCBBSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCBBSActionPerformed SwingUtils.openLink(C.URL_PUBLISH); }//GEN-LAST:event_btnMCBBSActionPerformed + private void chkEnableBlurItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkEnableBlurItemStateChanged + Settings.getInstance().setEnableBlur(chkEnableBlur.isSelected()); + }//GEN-LAST:event_chkEnableBlurItemStateChanged + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnCheckUpdate; private javax.swing.JButton btnMCBBS; @@ -449,7 +440,7 @@ public class LauncherSettingsPanel extends AnimatedPanel { private javax.swing.JComboBox cboLang; private javax.swing.JComboBox cboTheme; private javax.swing.JCheckBox chkDecorated; - private javax.swing.JCheckBox chkEnableAnimation; + private javax.swing.JCheckBox chkEnableBlur; private javax.swing.JCheckBox chkEnableShadow; private javax.swing.JLabel lblAbout; private javax.swing.JLabel lblBackground; 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 1790f2c06..e88a07ce8 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 @@ -31,11 +31,11 @@ import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.Event; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.func.Consumer; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.system.JavaProcessMonitor; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.JavaProcessMonitor; import org.jackhuang.hellominecraft.util.ui.LogWindow; -import org.jackhuang.hellominecraft.util.ui.WebFrame; +import org.jackhuang.hellominecraft.util.net.WebFrame; /** * @@ -110,19 +110,17 @@ public class LaunchingUIDaemon { String msg = C.i18n("launch.exited_abnormally") + " exit code: " + t; if (errorText != null) msg += ", advice: " + MinecraftCrashAdvicer.getAdvice(FileUtils.readQuietly(new File(errorText))); - MessageBox.Show(msg); WebFrame f = new WebFrame(logs); f.setModal(true); - f.setTitle("Game output"); + f.setTitle(msg); f.setVisible(true); checkExit((LauncherVisibility) obj.getTag()); }); jpm.jvmLaunchFailedEvent.register(t -> { HMCLog.err("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.setModal(true); - f.setTitle("Game output"); + f.setTitle(C.i18n("launch.cannot_create_jvm") + " exit code: " + t); f.setVisible(true); checkExit((LauncherVisibility) obj.getTag()); }); @@ -138,10 +136,6 @@ public class LaunchingUIDaemon { return true; }; - private static void getCrashReport() { - - } - private static void checkExit(LauncherVisibility v) { if (v != LauncherVisibility.KEEP && !LogWindow.INSTANCE.isVisible()) { HMCLog.log("Launcher will exit now."); @@ -154,10 +148,10 @@ public class LaunchingUIDaemon { try { String s = JOptionPane.showInputDialog(C.i18n("mainwindow.enter_script_name")); if (s != null) - MessageBox.Show(C.i18n("mainwindow.make_launch_succeed") + " " + ((GameLauncher) sender).makeLauncher(s, str).getAbsolutePath()); + MessageBox.show(C.i18n("mainwindow.make_launch_succeed") + " " + ((GameLauncher) sender).makeLauncher(s, str).getAbsolutePath()); flag = true; } catch (IOException ex) { - MessageBox.Show(C.i18n("mainwindow.make_launch_script_failed")); + MessageBox.show(C.i18n("mainwindow.make_launch_script_failed")); HMCLog.err("Failed to create script file.", ex); } MainFrame.INSTANCE.closeMessage(); 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 8457cba22..caed3133e 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 @@ -17,6 +17,8 @@ */ package org.jackhuang.hellominecraft.launcher.ui; +import org.jackhuang.hellominecraft.util.ui.GaussionPanel; +import org.jackhuang.hellominecraft.util.ui.IRepaint; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; @@ -25,7 +27,9 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; +import java.awt.Rectangle; import java.awt.Transparency; +import java.awt.Window; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; @@ -33,6 +37,8 @@ import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.awt.image.BufferedImage; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.List; import javax.swing.BorderFactory; @@ -40,35 +46,38 @@ import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingUtilities; -import org.jackhuang.hellominecraft.util.C; -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.util.ui.GraphicsUtils; +import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.lookandfeel.Theme; +import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.ui.DropShadowBorder; -import org.jackhuang.hellominecraft.util.ui.TintablePanel; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.ui.BasicColors; +import org.jackhuang.hellominecraft.util.ui.DropShadowBorder; +import org.jackhuang.hellominecraft.util.ui.GraphicsUtils; import org.jackhuang.hellominecraft.util.ui.SwingUtils; +import org.jackhuang.hellominecraft.util.ui.TintablePanel; + /** * * @author huangyuhui */ -public final class MainFrame extends DraggableFrame { +public final class MainFrame extends DraggableFrame implements IRepaint { public static final MainFrame INSTANCE = new MainFrame(); TintablePanel centralPanel; JPanel header, infoSwap, realPanel; CardLayout infoLayout; - JLabel backgroundLabel, windowTitle; + JLabel windowTitle; + GaussionPanel backgroundLabel; DropShadowBorder border; boolean enableShadow; String defaultTitle; @@ -89,7 +98,7 @@ public final class MainFrame extends DraggableFrame { setContentSize(834, 542); else setContentSize(802, 511); - setDefaultCloseOperation(3); + setDefaultCloseOperation(EXIT_ON_CLOSE); setTitle(Main.makeTitle()); initComponents(); loadBackground(); @@ -152,6 +161,7 @@ public final class MainFrame extends DraggableFrame { } private void initComponents() { + setLayout(null); initBorderColor(Settings.getInstance().getTheme()); realPanel = new JPanel(); @@ -242,14 +252,13 @@ public final class MainFrame extends DraggableFrame { truePanel.setBounds(0, 0, 800, 480); centralPanel.setBounds(0, 30, 800, 480); - setLayout(null); realPanel.setBounds(1, 0, 800, 511); add(realPanel); } - private final ActionListener tabListener = e -> MainFrame.this.selectTab(e.getActionCommand()); + private transient final ActionListener tabListener = e -> MainFrame.this.selectTab(e.getActionCommand()); - private void initializeTab(AnimatedPanel inst, String cmd) { + private void initializeTab(Page inst, String cmd) { HeaderTab tab = new HeaderTab(C.i18n("launcher.title." + cmd)); tab.setActionCommand(cmd); tab.setForeground(BasicColors.COLOR_WHITE_TEXT); @@ -263,11 +272,11 @@ public final class MainFrame extends DraggableFrame { private final List tabHeader = new ArrayList<>(); private JPanel tabWrapper[]; - private final List tabContent = new ArrayList<>(); + private final List tabContent = new ArrayList<>(); public void selectTab(String tabName) { int chosen = -1; - AnimatedPanel onCreate = null, onSelect = null; + Page onCreate = null, onSelect = null; for (int i = 0; i < tabHeader.size(); i++) if (tabName.equalsIgnoreCase(tabHeader.get(i).getActionCommand())) { if (!tabContent.get(i).isCreated()) { @@ -318,14 +327,15 @@ public final class MainFrame extends DraggableFrame { public void loadBackground() { background = SwingUtils.searchBackgroundImage(Main.getIcon(Settings.getInstance().getTheme().settings.get("Customized.MainFrame.background_image")), Settings.getInstance().getBgpath(), 800, 480); - if (background != null) + if (background != null) { if (backgroundLabel == null) { - backgroundLabel = new JLabel(background); + backgroundLabel = new GaussionPanel(); + backgroundLabel.addAeroObject(backgroundLabel); backgroundLabel.setBounds(0, 0, 800, 480); centralPanel.add(backgroundLabel, -1); - } else - backgroundLabel.setIcon(background); - else + } + backgroundLabel.setBackgroundImage(background.getImage()); + } else HMCLog.warn("No background image here! The background will be empty!"); } @@ -340,7 +350,7 @@ public final class MainFrame extends DraggableFrame { isShowedMessage = false; reloadColor(Settings.getInstance().getTheme()); windowTitle.setText(defaultTitle); - windowTitle.setForeground(Settings.UPDATE_CHECKER.OUT_DATED ? Color.red : Color.white); + windowTitle.setForeground(Settings.UPDATE_CHECKER.isOutOfDate() ? Color.red : Color.white); } } @@ -407,7 +417,7 @@ public final class MainFrame extends DraggableFrame { int contentWidth = width - off - off; int contentHeight = height - off - off; BufferedImage contentImage = new BufferedImage(contentWidth, - contentHeight, Transparency.OPAQUE); + contentHeight, Transparency.OPAQUE); Graphics2D contentG2d = contentImage.createGraphics(); contentG2d.translate(-off, -off); paintImpl(g); @@ -426,6 +436,25 @@ public final class MainFrame extends DraggableFrame { } } + @Override + public JComponent getRepaintComponent() { + return null; + } + + @Override + public Window getRepaintWindow() { + return this; + } + + @Override + public Collection getRepaintRects() { + int off = MainFrame.INSTANCE.enableShadow ? 16 : 0, yoff = MainFrame.INSTANCE.getInsets().top + off, xoff = MainFrame.INSTANCE.getInsets().left + off; + int width = 800, height = MainFrame.INSTANCE.header.getHeight() + 480 - 1; + return Arrays.asList(new Rectangle(xoff, yoff, xoff, height + yoff + 1), + new Rectangle(xoff + width + 1, yoff, xoff + width + 1, height + yoff + 1), + new Rectangle(xoff, height + yoff + 1, xoff + width + 1, height + yoff + 1)); + } + private static class MouseListenerImpl implements MouseListener { public static final MouseListenerImpl INSTANCE = new MouseListenerImpl(); @@ -454,14 +483,12 @@ public final class MainFrame extends DraggableFrame { public void failed(String s) { if (s != null) - MessageBox.Show(s); + MessageBox.show(s); closeMessage(); } - LaunchingUIDaemon daemon = new LaunchingUIDaemon(); - - final HashMap actions = new HashMap<>(); - + transient LaunchingUIDaemon daemon = new LaunchingUIDaemon(); + transient final HashMap actions = new HashMap<>(); void invokeAction(String name) { if (actions.containsKey(name)) actions.get(name).run(); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.form b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.form index 4a7db3ca7..8b2c13b60 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.form +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.form @@ -18,264 +18,287 @@ - - - - - - - + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file 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 c621b7ba7..374d3c668 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 @@ -17,13 +17,14 @@ */ package org.jackhuang.hellominecraft.launcher.ui; +import org.jackhuang.hellominecraft.util.ui.WideComboBox; +import org.jackhuang.hellominecraft.util.ui.GaussionPanel; import java.awt.CardLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ItemEvent; import java.awt.event.KeyEvent; import javax.swing.DefaultComboBoxModel; -import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.filechooser.FileNameExtensionFilter; @@ -38,12 +39,13 @@ 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.launcher.util.HMCLMinecraftService; -import org.jackhuang.hellominecraft.util.ui.GraphicsUtils; import org.jackhuang.hellominecraft.util.Event; -import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton; +import org.jackhuang.hellominecraft.lookandfeel.ConstomButton; import org.jackhuang.hellominecraft.util.func.Consumer; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.task.TaskWindow; +import org.jackhuang.hellominecraft.util.ui.GraphicsUtils; +import org.jackhuang.hellominecraft.util.ui.JSystemFileChooser; import org.jackhuang.hellominecraft.util.ui.SwingUtils; import org.jackhuang.hellominecraft.util.ui.wizard.api.WizardDisplayer; @@ -51,11 +53,8 @@ import org.jackhuang.hellominecraft.util.ui.wizard.api.WizardDisplayer; * * @author huangyuhui */ -public class MainPagePanel extends AnimatedPanel { +public class MainPagePanel extends Page { - /** - * Creates new form MainPagePanel - */ public MainPagePanel() { } @@ -76,7 +75,7 @@ public class MainPagePanel extends AnimatedPanel { btnRun.setFont(newFont); btnRun.addActionListener(e -> MainFrame.INSTANCE.daemon.runGame(Settings.getLastProfile())); - this.add(pnlButtons); + pnlRoot.add(pnlButtons); pnlButtons.setBounds(0, 0, w, h); this.setSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT)); @@ -93,7 +92,11 @@ public class MainPagePanel extends AnimatedPanel { prepareAuths(); - animationEnabled = false; + if (Settings.getInstance().isEnableBlur()) + ((GaussionPanel) pnlRoot).addAeroObject(pnlMore); + ((GaussionPanel) pnlRoot).setBackgroundImage(MainFrame.INSTANCE.background.getImage()); + + ((RepaintPage) pnlMore).setRepainter(pnlRoot); } /** @@ -105,26 +108,29 @@ public class MainPagePanel extends AnimatedPanel { // //GEN-BEGIN:initComponents private void initComponents() { - pnlMore = new javax.swing.JPanel(); + pnlRoot = new GaussionPanel(); + pnlMore = new org.jackhuang.hellominecraft.launcher.ui.RepaintPage(); txtPlayerName = new javax.swing.JTextField(); - jLabel7 = new javax.swing.JLabel(); + lblLogin = new javax.swing.JLabel(); cboLoginMode = new javax.swing.JComboBox(); lblUserName = new javax.swing.JLabel(); - jLabel10 = new javax.swing.JLabel(); + lblProfile = new javax.swing.JLabel(); cboProfiles = new javax.swing.JComboBox(); lblVersion = new javax.swing.JLabel(); - cboVersions = new javax.swing.JComboBox(); + cboVersions = new WideComboBox(); pnlPassword = new javax.swing.JPanel(); - jPanel1 = new javax.swing.JPanel(); - jLabel9 = new javax.swing.JLabel(); + pnlLogIn = new javax.swing.JPanel(); + lblPassword = new javax.swing.JLabel(); txtPassword = new javax.swing.JPasswordField(); - jPanel3 = new javax.swing.JPanel(); + pnlLogOut = new javax.swing.JPanel(); btnLogout = new javax.swing.JButton(); btnImportModpack = new javax.swing.JButton(); btnExportModpack = new javax.swing.JButton(); setLayout(null); + pnlRoot.setLayout(null); + pnlMore.setBackground(new java.awt.Color(204, 204, 204)); pnlMore.setOpaque(false); @@ -142,7 +148,7 @@ public class MainPagePanel extends AnimatedPanel { } }); - jLabel7.setText(C.i18n("login.type")); // NOI18N + lblLogin.setText(C.i18n("login.type")); // NOI18N cboLoginMode.addItemListener(new java.awt.event.ItemListener() { public void itemStateChanged(java.awt.event.ItemEvent evt) { @@ -152,7 +158,7 @@ public class MainPagePanel extends AnimatedPanel { lblUserName.setText(C.i18n("login.username")); // NOI18N - jLabel10.setText(C.i18n("ui.label.profile")); // NOI18N + lblProfile.setText(C.i18n("ui.label.profile")); // NOI18N cboProfiles.addItemListener(new java.awt.event.ItemListener() { public void itemStateChanged(java.awt.event.ItemEvent evt) { @@ -171,7 +177,7 @@ public class MainPagePanel extends AnimatedPanel { pnlPassword.setLayout(new java.awt.CardLayout()); - jLabel9.setText(C.i18n("ui.label.password")); // NOI18N + lblPassword.setText(C.i18n("ui.label.password")); // NOI18N txtPassword.addCaretListener(new javax.swing.event.CaretListener() { public void caretUpdate(javax.swing.event.CaretEvent evt) { @@ -194,25 +200,25 @@ public class MainPagePanel extends AnimatedPanel { } }); - javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel9) + javax.swing.GroupLayout pnlLogInLayout = new javax.swing.GroupLayout(pnlLogIn); + pnlLogIn.setLayout(pnlLogInLayout); + pnlLogInLayout.setHorizontalGroup( + pnlLogInLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnlLogInLayout.createSequentialGroup() + .addComponent(lblPassword) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(txtPassword)) ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + pnlLogInLayout.setVerticalGroup( + pnlLogInLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlLogInLayout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(pnlLogInLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lblPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))) ); - pnlPassword.add(jPanel1, "card2"); + pnlPassword.add(pnlLogIn, "card2"); btnLogout.setText(C.i18n("ui.button.logout")); // NOI18N btnLogout.addActionListener(new java.awt.event.ActionListener() { @@ -221,18 +227,18 @@ public class MainPagePanel extends AnimatedPanel { } }); - javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); - jPanel3.setLayout(jPanel3Layout); - jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + javax.swing.GroupLayout pnlLogOutLayout = new javax.swing.GroupLayout(pnlLogOut); + pnlLogOut.setLayout(pnlLogOutLayout); + pnlLogOutLayout.setHorizontalGroup( + pnlLogOutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(btnLogout, javax.swing.GroupLayout.DEFAULT_SIZE, 170, Short.MAX_VALUE) ); - jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + pnlLogOutLayout.setVerticalGroup( + pnlLogOutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(btnLogout, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); - pnlPassword.add(jPanel3, "card3"); + pnlPassword.add(pnlLogOut, "card3"); btnImportModpack.setText(C.i18n("modpack.task.install")); // NOI18N btnImportModpack.addActionListener(new java.awt.event.ActionListener() { @@ -258,16 +264,16 @@ public class MainPagePanel extends AnimatedPanel { .addComponent(pnlPassword, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(pnlMoreLayout.createSequentialGroup() .addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel10, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(lblProfile, javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(lblVersion, javax.swing.GroupLayout.Alignment.TRAILING)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(cboProfiles, 0, 128, Short.MAX_VALUE) + .addComponent(cboProfiles, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(cboVersions, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGroup(pnlMoreLayout.createSequentialGroup() .addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(lblUserName) - .addComponent(jLabel7)) + .addComponent(lblLogin)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(cboLoginMode, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) @@ -281,7 +287,7 @@ public class MainPagePanel extends AnimatedPanel { .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlMoreLayout.createSequentialGroup() .addContainerGap() .addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel10) + .addComponent(lblProfile) .addComponent(cboProfiles, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) @@ -289,7 +295,7 @@ public class MainPagePanel extends AnimatedPanel { .addComponent(lblVersion)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel7) + .addComponent(lblLogin) .addComponent(cboLoginMode, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) @@ -297,15 +303,18 @@ public class MainPagePanel extends AnimatedPanel { .addComponent(txtPlayerName, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(pnlPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 248, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 254, Short.MAX_VALUE) .addComponent(btnImportModpack) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnExportModpack) .addContainerGap()) ); - add(pnlMore); + pnlRoot.add(pnlMore); pnlMore.setBounds(0, 0, 190, 480); + + add(pnlRoot); + pnlRoot.setBounds(0, 0, 800, 480); }// //GEN-END:initComponents private void txtPlayerNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPlayerNameFocusGained @@ -374,8 +383,8 @@ public class MainPagePanel extends AnimatedPanel { }//GEN-LAST:event_txtPasswordKeyPressed private void btnImportModpackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnImportModpackActionPerformed - JFileChooser fc = new JFileChooser(); - fc.setFileSelectionMode(JFileChooser.FILES_ONLY); + JSystemFileChooser fc = new JSystemFileChooser(); + fc.setFileSelectionMode(JSystemFileChooser.FILES_ONLY); fc.setDialogTitle(C.i18n("modpack.choose")); fc.setMultiSelectionEnabled(false); fc.setFileFilter(new FileNameExtensionFilter(C.i18n("modpack"), "zip")); @@ -383,7 +392,7 @@ public class MainPagePanel extends AnimatedPanel { if (fc.getSelectedFile() == null) return; String suggestedModpackId = JOptionPane.showInputDialog("Please enter your favourite game name", FileUtils.getBaseName(fc.getSelectedFile().getName())); - TaskWindow.factory().append(ModpackManager.install(MainFrame.INSTANCE, fc.getSelectedFile(), Settings.getLastProfile().service(), suggestedModpackId)).create(); + TaskWindow.factory().append(ModpackManager.install(MainFrame.INSTANCE, fc.getSelectedFile(), Settings.getLastProfile().service(), suggestedModpackId)).execute(); Settings.getLastProfile().service().version().refreshVersions(); }//GEN-LAST:event_btnImportModpackActionPerformed @@ -398,6 +407,7 @@ public class MainPagePanel extends AnimatedPanel { }//GEN-LAST:event_txtPasswordCaretUpdate // + private void prepareAuths() { preparingAuth = true; cboLoginMode.removeAllItems(); @@ -434,15 +444,16 @@ public class MainPagePanel extends AnimatedPanel { private javax.swing.JComboBox cboLoginMode; private javax.swing.JComboBox cboProfiles; private javax.swing.JComboBox cboVersions; - private javax.swing.JLabel jLabel10; - private javax.swing.JLabel jLabel7; - private javax.swing.JLabel jLabel9; - private javax.swing.JPanel jPanel1; - private javax.swing.JPanel jPanel3; + private javax.swing.JLabel lblLogin; + private javax.swing.JLabel lblPassword; + private javax.swing.JLabel lblProfile; private javax.swing.JLabel lblUserName; private javax.swing.JLabel lblVersion; + private javax.swing.JPanel pnlLogIn; + private javax.swing.JPanel pnlLogOut; private javax.swing.JPanel pnlMore; private javax.swing.JPanel pnlPassword; + private javax.swing.JPanel pnlRoot; private javax.swing.JPasswordField txtPassword; private javax.swing.JTextField txtPlayerName; // End of variables declaration//GEN-END:variables @@ -469,16 +480,14 @@ public class MainPagePanel extends AnimatedPanel { return true; }; - final Runnable onLoadingProfiles = this::loadProfiles; - - private void loadProfiles() { + final Runnable onLoadingProfiles = () -> { isLoading = true; - DefaultComboBoxModel model = new DefaultComboBoxModel(); + DefaultComboBoxModel model = new DefaultComboBoxModel<>(); for (Profile s : Settings.getProfilesFiltered()) model.addElement(s.getName()); cboProfiles.setModel(model); isLoading = false; - } + }; final Consumer onRefreshedVersions = t -> { if (Settings.getLastProfile().service() == t) @@ -495,7 +504,7 @@ public class MainPagePanel extends AnimatedPanel { if (!showedNoVersion && ((HMCLMinecraftService) Settings.getLastProfile().service()).checkedModpack) { showedNoVersion = true; SwingUtilities.invokeLater(() -> { - if (MessageBox.Show(C.i18n("mainwindow.no_version"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) + if (MessageBox.show(C.i18n("mainwindow.no_version"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) MainFrame.INSTANCE.invokeAction("showGameDownloads"); }); } @@ -516,7 +525,7 @@ public class MainPagePanel extends AnimatedPanel { void versionChanged(String selectedVersion) { isLoading = true; - DefaultComboBoxModel model = (DefaultComboBoxModel) cboVersions.getModel(); + DefaultComboBoxModel model = (DefaultComboBoxModel) cboVersions.getModel(); for (int i = 0; i < model.getSize(); ++i) if (model.getElementAt(i).equals(selectedVersion)) { model.setSelectedItem(selectedVersion); @@ -532,7 +541,7 @@ public class MainPagePanel extends AnimatedPanel { t.launcher().launchingStateChanged.register(launchingStateChanged); isLoading = true; - DefaultComboBoxModel model = (DefaultComboBoxModel) cboProfiles.getModel(); + DefaultComboBoxModel model = (DefaultComboBoxModel) cboProfiles.getModel(); for (int i = 0; i < model.getSize(); ++i) if (model.getElementAt(i).equals(t.getName())) { model.setSelectedItem(t.getName()); diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DecompressTask.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/Page.java similarity index 59% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DecompressTask.java rename to HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/Page.java index 1163b6b77..23d5d2ddd 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DecompressTask.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/Page.java @@ -1,5 +1,5 @@ /* - * Hello Minecraft!. + * Hello Minecraft! Launcher. * Copyright (C) 2013 huangyuhui * * This program is free software: you can redistribute it and/or modify @@ -15,32 +15,42 @@ * 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.tasks; +package org.jackhuang.hellominecraft.launcher.ui; -import java.io.File; -import org.jackhuang.hellominecraft.util.system.Compressor; +import javax.swing.JPanel; /** * * @author huangyuhui */ -public class DecompressTask extends Task { +public class Page extends JPanel implements Selectable { - File src, dest; + boolean selected = false; - public DecompressTask(File src, File dest) { - this.src = src; - this.dest = dest; + @Override + public boolean isSelected() { + return selected; } @Override - public void executeTask() throws Throwable { - Compressor.unzip(src, dest); + public void onSelect() { + selected = true; } @Override - public String getInfo() { - return "Decompress: " + src.getAbsolutePath() + " to " + dest.getAbsolutePath(); + public void onLeave() { + selected = false; } + boolean created = false; + + @Override + public void onCreate() { + created = true; + } + + @Override + public boolean isCreated() { + return created; + } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/ContentGetAndShowTask.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/RepaintPage.java old mode 100755 new mode 100644 similarity index 50% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/ContentGetAndShowTask.java rename to HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/RepaintPage.java index b4b381dd0..c376e526f --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/ContentGetAndShowTask.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/RepaintPage.java @@ -1,7 +1,7 @@ /* - * Hello Minecraft!. + * 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 @@ -15,40 +15,43 @@ * 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.tasks.download; +package org.jackhuang.hellominecraft.launcher.ui; -import org.jackhuang.hellominecraft.util.Event; -import org.jackhuang.hellominecraft.util.ui.LogWindow; +import org.jackhuang.hellominecraft.util.ui.IRepaint; +import java.awt.Rectangle; +import java.awt.Window; +import java.util.Arrays; +import java.util.Collection; +import javax.swing.JComponent; /** * - * @author huangyuhui + * @author huang */ -public class ContentGetAndShowTask extends HTTPGetTask implements Event { +public class RepaintPage extends Page implements IRepaint { - public ContentGetAndShowTask(String info, String changeLogUrl) { - super(changeLogUrl); - this.info = info; + public RepaintPage() { + super(); + } + + JComponent repainter; + + @Override + public JComponent getRepaintComponent() { + return repainter; + } + + public void setRepainter(JComponent repainter) { + this.repainter = repainter; } @Override - public void executeTask() throws Exception { - tdtsl.register(this); - super.executeTask(); - } - - String info; - - @Override - public String getInfo() { - return info; + public Collection getRepaintRects() { + return Arrays.asList(this.getBounds()); } @Override - public boolean call(Object sender, String value) { - LogWindow.INSTANCE.clean(); - LogWindow.INSTANCE.log(value); - LogWindow.INSTANCE.setVisible(true); - return true; + public Window getRepaintWindow() { + return null; } } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackDescriptionPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackDescriptionPanel.java index f66e9c008..eab84035c 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackDescriptionPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackDescriptionPanel.java @@ -18,12 +18,14 @@ package org.jackhuang.hellominecraft.launcher.ui.modpack; import java.awt.Dimension; +import java.awt.HeadlessException; +import java.io.IOException; import java.util.Map; import javax.swing.JOptionPane; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.ui.WebPage; +import org.jackhuang.hellominecraft.util.net.WebPage; import org.jackhuang.hellominecraft.util.ui.wizard.spi.WizardController; import org.markdown4j.Markdown4jProcessor; @@ -113,8 +115,8 @@ public class ModpackDescriptionPanel extends javax.swing.JPanel { msgs[1] = new WebPage(new Markdown4jProcessor().process(txtDescription.getText())); ((WebPage) msgs[1]).setPreferredSize(new Dimension(800, 350)); JOptionPane.showOptionDialog(null, msgs, (String) msgs[0], JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); - } catch (Exception e) { - MessageBox.Show(StrUtils.getStackTrace(e), C.i18n("message.error"), MessageBox.WARNING_MESSAGE); + } catch (HeadlessException | IOException e) { + MessageBox.show(StrUtils.getStackTrace(e), C.i18n("message.error"), MessageBox.WARNING_MESSAGE); } }//GEN-LAST:event_jButton1ActionPerformed diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackFileSelectionPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackFileSelectionPanel.java index ff003c8cb..1332fcf41 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackFileSelectionPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackFileSelectionPanel.java @@ -26,7 +26,7 @@ import javax.swing.tree.DefaultTreeModel; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.Pair; import org.jackhuang.hellominecraft.util.func.BiFunction; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.util.ui.checktree.CheckBoxTreeCellRenderer; import org.jackhuang.hellominecraft.util.ui.checktree.CheckBoxTreeNode; import org.jackhuang.hellominecraft.util.ui.checktree.CheckBoxTreeNodeSelectionListener; diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackInitializationPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackInitializationPanel.java index 0f2bda974..998d49fe8 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackInitializationPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackInitializationPanel.java @@ -21,9 +21,9 @@ import java.util.Map; import java.util.Vector; import java.util.regex.Pattern; import javax.swing.DefaultComboBoxModel; -import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; import org.jackhuang.hellominecraft.util.C; +import org.jackhuang.hellominecraft.util.ui.JSystemFileChooser; import org.jackhuang.hellominecraft.util.ui.wizard.spi.WizardController; /** @@ -38,12 +38,12 @@ public class ModpackInitializationPanel extends javax.swing.JPanel { public static final String KEY_INCLUDING_LAUNCHER = "launcher"; private final transient WizardController controller; - private final Map wizardData; + private final Map wizardData; /** * Creates new form ModpackInitializationPanel */ - public ModpackInitializationPanel(WizardController controller, Map wizardData, Vector versions, String selVersion) { + public ModpackInitializationPanel(WizardController controller, Map wizardData, Vector versions, String selVersion) { initComponents(); this.controller = controller; @@ -172,8 +172,8 @@ public class ModpackInitializationPanel extends javax.swing.JPanel { }// //GEN-END:initComponents private void cboModpackLocationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cboModpackLocationActionPerformed - JFileChooser fc = new JFileChooser(); - fc.setFileSelectionMode(JFileChooser.FILES_ONLY); + JSystemFileChooser fc = new JSystemFileChooser(); + fc.setFileSelectionMode(JSystemFileChooser.FILES_ONLY); fc.setDialogTitle(C.i18n("modpack.wizard.step.initialization.save")); fc.setMultiSelectionEnabled(false); fc.setFileFilter(new FileNameExtensionFilter(C.i18n("modpack") + "(*.zip)", "zip")); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackWizard.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackWizard.java index 60903615c..c26ef3163 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackWizard.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackWizard.java @@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.launcher.ui.modpack; import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; @@ -38,10 +39,10 @@ import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.Pair; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.Utils; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.IOUtils; -import org.jackhuang.hellominecraft.util.system.ZipEngine; -import org.jackhuang.hellominecraft.util.ui.WebPage; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.IOUtils; +import org.jackhuang.hellominecraft.util.sys.ZipEngine; +import org.jackhuang.hellominecraft.util.net.WebPage; import org.jackhuang.hellominecraft.util.ui.checktree.CheckBoxTreeNode; import org.jackhuang.hellominecraft.util.ui.wizard.spi.DeferredWizardResult; import org.jackhuang.hellominecraft.util.ui.wizard.spi.ResultProgressHandle; @@ -95,7 +96,7 @@ public class ModpackWizard extends WizardBranchController { if (settings.containsKey(ModpackDescriptionPanel.KEY_MODPACK_DESCRITION)) try { map.put("description", new org.markdown4j.Markdown4jProcessor().process((String) settings.get(ModpackDescriptionPanel.KEY_MODPACK_DESCRITION))); - } catch (Exception ex) { + } catch (IOException ex) { progress.failed(C.i18n("modpack.export_error") + ": " + StrUtils.getStackTrace(ex), true); } try { @@ -113,33 +114,33 @@ public class ModpackWizard extends WizardBranchController { boolean including = false; if ((Boolean) settings.get(ModpackInitializationPanel.KEY_INCLUDING_LAUNCHER)) { boolean flag = true; - ZipEngine engine = new ZipEngine(loc); - Config s = new Config(); - if (!IOUtils.isAbsolutePath(Settings.getInstance().getBgpath())) - s.setBgpath(Settings.getInstance().getBgpath()); - s.setDownloadType(Settings.getInstance().getDownloadType()); - engine.putTextFile(C.GSON.toJson(s), "hmcl.json"); - engine.putFile(modpack, "modpack.zip"); - File bg = new File("bg"); - if (bg.isDirectory()) - engine.putDirectory(bg); - bg = new File("background.png"); - if (bg.isFile()) - engine.putFile(bg, "background.png"); - bg = new File("background.jpg"); - if (bg.isFile()) - engine.putFile(bg, "background.jpg"); - for (URL u : Utils.getURL()) - try { - File f = new File(u.toURI()); - if (f.getName().endsWith(".exe") || f.getName().endsWith(".jar")) - engine.putFile(f, f.getName()); - } catch (Exception e) { - HMCLog.err("Failed to add launcher files.", e); - flag = false; - break; - } - engine.closeFile(); + try (ZipEngine engine = new ZipEngine(loc)) { + Config s = new Config(); + if (!IOUtils.isAbsolutePath(Settings.getInstance().getBgpath())) + s.setBgpath(Settings.getInstance().getBgpath()); + s.setDownloadType(Settings.getInstance().getDownloadType()); + engine.putTextFile(C.GSON.toJson(s), "hmcl.json"); + engine.putFile(modpack, "modpack.zip"); + File bg = new File("bg"); + if (bg.isDirectory()) + engine.putDirectory(bg); + bg = new File("background.png"); + if (bg.isFile()) + engine.putFile(bg, "background.png"); + bg = new File("background.jpg"); + if (bg.isFile()) + engine.putFile(bg, "background.jpg"); + for (URL u : Utils.getURL()) + try { + File f = new File(u.toURI()); + if (f.getName().endsWith(".exe") || f.getName().endsWith(".jar")) + engine.putFile(f, f.getName()); + } catch (IOException | URISyntaxException e) { + HMCLog.err("Failed to add launcher files.", e); + flag = false; + break; + } + } if (flag) { including = true; if (!modpack.delete()) diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/CrashReporter.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/CrashReporter.java index ba507757d..54c6cf464 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/CrashReporter.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/CrashReporter.java @@ -26,13 +26,13 @@ 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.log.HMCLog; import static org.jackhuang.hellominecraft.launcher.Main.LAUNCHER_VERSION; import org.jackhuang.hellominecraft.launcher.setting.Settings; -import org.jackhuang.hellominecraft.util.NetUtils; +import org.jackhuang.hellominecraft.util.net.NetUtils; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.system.OS; +import org.jackhuang.hellominecraft.util.sys.OS; import org.jackhuang.hellominecraft.util.ui.LogWindow; /** @@ -48,6 +48,7 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler { put("MessageBox", ""); put("AWTError", ""); put("JFileChooser", "Has your operating system been installed completely or is a ghost system?"); + put("JSystemFileChooser", "Has your operating system been installed completely or is a ghost system?"); put("Jce", "Has your operating system been installed completely or is a ghost system?"); put("couldn't create component peer", "Fucking computer!"); put("sun.awt.shell.Win32ShellFolder2", "crash.user_fault"); @@ -110,8 +111,8 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler { System.out.println(text); if (checkThrowable(e) && !System.getProperty("java.vm.name").contains("OpenJDK")) { - SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.showAsCrashWindow(Settings.UPDATE_CHECKER.OUT_DATED)); - if (!Settings.UPDATE_CHECKER.OUT_DATED) + SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.showAsCrashWindow(Settings.UPDATE_CHECKER.isOutOfDate())); + if (!Settings.UPDATE_CHECKER.isOutOfDate()) reportToServer(text, s); } } catch (Throwable ex) { @@ -122,7 +123,7 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler { void showMessage(String s) { try { - MessageBox.Show(s, "ERROR", MessageBox.ERROR_MESSAGE); + MessageBox.show(s, "ERROR", MessageBox.ERROR_MESSAGE); } catch (Throwable e) { LOGGER.log(Level.SEVERE, "ERROR", e); } @@ -131,7 +132,7 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler { private static final HashSet THROWABLE_SET = new HashSet<>(); void reportToServer(final String text, String stacktrace) { - if (THROWABLE_SET.contains(stacktrace)) + if (THROWABLE_SET.contains(stacktrace) || stacktrace.contains("Font") || stacktrace.contains("InternalError")) return; THROWABLE_SET.add(stacktrace); Thread t = new Thread(() -> { diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/DefaultPlugin.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/DefaultPlugin.java index f744d9490..096cb3443 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/DefaultPlugin.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/DefaultPlugin.java @@ -17,11 +17,11 @@ */ package org.jackhuang.hellominecraft.launcher.util; +import java.util.ArrayList; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.api.IPlugin; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.OfflineAuthenticator; -import org.jackhuang.hellominecraft.launcher.core.auth.SkinmeAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider; import org.jackhuang.hellominecraft.launcher.core.auth.YggdrasilAuthenticator; import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions; @@ -37,9 +37,7 @@ import org.jackhuang.hellominecraft.util.func.Consumer; */ public class DefaultPlugin implements IPlugin { - YggdrasilAuthenticator YGGDRASIL_LOGIN = null; - OfflineAuthenticator OFFLINE_LOGIN = null; - SkinmeAuthenticator SKINME_LOGIN = null; + ArrayList auths = new ArrayList<>(); @Override public IMinecraftService provideMinecraftService(Object profile) { @@ -49,20 +47,17 @@ public class DefaultPlugin implements IPlugin { @Override public void onRegisterAuthenticators(Consumer apply) { String clientToken = Settings.getInstance().getClientToken(); - OFFLINE_LOGIN = new OfflineAuthenticator(clientToken); - OFFLINE_LOGIN.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(OFFLINE_LOGIN.id())); - YGGDRASIL_LOGIN = new YggdrasilAuthenticator(clientToken); - YGGDRASIL_LOGIN.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(YGGDRASIL_LOGIN.id())); + auths.add(new OfflineAuthenticator(clientToken)); + auths.add(new YggdrasilAuthenticator(clientToken)); - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - Settings.getInstance().setAuthenticatorConfig(OFFLINE_LOGIN.id(), OFFLINE_LOGIN.onSaveSettings()); - Settings.getInstance().setAuthenticatorConfig(YGGDRASIL_LOGIN.id(), YGGDRASIL_LOGIN.onSaveSettings()); - } - }); - apply.accept(OFFLINE_LOGIN); - apply.accept(YGGDRASIL_LOGIN); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + for (IAuthenticator i : auths) + Settings.getInstance().setAuthenticatorConfig(i.id(), i.onSaveSettings()); + })); + for (IAuthenticator i : auths) { + i.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(i.id())); + apply.accept(i); + } } @Override diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/FileNameFilter.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/FileNameFilter.java index 8799bf6f5..74778cf6f 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/FileNameFilter.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/FileNameFilter.java @@ -19,7 +19,7 @@ package org.jackhuang.hellominecraft.launcher.util; import java.io.File; import javax.swing.filechooser.FileFilter; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; /** * diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLGameLauncher.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLGameLauncher.java index adb69233f..71588aa10 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLGameLauncher.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLGameLauncher.java @@ -31,7 +31,7 @@ import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.util.func.Consumer; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLMinecraftService.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLMinecraftService.java index b94c4a3aa..ce8831bd2 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLMinecraftService.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLMinecraftService.java @@ -29,22 +29,16 @@ import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider; import org.jackhuang.hellominecraft.launcher.core.download.MinecraftDownloadService; import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions; import org.jackhuang.hellominecraft.launcher.core.launch.MinecraftLoader; -import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService; -import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftDownloadService; -import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftInstallerService; -import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader; -import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftModService; -import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider; -import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; +import org.jackhuang.hellominecraft.launcher.core.service.*; import org.jackhuang.hellominecraft.launcher.core.mod.MinecraftModService; import org.jackhuang.hellominecraft.launcher.core.mod.ModpackManager; import org.jackhuang.hellominecraft.launcher.setting.Profile; import org.jackhuang.hellominecraft.launcher.setting.VersionSetting; import org.jackhuang.hellominecraft.launcher.ui.MainFrame; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.task.TaskWindow; /** * @@ -60,7 +54,20 @@ public class HMCLMinecraftService extends IMinecraftService { this.provider = new HMCLGameProvider(this); provider.initializeMiencraft(); provider.onRefreshingVersions.register(versionSettings::clear); - provider.onRefreshedVersions.register(this::checkModpack); + provider.onRefreshedVersions.register(() -> { + if (!checkingModpack) { + checkingModpack = true; + if (version().getVersionCount() == 0) { + File modpack = new File("modpack.zip"); + if (modpack.exists()) + SwingUtilities.invokeLater(() -> { + if (TaskWindow.factory().execute(ModpackManager.install(MainFrame.INSTANCE, modpack, this, null))) + version().refreshVersions(); + checkedModpack = true; + }); + } + } + }); provider.onLoadedVersion.register(this::loadVersionSetting); this.mms = new MinecraftModService(this); this.mds = new MinecraftDownloadService(this); @@ -70,21 +77,6 @@ public class HMCLMinecraftService extends IMinecraftService { public boolean checkedModpack = false, checkingModpack = false; - private void checkModpack() { - if (!checkingModpack) { - checkingModpack = true; - if (version().getVersionCount() == 0) { - File modpack = new File("modpack.zip"); - if (modpack.exists()) - SwingUtilities.invokeLater(() -> { - if (TaskWindow.execute(ModpackManager.install(MainFrame.INSTANCE, modpack, this, null))) - version().refreshVersions(); - checkedModpack = true; - }); - } - } - } - private void loadVersionSetting(String id) { if (provider.getVersionById(id) == null) return; diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/MinecraftCrashAdvicer.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/MinecraftCrashAdvicer.java index 39d4c907c..a5bb7bc01 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/MinecraftCrashAdvicer.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/MinecraftCrashAdvicer.java @@ -43,7 +43,7 @@ public final class MinecraftCrashAdvicer { return C.i18n("crash.advice.ConcurrentModificationException"); else if (trace.contains("securityexception")) return C.i18n("crash.advice.SecurityException"); - else if (trace.contains("nosuchfieldexception") || trace.contains("nosuchfielderror")) + else if (trace.contains("nosuchfieldexception") || trace.contains("nosuchmethodexception") || trace.contains("nosuchfielderror") || trace.contains("nosuchmethoderror")) return C.i18n("crash.advice.NoSuchFieldError"); else if (trace.contains("outofmemory") || trace.contains("out of memory")) return C.i18n("crash.advice.OutOfMemoryError"); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/AppDataUpgrader.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/AppDataUpgrader.java index 784f64a34..67132f855 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/AppDataUpgrader.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/AppDataUpgrader.java @@ -18,8 +18,6 @@ package org.jackhuang.hellominecraft.launcher.util.upgrade; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -37,19 +35,19 @@ import java.util.jar.JarOutputStream; import java.util.jar.Pack200; import java.util.zip.GZIPInputStream; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.launcher.core.MCUtils; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; -import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.TaskWindow; +import org.jackhuang.hellominecraft.util.net.FileDownloadTask; import org.jackhuang.hellominecraft.util.ArrayUtils; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.UpdateChecker; import org.jackhuang.hellominecraft.util.Utils; import org.jackhuang.hellominecraft.util.VersionNumber; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.system.IOUtils; -import org.jackhuang.hellominecraft.util.system.OS; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; +import org.jackhuang.hellominecraft.util.sys.OS; /** * @@ -101,7 +99,7 @@ public class AppDataUpgrader extends IUpgrader { @Override public boolean call(Object sender, final VersionNumber number) { ((UpdateChecker) sender).requestDownloadLink().reg(map -> { - if (MessageBox.Show(C.i18n("update.newest_version") + number.firstVer + "." + number.secondVer + "." + number.thirdVer + "\n" + if (MessageBox.show(C.i18n("update.newest_version") + number.firstVer + "." + number.secondVer + "." + number.thirdVer + "\n" + C.i18n("update.should_open_link"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) if (map != null && map.containsKey("pack")) @@ -109,7 +107,7 @@ public class AppDataUpgrader extends IUpgrader { String hash = null; if (map.containsKey("packsha1")) hash = map.get("packsha1"); - if (TaskWindow.factory().append(new AppDataUpgraderTask(map.get("pack"), number.version, hash)).create()) { + if (TaskWindow.factory().append(new AppDataUpgraderTask(map.get("pack"), number.version, hash)).execute()) { new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(number.version).getAbsolutePath() }).directory(new File(".")).start(); System.exit(0); } @@ -130,7 +128,7 @@ public class AppDataUpgrader extends IUpgrader { } catch (URISyntaxException | IOException e) { HMCLog.warn("Failed to browse uri: " + url, e); Utils.setClipborad(url); - MessageBox.Show(C.i18n("update.no_browser")); + MessageBox.show(C.i18n("update.no_browser")); } } }).execute(); @@ -162,10 +160,10 @@ public class AppDataUpgrader extends IUpgrader { } @Override - public void executeTask() throws Exception { + public void executeTask(boolean areDependTasksSucceeded) throws Exception { HashMap json = new HashMap<>(); File f = getSelf(newestVersion); - if (!f.getParentFile().exists() && !f.getParentFile().mkdirs()) + if (!FileUtils.makeDirectory(f.getParentFile())) HMCLog.warn("Failed to make directories: " + f.getParent()); for (int i = 0; f.exists(); i++) @@ -173,8 +171,8 @@ public class AppDataUpgrader extends IUpgrader { if (!f.createNewFile()) HMCLog.warn("Failed to create new file: " + f); - try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(f))) { - Pack200.newUnpacker().unpack(new GZIPInputStream(new FileInputStream(tempFile)), jos); + try (JarOutputStream jos = new JarOutputStream(FileUtils.openOutputStream(f))) { + Pack200.newUnpacker().unpack(new GZIPInputStream(FileUtils.openInputStream(tempFile)), jos); } json.put("ver", newestVersion); json.put("loc", f.getAbsolutePath()); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/NewFileUpgrader.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/NewFileUpgrader.java index 5c07d76de..ee3c7e091 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/NewFileUpgrader.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/NewFileUpgrader.java @@ -19,13 +19,13 @@ package org.jackhuang.hellominecraft.launcher.util.upgrade; import java.io.File; import java.io.IOException; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; -import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.task.TaskWindow; +import org.jackhuang.hellominecraft.util.net.FileDownloadTask; import org.jackhuang.hellominecraft.util.ArrayUtils; import org.jackhuang.hellominecraft.util.VersionNumber; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * @@ -48,7 +48,7 @@ public class NewFileUpgrader extends IUpgrader { public boolean call(Object sender, VersionNumber number) { String str = requestDownloadLink(); File newf = new File(FileUtils.getName(str)); - if (TaskWindow.factory().append(new FileDownloadTask(str, newf)).create()) { + if (TaskWindow.factory().append(new FileDownloadTask(str, newf)).execute()) { try { new ProcessBuilder(new String[] { IOUtils.tryGetCanonicalFilePath(newf), "--removeOldLauncher", IOUtils.getRealPath() }).directory(new File(".")).start(); } catch (IOException ex) { diff --git a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/comp/ConstomButton.java b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ConstomButton.java similarity index 91% rename from HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/comp/ConstomButton.java rename to HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ConstomButton.java index 4ba9f5025..b2071a6a9 100755 --- a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/comp/ConstomButton.java +++ b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ConstomButton.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. */ -package org.jackhuang.hellominecraft.lookandfeel.comp; +package org.jackhuang.hellominecraft.lookandfeel; import java.awt.Color; import org.jackhuang.hellominecraft.util.ui.GraphicsUtils; @@ -28,7 +28,5 @@ public class ConstomButton extends javax.swing.JButton { prelightFg = GraphicsUtils.getWebColorWithAlpha("FFFFFF7F"), prelightBg = GraphicsUtils.getWebColorWithAlpha("FFFFFF7F"), activeFg = GraphicsUtils.getWebColorWithAlpha("EAEDF83F"), activeBg = GraphicsUtils.getWebColorWithAlpha("EAEDF83F"); public int drawPercent = 0; - public long lastDrawTime = 0; public int radix = 0; - public boolean notDraw = false; } diff --git a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/HelloMinecraftLookAndFeel.java b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/HelloMinecraftLookAndFeel.java index 868d39df8..24cfd7210 100755 --- a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/HelloMinecraftLookAndFeel.java +++ b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/HelloMinecraftLookAndFeel.java @@ -18,12 +18,13 @@ package org.jackhuang.hellominecraft.lookandfeel; import java.awt.Color; import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.text.ParseException; import java.util.Map; import javax.swing.UIDefaults; import javax.swing.plaf.synth.SynthLookAndFeel; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.NetUtils; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * @@ -37,7 +38,7 @@ public class HelloMinecraftLookAndFeel extends SynthLookAndFeel { * Creates a new instance of NimbusLookAndFeel * * @throws java.text.ParseException error parsing the xml, it must not - * happen. + * happen. */ public HelloMinecraftLookAndFeel() throws ParseException { this(DEFAULT_SETTINGS); @@ -45,14 +46,18 @@ public class HelloMinecraftLookAndFeel extends SynthLookAndFeel { public HelloMinecraftLookAndFeel(Map settings) throws ParseException { try { - String s = NetUtils.getStreamContent(HelloMinecraftLookAndFeel.class.getResourceAsStream("/org/jackhuang/hellominecraft/lookandfeel/synth.xml"), "UTF-8"); - for (String ss : settings.keySet()) - s = s.replace("${" + ss + "}", settings.get(ss)); - load(new ByteArrayInputStream(s.getBytes("UTF-8")), HelloMinecraftLookAndFeel.class); + try (InputStream is = HelloMinecraftLookAndFeel.class.getResourceAsStream("/org/jackhuang/hellominecraft/lookandfeel/synth.xml")) { + String s = IOUtils.toString(is, "UTF-8"); + for (Map.Entry ss : settings.entrySet()) + s = s.replace("${" + ss.getKey() + "}", ss.getValue()); + load(new ByteArrayInputStream(s.getBytes("UTF-8")), HelloMinecraftLookAndFeel.class); + } } catch (Throwable ex) { HMCLog.err("This fucking exception should not happen. Retry backup solution.", ex); try { - load(HelloMinecraftLookAndFeel.class.getResourceAsStream("/org/jackhuang/hellominecraft/lookandfeel/synth_backup.xml"), HelloMinecraftLookAndFeel.class); + try (InputStream is = HelloMinecraftLookAndFeel.class.getResourceAsStream("/org/jackhuang/hellominecraft/lookandfeel/synth_backup.xml")) { + load(is, HelloMinecraftLookAndFeel.class); + } } catch (Throwable e) { HMCLog.err("User fault", e); } diff --git a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/Theme.java b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/Theme.java index d89898f9b..554105d49 100755 --- a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/Theme.java +++ b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/Theme.java @@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.lookandfeel; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import org.jackhuang.hellominecraft.util.C; /** @@ -85,9 +86,7 @@ public enum Theme { public final Map settings; private Theme(String localizedName, Map settings) { - if (settings == null) - throw new NullPointerException("Theme settings map should not be null."); this.localizedName = localizedName; - this.settings = settings; + this.settings = Objects.requireNonNull(settings, "Theme settings map may not be null."); } } diff --git a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/comp/IConstomable.java b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/comp/IConstomable.java deleted file mode 100755 index 38756e3b4..000000000 --- a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/comp/IConstomable.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 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 2 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. - */ -package org.jackhuang.hellominecraft.lookandfeel.comp; - -/** - * - * @author huangyuhui - */ -public interface IConstomable { - boolean constomBackground(); - boolean constomForeground(); -} diff --git a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ButtonPainter.java b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ButtonPainter.java index 103983a36..b0001cb11 100755 --- a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ButtonPainter.java +++ b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/painter/ButtonPainter.java @@ -31,7 +31,7 @@ import javax.swing.plaf.synth.SynthConstants; import javax.swing.plaf.synth.SynthContext; import javax.swing.plaf.synth.SynthPainter; import org.jackhuang.hellominecraft.util.ui.GraphicsUtils; -import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton; +import org.jackhuang.hellominecraft.lookandfeel.ConstomButton; /** * ButtonPainter - handles painting Nimbus style buttons with Java2D @@ -42,22 +42,22 @@ import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton; public class ButtonPainter extends SynthPainter { private static final String DEFAULT_NORMAL = "D5D5D5"; - private static final Color[] DEFAULT_NORMAL_FG = new Color[] { + private static final Color[] DEFAULT_NORMAL_FG = new Color[]{ GraphicsUtils.getWebColor(DEFAULT_NORMAL), GraphicsUtils.getWebColor(DEFAULT_NORMAL) }; private static final String DEFAULT_PRELIGHT = "A9A9A9"; - private static final Color[] DEFAULT_PRELIGHT_FG = new Color[] { + private static final Color[] DEFAULT_PRELIGHT_FG = new Color[]{ GraphicsUtils.getWebColor(DEFAULT_PRELIGHT), GraphicsUtils.getWebColor(DEFAULT_PRELIGHT) }; private static final String DEFAULT_ACTIVE = "222222"; - private static final Color[] DEFAULT_ACTIVE_FG = new Color[] { + private static final Color[] DEFAULT_ACTIVE_FG = new Color[]{ GraphicsUtils.getWebColor(DEFAULT_ACTIVE), GraphicsUtils.getWebColor(DEFAULT_ACTIVE) }; - private static final Color[] DISABLED_BG = new Color[] { + private static final Color[] DISABLED_BG = new Color[]{ GraphicsUtils.getWebColor("E3EFE9"), GraphicsUtils.getMidWebColor("E3EFE9", "DFE2E6"), GraphicsUtils.getWebColor("DFE2E6"), @@ -68,7 +68,7 @@ public class ButtonPainter extends SynthPainter { GraphicsUtils.getWebColor("D8DBE1"), GraphicsUtils.getWebColor("DADDE3") }; - private static final Color[] DISABLED_FG = new Color[] { + private static final Color[] DISABLED_FG = new Color[]{ GraphicsUtils.getWebColor("C9CCD2"), GraphicsUtils.getWebColor("C9CCD2"), GraphicsUtils.getWebColor("BCBFC5"), @@ -106,8 +106,8 @@ public class ButtonPainter extends SynthPainter { if ((context.getComponentState() & SynthConstants.PRESSED) != 0) if (context.getComponent() instanceof ConstomButton) { ConstomButton c = (ConstomButton) context.getComponent(); - fg = new Color[] { c.activeFg, c.activeFg }; - bg = new Color[] { c.activeFg, c.activeFg }; + fg = new Color[]{c.activeFg, c.activeFg}; + bg = new Color[]{c.activeFg, c.activeFg}; } else { fg = DEFAULT_ACTIVE_FG; bg = DEFAULT_ACTIVE_FG; @@ -122,8 +122,8 @@ public class ButtonPainter extends SynthPainter { return; Color fgs = GraphicsUtils.getMidWebColor(c.normalFg, c.prelightFg, c.drawPercent); Color bgs = GraphicsUtils.getMidWebColor(c.normalBg, c.prelightBg, c.drawPercent); - fg = new Color[] { fgs, fgs }; - bg = new Color[] { bgs, bgs }; + fg = new Color[]{fgs, fgs}; + bg = new Color[]{bgs, bgs}; } else { fg = DEFAULT_PRELIGHT_FG; bg = DEFAULT_PRELIGHT_FG; @@ -134,8 +134,8 @@ public class ButtonPainter extends SynthPainter { return; Color fgs = GraphicsUtils.getMidWebColor(c.normalFg, c.prelightFg, c.drawPercent); Color bgs = GraphicsUtils.getMidWebColor(c.normalBg, c.prelightBg, c.drawPercent); - fg = new Color[] { fgs, fgs }; - bg = new Color[] { bgs, bgs }; + fg = new Color[]{fgs, fgs}; + bg = new Color[]{bgs, bgs}; } else { fg = DEFAULT_NORMAL_FG; bg = DEFAULT_NORMAL_FG; @@ -143,8 +143,8 @@ public class ButtonPainter extends SynthPainter { else if ((context.getComponentState() & SynthConstants.PRESSED) != 0) if (context.getComponent() instanceof ConstomButton) { ConstomButton c = (ConstomButton) context.getComponent(); - fg = new Color[] { c.activeFg, c.activeFg }; - bg = new Color[] { c.activeFg, c.activeFg }; + fg = new Color[]{c.activeFg, c.activeFg}; + bg = new Color[]{c.activeFg, c.activeFg}; } else { fg = DEFAULT_ACTIVE_FG; bg = DEFAULT_ACTIVE_FG; @@ -159,12 +159,12 @@ public class ButtonPainter extends SynthPainter { return; Color fgs = GraphicsUtils.getMidWebColor(c.normalFg, c.prelightFg, c.drawPercent); Color bgs = GraphicsUtils.getMidWebColor(c.normalBg, c.prelightBg, c.drawPercent); - fg = new Color[] { fgs, fgs }; - bg = new Color[] { bgs, bgs }; + fg = new Color[]{fgs, fgs}; + bg = new Color[]{bgs, bgs}; } else if (context.getComponent() instanceof ConstomButton) { ConstomButton c = (ConstomButton) context.getComponent(); - fg = new Color[] { c.prelightFg, c.prelightFg }; - bg = new Color[] { c.prelightBg, c.prelightBg }; + fg = new Color[]{c.prelightFg, c.prelightFg}; + bg = new Color[]{c.prelightBg, c.prelightBg}; } else { fg = DEFAULT_PRELIGHT_FG; bg = DEFAULT_PRELIGHT_FG; @@ -175,8 +175,8 @@ public class ButtonPainter extends SynthPainter { return; Color fgs = GraphicsUtils.getMidWebColor(c.normalFg, c.prelightFg, c.drawPercent); Color bgs = GraphicsUtils.getMidWebColor(c.normalBg, c.prelightBg, c.drawPercent); - fg = new Color[] { fgs, fgs }; - bg = new Color[] { bgs, bgs }; + fg = new Color[]{fgs, fgs}; + bg = new Color[]{bgs, bgs}; } else { fg = DEFAULT_NORMAL_FG; bg = DEFAULT_NORMAL_FG; @@ -207,21 +207,8 @@ public class ButtonPainter extends SynthPainter { Graphics2D g2 = (Graphics2D) g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Color[] fg, bg; - if ((context.getComponentState() & SynthConstants.DEFAULT) != 0) - if ((context.getComponentState() & SynthConstants.PRESSED) != 0 || (context.getComponentState() & SynthConstants.SELECTED) != 0) { - fg = DEFAULT_ACTIVE_FG; - bg = DEFAULT_ACTIVE_FG; - } else if ((context.getComponentState() & SynthConstants.DISABLED) != 0) { - fg = DISABLED_FG; - bg = DISABLED_BG; - } else if ((context.getComponentState() & SynthConstants.MOUSE_OVER) != 0) { - fg = DEFAULT_PRELIGHT_FG; - bg = DEFAULT_PRELIGHT_FG; - } else { - fg = DEFAULT_NORMAL_FG; - bg = DEFAULT_NORMAL_FG; - } - else if ((context.getComponentState() & SynthConstants.PRESSED) != 0 || (context.getComponentState() & SynthConstants.SELECTED) != 0) { + //if ((context.getComponentState() & SynthConstants.DEFAULT) != 0) + if ((context.getComponentState() & SynthConstants.PRESSED) != 0 || (context.getComponentState() & SynthConstants.SELECTED) != 0) { fg = DEFAULT_ACTIVE_FG; bg = DEFAULT_ACTIVE_FG; } else if ((context.getComponentState() & SynthConstants.DISABLED) != 0) { @@ -234,6 +221,19 @@ public class ButtonPainter extends SynthPainter { fg = DEFAULT_NORMAL_FG; bg = DEFAULT_NORMAL_FG; } + /*else if ((context.getComponentState() & SynthConstants.PRESSED) != 0 || (context.getComponentState() & SynthConstants.SELECTED) != 0) { + fg = DEFAULT_ACTIVE_FG; + bg = DEFAULT_ACTIVE_FG; + } else if ((context.getComponentState() & SynthConstants.DISABLED) != 0) { + fg = DISABLED_FG; + bg = DISABLED_BG; + } else if ((context.getComponentState() & SynthConstants.MOUSE_OVER) != 0) { + fg = DEFAULT_PRELIGHT_FG; + bg = DEFAULT_PRELIGHT_FG; + } else { + fg = DEFAULT_NORMAL_FG; + bg = DEFAULT_NORMAL_FG; + }*/ g2.setColor(fg[0]); Rectangle2D fgshape = new Rectangle2D.Float(x, y, w, h); g2.draw(fgshape); diff --git a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ComboBoxUI.java b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ComboBoxUI.java index 939865504..2fb6b0eb9 100755 --- a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ComboBoxUI.java +++ b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ComboBoxUI.java @@ -18,6 +18,8 @@ import java.awt.Container; import java.awt.image.BufferedImage; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; +import javax.swing.plaf.basic.BasicComboPopup; +import javax.swing.plaf.basic.ComboPopup; /** * NimbusComboBoxUI @@ -87,6 +89,13 @@ public class ComboBoxUI extends BasicComboBoxUI implements MouseListener { return new Dimension(size); } + @Override + protected ComboPopup createPopup() { + BasicComboPopup p = new BasicComboPopup(comboBox); + //p.setPopupSize(100, comboBox.getPreferredSize().height); + return p; + } + @Override protected JButton createArrowButton() { JButton button = new JButton() { @@ -101,8 +110,8 @@ public class ComboBoxUI extends BasicComboBoxUI implements MouseListener { else if (mouseInside) img = COMBO_OVER; g.drawImage(img, - 0, 0, getWidth(), getHeight(), - 0, 0, img.getWidth(), img.getHeight(), comboBox); + 0, 0, getWidth(), getHeight(), + 0, 0, img.getWidth(), img.getHeight(), comboBox); } } }; @@ -141,14 +150,14 @@ public class ComboBoxUI extends BasicComboBoxUI implements MouseListener { else if (mouseInside) img = COMBO_OVER; g.drawImage(img, - bounds.x, bounds.y, bounds.x + 4, bounds.y + bounds.height, - 0, 0, 1, 26, comboBox); + bounds.x, bounds.y, bounds.x + 4, bounds.y + bounds.height, + 0, 0, 1, 26, comboBox); g.drawImage(img, - bounds.x + 1, bounds.y, bounds.x + bounds.width - 25, bounds.y + bounds.height, - 1, 0, 3, 26, comboBox); + bounds.x + 1, bounds.y, bounds.x + bounds.width - 25, bounds.y + bounds.height, + 1, 0, 3, 26, comboBox); g.drawImage(img, - bounds.x + bounds.width - 25, bounds.y, bounds.x + bounds.width, bounds.y + bounds.height, - 4, 0, 29, 26, comboBox); + bounds.x + bounds.width - 25, bounds.y, bounds.x + bounds.width, bounds.y + bounds.height, + 4, 0, 29, 26, comboBox); } else { /*g.setColor(Color.WHITE); g.fillRect(bounds.x, bounds.y, bounds.width - btnSize.width, bounds.height - 1); @@ -257,23 +266,25 @@ public class ComboBoxUI extends BasicComboBoxUI implements MouseListener { @Override public void layoutContainer(Container parent) { - JComboBox cb = (JComboBox) parent; - int width = cb.getWidth(); + if (parent instanceof JComboBox) { + JComboBox cb = (JComboBox) parent; + int width = cb.getWidth(); - Insets insets = getInsets(); - Rectangle cvb; + Insets insets = getInsets(); + Rectangle cvb; - if (arrowButton != null) - if (cb.getComponentOrientation().isLeftToRight()) - arrowButton.setBounds(width - (insets.right + btnSize.width), - insets.top, - btnSize.width, btnSize.height); - else - arrowButton.setBounds(insets.left, insets.top, - btnSize.width, btnSize.height); - if (editor != null) { - cvb = rectangleForCurrentValue(); - editor.setBounds(cvb.x, cvb.y, cvb.width, cvb.height); + if (arrowButton != null) + if (cb.getComponentOrientation().isLeftToRight()) + arrowButton.setBounds(width - (insets.right + btnSize.width), + insets.top, + btnSize.width, btnSize.height); + else + arrowButton.setBounds(insets.left, insets.top, + btnSize.width, btnSize.height); + if (editor != null) { + cvb = rectangleForCurrentValue(); + editor.setBounds(cvb.x, cvb.y, cvb.width, cvb.height); + } } } } diff --git a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ListCellRender.java b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ListCellRender.java index 1200d9e25..215145dd7 100755 --- a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ListCellRender.java +++ b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ListCellRender.java @@ -34,7 +34,7 @@ import java.awt.Component; public class ListCellRender extends DefaultListCellRenderer { @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { setOpaque(true); setBackground(Color.magenta); diff --git a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ScrollButton.java b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ScrollButton.java index 337e81ccc..616c7d4e0 100755 --- a/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ScrollButton.java +++ b/HMCLaF/src/main/java/org/jackhuang/hellominecraft/lookandfeel/ui/ScrollButton.java @@ -20,10 +20,6 @@ */ package org.jackhuang.hellominecraft.lookandfeel.ui; -import static javax.swing.SwingConstants.NORTH; -import static javax.swing.SwingConstants.SOUTH; - -import javax.swing.SwingConstants; import javax.swing.plaf.metal.MetalScrollButton; import java.awt.Dimension; import java.awt.Graphics; @@ -35,7 +31,7 @@ import java.awt.Graphics; * @author Created by Jasper Potts (Jan 17, 2007) * @version 1.0 */ -public class ScrollButton extends MetalScrollButton implements SwingConstants { +public class ScrollButton extends MetalScrollButton { private final int btnWidth, btnHeight; diff --git a/HMCSM/build.gradle b/HMCSM/build.gradle index ba1d513c5..81d9214a8 100755 --- a/HMCSM/build.gradle +++ b/HMCSM/build.gradle @@ -21,7 +21,7 @@ buildscript { mavenCentral(); dependencies { classpath 'edu.sc.seis.gradle:launch4j:1.0.6' - classpath 'me.tatarka:gradle-retrolambda:3.1.0' + classpath 'me.tatarka:gradle-retrolambda:3.4.0' } } } diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/Main.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/Main.java index 2239ea798..6cdee6718 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/Main.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/Main.java @@ -18,12 +18,10 @@ package org.jackhuang.hellominecraft.svrmgr; import java.awt.Font; -import java.io.PrintWriter; -import java.io.StringWriter; import java.text.ParseException; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.ui.LogWindow; import org.jackhuang.hellominecraft.svrmgr.setting.SettingsManager; import org.jackhuang.hellominecraft.util.UpdateChecker; @@ -56,17 +54,11 @@ public class Main { } catch (ParseException | UnsupportedLookAndFeelException ex) { HMCLog.warn("Failed to set look and feel", ex); } - UPDATE_CHECKER.process(false).reg(t -> MessageBox.Show("发现更新!" + t.version)).execute(); + UPDATE_CHECKER.process(false).reg(t -> MessageBox.show("发现更新!" + t.version)).execute(); new MainWindow().setVisible(true); } catch (Throwable t) { HMCLog.err("There's something wrong when running server holder.", t); - - LogWindow.INSTANCE.clean(); - LogWindow.INSTANCE.warning("开服器崩溃了QAQ"); - StringWriter trace = new StringWriter(); - t.printStackTrace(new PrintWriter(trace)); - LogWindow.INSTANCE.warning(trace.toString()); - LogWindow.INSTANCE.setVisible(true); + LogWindow.INSTANCE.showAsCrashWindow(false); System.exit(-1); } diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/bukkit/BukkitFormatThread.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/bukkit/BukkitFormatThread.java index 07b861b06..27d9c2dd8 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/bukkit/BukkitFormatThread.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/bukkit/BukkitFormatThread.java @@ -20,7 +20,7 @@ package org.jackhuang.hellominecraft.svrmgr.install.bukkit; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.func.Consumer; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/cauldron/ForgeFormatThread.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/cauldron/ForgeFormatThread.java index 5fd74f295..0c4f62a8c 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/cauldron/ForgeFormatThread.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/cauldron/ForgeFormatThread.java @@ -23,7 +23,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import org.jackhuang.hellominecraft.util.func.Consumer; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/cauldron/ForgeInstaller.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/cauldron/ForgeInstaller.java index 3c01366cb..d0e4dd576 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/cauldron/ForgeInstaller.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/install/cauldron/ForgeInstaller.java @@ -36,15 +36,14 @@ import java.util.jar.Pack200; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.swing.JOptionPane; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.code.DigestUtils; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; import org.jackhuang.hellominecraft.util.MessageBox; -import org.jackhuang.hellominecraft.util.NetUtils; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; -import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask; +import org.jackhuang.hellominecraft.util.task.TaskWindow; +import org.jackhuang.hellominecraft.util.net.FileDownloadTask; import org.tukaani.xz.XZInputStream; /** @@ -67,7 +66,7 @@ public class ForgeInstaller { ZipFile zipFile = new ZipFile(forgeInstaller); ZipEntry entry = zipFile.getEntry("install_profile.json"); - String content = NetUtils.getStreamContent(zipFile.getInputStream(entry)); + String content = IOUtils.toString(zipFile.getInputStream(entry)); InstallProfile profile = gson.fromJson(content, InstallProfile.class); HMCLog.log("Extracting cauldron server pack..." + profile.install.filePath); @@ -88,8 +87,8 @@ public class ForgeInstaller { File minecraftserver = new File(gameDir, "minecraft_server." + profile.install.minecraft + ".jar"); if (minecraftserver.exists() && JOptionPane.showConfirmDialog(null, "已发现官方服务端文件,是否要重新下载?") == JOptionPane.YES_OPTION) if (!TaskWindow.factory().append(new FileDownloadTask("https://s3.amazonaws.com/Minecraft.Download/versions/{MCVER}/minecraft_server.{MCVER}.jar".replace("{MCVER}", profile.install.minecraft), - minecraftserver).setTag("minecraft_server")).create()) - MessageBox.Show("Minecraft官方服务端下载失败!"); + minecraftserver).setTag("minecraft_server")).execute()) + MessageBox.show("Minecraft官方服务端下载失败!"); TaskWindow.TaskWindowFactory tw = TaskWindow.factory(); for (MinecraftLibrary library : profile.versionInfo.libraries) { library.init(); @@ -99,8 +98,8 @@ public class ForgeInstaller { libURL = library.url; tw.append(new FileDownloadTask(libURL + library.formatted.replace("\\", "/"), lib).setTag(library.name)); } - if (!tw.create()) - MessageBox.Show("压缩库下载失败!"); + if (!tw.execute()) + MessageBox.show("压缩库下载失败!"); tw = TaskWindow.factory(); for (MinecraftLibrary library : profile.versionInfo.libraries) { @@ -114,8 +113,8 @@ public class ForgeInstaller { libURL = library.url; tw.append(new FileDownloadTask(libURL + library.formatted.replace("\\", "/"), lib).setTag(library.name)); } - if (!tw.create()) - MessageBox.Show("库下载失败!"); + if (!tw.execute()) + MessageBox.show("库下载失败!"); ArrayList badLibs = new ArrayList<>(); for (MinecraftLibrary library : profile.versionInfo.libraries) { @@ -123,7 +122,7 @@ public class ForgeInstaller { File packFile = new File(gameDir, "libraries" + File.separator + library.formatted + ".pack.xz"); if (packFile.exists() && packFile.isFile()) try { - unpackLibrary(lib.getParentFile(), NetUtils.getBytesFromStream(FileUtils.openInputStream(packFile))); + unpackLibrary(lib.getParentFile(), IOUtils.toByteArray(FileUtils.openInputStream(packFile))); if (!checksumValid(lib, Arrays.asList(library.checksums))) badLibs.add(library.name); } catch (IOException e) { @@ -132,7 +131,7 @@ public class ForgeInstaller { } } if (badLibs.size() > 0) - MessageBox.Show("这些库在解压的时候出现了问题" + badLibs.toString()); + MessageBox.show("这些库在解压的时候出现了问题" + badLibs.toString()); } public static void unpackLibrary(File output, byte[] data) @@ -140,7 +139,7 @@ public class ForgeInstaller { if (output.exists()) output.delete(); - byte[] decompressed = IOUtils.readFully(new XZInputStream(new ByteArrayInputStream(data))).toByteArray(); + byte[] decompressed = IOUtils.toByteArray(new XZInputStream(new ByteArrayInputStream(data))); String end = new String(decompressed, decompressed.length - 4, 4); if (!end.equals("SIGN")) { @@ -166,7 +165,7 @@ public class ForgeInstaller { private static boolean checksumValid(File libPath, List checksums) { try { - byte[] fileData = NetUtils.getBytesFromStream(FileUtils.openInputStream(libPath)); + byte[] fileData = IOUtils.toByteArray(FileUtils.openInputStream(libPath)); boolean valid = (checksums == null) || (checksums.isEmpty()) || (checksums.contains(DigestUtils.sha1Hex(fileData))); if ((!valid) && (libPath.getName().endsWith(".jar"))) valid = validateJar(libPath, fileData, checksums); @@ -185,7 +184,7 @@ public class ForgeInstaller { try (JarInputStream jar = new JarInputStream(new ByteArrayInputStream(data))) { JarEntry entry = jar.getNextJarEntry(); while (entry != null) { - byte[] eData = IOUtils.readFully(jar).toByteArray(); + byte[] eData = IOUtils.toByteArray(jar); if (entry.getName().equals("checksums.sha1")) hashes = new String(eData, Charset.forName("UTF-8")).split("\n"); diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/plugin/PluginManager.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/plugin/PluginManager.java index 036496039..a6915f8a1 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/plugin/PluginManager.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/plugin/PluginManager.java @@ -27,7 +27,7 @@ import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.ho.yaml.Yaml; -import org.jackhuang.hellominecraft.util.NetUtils; +import org.jackhuang.hellominecraft.util.net.NetUtils; import org.jackhuang.hellominecraft.util.StrUtils; /** diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/BackupManager.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/BackupManager.java index 0753a6579..ba84fe512 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/BackupManager.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/BackupManager.java @@ -21,13 +21,13 @@ import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.Compressor; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.CompressingUtils; import org.jackhuang.hellominecraft.svrmgr.setting.SettingsManager; import org.jackhuang.hellominecraft.svrmgr.util.Utilities; import org.jackhuang.hellominecraft.util.func.Consumer; -import org.jackhuang.hellominecraft.util.system.FileUtils; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * @@ -50,7 +50,7 @@ public class BackupManager { public void run() { try { SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); - Compressor.zip(Utilities.getGameDir() + folder + File.separator, + CompressingUtils.zip(Utilities.getGameDir() + folder + File.separator, backupDir() + "world+" + f.format(new Date()) + "+" + folder + ".zip"); } catch (IOException ex) { HMCLog.warn("Failed to compress world pack.", ex); @@ -79,7 +79,7 @@ public class BackupManager { File world = new File(Utilities.getGameDir() + folder + File.separator); FileUtils.deleteDirectoryQuietly(world); world.mkdirs(); - Compressor.unzip(backupFile, world); + CompressingUtils.unzip(backupFile, world); } catch (IOException ex) { HMCLog.warn("Failed to decompress world pack.", ex); } @@ -99,7 +99,7 @@ public class BackupManager { public void run() { try { SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); - Compressor.zip(Utilities.getGameDir() + "plugins" + File.separator, + CompressingUtils.zip(Utilities.getGameDir() + "plugins" + File.separator, backupDir() + "plugin+" + f.format(new Date()) + "+plugins.zip"); } catch (IOException ex) { HMCLog.warn("Failed to compress world pack with plugins.", ex); diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/Server.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/Server.java index 52bf0a34a..8183bb3b4 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/Server.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/Server.java @@ -24,7 +24,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -35,8 +34,8 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.IOUtils; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.Pair; import org.jackhuang.hellominecraft.util.StrUtils; @@ -47,6 +46,7 @@ import org.jackhuang.hellominecraft.svrmgr.util.WaitForThread; import org.jackhuang.hellominecraft.svrmgr.util.Utilities; import org.jackhuang.hellominecraft.util.Event; import org.jackhuang.hellominecraft.util.EventHandler; +import org.jackhuang.hellominecraft.util.code.Charsets; import org.jackhuang.hellominecraft.util.func.Consumer; /** @@ -54,7 +54,7 @@ import org.jackhuang.hellominecraft.util.func.Consumer; * @author huangyuhui */ public class Server implements Event, MonitorThread.MonitorThreadListener, - ActionListener { + ActionListener { private static Server instance; private static boolean disactived = false; @@ -125,17 +125,13 @@ public class Server implements Event, MonitorThread.MonitorThreadListen pb.directory(new File(SettingsManager.settings.mainjar).getParentFile()); try { disactiveMods(SettingsManager.settings.inactiveExtMods, - SettingsManager.settings.inactiveCoreMods, - SettingsManager.settings.inactivePlugins); + SettingsManager.settings.inactiveCoreMods, + SettingsManager.settings.inactivePlugins); server = pb.start(); registerThread(threadA, server.getInputStream()); registerThread(threadB, server.getErrorStream()); registerThreadC(server); - try { - bw = new BufferedWriter(new OutputStreamWriter(server.getOutputStream(), System.getProperty("sun.jnu.encoding", "utf-8"))); - } catch (UnsupportedEncodingException ex) { - bw = new BufferedWriter(new OutputStreamWriter(server.getOutputStream())); - } + bw = new BufferedWriter(new OutputStreamWriter(server.getOutputStream(), Charsets.toCharset())); isRunning = true; startedEvent.execute(null); sendStatus("*** 启动服务端中 ***"); @@ -235,7 +231,7 @@ public class Server implements Event, MonitorThread.MonitorThreadListen try { run(); } catch (IOException ex) { - MessageBox.Show("重启失败!"); + MessageBox.show("重启失败!"); HMCLog.warn("Failed to launch!", ex); } isRestart = false; @@ -244,7 +240,7 @@ public class Server implements Event, MonitorThread.MonitorThreadListen } private static void disactiveMods(ArrayList inactiveExtMods, - ArrayList inactiveCoreMods, ArrayList inactivePlugins) { + ArrayList inactiveCoreMods, ArrayList inactivePlugins) { disactiveModsByType(inactiveExtMods, "mods"); disactiveModsByType(inactiveCoreMods, "coremods"); disactiveModsByType(inactivePlugins, "plugins"); @@ -267,7 +263,7 @@ public class Server implements Event, MonitorThread.MonitorThreadListen String name = file.getName(); if ((!paramArrayOfString.contains(name)) - || ((!name.toLowerCase().endsWith(".zip")) && (!name.toLowerCase().endsWith(".jar")))) + || ((!name.toLowerCase().endsWith(".zip")) && (!name.toLowerCase().endsWith(".jar")))) continue; String newName = name + "X"; diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/ServerChecker.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/ServerChecker.java index 9a890008a..9f2ae707c 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/ServerChecker.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/ServerChecker.java @@ -20,7 +20,7 @@ package org.jackhuang.hellominecraft.svrmgr.server; import java.io.File; import java.io.IOException; import java.util.zip.ZipFile; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/schedule/AutoExecuteSchedule.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/schedule/AutoExecuteSchedule.java index 9284e8602..4b445d4c6 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/schedule/AutoExecuteSchedule.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/server/schedule/AutoExecuteSchedule.java @@ -19,7 +19,7 @@ package org.jackhuang.hellominecraft.svrmgr.server.schedule; import java.io.IOException; import java.util.TimerTask; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.svrmgr.server.Server; import org.jackhuang.hellominecraft.svrmgr.setting.Schedule; diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/PlayerList.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/PlayerList.java index b0236de4a..39df966a6 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/PlayerList.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/PlayerList.java @@ -22,8 +22,8 @@ import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.UUID; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.svrmgr.setting.PlayerList.BasePlayer; @@ -90,7 +90,7 @@ public abstract class PlayerList { op = null; if (txt.exists()) try { - initByText(FileUtils.readIgnoreFileNotFound(txt)); + initByText(FileUtils.read(txt)); if (op != null) player.addAll(op); } catch (IOException e) { @@ -100,7 +100,7 @@ public abstract class PlayerList { } public void saveAsText(File file) throws IOException { - FileUtils.write(file, StrUtils.parseParams("", op, System.getProperty("line.separator"))); + FileUtils.write(file, StrUtils.parseParams("", op.toArray(), System.getProperty("line.separator"))); } public void saveAsJson(File file) throws IOException { diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/ServerProperties.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/ServerProperties.java index 73de504d2..a1cd4561b 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/ServerProperties.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/ServerProperties.java @@ -25,7 +25,9 @@ import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * @@ -57,7 +59,7 @@ public class ServerProperties { public String getProperty(String key, String defaultValue) { try { - is = new FileInputStream(new File(path, "server.properties")); + is = FileUtils.openInputStream(new File(path, "server.properties")); p = new Properties(); p.load(is); return p.getProperty(key, defaultValue); @@ -65,12 +67,7 @@ public class ServerProperties { HMCLog.warn("Failed to get property in server.properties", ex); return ""; } finally { - try { - if (is != null) - is.close(); - } catch (IOException ex) { - HMCLog.warn("Failed to close InputStream for server.properties", ex); - } + IOUtils.closeQuietly(is); } } @@ -88,22 +85,17 @@ public class ServerProperties { public void setProperty(String key, String value) { try { - is = new FileInputStream(new File(path, "server.properties")); + is = FileUtils.openInputStream(new File(path, "server.properties")); p = new Properties(); p.load(is); p.setProperty(key, value); SimpleDateFormat f = new SimpleDateFormat("E M d HH:mm:ss z y"); - p.store(new FileOutputStream(new File(path, "server.properties")), + p.store(FileUtils.openOutputStream(new File(path, "server.properties")), "Minecraft server properties\n" + f.format(new Date())); } catch (IOException ex) { HMCLog.warn("Failed to set property in server.properties", ex); } finally { - try { - if (is != null) - is.close(); - } catch (IOException ex) { - HMCLog.warn("Failed to close OutputStream for server.properties", ex); - } + IOUtils.closeQuietly(is); } } diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/SettingsManager.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/SettingsManager.java index d4ab35eb6..7bc37a98f 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/SettingsManager.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/setting/SettingsManager.java @@ -24,8 +24,8 @@ package org.jackhuang.hellominecraft.svrmgr.setting; import com.google.gson.Gson; import java.io.File; import java.io.IOException; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.FileUtils; /** * diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/ui/MainWindow.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/ui/MainWindow.java index d1cd4f674..e4553ace2 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/ui/MainWindow.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/ui/MainWindow.java @@ -46,14 +46,14 @@ import javax.swing.JPopupMenu; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.table.DefaultTableModel; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; -import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask; -import org.jackhuang.hellominecraft.util.tasks.download.HTTPGetTask; -import org.jackhuang.hellominecraft.util.system.FileUtils; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.TaskWindow; +import org.jackhuang.hellominecraft.util.net.FileDownloadTask; +import org.jackhuang.hellominecraft.util.net.HTTPGetTask; +import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.svrmgr.util.IMonitorService; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.svrmgr.util.ModType; import org.jackhuang.hellominecraft.svrmgr.util.MonitorInfoBean; @@ -86,7 +86,7 @@ import org.jackhuang.hellominecraft.svrmgr.util.IPGet; import org.jackhuang.hellominecraft.svrmgr.util.Utilities; import org.jackhuang.hellominecraft.util.ui.SwingUtils; import org.jackhuang.hellominecraft.svrmgr.util.version.MinecraftRemoteVersion; -import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton; +import org.jackhuang.hellominecraft.lookandfeel.ConstomButton; import org.jackhuang.hellominecraft.util.Event; import org.jackhuang.hellominecraft.util.StrUtils; @@ -2975,7 +2975,7 @@ public final class MainWindow extends javax.swing.JFrame } @Override - public void executeTask() { + public void executeTask(boolean areDependTasksSucceeded) { javax.swing.JTable table = MainWindow.this.lstDownloads; DefaultTableModel model = (DefaultTableModel) table.getModel(); @@ -2999,7 +2999,7 @@ public final class MainWindow extends javax.swing.JFrame void refreshDownloads() { clearListDownloads(); - TaskWindow.factory().append(new RefreshDownloadsDone()).create(); + TaskWindow.factory().append(new RefreshDownloadsDone()).execute(); } void refreshInfos() { @@ -3092,7 +3092,7 @@ public final class MainWindow extends javax.swing.JFrame lstPlayers.setModel(lstPlayersModel); }); else - MessageBox.Show("服务器未开启!"); + MessageBox.show("服务器未开启!"); } class ServerBeginListener implements Event { @@ -3137,7 +3137,7 @@ public final class MainWindow extends javax.swing.JFrame else if (option == JOptionPane.NO_OPTION) FileUtils.write(eula, "eula=false"); } catch (IOException e) { - MessageBox.Show("确认rula失败"); + MessageBox.show("确认rula失败"); } } File serverproperties = new File(new File(SettingsManager.settings.mainjar).getParentFile(), "server.properties"); @@ -3164,7 +3164,7 @@ public final class MainWindow extends javax.swing.JFrame try { Server.getInstance().run(); } catch (IOException ex) { - MessageBox.Show("启动服务端失败!"); + MessageBox.show("启动服务端失败!"); HMCLog.err("Failed to launch!", ex); } }//GEN-LAST:event_btnLaunchActionPerformed @@ -3335,7 +3335,7 @@ public final class MainWindow extends javax.swing.JFrame op.saveAsBoth(new File(dir, "ops.txt"), new File(dir, "ops.json")); } catch (IOException ex) { HMCLog.warn("Failed to save ops", ex); - MessageBox.Show("添加失败。。。"); + MessageBox.show("添加失败。。。"); } } }//GEN-LAST:event_btnAddOPActionPerformed @@ -3355,7 +3355,7 @@ public final class MainWindow extends javax.swing.JFrame op.saveAsBoth(new File(dir, "ops.txt"), new File(dir, "ops.json")); } catch (IOException ex) { HMCLog.warn("Failed to save ops", ex); - MessageBox.Show("删除失败。。。"); + MessageBox.show("删除失败。。。"); } } }//GEN-LAST:event_btnDeleteOPActionPerformed @@ -3374,7 +3374,7 @@ public final class MainWindow extends javax.swing.JFrame whitelist.saveAsBoth(new File(dir, "white-list.txt"), new File(dir, "white-list.json")); } catch (IOException ex) { HMCLog.warn("Failed to save white-list", ex); - MessageBox.Show("添加失败。。。"); + MessageBox.show("添加失败。。。"); } } }//GEN-LAST:event_btnAddWhiteActionPerformed @@ -3394,7 +3394,7 @@ public final class MainWindow extends javax.swing.JFrame whitelist.saveAsBoth(new File(dir, "white-list.txt"), new File(dir, "white-list.json")); } catch (IOException ex) { HMCLog.warn("Failed to save white-list", ex); - MessageBox.Show("删除失败。。。"); + MessageBox.show("删除失败。。。"); } } }//GEN-LAST:event_btnDeleteWhiteActionPerformed @@ -3421,7 +3421,7 @@ public final class MainWindow extends javax.swing.JFrame model.addRow(new Object[] { fc.getSelectedFile().getName(), ModType.getModTypeShowName(ModType.getModType(newf)) }); lstExternalMods.updateUI(); } catch (IOException e) { - MessageBox.Show(C.i18n("mods.failed")); + MessageBox.show(C.i18n("mods.failed")); HMCLog.warn("Failed to add ext mods", e); } }//GEN-LAST:event_btnAddExternelModActionPerformed @@ -3460,7 +3460,7 @@ public final class MainWindow extends javax.swing.JFrame model.addRow(new Object[] { fc.getSelectedFile().getName(), ModType.getModTypeShowName(ModType.getModType(newf)) }); FileUtils.copyFile(new File(path), newf); } catch (IOException e) { - MessageBox.Show(C.i18n("mods.failed")); + MessageBox.show(C.i18n("mods.failed")); HMCLog.warn("Failed to add ext core mod.", e); } }//GEN-LAST:event_btnAddExternelCoreModActionPerformed @@ -3500,7 +3500,7 @@ public final class MainWindow extends javax.swing.JFrame model.addRow(new Object[] { fc.getSelectedFile().getName(), ModType.getModTypeShowName(ModType.getModType(newf)) }); FileUtils.copyFile(new File(path), newf); } catch (IOException e) { - MessageBox.Show(C.i18n("mods.failed")); + MessageBox.show(C.i18n("mods.failed")); HMCLog.warn("Failed to add plugin", e); } }//GEN-LAST:event_btnAddPluginsActionPerformed @@ -3566,7 +3566,7 @@ public final class MainWindow extends javax.swing.JFrame whitelist.saveAsBoth(new File(dir, "banned-players.txt"), new File(dir, "banned-players.json")); } catch (IOException ex) { HMCLog.warn("Failed to save banned-players", ex); - MessageBox.Show(C.i18n("mods.failed")); + MessageBox.show(C.i18n("mods.failed")); } } }//GEN-LAST:event_btnAddBanActionPerformed @@ -3606,7 +3606,7 @@ public final class MainWindow extends javax.swing.JFrame resizeBackgroundLabel(); } catch (IOException e) { HMCLog.warn("Failed to set background path", e); - MessageBox.Show(C.i18n("ui.label.failed_set") + e.getMessage()); + MessageBox.show(C.i18n("ui.label.failed_set") + e.getMessage()); } }//GEN-LAST:event_btnSetBackgroundPathActionPerformed @@ -3628,7 +3628,7 @@ public final class MainWindow extends javax.swing.JFrame s.per = Double.parseDouble(txtTimerTaskPeriod.getText()); } catch (NumberFormatException e) { HMCLog.warn("Failed to parse double: " + txtTimerTaskPeriod.getText(), e); - MessageBox.Show("错误的间隔时间"); + MessageBox.show("错误的间隔时间"); return; } SettingsManager.settings.schedules.add(s); @@ -3720,7 +3720,7 @@ public final class MainWindow extends javax.swing.JFrame serverjar.delete(); String downloadURL = url + "minecraft_server." + id + ".jar"; - TaskWindow.factory().append(new FileDownloadTask(downloadURL, serverjar).setTag(id)).create(); + TaskWindow.factory().append(new FileDownloadTask(downloadURL, serverjar).setTag(id)).execute(); }//GEN-LAST:event_btnMinecraftServerDownloadActionPerformed private void btnRefreshInfosActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshInfosActionPerformed @@ -3783,7 +3783,7 @@ public final class MainWindow extends javax.swing.JFrame txtCrashReport.setText(content); } catch (IOException ex) { HMCLog.warn("Failed to get crash-report.", ex); - MessageBox.Show("无法获取崩溃报告"); + MessageBox.show("无法获取崩溃报告"); } }//GEN-LAST:event_btnShowReportActionPerformed @@ -3855,7 +3855,7 @@ public final class MainWindow extends javax.swing.JFrame BukkitVersion v = cb.get(idx); File file = new File("craftbukkit-" + ext + "-" + v.version + ".jar"); TaskWindow.factory().append(new FileDownloadTask(v.downloadLink, IOUtils.tryGetCanonicalFile(file)).setTag("bukkit-" + ext + "-" + v.version)) - .create(); + .execute(); }//GEN-LAST:event_btnDownloadCraftbukkitActionPerformed private void btnDownloadMCPCActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDownloadMCPCActionPerformed @@ -3866,8 +3866,8 @@ public final class MainWindow extends javax.swing.JFrame String url; File filepath = new File("forge-installer.jar"); url = v.installer[1]; - if (!TaskWindow.factory().append(new FileDownloadTask(url, filepath).setTag("cauldron-" + v.ver)).create()) - MessageBox.Show(C.i18n("install.failed_download_forge")); + if (!TaskWindow.factory().append(new FileDownloadTask(url, filepath).setTag("cauldron-" + v.ver)).execute()) + MessageBox.show(C.i18n("install.failed_download_forge")); else installMCPC(filepath); }//GEN-LAST:event_btnDownloadMCPCActionPerformed @@ -3876,10 +3876,10 @@ public final class MainWindow extends javax.swing.JFrame try { ForgeInstaller installer = new ForgeInstaller(new File("."), filepath); installer.install(); - MessageBox.Show(C.i18n("install.success")); + MessageBox.show(C.i18n("install.success")); } catch (Exception e) { HMCLog.warn("Failed to install liteloader", e); - MessageBox.Show(C.i18n("install.failed_forge")); + MessageBox.show(C.i18n("install.failed_forge")); } } @@ -3907,7 +3907,7 @@ public final class MainWindow extends javax.swing.JFrame private void btnInstallMCPCActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnInstallMCPCActionPerformed File filepath = new File("forge-installer.jar"); if (!filepath.exists()) { - MessageBox.Show("您还未下载Cauldron!请点击下载按钮下载并自动安装!"); + MessageBox.show("您还未下载Cauldron!请点击下载按钮下载并自动安装!"); return; } installMCPC(filepath); diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/ui/PluginInfoDialog.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/ui/PluginInfoDialog.java index 02f69435c..cf0044e5e 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/ui/PluginInfoDialog.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/ui/PluginInfoDialog.java @@ -19,8 +19,8 @@ package org.jackhuang.hellominecraft.svrmgr.ui; import java.io.File; import javax.swing.table.DefaultTableModel; -import org.jackhuang.hellominecraft.util.tasks.TaskWindow; -import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask; +import org.jackhuang.hellominecraft.util.task.TaskWindow; +import org.jackhuang.hellominecraft.util.net.FileDownloadTask; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.svrmgr.plugin.PluginInfo; import org.jackhuang.hellominecraft.svrmgr.plugin.PluginVersion; @@ -234,7 +234,7 @@ public class PluginInfoDialog extends javax.swing.JDialog { TaskWindow.factory() .append(new FileDownloadTask(url, new File(Utilities.getGameDir() + "plugins" + File.separator + pi.versions.get(index).filename))) - .create(); + .execute(); }//GEN-LAST:event_jButton1ActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/FolderOpener.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/FolderOpener.java index 31598d168..4eeeb96d9 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/FolderOpener.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/FolderOpener.java @@ -32,7 +32,7 @@ public class FolderOpener { f.mkdirs(); java.awt.Desktop.getDesktop().open(f); } catch (Exception ex) { - MessageBox.Show("无法打开资源管理器: " + ex.getMessage()); + MessageBox.show("无法打开资源管理器: " + ex.getMessage()); } } diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/IPGet.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/IPGet.java index 96f0aecb8..fef2a758b 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/IPGet.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/IPGet.java @@ -19,8 +19,8 @@ package org.jackhuang.hellominecraft.svrmgr.util; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.NetUtils; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.net.NetUtils; import org.jackhuang.hellominecraft.util.func.Consumer; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/ModType.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/ModType.java index cb809f106..31f0632ef 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/ModType.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/ModType.java @@ -24,6 +24,7 @@ import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.jackhuang.hellominecraft.util.C; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * 判断mod类型 @@ -68,14 +69,7 @@ public class ModType { } catch (Exception e) { } finally { - try { - if (zipFile != null) - zipFile.close(); - } catch (IOException ex) { - Logger.getLogger(ModType.class.getName()).log(Level.SEVERE, null, ex); - } catch (Throwable t) { - - } + IOUtils.closeQuietly(zipFile); } if (isModLoader) return MODLOADER_MOD; diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/MonitorServiceImpl.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/MonitorServiceImpl.java index 73cffa7a6..8b4d18bcc 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/MonitorServiceImpl.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/MonitorServiceImpl.java @@ -26,7 +26,8 @@ import java.lang.management.ManagementFactory; import java.util.StringTokenizer; import com.sun.management.OperatingSystemMXBean; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * @@ -39,7 +40,7 @@ public class MonitorServiceImpl implements IMonitorService { private static final int CPUTIME = 30; private static final int PERCENT = 100; private static final int FAULTLENGTH = 10; - private static final String linuxVersion = null; + private static final String LINUX_VERSION = null; /** * 获得当前的监控对象. @@ -77,7 +78,7 @@ public class MonitorServiceImpl implements IMonitorService { else if (osName.toLowerCase().startsWith("mac")) cpuRatio = this.getCpuRatioForMac(); else - cpuRatio = this.getCpuRatioForLinux(); + cpuRatio = getCpuRatioForLinux(); // 构造返回对象 MonitorInfoBean infoBean = new MonitorInfoBean(); infoBean.setFreeMemory(freeMemory); @@ -100,20 +101,22 @@ public class MonitorServiceImpl implements IMonitorService { String command = "cat /proc/stat"; long startTime = System.currentTimeMillis(); pro1 = r.exec(command); - BufferedReader in1 = new BufferedReader(new InputStreamReader(pro1.getInputStream())); - String line = null; - long idleCpuTime1 = 0, totalCpuTime1 = 0; //分别为系统启动后空闲的CPU时间和总的CPU时间 - while ((line = in1.readLine()) != null) - if (line.startsWith("cpu")) { - line = line.trim(); - String[] temp = line.split("\\s+"); - idleCpuTime1 = Long.parseLong(temp[4]); - for (String s : temp) - if (!s.equals("cpu")) - totalCpuTime1 += Long.parseLong(s); - break; - } - in1.close(); + String line; + long idleCpuTime1, totalCpuTime1; //分别为系统启动后空闲的CPU时间和总的CPU时间 + try (BufferedReader in1 = new BufferedReader(new InputStreamReader(pro1.getInputStream()))) { + idleCpuTime1 = 0; + totalCpuTime1 = 0; //分别为系统启动后空闲的CPU时间和总的CPU时间 + while ((line = in1.readLine()) != null) + if (line.startsWith("cpu")) { + line = line.trim(); + String[] temp = line.split("\\s+"); + idleCpuTime1 = Long.parseLong(temp[4]); + for (String s : temp) + if (!s.equals("cpu")) + totalCpuTime1 += Long.parseLong(s); + break; + } + } pro1.destroy(); try { Thread.sleep(100); @@ -123,21 +126,21 @@ public class MonitorServiceImpl implements IMonitorService { //第二次采集CPU时间 long endTime = System.currentTimeMillis(); pro2 = r.exec(command); - BufferedReader in2 = new BufferedReader(new InputStreamReader(pro2.getInputStream())); - long idleCpuTime2 = 0, totalCpuTime2 = 0; //分别为系统启动后空闲的CPU时间和总的CPU时间 - while ((line = in2.readLine()) != null) - if (line.startsWith("cpu")) { - line = line.trim(); - String[] temp = line.split("\\s+"); - idleCpuTime2 = Long.parseLong(temp[4]); - for (String s : temp) - if (!s.equals("cpu")) - totalCpuTime2 += Long.parseLong(s); - break; - } - if (idleCpuTime1 != 0 && totalCpuTime1 != 0 && idleCpuTime2 != 0 && totalCpuTime2 != 0) - cpuUsage = 1 - (float) (idleCpuTime2 - idleCpuTime1) / (float) (totalCpuTime2 - totalCpuTime1); - in2.close(); + try (BufferedReader in2 = new BufferedReader(new InputStreamReader(pro2.getInputStream()))) { + long idleCpuTime2 = 0, totalCpuTime2 = 0; //分别为系统启动后空闲的CPU时间和总的CPU时间 + while ((line = in2.readLine()) != null) + if (line.startsWith("cpu")) { + line = line.trim(); + String[] temp = line.split("\\s+"); + idleCpuTime2 = Long.parseLong(temp[4]); + for (String s : temp) + if (!s.equals("cpu")) + totalCpuTime2 += Long.parseLong(s); + break; + } + if (idleCpuTime1 != 0 && totalCpuTime1 != 0 && idleCpuTime2 != 0 && totalCpuTime2 != 0) + cpuUsage = 1 - (float) (idleCpuTime2 - idleCpuTime1) / (float) (totalCpuTime2 - totalCpuTime1); + } pro2.destroy(); } catch (IOException e) { HMCLog.err("Failed to catch sysout", e); @@ -174,21 +177,9 @@ public class MonitorServiceImpl implements IMonitorService { System.out.println(ioe.getMessage()); return 1; } finally { - freeResource(is, isr, brStat); - } - } - - private static void freeResource(InputStream is, InputStreamReader isr, - BufferedReader br) { - try { - if (is != null) - is.close(); - if (isr != null) - isr.close(); - if (br != null) - br.close(); - } catch (IOException ioe) { - System.out.println(ioe.getMessage()); + IOUtils.closeQuietly(is); + IOUtils.closeQuietly(isr); + IOUtils.closeQuietly(brStat); } } @@ -217,6 +208,14 @@ public class MonitorServiceImpl implements IMonitorService { return 0.0; } } + + public static String substring(String src, int start_idx, int end_idx) { + byte[] b = src.getBytes(); + String tgt = ""; + for (int i = start_idx; i <= end_idx; i++) + tgt += (char) b[i]; + return tgt; + } /** * 读取CPU信息. @@ -250,12 +249,12 @@ public class MonitorServiceImpl implements IMonitorService { continue; // 字段出现顺序:Caption,CommandLine,KernelModeTime,ReadOperationCount, // ThreadCount,UserModeTime,WriteOperation - String caption = StrUtils.substring(line, capidx, cmdidx - 1).trim(); - String cmd = StrUtils.substring(line, cmdidx, kmtidx - 1).trim(); + String caption = substring(line, capidx, cmdidx - 1).trim(); + String cmd = substring(line, cmdidx, kmtidx - 1).trim(); if (cmd.contains("wmic.exe")) continue; - String s1 = StrUtils.substring(line, kmtidx, rocidx - 1).trim(); - String s2 = StrUtils.substring(line, umtidx, wocidx - 1).trim(); + String s1 = substring(line, kmtidx, rocidx - 1).trim(); + String s2 = substring(line, umtidx, wocidx - 1).trim(); if (caption.equals("System Idle Process") || caption.equals("System")) { if (s1.length() > 0) idletime += Long.parseLong(s1); @@ -274,11 +273,7 @@ public class MonitorServiceImpl implements IMonitorService { } catch (IOException | NumberFormatException ex) { ex.printStackTrace(); } finally { - try { - proc.getInputStream().close(); - } catch (Exception e) { - e.printStackTrace(); - } + IOUtils.closeQuietly(proc.getInputStream()); } return null; } diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/MonitorThread.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/MonitorThread.java index 581879058..9c7b9a904 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/MonitorThread.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/MonitorThread.java @@ -21,9 +21,9 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; import java.util.ArrayList; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.code.Charsets; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * @@ -42,11 +42,7 @@ public class MonitorThread extends Thread { public MonitorThread(InputStream is) { this.listeners = new ArrayList<>(5); - try { - br = new BufferedReader(new InputStreamReader(is, System.getProperty("sun.jnu.encoding", "gbk"))); - } catch (UnsupportedEncodingException ex) { - br = new BufferedReader(new InputStreamReader(is)); - } + br = new BufferedReader(new InputStreamReader(is, Charsets.toCharset(System.getProperty("sun.jnu.encoding", "gbk")))); } public void addListener(MonitorThreadListener l) { diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/Utilities.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/Utilities.java index 8e7181244..5644b9024 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/Utilities.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/Utilities.java @@ -19,7 +19,7 @@ package org.jackhuang.hellominecraft.svrmgr.util; import java.io.File; import org.jackhuang.hellominecraft.svrmgr.setting.SettingsManager; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * diff --git a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/WaitForThread.java b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/WaitForThread.java index 30b31f411..ab3b211d6 100755 --- a/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/WaitForThread.java +++ b/HMCSM/src/main/java/org/jackhuang/hellominecraft/svrmgr/util/WaitForThread.java @@ -17,9 +17,8 @@ */ package org.jackhuang.hellominecraft.svrmgr.util; -import java.util.logging.Level; -import java.util.logging.Logger; import org.jackhuang.hellominecraft.util.EventHandler; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * @@ -40,7 +39,7 @@ public class WaitForThread extends Thread { int exitCode = p.waitFor(); event.execute(exitCode); } catch (InterruptedException ex) { - Logger.getLogger(WaitForThread.class.getName()).log(Level.SEVERE, null, ex); + HMCLog.err("Game has been interrupted.", ex); event.execute(-1); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/OverridableSwingWorker.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/AbstractSwingWorker.java similarity index 85% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/OverridableSwingWorker.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/AbstractSwingWorker.java index b02735a6e..6a3f0fa4c 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/OverridableSwingWorker.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/AbstractSwingWorker.java @@ -20,6 +20,7 @@ package org.jackhuang.hellominecraft.util; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; import javax.swing.SwingWorker; import org.jackhuang.hellominecraft.util.func.Consumer; @@ -27,7 +28,7 @@ import org.jackhuang.hellominecraft.util.func.Consumer; * * @author huangyuhui */ -public abstract class OverridableSwingWorker extends SwingWorker { +public abstract class AbstractSwingWorker extends SwingWorker { List> processListeners = new ArrayList<>(); List doneListeners = new ArrayList<>(); @@ -46,15 +47,13 @@ public abstract class OverridableSwingWorker extends SwingWorker { return null; } - public OverridableSwingWorker reg(Consumer c) { - Utils.requireNonNull(c); - processListeners.add(c); + public AbstractSwingWorker reg(Consumer c) { + processListeners.add(Objects.requireNonNull(c)); return this; } - public OverridableSwingWorker regDone(Runnable c) { - Utils.requireNonNull(c); - doneListeners.add(c); + public AbstractSwingWorker regDone(Runnable c) { + doneListeners.add(Objects.requireNonNull(c)); return this; } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ArrayUtils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ArrayUtils.java index a127bd7fc..4fb48c1d4 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ArrayUtils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ArrayUtils.java @@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.util; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Map; @@ -26,7 +27,10 @@ import java.util.Map; * * @author huangyuhui */ -public class ArrayUtils { +public final class ArrayUtils { + + private ArrayUtils() { + } public static boolean isEmpty(T[] array) { return array == null || array.length <= 0; @@ -55,10 +59,6 @@ public class ArrayUtils { return -1; } - public static int lastIndexOf(T[] array, T valueToFind) { - return lastIndexOf(array, valueToFind, 2147483647); - } - public static int lastIndexOf(T[] array, T valueToFind, int startIndex) { if (array == null) return -1; @@ -72,42 +72,20 @@ public class ArrayUtils { return -1; } - public static ArrayList merge(List a, List b) { - ArrayList al = new ArrayList(a.size() + b.size()); + public static ArrayList merge(List a, List b) { + ArrayList al = new ArrayList<>(a.size() + b.size()); al.addAll(a); al.addAll(b); return al; } - public static K getEnd(K[] k) { - if (k == null) - return null; - else - return k[k.length - 1]; - } - - public static List tryGetMapWithList(Map map, String key) { - List l = (List) map.get(key); + public static List tryGetMapWithList(Map> map, String key) { + List l = (List) map.get(key); if (l == null) - map.put(key, l = new ArrayList()); + map.put(key, l = new ArrayList<>()); return l; } - - public static int matchArray(T[] a, T[] b) { - for (int i = 0; i < a.length - b.length; i++) { - int j = 1; - for (int k = 0; k < b.length; k++) { - if (b[k].equals(a[(i + k)])) - continue; - j = 0; - break; - } - if (j != 0) - return i; - } - return -1; - } - + public static int matchArray(byte[] a, byte[] b) { for (int i = 0; i < a.length - b.length; i++) { int j = 1; @@ -122,19 +100,8 @@ public class ArrayUtils { } return -1; } - - public static boolean equals(T[] a, T[] b) { - if (a == null && b == null) - return true; - if (a == null || b == null) - return false; - if (a.length != b.length) - return false; - Arrays.sort(a); - Arrays.sort(b); - for (int i = 0; i < a.length; i++) - if (a[i] == null && b[i] != null || a[i] != null && b[i] == null || !a[i].equals(b[i])) - return false; - return true; + + public static boolean hasDuplicateElements(T[] t) { + return new HashSet<>(Arrays.asList(t)).size() < t.length; } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/C.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/C.java index 2c8f5a111..8dba3ae2b 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/C.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/C.java @@ -35,10 +35,6 @@ public final class C { 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 FILE_MINECRAFT_VERSIONS = "versions"; - - public static final String LINE_SEPARATOR = System.getProperty("line.separator"); - 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/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/CollectionUtils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/CollectionUtils.java index 9f8284ae5..cbd840607 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/CollectionUtils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/CollectionUtils.java @@ -28,7 +28,10 @@ import java.util.Iterator; */ public final class CollectionUtils { - public static ArrayList map(Collection coll, Predicate p) { + private CollectionUtils() { + } + + public static ArrayList filter(Collection coll, Predicate p) { ArrayList newColl = new ArrayList<>(); for (T t : coll) if (p.apply(t)) diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/DoubleOutputStream.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/DoubleOutputStream.java index e11fd4033..c4d21d472 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/DoubleOutputStream.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/DoubleOutputStream.java @@ -26,47 +26,47 @@ import java.io.OutputStream; */ public class DoubleOutputStream extends OutputStream { - private OutputStream a = null; - private OutputStream b = null; - private boolean c = true; + private OutputStream os1 = null; + private OutputStream os2 = null; + private boolean autoFlush = true; - public DoubleOutputStream(OutputStream paramOutputStream1, OutputStream paramOutputStream2) { - this(paramOutputStream1, paramOutputStream2, true); + public DoubleOutputStream(OutputStream os1, OutputStream os2) { + this(os1, os2, true); } - private DoubleOutputStream(OutputStream paramOutputStream1, OutputStream paramOutputStream2, boolean paramBoolean) { - this.a = paramOutputStream1; - this.b = paramOutputStream2; - this.c = true; + private DoubleOutputStream(OutputStream os1, OutputStream os2, boolean autoFlush) { + this.os1 = os1; + this.os2 = os2; + this.autoFlush = autoFlush; } @Override public final void write(byte[] arr, int off, int len) throws IOException { - if (this.a != null) - this.a.write(arr, off, len); - if (this.b != null) - this.b.write(arr, off, len); - if (this.c) + if (this.os1 != null) + this.os1.write(arr, off, len); + if (this.os2 != null) + this.os2.write(arr, off, len); + if (this.autoFlush) flush(); } @Override public final void write(byte[] arr) throws IOException { - if (this.a != null) - this.a.write(arr); - if (this.b != null) - this.b.write(arr); - if (this.c) + if (this.os1 != null) + this.os1.write(arr); + if (this.os2 != null) + this.os2.write(arr); + if (this.autoFlush) flush(); } @Override public final void write(int i) throws IOException { - if (this.a != null) - this.a.write(i); - if (this.b != null) - this.b.write(i); - if (this.c) + if (this.os1 != null) + this.os1.write(i); + if (this.os2 != null) + this.os2.write(i); + if (this.autoFlush) flush(); } @@ -74,17 +74,17 @@ public class DoubleOutputStream extends OutputStream { public final void close() throws IOException { flush(); - if (this.a != null) - this.a.close(); - if (this.b != null) - this.b.close(); + if (this.os1 != null) + this.os1.close(); + if (this.os2 != null) + this.os2.close(); } @Override public final void flush() throws IOException { - if (this.a != null) - this.a.flush(); - if (this.b != null) - this.b.flush(); + if (this.os1 != null) + this.os1.flush(); + if (this.os2 != null) + this.os2.flush(); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/EventHandler.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/EventHandler.java index 450976a16..8f6f3a96f 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/EventHandler.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/EventHandler.java @@ -49,26 +49,14 @@ public class EventHandler { events.add(t); } - public void unregister(Event t) { - events.remove(t); - } - - public void unregister(Consumer t) { - events.remove(t); - } - - public void unregister(Runnable t) { - events.remove(t); - } - public boolean execute(T x) { boolean flag = true; for (Object t : events) if (t instanceof Event) { - if (!((Event) t).call(sender, x)) + if (!((Event) t).call(sender, x)) flag = false; } else if (t instanceof Consumer) - ((Consumer) t).accept(x); + ((Consumer) t).accept(x); else if (t instanceof Runnable) ((Runnable) t).run(); return flag; diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/IUpdateChecker.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/IUpdateChecker.java index 9a589ca0d..1bedf7225 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/IUpdateChecker.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/IUpdateChecker.java @@ -49,13 +49,13 @@ public interface IUpdateChecker { * * @return the process observable. */ - OverridableSwingWorker process(boolean showMessage); + AbstractSwingWorker process(boolean showMessage); /** * Get the download links. * * @return a JSON, which contains the server response. */ - OverridableSwingWorker> requestDownloadLink(); + AbstractSwingWorker> requestDownloadLink(); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/LauncherPrintStream.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/LauncherPrintStream.java deleted file mode 100755 index 0c0b81ace..000000000 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/LauncherPrintStream.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Hello Minecraft!. - * 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; - -import org.jackhuang.hellominecraft.util.func.Consumer; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.ArrayList; - -/** - * - * @author huangyuhui - */ -public class LauncherPrintStream extends PrintStream { - - private final ArrayList> printListeners = new ArrayList<>(); - - public LauncherPrintStream(OutputStream paramOutputStream) { - super(paramOutputStream); - } - - @Override - public final void println(String paramString) { - super.println(paramString); - - for (Consumer a1 : printListeners) - a1.accept(paramString); - } - - public final LauncherPrintStream addPrintListener(Consumer paraml) { - this.printListeners.add(paraml); - return this; - } -} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MathUtils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MathUtils.java index 18e605482..ffb49dadf 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MathUtils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MathUtils.java @@ -21,7 +21,10 @@ package org.jackhuang.hellominecraft.util; * * @author huang */ -public class MathUtils { +public final class MathUtils { + + private MathUtils() { + } public static int parseInt(String s, int def) { try { diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MessageBox.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MessageBox.java index d3fd908f6..6c4aaad5e 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MessageBox.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MessageBox.java @@ -92,7 +92,7 @@ public class MessageBox { * * @return user operation. */ - public static int Show(String Msg, String Title, int Option) { + public static int show(String Msg, String Title, int Option) { switch (Option) { case YES_NO_OPTION: case YES_NO_CANCEL_OPTION: @@ -112,8 +112,8 @@ public class MessageBox { * * @return User Operation */ - public static int Show(String Msg, int Option) { - return Show(Msg, TITLE, Option); + public static int show(String Msg, int Option) { + return show(Msg, TITLE, Option); } /** @@ -123,11 +123,11 @@ public class MessageBox { * * @return User Operation */ - public static int Show(String Msg) { - return Show(Msg, TITLE, INFORMATION_MESSAGE); + public static int show(String Msg) { + return show(Msg, TITLE, INFORMATION_MESSAGE); } - public static int ShowLocalized(String msg) { - return Show(C.i18n(msg)); + public static int showLocalized(String msg) { + return show(C.i18n(msg)); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MinecraftVersionRequest.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MinecraftVersionRequest.java index d983903e2..a00b13a91 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MinecraftVersionRequest.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/MinecraftVersionRequest.java @@ -22,15 +22,15 @@ import java.io.IOException; import java.io.Serializable; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.ArrayUtils; -import org.jackhuang.hellominecraft.util.NetUtils; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * @author huangyuhui */ public class MinecraftVersionRequest implements Serializable { + + private static final long serialVersionUID = 1L; public static final int UNKOWN = 0, INVALID = 1, INVALID_JAR = 2, MODIFIED = 3, OK = 4, NOT_FOUND = 5, UNREADABLE = 6, NOT_FILE = 7; @@ -38,34 +38,25 @@ public class MinecraftVersionRequest implements Serializable { public String version; public static String getResponse(MinecraftVersionRequest minecraftVersion) { - String text = ""; switch (minecraftVersion.type) { case MinecraftVersionRequest.INVALID: - text = C.i18n("minecraft.invalid"); - break; + return C.i18n("minecraft.invalid"); case MinecraftVersionRequest.INVALID_JAR: - text = C.i18n("minecraft.invalid_jar"); - break; + return C.i18n("minecraft.invalid_jar"); case MinecraftVersionRequest.NOT_FILE: - text = C.i18n("minecraft.not_a_file"); - break; + return C.i18n("minecraft.not_a_file"); case MinecraftVersionRequest.NOT_FOUND: - text = C.i18n("minecraft.not_found"); - break; + return C.i18n("minecraft.not_found"); case MinecraftVersionRequest.UNREADABLE: - text = C.i18n("minecraft.not_readable"); - break; + return C.i18n("minecraft.not_readable"); case MinecraftVersionRequest.MODIFIED: - text = C.i18n("minecraft.modified") + " "; + return C.i18n("minecraft.modified") + ' ' + minecraftVersion.version; case MinecraftVersionRequest.OK: - text += minecraftVersion.version; - break; + return minecraftVersion.version; case MinecraftVersionRequest.UNKOWN: default: - text = "???"; - break; + return "???"; } - return text; } private static int lessThan32(byte[] b, int x) { @@ -77,11 +68,11 @@ public class MinecraftVersionRequest implements Serializable { private static MinecraftVersionRequest getVersionOfOldMinecraft(ZipFile file, ZipEntry entry) throws IOException { MinecraftVersionRequest r = new MinecraftVersionRequest(); - byte[] tmp = NetUtils.getBytesFromStream(file.getInputStream(entry)); + byte[] tmp = IOUtils.toByteArray(file.getInputStream(entry)); byte[] bytes = "Minecraft Minecraft ".getBytes("ASCII"); - int j; - if ((j = ArrayUtils.matchArray(tmp, bytes)) < 0) { + int j = ArrayUtils.matchArray(tmp, bytes); + if (j < 0) { r.type = MinecraftVersionRequest.UNKOWN; return r; } @@ -101,7 +92,7 @@ public class MinecraftVersionRequest implements Serializable { private static MinecraftVersionRequest getVersionOfNewMinecraft(ZipFile file, ZipEntry entry) throws IOException { MinecraftVersionRequest r = new MinecraftVersionRequest(); - byte[] tmp = NetUtils.getBytesFromStream(file.getInputStream(entry)); + byte[] tmp = IOUtils.toByteArray(file.getInputStream(entry)); byte[] str = "-server.txt".getBytes("ASCII"); int j = ArrayUtils.matchArray(tmp, str); @@ -145,7 +136,7 @@ public class MinecraftVersionRequest implements Serializable { while (tmp[k] >= 48 && tmp[k] <= 57 || tmp[k] == (int) '-' || tmp[k] == (int) '.' || tmp[k] >= 97 && tmp[k] <= (int) 'z') k--; k++; - r.version = new String(tmp, k, i - k + 1); + r.version = new String(tmp, k, i - k + 1, "ASCII"); } r.type = file.getEntry("META-INF/MANIFEST.MF") == null ? MinecraftVersionRequest.MODIFIED : MinecraftVersionRequest.OK; @@ -166,30 +157,25 @@ public class MinecraftVersionRequest implements Serializable { r.type = MinecraftVersionRequest.UNREADABLE; return r; } - ZipFile localZipFile = null; + ZipFile f = null; try { - localZipFile = new ZipFile(file); - ZipEntry minecraft = localZipFile + f = new ZipFile(file); + ZipEntry minecraft = f .getEntry("net/minecraft/client/Minecraft.class"); if (minecraft != null) - return getVersionOfOldMinecraft(localZipFile, minecraft); - ZipEntry main = localZipFile.getEntry("net/minecraft/client/main/Main.class"); - ZipEntry minecraftserver = localZipFile.getEntry("net/minecraft/server/MinecraftServer.class"); + return getVersionOfOldMinecraft(f, minecraft); + ZipEntry main = f.getEntry("net/minecraft/client/main/Main.class"); + ZipEntry minecraftserver = f.getEntry("net/minecraft/server/MinecraftServer.class"); if ((main != null) && (minecraftserver != null)) - return getVersionOfNewMinecraft(localZipFile, minecraftserver); + return getVersionOfNewMinecraft(f, minecraftserver); r.type = MinecraftVersionRequest.INVALID; return r; - } catch (IOException localException) { - HMCLog.warn("Zip file is invalid", localException); + } catch (IOException e) { + HMCLog.warn("Zip file is invalid", e); r.type = MinecraftVersionRequest.INVALID_JAR; return r; } finally { - if (localZipFile != null) - try { - localZipFile.close(); - } catch (IOException ex) { - HMCLog.warn("Failed to close zip file", ex); - } + IOUtils.closeQuietly(f); } } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/StrUtils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/StrUtils.java index f2ec6038f..d6f9db641 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/StrUtils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/StrUtils.java @@ -17,7 +17,6 @@ */ package org.jackhuang.hellominecraft.util; -import java.awt.Dimension; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Array; @@ -33,13 +32,8 @@ import org.jackhuang.hellominecraft.util.func.Predicate; * @author huang */ public final class StrUtils { - - public static String substring(String src, int start_idx, int end_idx) { - byte[] b = src.getBytes(); - String tgt = ""; - for (int i = start_idx; i <= end_idx; i++) - tgt += (char) b[i]; - return tgt; + + private StrUtils() { } public static String makeCommand(List cmd) { @@ -77,15 +71,6 @@ public final class StrUtils { return base != null && base.startsWith(match); } - public static boolean startsWithOne(String[] a, String match) { - if (a == null) - return false; - for (String b : a) - if (startsWith(match, b)) - return true; - return false; - } - public static boolean startsWithOne(Collection a, String match) { if (a == null) return false; @@ -102,21 +87,6 @@ public final class StrUtils { return false; } - public static boolean containsOne(String base, String... match) { - for (String s : match) - if (base.contains(s)) - return true; - return false; - } - - public static boolean containsOne(List base, List match) { - for (String a : base) - for (String b : match) - if (a.toLowerCase().contains(b.toLowerCase())) - return true; - return false; - } - public static boolean containsOne(List base, List match, Predicate pred) { for (String a : base) for (String b : match) @@ -147,12 +117,12 @@ public final class StrUtils { return ver; } - public static String parseParams(String addBefore, Collection paramArrayOfObject, String paramString) { - return parseParams(addBefore, paramArrayOfObject.toArray(), paramString); + public static String parseParams(String addBefore, Collection objects, String addAfter) { + return parseParams(addBefore, objects.toArray(), addAfter); } - public static String parseParams(String addBefore, Object[] params, String addAfter) { - return parseParams(t -> addBefore, params, t -> addAfter); + public static String parseParams(String addBefore, Object[] objects, String addAfter) { + return parseParams(t -> addBefore, objects, t -> addAfter); } public static String parseParams(Function beforeFunc, Object[] params, Function afterFunc) { @@ -184,46 +154,19 @@ public final class StrUtils { return sb.toString(); } - public static boolean equals(String base, String to) { - if (base == null) - return (to == null); - else - return base.equals(to); - } - - public static Dimension parseDimension(String str) { - String[] tokenized = tokenize(str, "x,"); - if (tokenized.length != 2) - return null; - int i = MathUtils.parseInt(tokenized[0], -1); - int j = MathUtils.parseInt(tokenized[1], -1); - if ((i < 0) || (j < 0)) - return null; - return new Dimension(i, j); - } - public static String[] tokenize(String paramString1) { return tokenize(paramString1, " \t\n\r\f"); } - public static String[] tokenize(String paramString1, String paramString2) { - ArrayList localArrayList = new ArrayList(); - StringTokenizer tokenizer = new StringTokenizer(paramString1, paramString2); + public static String[] tokenize(String str, String delim) { + ArrayList al = new ArrayList<>(); + StringTokenizer tokenizer = new StringTokenizer(str, delim); while (tokenizer.hasMoreTokens()) { - paramString2 = tokenizer.nextToken(); - localArrayList.add(paramString2); + delim = tokenizer.nextToken(); + al.add(delim); } - return (String[]) localArrayList.toArray(new String[localArrayList.size()]); - } - - public static String trimExtension(String filename) { - if ((filename != null) && (filename.length() > 0)) { - int i = filename.lastIndexOf('.'); - if ((i > -1) && (i < (filename.length()))) - return filename.substring(0, i); - } - return filename; + return al.toArray(new String[al.size()]); } public static boolean isBlank(String s) { @@ -240,14 +183,4 @@ public final class StrUtils { t.printStackTrace(writer); return trace.toString(); } - - public static List findAllPos(String t, String p) { - ArrayList ret = new ArrayList<>(); - int i = 0, index; - while ((index = t.indexOf(p, i)) != -1) { - ret.add(index); - i = index + p.length(); - } - return ret; - } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/UpdateChecker.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/UpdateChecker.java index e440e0995..d4b84d92b 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/UpdateChecker.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/UpdateChecker.java @@ -17,7 +17,10 @@ */ package org.jackhuang.hellominecraft.util; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.net.NetUtils; +import com.google.gson.JsonSyntaxException; +import java.io.IOException; +import org.jackhuang.hellominecraft.util.log.HMCLog; import java.util.Map; /** @@ -26,7 +29,7 @@ import java.util.Map; */ public final class UpdateChecker implements IUpdateChecker { - public boolean OUT_DATED = false; + private volatile boolean outOfDate = false; public VersionNumber base; public String versionString; public String type; @@ -39,9 +42,13 @@ public final class UpdateChecker implements IUpdateChecker { VersionNumber value; + public boolean isOutOfDate() { + return outOfDate; + } + @Override - public OverridableSwingWorker process(final boolean showMessage) { - return new OverridableSwingWorker() { + public AbstractSwingWorker process(final boolean showMessage) { + return new AbstractSwingWorker() { @Override protected void work() throws Exception { if (value == null) { @@ -52,10 +59,10 @@ public final class UpdateChecker implements IUpdateChecker { if (value == null) { HMCLog.warn("Failed to check update..."); if (showMessage) - MessageBox.Show(C.i18n("update.failed")); + MessageBox.show(C.i18n("update.failed")); } else if (VersionNumber.isOlder(base, value)) - OUT_DATED = true; - if (OUT_DATED) + outOfDate = true; + if (outOfDate) publish(value); } }; @@ -67,14 +74,14 @@ public final class UpdateChecker implements IUpdateChecker { } @Override - public synchronized OverridableSwingWorker> requestDownloadLink() { - return new OverridableSwingWorker() { + public synchronized AbstractSwingWorker> requestDownloadLink() { + return new AbstractSwingWorker>() { @Override protected void work() throws Exception { if (download_link == null) try { - download_link = C.GSON.fromJson(NetUtils.get("http://huangyuhui.duapp.com/update_link.php?type=" + type), Map.class); - } catch (Exception e) { + download_link = C.GSON.>fromJson(NetUtils.get("http://huangyuhui.duapp.com/update_link.php?type=" + type), Map.class); + } catch (JsonSyntaxException | IOException e) { HMCLog.warn("Failed to get update link.", e); } publish(download_link); @@ -82,11 +89,11 @@ public final class UpdateChecker implements IUpdateChecker { }; } - public final EventHandler outdated = new EventHandler<>(this); + public final EventHandler outOfDateEvent = new EventHandler<>(this); @Override public void checkOutdate() { - if (OUT_DATED) - outdated.execute(getNewVersion()); + if (outOfDate) + outOfDateEvent.execute(getNewVersion()); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/Utils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/Utils.java index 3deec8dce..b90acdf42 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/Utils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/Utils.java @@ -17,49 +17,32 @@ */ package org.jackhuang.hellominecraft.util; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import com.sun.management.OperatingSystemMXBean; +import java.awt.HeadlessException; import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; -import java.lang.management.ManagementFactory; import java.lang.reflect.Method; -import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; /** * @author huangyuhui */ public final class Utils { - @SuppressWarnings("ResultOfObjectAllocationIgnored") - public static boolean isURL(String s) { - try { - new URL(s); - return true; - } catch (MalformedURLException ex) { - return false; - } + private Utils() { } public static URL[] getURL() { return ((URLClassLoader) Utils.class.getClassLoader()).getURLs(); } - public static int getSuggestedMemorySize() { - try { - OperatingSystemMXBean osmb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); - int memory = (int) (osmb.getTotalPhysicalMemorySize() / 1024 / 1024) / 4; - memory = Math.round((float) memory / 128.0f) * 128; - return memory; - } catch (Throwable t) { - HMCLog.warn("Failed to get total memory size, use 1024MB.", t); - return 1024; - } - } - public static void setClipborad(String text) { - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text), null); + try { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text), null); + } catch(HeadlessException ignored) { + } } /** @@ -68,21 +51,12 @@ public final class Utils { * @param status exit code */ public static void shutdownForcely(int status) throws Exception { - Class z = Class.forName("java.lang.Shutdown"); - Method exit = z.getDeclaredMethod("exit", int.class); - exit.setAccessible(true); - exit.invoke(z, status); - } - - public static void requireNonNull(Object o) { - if (o == null) - throw new NullPointerException("Oh dear, there is a problem..."); - } - - public static Object firstNonNull(Object... o) { - for (Object s : o) - if (s != null) - return s; - return null; + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + Class z = Class.forName("java.lang.Shutdown"); + Method exit = z.getDeclaredMethod("exit", int.class); + exit.setAccessible(true); + exit.invoke(z, status); + return null; + }); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/VersionNumber.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/VersionNumber.java index bb0025917..9b85d6168 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/VersionNumber.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/VersionNumber.java @@ -17,7 +17,7 @@ */ package org.jackhuang.hellominecraft.util; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * @@ -78,6 +78,33 @@ public final class VersionNumber implements Comparable { return false; } + @Override + public int hashCode() { + int hash = 3; + hash = 83 * hash + this.firstVer; + hash = 83 * hash + this.secondVer; + hash = 83 * hash + this.thirdVer; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final VersionNumber other = (VersionNumber) obj; + if (this.firstVer != other.firstVer) + return false; + if (this.secondVer != other.secondVer) + return false; + if (this.thirdVer != other.thirdVer) + return false; + return true; + } + @Override public int compareTo(VersionNumber o) { if (isOlder(this, o)) diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Base64.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Base64.java deleted file mode 100755 index 4250861f8..000000000 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Base64.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Hello Minecraft!. - * 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.code; - -import java.io.UnsupportedEncodingException; - -/** - * - * @author huangyuhui - */ -public class Base64 { - - public static char[] encode(byte[] data) { - char[] out = new char[((data.length + 2) / 3) * 4]; - for (int i = 0, index = 0; i < data.length; i += 3, index += 4) { - boolean quad = false; - boolean trip = false; - int val = (0xFF & (int) data[i]); - val <<= 8; - if ((i + 1) < data.length) { - val |= (0xFF & (int) data[i + 1]); - trip = true; - } - val <<= 8; - if ((i + 2) < data.length) { - val |= (0xFF & (int) data[i + 2]); - quad = true; - } - out[index + 3] = ALPHABET[(quad ? (val & 0x3F) : 64)]; - val >>= 6; - out[index + 2] = ALPHABET[(trip ? (val & 0x3F) : 64)]; - val >>= 6; - out[index + 1] = ALPHABET[val & 0x3F]; - val >>= 6; - out[index + 0] = ALPHABET[val & 0x3F]; - } - return out; - } - - public static char[] encode(String s, String charset) throws UnsupportedEncodingException { - return encode(s.getBytes(charset)); - } - - public static char[] encode(String s) { - return encode(s.getBytes()); - } - - public static byte[] decode(char[] data) { - int len = ((data.length + 3) / 4) * 3; - if (data.length > 0 && data[data.length - 1] == '=') - --len; - if (data.length > 1 && data[data.length - 2] == '=') - --len; - byte[] out = new byte[len]; - int shift = 0; - int accum = 0; - int index = 0; - for (int ix = 0; ix < data.length; ix++) { - int value = CODES[data[ix] & 0xFF]; - if (value >= 0) { - accum <<= 6; - shift += 6; - accum |= value; - if (shift >= 8) { - shift -= 8; - out[index++] = (byte) ((accum >> shift) & 0xff); - } - } - } - if (index != out.length) - throw new Error("miscalculated data length!"); - return out; - } - private static final char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" - .toCharArray(); - private static final byte[] CODES = new byte[256]; - - static { - for (int i = 0; i < 256; i++) - CODES[i] = -1; - for (int i = 'A'; i <= 'Z'; i++) - CODES[i] = (byte) (i - 'A'); - for (int i = 'a'; i <= 'z'; i++) - CODES[i] = (byte) (26 + i - 'a'); - for (int i = '0'; i <= '9'; i++) - CODES[i] = (byte) (52 + i - '0'); - CODES['+'] = 62; - CODES['/'] = 63; - } -} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Charsets.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Charsets.java index 2d8d52322..a73a2e28d 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Charsets.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Charsets.java @@ -18,10 +18,15 @@ package org.jackhuang.hellominecraft.util.code; import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; +import org.jackhuang.hellominecraft.util.sys.IOUtils; -public class Charsets { +public final class Charsets { + + private Charsets() { + } - public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); + /*public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); public static final Charset US_ASCII = Charset.forName("US-ASCII"); @@ -29,15 +34,22 @@ public class Charsets { public static final Charset UTF_16BE = Charset.forName("UTF-16BE"); - public static final Charset UTF_16LE = Charset.forName("UTF-16LE"); + public static final Charset UTF_16LE = Charset.forName("UTF-16LE");*/ public static final Charset UTF_8 = Charset.forName("UTF-8"); - - public static Charset toCharset(Charset charset) { - return charset == null ? Charset.defaultCharset() : charset; - } + + public static final Charset DEFAULT_CHARSET = UTF_8; public static Charset toCharset(String charset) { - return charset == null ? Charset.defaultCharset() : Charset.forName(charset); + if (charset == null) return Charset.defaultCharset(); + try { + return Charset.forName(charset); + } catch(UnsupportedCharsetException ignored) { + return Charset.defaultCharset(); + } + } + + public static Charset toCharset() { + return toCharset(System.getProperty("sun.jnu.encoding", IOUtils.DEFAULT_CHARSET)); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/DigestUtils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/DigestUtils.java index 5aedd9859..17d9b7350 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/DigestUtils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/DigestUtils.java @@ -26,7 +26,10 @@ import java.security.NoSuchAlgorithmException; * * @author huangyuhui */ -public class DigestUtils { +public final class DigestUtils { + + private DigestUtils() { + } private static final int STREAM_BUFFER_LENGTH = 1024; @@ -67,11 +70,6 @@ public class DigestUtils { return getDigest("SHA-512"); } - @Deprecated - public static MessageDigest getShaDigest() { - return getSha1Digest(); - } - public static byte[] md2(byte[] data) { return getMd2Digest().digest(data); } @@ -124,22 +122,6 @@ public class DigestUtils { return Hex.encodeHexString(md5(data)); } - @Deprecated - public static byte[] sha(byte[] data) { - return sha1(data); - } - - @Deprecated - public static byte[] sha(InputStream data) - throws IOException { - return sha1(data); - } - - @Deprecated - public static byte[] sha(String data) { - return sha1(data); - } - public static byte[] sha1(byte[] data) { return getSha1Digest().digest(data); } @@ -244,22 +226,6 @@ public class DigestUtils { return Hex.encodeHexString(sha512(data)); } - @Deprecated - public static String shaHex(byte[] data) { - return sha1Hex(data); - } - - @Deprecated - public static String shaHex(InputStream data) - throws IOException { - return sha1Hex(data); - } - - @Deprecated - public static String shaHex(String data) { - return sha1Hex(data); - } - public static MessageDigest updateDigest(MessageDigest messageDigest, byte[] valueToDigest) { messageDigest.update(valueToDigest); return messageDigest; diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Hex.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Hex.java index 9d5d969f6..44773f209 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Hex.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/code/Hex.java @@ -19,10 +19,8 @@ package org.jackhuang.hellominecraft.util.code; import java.nio.charset.Charset; -public class Hex { +public final class Hex { - public static final Charset DEFAULT_CHARSET = Charsets.UTF_8; - public static final String DEFAULT_CHARSET_NAME = "UTF-8"; private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; @@ -80,17 +78,13 @@ public class Hex { } public Hex() { - this.charset = DEFAULT_CHARSET; + this(Charsets.DEFAULT_CHARSET); } public Hex(Charset charset) { this.charset = charset; } - public Hex(String charsetName) { - this(Charset.forName(charsetName)); - } - public byte[] decode(byte[] array) throws Exception { return decodeHex(new String(array, getCharset()).toCharArray()); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/func/BiConsumer.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/func/BiConsumer.java deleted file mode 100755 index 0b9fd1bd1..000000000 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/func/BiConsumer.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Hello Minecraft!. - * 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.func; - -/** - * @author huangyuhui - */ -public interface BiConsumer { - - void call(V value, V2 value2); -} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/func/TriConsumer.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/func/TriConsumer.java deleted file mode 100755 index 5281028de..000000000 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/func/TriConsumer.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Hello Minecraft!. - * 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.func; - -/** - * - * @author huangyuhui - */ -public interface TriConsumer { - - void onDone(V1 v1, V2 v2, V3 v3); -} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/lang/Localization.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/lang/Localization.java index e5705c225..2f398343d 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/lang/Localization.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/lang/Localization.java @@ -22,42 +22,43 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Locale; import java.util.Map; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * * @author huangyuhui */ -public class Localization { +public final class Localization { private static final String ROOT_LOCATION = "/org/jackhuang/hellominecraft/lang/I18N%s.lang"; private static final Map INSTANCE = new HashMap<>(); - private final Map lang; + private final Map lang = new HashMap<>(); + + private static InputStream getStream(String id) { + return Localization.class.getResourceAsStream(String.format(ROOT_LOCATION, id)); + } private Localization(Locale locale) { - InputStream is = Localization.class.getResourceAsStream(String.format(ROOT_LOCATION, "_" + locale.getLanguage() + "_" + locale.getCountry())); + InputStream is = getStream("_" + locale.getLanguage() + "_" + locale.getCountry()); if (is == null) - is = Localization.class.getResourceAsStream(String.format(ROOT_LOCATION, "_" + locale.getLanguage())); + is = getStream("_" + locale.getLanguage()); if (is == null) - is = Localization.class.getResourceAsStream(String.format(ROOT_LOCATION, "")); + is = getStream(""); if (is == null) - throw new RuntimeException("LANG FILE MISSING"); + throw new InternalError("Language file missing"); - this.lang = new HashMap<>(); try { - String[] strings = IOUtils.readFully(is).toString("UTF-8").split("\n"); - for (String s : strings) + for (String s : IOUtils.readLines(is, IOUtils.DEFAULT_CHARSET)) if (!s.isEmpty() && s.charAt(0) != 35) { - int i = s.indexOf("="); + int i = s.indexOf('='); if (i == -1) continue; lang.put(s.substring(0, i), s.substring(i + 1)); } } catch (IOException ex) { - HMCLog.err("LANG FILE MISSING", ex); + throw new InternalError("Language file missing", ex); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/lang/SupportedLocales.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/lang/SupportedLocales.java index 3bc58d7b8..edc0dd735 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/lang/SupportedLocales.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/lang/SupportedLocales.java @@ -24,7 +24,7 @@ import java.util.Locale; * @author huangyuhui */ public enum SupportedLocales { - def(Locale.getDefault(), "lang.default"), en(Locale.ENGLISH, null), zh_TW(Locale.TRADITIONAL_CHINESE, null), zh_CN(Locale.SIMPLIFIED_CHINESE, null); + def(Locale.getDefault(), "lang.default"), en(Locale.ENGLISH, null), zh(Locale.TRADITIONAL_CHINESE, null), zh_CN(Locale.SIMPLIFIED_CHINESE, null), vi(new Locale("vi"), null); public Locale self; private String showString, customized; @@ -36,9 +36,8 @@ public enum SupportedLocales { bundle = Localization.get(self); showString = bundle.localize("lang"); this.customized = customized; - } catch (Throwable t) { + } catch (Throwable ignore) { showString = name(); - t.printStackTrace(); } } @@ -54,8 +53,7 @@ public enum SupportedLocales { public String translate(String key, Object... format) { try { return String.format(bundle.localize(key), format); - } catch (Exception ex) { - ex.printStackTrace(); + } catch (Exception ignore) { return key; } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/AppenderControl.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/AppenderControl.java similarity index 91% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/AppenderControl.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/AppenderControl.java index bdfce4e94..8531bcb05 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/AppenderControl.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/AppenderControl.java @@ -15,13 +15,13 @@ * 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.logging; +package org.jackhuang.hellominecraft.util.log; -import org.jackhuang.hellominecraft.util.logging.appender.IAppender; +import org.jackhuang.hellominecraft.util.log.appender.IAppender; public class AppenderControl { - private final ThreadLocal recursive = new ThreadLocal(); + private final ThreadLocal recursive = new ThreadLocal<>(); private final IAppender appender; private final Level level; private final int intLevel; @@ -37,8 +37,8 @@ public class AppenderControl { } public void callAppender(LogEvent event) { - if ((this.level != null) - && (this.intLevel < event.level.level)) + if (this.level != null + && this.intLevel < event.level.level) return; if (this.recursive.get() != null) { diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/Configuration.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/Configuration.java similarity index 81% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/Configuration.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/Configuration.java index 711e68f9d..b6ed6579e 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/Configuration.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/Configuration.java @@ -15,12 +15,12 @@ * 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.logging; +package org.jackhuang.hellominecraft.util.log; import java.util.ArrayList; -import org.jackhuang.hellominecraft.util.logging.appender.ConsoleAppender; -import org.jackhuang.hellominecraft.util.logging.appender.IAppender; -import org.jackhuang.hellominecraft.util.logging.layout.DefaultLayout; +import org.jackhuang.hellominecraft.util.log.appender.ConsoleAppender; +import org.jackhuang.hellominecraft.util.log.appender.IAppender; +import org.jackhuang.hellominecraft.util.log.layout.DefaultLayout; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/HMCLog.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/HMCLog.java similarity index 81% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/HMCLog.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/HMCLog.java index 10b753129..0888a38d8 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/HMCLog.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/HMCLog.java @@ -15,9 +15,9 @@ * 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.logging; +package org.jackhuang.hellominecraft.util.log; -import org.jackhuang.hellominecraft.util.logging.logger.Logger; +import org.jackhuang.hellominecraft.util.log.logger.Logger; /** * @@ -35,18 +35,10 @@ public class HMCLog { LOGGER.warn(message); } - public static void debug(String message) { - LOGGER.debug(message); - } - public static void warn(String msg, Throwable t) { LOGGER.warn(msg, t); } - public static void debug(String msg, Throwable t) { - LOGGER.debug(msg, t); - } - public static void err(String msg) { LOGGER.error(msg); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/Level.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/Level.java similarity index 95% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/Level.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/Level.java index 7bba9c70b..e29b13705 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/Level.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/Level.java @@ -15,7 +15,7 @@ * 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.logging; +package org.jackhuang.hellominecraft.util.log; import java.awt.Color; import java.util.regex.Matcher; @@ -27,7 +27,6 @@ import java.util.regex.Pattern; */ public enum Level { - OFF(0, Color.gray), FATAL(1, Color.red), ERROR(2, Color.red), WARN(3, Color.orange), @@ -48,10 +47,6 @@ public enum Level { return this.level <= level.level; } - public boolean lessOrEqual(int level) { - return this.level <= level; - } - public static final Pattern MINECRAFT_LOGGER = Pattern.compile("\\[(?[0-9:]+)\\] \\[[^/]+/(?[^\\]]+)\\]"); public static final String JAVA_SYMBOL = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*"; diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/LogEvent.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/LogEvent.java similarity index 88% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/LogEvent.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/LogEvent.java index e182bb707..045af68e5 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/LogEvent.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/LogEvent.java @@ -15,9 +15,9 @@ * 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.logging; +package org.jackhuang.hellominecraft.util.log; -import org.jackhuang.hellominecraft.util.logging.message.IMessage; +import org.jackhuang.hellominecraft.util.log.message.IMessage; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/LoggingException.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/LoggingException.java similarity index 94% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/LoggingException.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/LoggingException.java index f97e273e2..9eef0235a 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/LoggingException.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/LoggingException.java @@ -15,7 +15,7 @@ * 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.logging; +package org.jackhuang.hellominecraft.util.log; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/AbstractAppender.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/AbstractAppender.java similarity index 92% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/AbstractAppender.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/AbstractAppender.java index 856ff9624..cfe28fe26 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/AbstractAppender.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/AbstractAppender.java @@ -15,10 +15,10 @@ * 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.logging.appender; +package org.jackhuang.hellominecraft.util.log.appender; import java.io.Serializable; -import org.jackhuang.hellominecraft.util.logging.layout.ILayout; +import org.jackhuang.hellominecraft.util.log.layout.ILayout; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/ConsoleAppender.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/ConsoleAppender.java similarity index 94% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/ConsoleAppender.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/ConsoleAppender.java index eb3582235..f868f5274 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/ConsoleAppender.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/ConsoleAppender.java @@ -15,12 +15,12 @@ * 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.logging.appender; +package org.jackhuang.hellominecraft.util.log.appender; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; -import org.jackhuang.hellominecraft.util.logging.layout.ILayout; +import org.jackhuang.hellominecraft.util.log.layout.ILayout; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/IAppender.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/IAppender.java similarity index 84% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/IAppender.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/IAppender.java index d48b7bd1d..1c08c07d5 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/IAppender.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/IAppender.java @@ -15,11 +15,11 @@ * 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.logging.appender; +package org.jackhuang.hellominecraft.util.log.appender; import java.io.Serializable; -import org.jackhuang.hellominecraft.util.logging.LogEvent; -import org.jackhuang.hellominecraft.util.logging.layout.ILayout; +import org.jackhuang.hellominecraft.util.log.LogEvent; +import org.jackhuang.hellominecraft.util.log.layout.ILayout; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/OutputStreamAppender.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/OutputStreamAppender.java similarity index 89% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/OutputStreamAppender.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/OutputStreamAppender.java index 9d0a7c8a5..23c9f4615 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/appender/OutputStreamAppender.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/appender/OutputStreamAppender.java @@ -15,7 +15,7 @@ * 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.logging.appender; +package org.jackhuang.hellominecraft.util.log.appender; import java.io.IOException; import java.io.OutputStream; @@ -23,9 +23,9 @@ import java.io.PrintStream; import java.io.Serializable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.jackhuang.hellominecraft.util.logging.LogEvent; -import org.jackhuang.hellominecraft.util.logging.LoggingException; -import org.jackhuang.hellominecraft.util.logging.layout.ILayout; +import org.jackhuang.hellominecraft.util.log.LogEvent; +import org.jackhuang.hellominecraft.util.log.LoggingException; +import org.jackhuang.hellominecraft.util.log.layout.ILayout; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/layout/AbstractStringLayout.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/layout/AbstractStringLayout.java similarity index 89% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/layout/AbstractStringLayout.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/layout/AbstractStringLayout.java index c67b9e580..2554a25a5 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/layout/AbstractStringLayout.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/layout/AbstractStringLayout.java @@ -15,9 +15,9 @@ * 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.logging.layout; +package org.jackhuang.hellominecraft.util.log.layout; -import org.jackhuang.hellominecraft.util.logging.LogEvent; +import org.jackhuang.hellominecraft.util.log.LogEvent; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/layout/DefaultLayout.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/layout/DefaultLayout.java similarity index 91% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/layout/DefaultLayout.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/layout/DefaultLayout.java index ed6deb46d..1eb845185 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/layout/DefaultLayout.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/layout/DefaultLayout.java @@ -15,11 +15,11 @@ * 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.logging.layout; +package org.jackhuang.hellominecraft.util.log.layout; import java.text.SimpleDateFormat; import java.util.Date; -import org.jackhuang.hellominecraft.util.logging.LogEvent; +import org.jackhuang.hellominecraft.util.log.LogEvent; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/layout/ILayout.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/layout/ILayout.java similarity index 89% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/layout/ILayout.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/layout/ILayout.java index 0e2da34b3..742702b17 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/layout/ILayout.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/layout/ILayout.java @@ -15,10 +15,10 @@ * 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.logging.layout; +package org.jackhuang.hellominecraft.util.log.layout; import java.io.Serializable; -import org.jackhuang.hellominecraft.util.logging.LogEvent; +import org.jackhuang.hellominecraft.util.log.LogEvent; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/AbstractLogger.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/logger/AbstractLogger.java similarity index 78% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/AbstractLogger.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/logger/AbstractLogger.java index ce5269594..5044d2e16 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/AbstractLogger.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/logger/AbstractLogger.java @@ -15,20 +15,19 @@ * 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.logging.logger; +package org.jackhuang.hellominecraft.util.log.logger; -import org.jackhuang.hellominecraft.util.logging.Level; -import org.jackhuang.hellominecraft.util.logging.message.IMessage; -import org.jackhuang.hellominecraft.util.logging.message.IMessageFactory; -import org.jackhuang.hellominecraft.util.logging.message.ParameterizedMessageFactory; -import org.jackhuang.hellominecraft.util.logging.message.StringFormattedMessage; +import org.jackhuang.hellominecraft.util.log.Level; +import org.jackhuang.hellominecraft.util.log.message.IMessage; +import org.jackhuang.hellominecraft.util.log.message.IMessageFactory; +import org.jackhuang.hellominecraft.util.log.message.ParameterizedMessageFactory; +import org.jackhuang.hellominecraft.util.log.message.StringFormattedMessage; public abstract class AbstractLogger implements ILogger { public static final Class DEFAULT_MESSAGE_FACTORY_CLASS = ParameterizedMessageFactory.class; - private static final String FQCN = AbstractLogger.class.getName(); private static final String THROWING = "throwing"; private static final String CATCHING = "catching"; private final String name; @@ -68,50 +67,6 @@ public abstract class AbstractLogger catching(Level.ERROR, t); } - @Override - public void debug(IMessage msg) { - if (isEnabled(Level.DEBUG, msg, null)) - log(Level.DEBUG, msg, null); - } - - @Override - public void debug(IMessage msg, Throwable t) { - if (isEnabled(Level.DEBUG, msg, t)) - log(Level.DEBUG, msg, t); - } - - @Override - public void debug(Object message) { - if (isEnabled(Level.DEBUG, message, null)) - log(Level.DEBUG, this.messageFactory.newMessage(message), null); - } - - @Override - public void debug(Object message, Throwable t) { - if (isEnabled(Level.DEBUG, message, t)) - log(Level.DEBUG, this.messageFactory.newMessage(message), t); - } - - @Override - public void debug(String message) { - if (isEnabled(Level.DEBUG, message)) - log(Level.DEBUG, this.messageFactory.newMessage(message), null); - } - - @Override - public void debug(String message, Object[] params) { - if (isEnabled(Level.DEBUG, message, params)) { - IMessage msg = this.messageFactory.newMessage(message, params); - log(Level.DEBUG, msg, msg.getThrowable()); - } - } - - @Override - public void debug(String message, Throwable t) { - if (isEnabled(Level.DEBUG, message, t)) - log(Level.DEBUG, this.messageFactory.newMessage(message), t); - } - @Override public void entry() { entry(new Object[0]); @@ -395,50 +350,6 @@ public abstract class AbstractLogger return this.name; } - @Override - public void trace(IMessage msg) { - if (isEnabled(Level.TRACE, msg, null)) - log(Level.TRACE, msg, null); - } - - @Override - public void trace(IMessage msg, Throwable t) { - if (isEnabled(Level.TRACE, msg, t)) - log(Level.TRACE, msg, t); - } - - @Override - public void trace(Object message) { - if (isEnabled(Level.TRACE, message, null)) - log(Level.TRACE, this.messageFactory.newMessage(message), null); - } - - @Override - public void trace(Object message, Throwable t) { - if (isEnabled(Level.TRACE, message, t)) - log(Level.TRACE, this.messageFactory.newMessage(message), t); - } - - @Override - public void trace(String message) { - if (isEnabled(Level.TRACE, message)) - log(Level.TRACE, this.messageFactory.newMessage(message), null); - } - - @Override - public void trace(String message, Object[] params) { - if (isEnabled(Level.TRACE, message, params)) { - IMessage msg = this.messageFactory.newMessage(message, params); - log(Level.TRACE, msg, msg.getThrowable()); - } - } - - @Override - public void trace(String message, Throwable t) { - if (isEnabled(Level.TRACE, message, t)) - log(Level.TRACE, this.messageFactory.newMessage(message), t); - } - @Override public void warn(IMessage msg) { if (isEnabled(Level.WARN, msg, null)) diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/ILogger.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/logger/ILogger.java similarity index 78% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/ILogger.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/logger/ILogger.java index b4355607a..65958c7ab 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/ILogger.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/logger/ILogger.java @@ -15,10 +15,10 @@ * 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.logging.logger; +package org.jackhuang.hellominecraft.util.log.logger; -import org.jackhuang.hellominecraft.util.logging.Level; -import org.jackhuang.hellominecraft.util.logging.message.IMessage; +import org.jackhuang.hellominecraft.util.log.Level; +import org.jackhuang.hellominecraft.util.log.message.IMessage; /** * @@ -30,20 +30,6 @@ public interface ILogger { void catching(Throwable paramThrowable); - void debug(IMessage paramIMessage); - - void debug(IMessage paramIMessage, Throwable paramThrowable); - - void debug(Object paramObject); - - void debug(Object paramObject, Throwable paramThrowable); - - void debug(String paramString); - - void debug(String paramString, Object[] paramArrayOfObject); - - void debug(String paramString, Throwable paramThrowable); - void entry(); void entry(Object[] paramArrayOfObject); @@ -126,20 +112,6 @@ public interface ILogger { T throwing(T paramT); - void trace(IMessage paramIMessage); - - void trace(IMessage paramIMessage, Throwable paramThrowable); - - void trace(Object paramObject); - - void trace(Object paramObject, Throwable paramThrowable); - - void trace(String paramString); - - void trace(String paramString, Object[] paramArrayOfObject); - - void trace(String paramString, Throwable paramThrowable); - void warn(IMessage paramIMessage); void warn(IMessage paramIMessage, Throwable paramThrowable); diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/Logger.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/logger/Logger.java similarity index 88% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/Logger.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/logger/Logger.java index 9cc322ec9..8d3c2b05b 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/Logger.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/logger/Logger.java @@ -15,23 +15,23 @@ * 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.logging.logger; +package org.jackhuang.hellominecraft.util.log.logger; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.jackhuang.hellominecraft.util.logging.AppenderControl; -import org.jackhuang.hellominecraft.util.logging.Configuration; -import org.jackhuang.hellominecraft.util.logging.Level; -import org.jackhuang.hellominecraft.util.logging.LogEvent; -import org.jackhuang.hellominecraft.util.logging.appender.IAppender; -import org.jackhuang.hellominecraft.util.logging.message.IMessage; -import org.jackhuang.hellominecraft.util.logging.message.IMessageFactory; +import org.jackhuang.hellominecraft.util.log.AppenderControl; +import org.jackhuang.hellominecraft.util.log.Configuration; +import org.jackhuang.hellominecraft.util.log.Level; +import org.jackhuang.hellominecraft.util.log.LogEvent; +import org.jackhuang.hellominecraft.util.log.appender.IAppender; +import org.jackhuang.hellominecraft.util.log.message.IMessage; +import org.jackhuang.hellominecraft.util.log.message.IMessageFactory; public class Logger extends AbstractLogger { protected volatile PrivateConfig config; - private final Map appenders = new ConcurrentHashMap(); + private final Map appenders = new ConcurrentHashMap<>(); public Logger(String name) { this(name, null, Level.INFO); @@ -109,8 +109,8 @@ public class Logger extends AbstractLogger { } public Map getAppenders() { - Map map = new HashMap(); - for (Map.Entry entry : this.appenders.entrySet()) + Map map = new HashMap<>(); + for (Map.Entry entry : this.appenders.entrySet()) map.put(entry.getKey(), ((AppenderControl) entry.getValue()).getAppender()); return map; } @@ -143,27 +143,22 @@ public class Logger extends AbstractLogger { } boolean filter(Level level, String msg) { - return this.intLevel >= level.level; } boolean filter(Level level, String msg, Throwable t) { - return this.intLevel >= level.level; } boolean filter(Level level, String msg, Object[] p1) { - return this.intLevel >= level.level; } boolean filter(Level level, Object msg, Throwable t) { - return this.intLevel >= level.level; } boolean filter(Level level, IMessage msg, Throwable t) { - return this.intLevel >= level.level; } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/AbstractMessageFactory.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/AbstractMessageFactory.java similarity index 94% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/AbstractMessageFactory.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/AbstractMessageFactory.java index 6c4e0785b..7b70d79da 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/AbstractMessageFactory.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/AbstractMessageFactory.java @@ -15,7 +15,7 @@ * 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.logging.message; +package org.jackhuang.hellominecraft.util.log.message; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/IMessage.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/IMessage.java similarity index 94% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/IMessage.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/IMessage.java index bd3143acd..22c11cc02 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/IMessage.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/IMessage.java @@ -15,7 +15,7 @@ * 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.logging.message; +package org.jackhuang.hellominecraft.util.log.message; import java.io.Serializable; diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/IMessageFactory.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/IMessageFactory.java similarity index 94% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/IMessageFactory.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/IMessageFactory.java index cdf628d18..8cacfa720 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/IMessageFactory.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/IMessageFactory.java @@ -15,7 +15,7 @@ * 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.logging.message; +package org.jackhuang.hellominecraft.util.log.message; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/ObjectMessage.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/ObjectMessage.java similarity index 95% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/ObjectMessage.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/ObjectMessage.java index 1ec991cec..ab046b6eb 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/ObjectMessage.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/ObjectMessage.java @@ -15,13 +15,13 @@ * 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.logging.message; +package org.jackhuang.hellominecraft.util.log.message; public class ObjectMessage implements IMessage { private static final long serialVersionUID = -5903272448334166185L; - private final transient Object obj; + private final Object obj; public ObjectMessage(Object obj) { if (obj == null) diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/ParameterizedMessage.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/ParameterizedMessage.java similarity index 93% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/ParameterizedMessage.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/ParameterizedMessage.java index 7a05ca2f7..17be6b993 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/ParameterizedMessage.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/ParameterizedMessage.java @@ -15,14 +15,13 @@ * 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.logging.message; +package org.jackhuang.hellominecraft.util.log.message; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -230,7 +229,7 @@ public class ParameterizedMessage if (o instanceof String) return (String) o; StringBuilder str = new StringBuilder(); - Set dejaVu = new HashSet(); + Set dejaVu = new HashSet<>(); recursiveDeepToString(o, str, dejaVu); return str.toString(); } @@ -244,7 +243,7 @@ public class ParameterizedMessage str.append(o); return; } - Class oClass = o.getClass(); + Class oClass = o.getClass(); if (oClass.isArray()) if (oClass == byte[].class) str.append(Arrays.toString((byte[]) (byte[]) o)); @@ -265,7 +264,7 @@ public class ParameterizedMessage else { String id = identityToString(o); if (dejaVu.contains(id)) - str.append("[...").append(id).append("...]"); + str.append(RECURSION_PREFIX).append(id).append(RECURSION_SUFFIX); else { dejaVu.add(id); Object[] oArray = (Object[]) (Object[]) o; @@ -276,7 +275,7 @@ public class ParameterizedMessage first = false; else str.append(", "); - recursiveDeepToString(current, str, new HashSet(dejaVu)); + recursiveDeepToString(current, str, new HashSet<>(dejaVu)); } str.append("]"); } @@ -284,42 +283,40 @@ public class ParameterizedMessage else if ((o instanceof Map)) { String id = identityToString(o); if (dejaVu.contains(id)) - str.append("[...").append(id).append("...]"); + str.append(RECURSION_PREFIX).append(id).append(RECURSION_SUFFIX); else { dejaVu.add(id); - Map oMap = (Map) o; + Map oMap = (Map) o; str.append("{"); boolean isFirst = true; - for (Object o1 : oMap.entrySet()) { - Map.Entry current = (Map.Entry) o1; + for (Map.Entry current : oMap.entrySet()) { if (isFirst) isFirst = false; else str.append(", "); Object key = current.getKey(); Object value = current.getValue(); - recursiveDeepToString(key, str, new HashSet(dejaVu)); + recursiveDeepToString(key, str, new HashSet<>(dejaVu)); str.append("="); - recursiveDeepToString(value, str, new HashSet(dejaVu)); + recursiveDeepToString(value, str, new HashSet<>(dejaVu)); } str.append("}"); } } else if ((o instanceof Collection)) { String id = identityToString(o); if (dejaVu.contains(id)) - str.append("[...").append(id).append("...]"); + str.append(RECURSION_PREFIX).append(id).append(RECURSION_SUFFIX); else { dejaVu.add(id); - Collection oCol = (Collection) o; + Collection oCol = (Collection) o; str.append("["); boolean isFirst = true; - for (Iterator i$ = oCol.iterator(); i$.hasNext();) { - Object anOCol = i$.next(); + for (Object anOCol : oCol) { if (isFirst) isFirst = false; else str.append(", "); - recursiveDeepToString(anOCol, str, new HashSet(dejaVu)); + recursiveDeepToString(anOCol, str, new HashSet<>(dejaVu)); } str.append("]"); } @@ -332,17 +329,17 @@ public class ParameterizedMessage try { str.append(o.toString()); } catch (Throwable t) { - str.append("[!!!"); + str.append(ERROR_PREFIX); str.append(identityToString(o)); - str.append("=>"); + str.append(ERROR_SEPARATOR); String msg = t.getMessage(); String className = t.getClass().getName(); str.append(className); if (!className.equals(msg)) { - str.append(":"); + str.append(ERROR_MSG_SEPARATOR); str.append(msg); } - str.append("!!!]"); + str.append(ERROR_SUFFIX); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/ParameterizedMessageFactory.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/ParameterizedMessageFactory.java similarity index 86% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/ParameterizedMessageFactory.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/ParameterizedMessageFactory.java index 95474e0e0..c78385350 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/ParameterizedMessageFactory.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/ParameterizedMessageFactory.java @@ -15,7 +15,7 @@ * 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.logging.message; +package org.jackhuang.hellominecraft.util.log.message; /** * @@ -23,8 +23,6 @@ package org.jackhuang.hellominecraft.util.logging.message; */ public final class ParameterizedMessageFactory extends AbstractMessageFactory { - public static final ParameterizedMessageFactory INSTANCE = new ParameterizedMessageFactory(); - @Override public IMessage newMessage(String message, Object[] params) { return new ParameterizedMessage(message, params); diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/SimpleMessage.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/SimpleMessage.java similarity index 97% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/SimpleMessage.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/SimpleMessage.java index d1998bd21..1590a73e9 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/SimpleMessage.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/SimpleMessage.java @@ -15,7 +15,7 @@ * 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.logging.message; +package org.jackhuang.hellominecraft.util.log.message; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/StringFormattedMessage.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/StringFormattedMessage.java similarity index 98% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/StringFormattedMessage.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/StringFormattedMessage.java index 75dc60f1e..9af3fd098 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/message/StringFormattedMessage.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/log/message/StringFormattedMessage.java @@ -15,7 +15,7 @@ * 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.logging.message; +package org.jackhuang.hellominecraft.util.log.message; import java.util.Arrays; import java.util.IllegalFormatException; diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/SimpleLogger.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/SimpleLogger.java deleted file mode 100755 index 077884456..000000000 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/logging/logger/SimpleLogger.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Hello Minecraft!. - * 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.logging.logger; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import org.jackhuang.hellominecraft.util.logging.Level; -import org.jackhuang.hellominecraft.util.logging.message.IMessage; -import org.jackhuang.hellominecraft.util.logging.message.IMessageFactory; - -public class SimpleLogger extends AbstractLogger { - - private static final char SPACE = ' '; - private DateFormat dateFormatter; - private Level level; - private final boolean showDateTime; - private final boolean showContextMap; - private PrintStream stream; - private final String logName; - - public SimpleLogger(String name, Level defaultLevel, boolean showLogName, boolean showShortLogName, boolean showDateTime, boolean showContextMap, String dateTimeFormat, IMessageFactory messageFactory, PrintStream stream) { - super(name, messageFactory); - this.level = defaultLevel; - if (showShortLogName) { - int index = name.lastIndexOf("."); - if ((index > 0) && (index < name.length())) - this.logName = name.substring(index + 1); - else - this.logName = name; - } else if (showLogName) - this.logName = name; - else - this.logName = null; - this.showDateTime = showDateTime; - this.showContextMap = showContextMap; - this.stream = stream; - - if (showDateTime) - try { - this.dateFormatter = new SimpleDateFormat(dateTimeFormat); - } catch (IllegalArgumentException e) { - this.dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS zzz"); - } - } - - public void setStream(PrintStream stream) { - this.stream = stream; - } - - public Level getLevel() { - return this.level; - } - - public void setLevel(Level level) { - if (level != null) - this.level = level; - } - - @Override - public void abstractLog(Level level, IMessage msg, Throwable throwable) { - StringBuilder sb = new StringBuilder(); - - if (this.showDateTime) { - Date now = new Date(); - String dateText; - synchronized (this.dateFormatter) { - dateText = this.dateFormatter.format(now); - } - sb.append(dateText); - sb.append(SPACE); - } - - sb.append(level.toString()); - sb.append(SPACE); - if ((this.logName != null) && (this.logName.length() > 0)) { - sb.append(this.logName); - sb.append(SPACE); - } - sb.append(msg.getFormattedMessage()); - Object[] params = msg.getParameters(); - Throwable t; - if ((throwable == null) && (params != null) && ((params[(params.length - 1)] instanceof Throwable))) - t = (Throwable) params[(params.length - 1)]; - else - t = throwable; - if (t != null) { - sb.append(SPACE); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - t.printStackTrace(new PrintStream(baos)); - sb.append(baos.toString()); - } - this.stream.println(sb.toString()); - } - - @Override - protected boolean isEnabled(Level level, String msg) { - return this.level.level >= level.level; - } - - @Override - protected boolean isEnabled(Level level, String msg, Throwable t) { - return this.level.level >= level.level; - } - - @Override - protected boolean isEnabled(Level level, String msg, Object[] p1) { - return this.level.level >= level.level; - } - - @Override - protected boolean isEnabled(Level level, Object msg, Throwable t) { - return this.level.level >= level.level; - } - - @Override - protected boolean isEnabled(Level level, IMessage msg, Throwable t) { - return this.level.level >= level.level; - } -} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/FileDownloadTask.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/FileDownloadTask.java similarity index 70% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/FileDownloadTask.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/FileDownloadTask.java index d4e97809f..1366f5971 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/FileDownloadTask.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/FileDownloadTask.java @@ -15,7 +15,7 @@ * 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.tasks.download; +package org.jackhuang.hellominecraft.util.net; import java.io.File; import java.io.IOException; @@ -29,11 +29,12 @@ import java.util.ArrayList; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.code.DigestUtils; import org.jackhuang.hellominecraft.util.func.Function; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.tasks.Task; -import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult; -import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResultRegistrar; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.sys.FileUtils; +import org.jackhuang.hellominecraft.util.task.Task; +import org.jackhuang.hellominecraft.util.task.comm.PreviousResult; +import org.jackhuang.hellominecraft.util.task.comm.PreviousResultRegistrar; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * @@ -42,9 +43,6 @@ import org.jackhuang.hellominecraft.util.system.IOUtils; // This class downloads a file from a URL. public class FileDownloadTask extends Task implements PreviousResult, PreviousResultRegistrar { - // Max size of download buffer. - protected static final int MAX_BUFFER_SIZE = 2048; - protected URL url; // download URL protected int downloaded = 0; // number of bytes downloaded protected File filePath; @@ -92,28 +90,15 @@ public class FileDownloadTask extends Task implements PreviousResult, Prev boolean shouldContinue = true; private void closeFiles() { - // Close file. - if (file != null) - try { - file.close(); - file = null; - } catch (IOException e) { - HMCLog.warn("Failed to close file", e); - } - - // Close connection to server. - if (stream != null) - try { - stream.close(); - stream = null; - } catch (IOException e) { - HMCLog.warn("Failed to close stream", e); - } + IOUtils.closeQuietly(file); + file = null; + IOUtils.closeQuietly(stream); + stream = null; } // Download file. @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { for (PreviousResult p : al) this.url = IOUtils.parseURL(p.getResult()); @@ -126,7 +111,7 @@ public class FileDownloadTask extends Task implements PreviousResult, Prev HMCLog.warn("Switch to: " + url); } } - HMCLog.log("Downloading: " + url + ", to: " + filePath); + HMCLog.log("Downloading: " + url + " to: " + filePath); if (!shouldContinue) break; try { @@ -134,38 +119,41 @@ public class FileDownloadTask extends Task implements PreviousResult, Prev ppl.setProgress(this, -1, 1); // Open connection to URL. - HttpURLConnection connection - = (HttpURLConnection) url.openConnection(); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); - connection.setConnectTimeout(5000); - connection.setRequestProperty("User-Agent", "Hello Minecraft!"); + con.setDoInput(true); + con.setConnectTimeout(15000); + con.setReadTimeout(15000); + con.setRequestProperty("User-Agent", "Hello Minecraft!"); // Connect to server. - connection.connect(); + con.connect(); // Make sure response code is in the 200 range. - if (connection.getResponseCode() / 100 != 2) - throw new NetException(C.i18n("download.not_200") + " " + connection.getResponseCode()); + if (con.getResponseCode() / 100 != 2) + throw new IOException(C.i18n("download.not_200") + " " + con.getResponseCode()); // Check for valid content length. - int contentLength = connection.getContentLength(); + int contentLength = con.getContentLength(); if (contentLength < 1) - throw new NetException("The content length is invalid."); + throw new IOException("The content length is invalid."); - filePath.getParentFile().mkdirs(); + if (!FileUtils.makeDirectory(filePath.getParentFile())) + throw new IOException("Could not make directory"); + // We use temp file to prevent files from aborting downloading and broken. File tempFile = new File(filePath.getAbsolutePath() + ".hmd"); if (!tempFile.exists()) tempFile.createNewFile(); else if (!tempFile.renameTo(tempFile)) // check file lock - throw new RuntimeException("The temp file is locked, maybe there is an application using the file?"); + throw new IllegalStateException("The temp file is locked, maybe there is an application using the file?"); // Open file and seek to the end of it. file = new RandomAccessFile(tempFile, "rw"); MessageDigest digest = DigestUtils.getSha1Digest(); - stream = connection.getInputStream(); + stream = con.getInputStream(); int lastDownloaded = 0; downloaded = 0; long lastTime = System.currentTimeMillis(); @@ -177,19 +165,21 @@ public class FileDownloadTask extends Task implements PreviousResult, Prev break; } - byte buffer[] = new byte[MAX_BUFFER_SIZE]; + byte buffer[] = new byte[IOUtils.MAX_BUFFER_SIZE]; // Read from server into buffer. int read = stream.read(buffer); if (read == -1) break; - digest.update(buffer, 0, read); + if (expectedHash != null) + digest.update(buffer, 0, read); // Write buffer to file. file.write(buffer, 0, read); downloaded += read; + // Update progress information per second long now = System.currentTimeMillis(); if (ppl != null && (now - lastTime) >= 1000) { ppl.setProgress(this, downloaded, contentLength); @@ -199,6 +189,8 @@ public class FileDownloadTask extends Task implements PreviousResult, Prev } } closeFiles(); + + // Restore temp file to original name. if (aborted) tempFile.delete(); else { @@ -210,15 +202,17 @@ public class FileDownloadTask extends Task implements PreviousResult, Prev break; if (downloaded != contentLength) throw new IllegalStateException("Unexptected file size: " + downloaded + ", expected: " + contentLength); - String hashCode = String.format("%1$040x", new Object[] { new BigInteger(1, digest.digest()) }); + + // Check hash code + String hashCode = String.format("%1$040x", new BigInteger(1, digest.digest())); if (expectedHash != null && !expectedHash.equals(hashCode)) throw new IllegalStateException("Unexpected hash code: " + hashCode + ", expected: " + expectedHash); if (ppl != null) ppl.onProgressProviderDone(this); return; - } catch (Exception e) { - setFailReason(new NetException(C.i18n("download.failed") + " " + url, e)); + } catch (IOException | IllegalStateException e) { + setFailReason(new IOException(C.i18n("download.failed") + " " + url, e)); } finally { closeFiles(); } @@ -227,17 +221,8 @@ public class FileDownloadTask extends Task implements PreviousResult, Prev throw failReason; } - public static void download(String url, String file, DownloadListener dl) throws Throwable { - download(url, new File(file), dl); - } - - public static void download(String url, File file, DownloadListener dl) throws Throwable { - ((Task) new FileDownloadTask(url, file).setProgressProviderListener(dl)).executeTask(); - } - @Override public boolean abort() { - //for (Downloader d : downloaders) d.abort(); shouldContinue = false; aborted = true; return true; @@ -245,7 +230,7 @@ public class FileDownloadTask extends Task implements PreviousResult, Prev @Override public String getInfo() { - return C.i18n("download") + ": " + url; + return C.i18n("download") + ": " + (tag == null ? url : tag); } @Override @@ -253,7 +238,7 @@ public class FileDownloadTask extends Task implements PreviousResult, Prev return filePath; } - ArrayList> al = new ArrayList(); + ArrayList> al = new ArrayList<>(); @Override public Task registerPreviousResult(PreviousResult pr) { diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/HTTPGetTask.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/HTTPGetTask.java similarity index 56% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/HTTPGetTask.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/HTTPGetTask.java index 9fe25a852..343282aad 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/HTTPGetTask.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/HTTPGetTask.java @@ -15,59 +15,63 @@ * 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.tasks.download; +package org.jackhuang.hellominecraft.util.net; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.Proxy; import java.net.URL; -import java.net.URLConnection; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.tasks.TaskInfo; -import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult; +import java.nio.charset.Charset; +import org.jackhuang.hellominecraft.util.C; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.task.comm.PreviousResult; import org.jackhuang.hellominecraft.util.EventHandler; +import org.jackhuang.hellominecraft.util.code.Charsets; +import org.jackhuang.hellominecraft.util.task.Task; /** * * @author huangyuhui */ -public class HTTPGetTask extends TaskInfo implements PreviousResult { +public class HTTPGetTask extends Task implements PreviousResult { - String url, encoding, result; - EventHandler tdtsl = new EventHandler<>(this); + String url, result; + Charset encoding; + EventHandler doneEvent = new EventHandler<>(this); boolean shouldContinue = true; public HTTPGetTask(String url) { - this(null, url); + this(url, Charsets.UTF_8); } - public HTTPGetTask(String info, String url) { - this(info, url, "UTF-8"); - } - - public HTTPGetTask(String info, String url, String encoding) { - super(info); + public HTTPGetTask(String url, Charset encoding) { this.url = url; this.encoding = encoding; } @Override - public void executeTask() throws Exception { + public void executeTask(boolean areDependTasksSucceeded) throws Exception { Exception t = null; - for (int repeat = 0; repeat < 6; repeat++) { - if (repeat > 0) - HMCLog.warn("Failed to download, repeat: " + repeat); + for (int time = 0; time < 6; time++) { + if (time > 0) + HMCLog.warn("Failed to download, repeat times: " + time); try { if (ppl != null) ppl.setProgress(this, -1, 1); - URLConnection conn = new URL(url).openConnection(); - InputStream is = conn.getInputStream(); + HttpURLConnection con = NetUtils.createConnection(new URL(url), Proxy.NO_PROXY); + + InputStream is = con.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buf = new byte[1024]; - int size = conn.getContentLength(), read = 0, len; + byte[] buf = new byte[4096]; + int size = con.getContentLength(), read = 0, len; long lastTime = System.currentTimeMillis(); while ((len = is.read(buf)) != -1) { baos.write(buf, 0, len); read += len; + + // Update progress information per second long now = System.currentTimeMillis(); if (ppl != null && (now - lastTime) >= 1000) { ppl.setProgress(this, read, size); @@ -76,11 +80,11 @@ public class HTTPGetTask extends TaskInfo implements PreviousResult { if (!shouldContinue) return; } - result = baos.toString(); - tdtsl.execute(result); + result = baos.toString(encoding.name()); + doneEvent.execute(result); return; - } catch (Exception ex) { - t = new NetException("Failed to get " + url, ex); + } catch (IOException ex) { + t = new IOException("Failed to get " + url, ex); } } if (t != null) @@ -90,13 +94,12 @@ public class HTTPGetTask extends TaskInfo implements PreviousResult { @Override public boolean abort() { shouldContinue = false; - aborted = true; - return true; + return aborted = true; } @Override public String getInfo() { - return super.getInfo() != null ? super.getInfo() : "Get: " + url; + return C.i18n("download") + ": " + (tag == null ? url : tag); } @Override diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/NetUtils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/NetUtils.java similarity index 56% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/NetUtils.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/NetUtils.java index adc12fd31..e146721ea 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/NetUtils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/NetUtils.java @@ -15,66 +15,48 @@ * 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; +package org.jackhuang.hellominecraft.util.net; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import java.io.ByteArrayOutputStream; +import org.jackhuang.hellominecraft.util.log.HMCLog; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.Proxy; import java.net.URL; import java.util.Map; -import org.jackhuang.hellominecraft.util.system.IOUtils; +import org.jackhuang.hellominecraft.util.code.Charsets; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * - * @author huang + * @author huangyuhui */ public final class NetUtils { - public static byte[] getBytesFromStream(InputStream is) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - IOUtils.copyStream(is, out); - is.close(); - return out.toByteArray(); + private NetUtils() { } - public static String getStreamContent(InputStream is) throws IOException { - return getStreamContent(is, DEFAULT_CHARSET); - } - - public static String getStreamContent(InputStream is, String encoding) - throws IOException { - if (is == null) - return null; - StringBuilder sb = new StringBuilder(); - try (InputStreamReader br = new InputStreamReader(is, encoding)) { - int len; - char[] buf = new char[16384]; - while ((len = br.read(buf)) != -1) - sb.append(buf, 0, len); - } - return sb.toString(); + public static HttpURLConnection createConnection(URL url, Proxy proxy) throws IOException { + HttpURLConnection con = (HttpURLConnection) url.openConnection(proxy); + con.setDoInput(true); + con.setUseCaches(false); + con.setConnectTimeout(15000); + con.setReadTimeout(15000); + return con; } public static String get(String url, String encoding) throws IOException { - return getStreamContent(new URL(url).openConnection().getInputStream()); + return IOUtils.toString(new URL(url).openConnection().getInputStream()); } public static String get(String url) throws IOException { - return get(url, DEFAULT_CHARSET); - } - - public static String get(URL url) throws IOException { - return get(url, Proxy.NO_PROXY); + return get(url, IOUtils.DEFAULT_CHARSET); } public static String get(URL url, Proxy proxy) throws IOException { - return getStreamContent(url.openConnection(proxy).getInputStream()); + return readData(createConnection(url, proxy)); } public static String post(URL u, Map params) throws IOException { @@ -96,17 +78,13 @@ public final class NetUtils { } public static String post(URL u, String post, String contentType, Proxy proxy) throws IOException { - HttpURLConnection con = (HttpURLConnection) u.openConnection(proxy); + byte[] bytes = post.getBytes(Charsets.UTF_8); + + HttpURLConnection con = createConnection(u, proxy); con.setRequestMethod("POST"); con.setDoOutput(true); - con.setDoInput(true); - con.setUseCaches(false); - con.setConnectTimeout(30000); - con.setReadTimeout(30000); con.setRequestProperty("Content-Type", contentType + "; charset=utf-8"); - byte[] bytes = post.getBytes(DEFAULT_CHARSET); con.setRequestProperty("Content-Length", "" + bytes.length); - con.connect(); OutputStream os = null; try { os = con.getOutputStream(); @@ -114,24 +92,25 @@ public final class NetUtils { } finally { IOUtils.closeQuietly(os); } + return readData(con); + } - String result; + private static String readData(HttpURLConnection con) throws IOException { InputStream is = null; try { is = con.getInputStream(); - result = getStreamContent(is); - } catch (IOException ex) { + return IOUtils.toString(is, Charsets.UTF_8); + } catch (IOException e) { IOUtils.closeQuietly(is); is = con.getErrorStream(); - result = getStreamContent(is); + if (is != null) + return IOUtils.toString(is, Charsets.UTF_8); + throw e; + } finally { + IOUtils.closeQuietly(is); } - - con.disconnect(); - return result; } - private static final String DEFAULT_CHARSET = "UTF-8"; - public static URL constantURL(String url) { try { return new URL(url); @@ -140,14 +119,4 @@ public final class NetUtils { return null; } } - - public static URL concatenateURL(URL url, String query) { - try { - if (url.getQuery() != null && url.getQuery().length() > 0) - return new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile() + "&" + query); - return new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile() + "?" + query); - } catch (MalformedURLException ex) { - throw new IllegalArgumentException("Could not concatenate given URL with GET arguments!", ex); - } - } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/WebFrame.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/WebFrame.java similarity index 88% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/WebFrame.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/WebFrame.java index 4ce0e0bfa..402bfba0b 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/WebFrame.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/WebFrame.java @@ -15,13 +15,15 @@ * 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; +package org.jackhuang.hellominecraft.util.net; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JDialog; import org.jackhuang.hellominecraft.util.StrUtils; -import org.jackhuang.hellominecraft.util.logging.Level; +import org.jackhuang.hellominecraft.util.log.Level; +import org.jackhuang.hellominecraft.util.ui.GraphicsUtils; +import org.jackhuang.hellominecraft.util.ui.SwingUtils; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/WebPage.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/WebPage.java similarity index 91% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/WebPage.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/WebPage.java index cdaa71347..5c8db5a97 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/WebPage.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/net/WebPage.java @@ -15,11 +15,12 @@ * 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; +package org.jackhuang.hellominecraft.util.net; import javax.swing.JScrollPane; import javax.swing.event.HyperlinkEvent; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.ui.SwingUtils; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/Compressor.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/CompressingUtils.java similarity index 75% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/Compressor.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/CompressingUtils.java index 9a5a3653a..77e84c312 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/Compressor.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/CompressingUtils.java @@ -15,12 +15,9 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -35,7 +32,10 @@ import org.jackhuang.hellominecraft.util.func.BiFunction; * * @author huangyuhui */ -public class Compressor { +public final class CompressingUtils { + + private CompressingUtils() { + } public static void zip(String sourceDir, String zipFile) throws IOException { zip(new File(sourceDir), new File(zipFile), null); @@ -52,9 +52,7 @@ public class Compressor { * @throws java.io.IOException 压缩失败或无法读取 */ public static void zip(File sourceDir, File zipFile, BiFunction pathNameCallback) throws IOException { - FileOutputStream os = new FileOutputStream(zipFile); - BufferedOutputStream bos = new BufferedOutputStream(os); - try (ZipOutputStream zos = new ZipOutputStream(bos)) { + try (ZipOutputStream zos = new ZipOutputStream(FileUtils.openOutputStream(zipFile))) { String basePath; if (sourceDir.isDirectory()) basePath = sourceDir.getPath(); @@ -65,30 +63,6 @@ public class Compressor { } } - /** - * 功能:把 sourceDir 目录下的所有文件进行 zip 格式的压缩,保存为指定 zip 文件 - * - * @param sourceDir 源文件夹 - * @param zipFile 压缩生成的zip文件路径。 - * @param pathNameCallback callback(pathName, isDirectory) returns your - * modified pathName - * - * @throws java.io.IOException 压缩失败或无法读取 - */ - public static ZipOutputStream zipContinuing(File sourceDir, File zipFile, BiFunction pathNameCallback) throws IOException { - FileOutputStream os = new FileOutputStream(zipFile); - BufferedOutputStream bos = new BufferedOutputStream(os); - try (ZipOutputStream zos = new ZipOutputStream(bos)) { - String basePath; - if (sourceDir.isDirectory()) - basePath = sourceDir.getPath(); - else//直接压缩单个文件时,取父目录 - basePath = sourceDir.getParent(); - zipFile(sourceDir, basePath, zos, pathNameCallback); - return zos; - } - } - /** * 将文件压缩成zip文件 * @@ -125,18 +99,13 @@ public class Compressor { pathName = pathNameCallback.apply(pathName, true); if (pathName == null) continue; - try (InputStream is = new FileInputStream(file)) { - BufferedInputStream bis = new BufferedInputStream(is); + try (InputStream is = FileUtils.openInputStream(file)) { zos.putNextEntry(new ZipEntry(pathName)); - IOUtils.copyStream(bis, zos, buf); + IOUtils.copyStream(is, zos, buf); } } } - public static void unzip(String zipFileName, String extPlace) throws IOException { - unzip(new File(zipFileName), new File(extPlace)); - } - public static void unzip(File zipFileName, File extPlace) throws IOException { unzip(zipFileName, extPlace, null, true); } @@ -154,7 +123,7 @@ public class Compressor { public static void unzip(File zipFileName, File extPlace, Predicate callback, boolean ignoreExistsFile) throws IOException { byte[] buf = new byte[1024]; extPlace.mkdirs(); - try (ZipInputStream zipFile = new ZipInputStream(new FileInputStream(zipFileName))) { + try (ZipInputStream zipFile = new ZipInputStream(FileUtils.openInputStream(zipFileName))) { if (zipFileName.exists()) { String strPath, gbkPath, strtemp; strPath = extPlace.getAbsolutePath(); @@ -183,7 +152,7 @@ public class Compressor { } if (ignoreExistsFile && new File(strtemp).exists()) continue; - try (FileOutputStream fos = new FileOutputStream(strtemp)) { + try (FileOutputStream fos = FileUtils.openOutputStream(new File(strtemp))) { IOUtils.copyStream(zipFile, fos, buf); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/FileUtils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/FileUtils.java similarity index 86% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/FileUtils.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/FileUtils.java index a32dcbdf7..2bedc68f7 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/FileUtils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/FileUtils.java @@ -15,7 +15,7 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; import java.io.File; import java.io.FileFilter; @@ -28,14 +28,21 @@ import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.List; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.NetUtils; +import java.util.Objects; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * * @author huangyuhui */ -public class FileUtils { +public final class FileUtils { + + private FileUtils() { + } + + public static boolean makeDirectory(File directory) { + return directory.isDirectory() || directory.mkdirs(); + } public static void deleteDirectory(File directory) throws IOException { @@ -75,7 +82,8 @@ public class FileUtils { public static void cleanDirectory(File directory) throws IOException { if (!directory.exists()) { - directory.mkdirs(); + if (!FileUtils.makeDirectory(directory)) + throw new IOException("Failed to create directory: " + directory); return; } @@ -118,8 +126,7 @@ public class FileUtils { public static boolean isSymlink(File file) throws IOException { - if (file == null) - throw new NullPointerException("File must not be null"); + Objects.requireNonNull(file, "File must not be null"); if (File.separatorChar == '\\') return false; File fileInCanonicalDir; @@ -140,10 +147,8 @@ public class FileUtils { public static void copyDirectory(File srcDir, File destDir, FileFilter filter) throws IOException { - if (srcDir == null) - throw new NullPointerException("Source must not be null"); - if (destDir == null) - throw new NullPointerException("Destination must not be null"); + Objects.requireNonNull(srcDir, "Source must not be null"); + Objects.requireNonNull(destDir, "Destination must not be null"); if (!srcDir.exists()) throw new FileNotFoundException("Source '" + srcDir + "' does not exist"); if (!srcDir.isDirectory()) @@ -151,11 +156,11 @@ public class FileUtils { if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())) throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same"); - List exclusionList = null; + List exclusionList = null; if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath())) { File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter); if ((srcFiles != null) && (srcFiles.length > 0)) { - exclusionList = new ArrayList(srcFiles.length); + exclusionList = new ArrayList<>(srcFiles.length); for (File srcFile : srcFiles) { File copiedFile = new File(destDir, srcFile.getName()); exclusionList.add(copiedFile.getCanonicalPath()); @@ -173,7 +178,7 @@ public class FileUtils { if (destDir.exists()) { if (!destDir.isDirectory()) throw new IOException("Destination '" + destDir + "' exists but is not a directory"); - } else if ((!destDir.mkdirs()) && (!destDir.isDirectory())) + } else if (!FileUtils.makeDirectory(destDir)) throw new IOException("Destination '" + destDir + "' directory cannot be created"); if (!destDir.canWrite()) @@ -186,17 +191,18 @@ public class FileUtils { else doCopyFile(srcFile, dstFile); } - destDir.setLastModified(srcDir.lastModified()); + if (!destDir.setLastModified(srcDir.lastModified())) + HMCLog.warn("Failed to set last modified date of dir: " + destDir); } public static String read(File file) throws IOException { - return NetUtils.getStreamContent(IOUtils.openInputStream(file)); + return IOUtils.toString(openInputStream(file)); } public static String readQuietly(File file) { try { - return NetUtils.getStreamContent(IOUtils.openInputStream(file)); + return IOUtils.toString(openInputStream(file)); } catch (IOException ex) { HMCLog.err("Failed to read file: " + file, ex); return null; @@ -205,15 +211,7 @@ public class FileUtils { public static String read(File file, String charset) throws IOException { - return NetUtils.getStreamContent(IOUtils.openInputStream(file), charset); - } - - public static String readIgnoreFileNotFound(File file) throws IOException { - try { - return NetUtils.getStreamContent(IOUtils.openInputStream(file)); - } catch (FileNotFoundException ex) { - return ""; - } + return IOUtils.toString(openInputStream(file), charset); } public static void copyFileQuietly(File srcFile, File destFile) { @@ -226,10 +224,8 @@ public class FileUtils { public static void copyFile(File srcFile, File destFile) throws IOException { - if (srcFile == null) - throw new NullPointerException("Source must not be null"); - if (destFile == null) - throw new NullPointerException("Destination must not be null"); + Objects.requireNonNull(srcFile, "Source must not be null"); + Objects.requireNonNull(destFile, "Destination must not be null"); if (!srcFile.exists()) throw new FileNotFoundException("Source '" + srcFile + "' does not exist"); if (srcFile.isDirectory()) @@ -237,11 +233,9 @@ public class FileUtils { if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same"); File parentFile = destFile.getParentFile(); - if ((parentFile != null) - && (!parentFile.mkdirs()) && (!parentFile.isDirectory())) + if (parentFile != null && !FileUtils.makeDirectory(parentFile)) throw new IOException("Destination '" + parentFile + "' directory cannot be created"); - - if ((destFile.exists()) && (!destFile.canWrite())) + if (destFile.exists() && !destFile.canWrite()) throw new IOException("Destination '" + destFile + "' exists but is read-only"); doCopyFile(srcFile, destFile); } @@ -259,14 +253,6 @@ public class FileUtils { return Math.max(lastUnixPos, lastWindowsPos); } - public static int indexOfExtension(String filename) { - if (filename == null) - return -1; - int extensionPos = filename.lastIndexOf(46); - int lastSeparator = indexOfLastSeparator(filename); - return lastSeparator > extensionPos ? -1 : extensionPos; - } - public static String getName(String filename) { if (filename == null) return null; @@ -285,6 +271,14 @@ public class FileUtils { return removeExtension(getName(filename)); } + public static int indexOfExtension(String filename) { + if (filename == null) + return -1; + int extensionPos = filename.lastIndexOf(46); + int lastSeparator = indexOfLastSeparator(filename); + return lastSeparator > extensionPos ? -1 : extensionPos; + } + public static String getExtension(String filename) { if (filename == null) return null; @@ -329,7 +323,6 @@ public class FileUtils { try { out = openOutputStream(file, append); IOUtils.write(data, out, encoding); - out.close(); } finally { IOUtils.closeQuietly(out); } @@ -361,23 +354,23 @@ public class FileUtils { throw new IOException("File '" + file + "' cannot be written to"); } else { File parent = file.getParentFile(); - if ((parent != null) - && (!parent.mkdirs()) && (!parent.isDirectory())) + if (parent != null && !FileUtils.makeDirectory(parent)) throw new IOException("Directory '" + parent + "' could not be created"); - file.createNewFile(); + if (!file.createNewFile()) + throw new IOException("File `" + file + "` cannot be created."); } return new FileOutputStream(file, append); } public static File[] searchSuffix(File dir, String suffix) { - ArrayList al = new ArrayList(); + ArrayList al = new ArrayList<>(); File[] files = dir.listFiles(); if (files == null) return new File[0]; for (File f : files) if (f.getName().endsWith(suffix)) al.add(f); - return al.toArray(new File[0]); + return al.toArray(new File[al.size()]); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/IOUtils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/IOUtils.java similarity index 77% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/IOUtils.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/IOUtils.java index 86f3e7790..5b09c2879 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/IOUtils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/IOUtils.java @@ -15,34 +15,39 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.NetworkInterface; import java.net.SocketException; import java.net.URL; import java.net.UnknownHostException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import org.jackhuang.hellominecraft.util.func.Consumer; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.func.Function; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * * @author huang */ -public class IOUtils { +public final class IOUtils { + + private IOUtils() { + } public static String addSeparator(String path) { if (path == null || path.trim().length() == 0) @@ -74,16 +79,6 @@ public class IOUtils { return t; } - public static String extractLastDirectory(String dir) { - String t = removeLastSeparator(dir); - int i = t.length() - 1; - while (i >= 0 && !isSeparator(dir.charAt(i))) - i--; - if (i < 0) - return t; - return t.substring(i + 1, (t.length() - i) + (i + 1) - 1); - } - public static void findAllFile(File f, Consumer callback) { if (f.isDirectory()) { File[] f1 = f.listFiles(); @@ -103,13 +98,13 @@ public class IOUtils { callback.accept(f1[i].getName()); } } - + public static String getRealPath() { String realPath = IOUtils.class.getClassLoader().getResource("").getFile(); java.io.File file = new java.io.File(realPath); realPath = file.getAbsolutePath(); try { - realPath = java.net.URLDecoder.decode(realPath, "utf-8"); + realPath = java.net.URLDecoder.decode(realPath, DEFAULT_CHARSET); } catch (Exception e) { e.printStackTrace(); } @@ -119,7 +114,7 @@ public class IOUtils { public static boolean isAbsolutePath(String path) { if (path == null) return true; - return path.startsWith("/") || path.indexOf(":") > 0; + return path.startsWith("/") || path.indexOf(':') > 0; } public static String getLocalMAC() { @@ -164,11 +159,6 @@ public class IOUtils { return mac; } - public static String extractFileName(String fileName) { - File file = new File(fileName); - return file.getName(); - } - public static String getJavaDir() { return getJavaDir(System.getProperty("java.home")); } @@ -181,9 +171,16 @@ public class IOUtils { else return path + "java"; } + + public static List readLines(InputStream stream, String charset) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(stream, charset)); + ArrayList ret = new ArrayList<>(); + for (String line; (line = br.readLine()) != null; ret.add(line)); + return ret; + } public static ByteArrayOutputStream readFully(InputStream stream) throws IOException { - byte[] data = new byte[4096]; + byte[] data = new byte[MAX_BUFFER_SIZE]; ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream(); int len; do { @@ -195,6 +192,22 @@ public class IOUtils { return entryBuffer; } + + public static byte[] toByteArray(InputStream stream) throws IOException { + return readFully(stream).toByteArray(); + } + + public static String toString(InputStream is) throws IOException { + return readFully(is).toString(); + } + + public static String toString(InputStream is, String charset) throws IOException { + return readFully(is).toString(charset); + } + + public static String toString(InputStream is, Charset charset) throws IOException { + return readFully(is).toString(charset.name()); + } public static void closeQuietly(Closeable closeable) { try { @@ -205,29 +218,17 @@ public class IOUtils { } public static void write(byte[] data, OutputStream output) - throws IOException { + throws IOException { if (data != null) output.write(data); } public static void write(String data, OutputStream output, String encoding) - throws IOException { + throws IOException { if (data != null) output.write(data.getBytes(encoding)); } - public static FileInputStream openInputStream(File file) - throws IOException { - if (file.exists()) { - if (file.isDirectory()) - throw new IOException("File '" + file + "' exists but is a directory"); - if (!file.canRead()) - throw new IOException("File '" + file + "' cannot be read"); - } else - throw new FileNotFoundException("File '" + file + "' does not exist"); - return new FileInputStream(file); - } - public static String tryGetCanonicalFolderPath(File file) { try { return IOUtils.addSeparator(file.getCanonicalPath()); @@ -266,21 +267,17 @@ public class IOUtils { } public static List readProcessByInputStream(String[] cmd) throws IOException, InterruptedException { - JavaProcess jp = new JavaProcess(cmd, new ProcessBuilder(cmd).start(), null); - ArrayList lines = new ArrayList<>(); - try (BufferedReader br = new BufferedReader(new InputStreamReader(jp.getRawProcess().getInputStream()))) { - jp.getRawProcess().waitFor(); - String line; - while ((line = br.readLine()) != null) - lines.add(line); - } - return lines; + return readProcessImpl(cmd, p -> p.getInputStream()); } public static List readProcessByErrorStream(String[] cmd) throws IOException, InterruptedException { + return readProcessImpl(cmd, p -> p.getErrorStream()); + } + + private static List readProcessImpl(String[] cmd, Function callback) throws IOException, InterruptedException { JavaProcess jp = new JavaProcess(cmd, new ProcessBuilder(cmd).start(), null); ArrayList lines = new ArrayList<>(); - try (BufferedReader br = new BufferedReader(new InputStreamReader(jp.getRawProcess().getErrorStream()))) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(callback.apply(jp.getRawProcess()), Charset.defaultCharset()))) { jp.getRawProcess().waitFor(); String line; while ((line = br.readLine()) != null) @@ -290,7 +287,7 @@ public class IOUtils { } public static void copyStream(InputStream input, OutputStream output) throws IOException { - copyStream(input, output, new byte[1024]); + copyStream(input, output, new byte[MAX_BUFFER_SIZE]); } public static void copyStream(InputStream input, OutputStream output, byte[] buf) throws IOException { @@ -298,4 +295,19 @@ public class IOUtils { while ((length = input.read(buf)) != -1) output.write(buf, 0, length); } + + /** + * Max buffer size downloading. + */ + public static final int MAX_BUFFER_SIZE = 4096; + + public static final String DEFAULT_CHARSET = "UTF-8"; + + public static PrintStream createPrintStream(OutputStream out, Charset charset) { + try { + return new PrintStream(out, false, charset.name()); + } catch (UnsupportedEncodingException ignore) { + return null; + } + } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/Java.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/Java.java similarity index 86% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/Java.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/Java.java index ef91647ec..8a850803a 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/Java.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/Java.java @@ -15,15 +15,17 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * @@ -38,8 +40,8 @@ public class Java { temp.add(new Java("Default", System.getProperty("java.home"))); temp.add(new Java("Custom", null)); if (OS.os() == OS.WINDOWS) - temp.addAll(Java.queryAllJavaHomeInWindowsByReg()); - if (OS.os() == OS.OSX) + temp.addAll(Java.queryAllJavaHomeInWindowsByReg().values()); + else if (OS.os() == OS.OSX) temp.addAll(Java.queryAllJDKInMac()); JAVA = Collections.unmodifiableList(temp); } @@ -114,18 +116,18 @@ public class Java { * WINDOWS * ----------------------------------- */ - public static List queryAllJavaHomeInWindowsByReg() { - List ans = new ArrayList<>(); + public static Map queryAllJavaHomeInWindowsByReg() { + Map ans = new HashMap<>(); try { - queryJava(ans, "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment"); - queryJava(ans, "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit"); + queryJava(ans, "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\"); + queryJava(ans, "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\"); } catch (IOException | InterruptedException ex) { HMCLog.err("Faield to query java", ex); } return ans; } - private static void queryJava(List ans, String location) throws IOException, InterruptedException { + private static void queryJava(Map ans, String location) throws IOException, InterruptedException { for (String java : queryRegSubFolders(location)) { int s = 0; for (char c : java.toCharArray()) @@ -133,9 +135,9 @@ public class Java { ++s; if (s <= 1) continue; - String javahome = queryRegValue(java, "JavaHome"); - if (javahome != null) - ans.add(new Java(java.substring(location.length()), javahome)); + String javahome = queryRegValue(java, "JavaHome"), ver = java.substring(location.length()); + if (javahome != null && !ans.containsKey(ver)) + ans.put(ver, new Java(ver, javahome)); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcess.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/JavaProcess.java similarity index 92% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcess.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/JavaProcess.java index d4b06d847..5f44eeda4 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcess.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/JavaProcess.java @@ -15,7 +15,7 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; import java.util.ArrayList; import java.util.Arrays; @@ -30,10 +30,12 @@ public class JavaProcess { private final List commands; private final Process process; private final ArrayList stdOutLines = new ArrayList<>(); + private final ProcessManager pm; public JavaProcess(List commands, Process process, ProcessManager pm) { this.commands = commands; this.process = process; + this.pm = pm; if (pm != null) pm.registerProcess(this); } @@ -53,6 +55,10 @@ public class JavaProcess { public String getStartupCommand() { return this.process.toString(); } + + public ProcessManager getProcessManager() { + return pm; + } public ArrayList getStdOutLines() { return this.stdOutLines; diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcessMonitor.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/JavaProcessMonitor.java similarity index 91% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcessMonitor.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/JavaProcessMonitor.java index d61a62bef..a5c40eb76 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/JavaProcessMonitor.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/JavaProcessMonitor.java @@ -15,15 +15,15 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; import java.util.Arrays; import java.util.HashSet; import org.jackhuang.hellominecraft.util.CollectionUtils; 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; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.log.Level; /** * @@ -78,9 +78,8 @@ public class JavaProcessMonitor { al.add(a); } - void processThreadStopped(ProcessThread t, boolean forceTermintate) { - al.remove(t); - al.removeAll(CollectionUtils.map(al, t1 -> !t1.isAlive())); + void processThreadStopped(ProcessThread t1, boolean forceTermintate) { + CollectionUtils.removeIf(al, t -> t == t1 || !t.isAlive()); if (al.isEmpty() || forceTermintate) { for (Thread a : al) a.interrupt(); diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/JdkVersion.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/JdkVersion.java similarity index 72% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/JdkVersion.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/JdkVersion.java index 0a5e1c1ba..fe8a7f0f0 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/JdkVersion.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/JdkVersion.java @@ -15,13 +15,13 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; import java.io.File; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.StrUtils; /** @@ -59,9 +59,12 @@ public final class JdkVersion implements Cloneable { if (!(obj instanceof JdkVersion)) return false; JdkVersion b = (JdkVersion) obj; - if (b.location == null || location == null) - return b.location == location; - return new File(b.location).equals(new File(location)); + if (b.location == null && location == null) + return true; + else if (b.location == null || location == null) + return false; + else + return new File(b.location).equals(new File(location)); } @Override @@ -112,15 +115,6 @@ public final class JdkVersion implements Cloneable { */ public static final int JAVA_19 = 6; - private static final String JAVA_VER; - private static final int MAJOR_JAVA_VER; - - static { - JAVA_VER = System.getProperty("java.version"); - // version String should look like "1.4.2_10" - MAJOR_JAVA_VER = parseVersion(JAVA_VER); - } - private static int parseVersion(String javaVersion) { if (StrUtils.isBlank(javaVersion)) return UNKOWN; @@ -136,46 +130,10 @@ public final class JdkVersion implements Cloneable { return a; } - /** - * Return the full Java version string, as returned by - * System.getProperty("java.version"). - * - * @return the full Java version string - * - * @see System#getProperty(String) - */ - public static String getJavaVersion() { - return JAVA_VER; - } - - /** - * Get the major version code. This means we can do things like - * if (getMajorJavaVersion() < JAVA_14). @retu - * - * - * rn a code comparable to the JAVA_XX codes in this class - * - * @return - * - * @see #JAVA_13 - * @see #JAVA_14 - * @see #JAVA_15 - * @see #JAVA_16 - * @see #JAVA_17 - */ - public static int getMajorJavaVersion() { - return MAJOR_JAVA_VER; - } - - public static boolean isJava64Bit() { - String jdkBit = System.getProperty("sun.arch.data.model"); - return jdkBit.contains("64"); - } - private static final Pattern p = Pattern.compile("java version \"[1-9]*\\.[1-9]*\\.[0-9]*(.*?)\""); public static JdkVersion getJavaVersionFromExecutable(String file) throws IOException { - String[] str = new String[] { file, "-version" }; + String[] str = new String[]{file, "-version"}; Platform platform = Platform.BIT_32; String ver = null; try { @@ -194,11 +152,6 @@ public final class JdkVersion implements Cloneable { return new JdkVersion(file, ver, platform); } - public void write(File f) throws IOException { - if (ver != null && getPlatform() != Platform.UNKNOWN) - FileUtils.write(f, ver + "\n" + platform); - } - public boolean isEarlyAccess() { return getVersion() != null && getVersion().endsWith("-ea"); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/OS.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/OS.java similarity index 65% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/OS.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/OS.java index 904f0cf4a..319b43ebf 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/OS.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/OS.java @@ -15,17 +15,18 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; import com.sun.management.OperatingSystemMXBean; import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.lang.management.ManagementFactory; +import java.util.Locale; import java.util.StringTokenizer; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.code.Charsets; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * @author huangyuhui @@ -46,7 +47,7 @@ public enum OS { } public static OS os() { - String str = System.getProperty("os.name").toLowerCase(); + String str = System.getProperty("os.name").toLowerCase(Locale.US); if (str.contains("win")) return OS.WINDOWS; if (str.contains("mac")) @@ -79,33 +80,42 @@ public enum OS { } } + public static int getSuggestedMemorySize() { + long total = getTotalPhysicalMemory(); + if (total == -1) + return 1024; + int memory = (int) (total / 1024 / 1024) / 4; + memory = Math.round((float) memory / 128.0f) * 128; + return memory; + } + public static long[] memoryInfoForLinux() throws IOException { File file = new File("/proc/meminfo"); - BufferedReader br = new BufferedReader(new InputStreamReader( - new FileInputStream(file))); - long[] result = new long[4]; - String str; - StringTokenizer token; - while ((str = br.readLine()) != null) { - token = new StringTokenizer(str); - if (!token.hasMoreTokens()) - continue; + try (BufferedReader br = new BufferedReader(new InputStreamReader(FileUtils.openInputStream(file), Charsets.UTF_8))) { + long[] result = new long[4]; + String str; + StringTokenizer token; + while ((str = br.readLine()) != null) { + token = new StringTokenizer(str); + if (!token.hasMoreTokens()) + continue; - str = token.nextToken(); - if (!token.hasMoreTokens()) - continue; + str = token.nextToken(); + if (!token.hasMoreTokens()) + continue; - if (str.equalsIgnoreCase("MemTotal:")) - result[0] = Long.parseLong(token.nextToken()); - else if (str.equalsIgnoreCase("MemFree:")) - result[1] = Long.parseLong(token.nextToken()); - else if (str.equalsIgnoreCase("SwapTotal:")) - result[2] = Long.parseLong(token.nextToken()); - else if (str.equalsIgnoreCase("SwapFree:")) - result[3] = Long.parseLong(token.nextToken()); + if (str.equalsIgnoreCase("MemTotal:")) + result[0] = Long.parseLong(token.nextToken()); + else if (str.equalsIgnoreCase("MemFree:")) + result[1] = Long.parseLong(token.nextToken()); + else if (str.equalsIgnoreCase("SwapTotal:")) + result[2] = Long.parseLong(token.nextToken()); + else if (str.equalsIgnoreCase("SwapFree:")) + result[3] = Long.parseLong(token.nextToken()); + } + + return result; } - - return result; } public static String getLinuxReleaseVersion() throws IOException { diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/Platform.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/Platform.java similarity index 96% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/Platform.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/Platform.java index c7aabc5bb..7584050fe 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/Platform.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/Platform.java @@ -15,7 +15,7 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ProcessManager.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/ProcessManager.java similarity index 95% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ProcessManager.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/ProcessManager.java index 31dd171dc..70dbb8cf4 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ProcessManager.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/ProcessManager.java @@ -15,7 +15,7 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; import java.util.HashSet; @@ -25,7 +25,7 @@ import java.util.HashSet; */ public class ProcessManager { - private static final HashSet GAME_PROCESSES = new HashSet(); + private static final HashSet GAME_PROCESSES = new HashSet<>(); public void registerProcess(JavaProcess jp) { GAME_PROCESSES.add(jp); diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ProcessThread.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/ProcessThread.java similarity index 61% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ProcessThread.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/ProcessThread.java index c472a5bf7..7e531710e 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ProcessThread.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/ProcessThread.java @@ -15,13 +15,15 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; +import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.EventHandler; +import org.jackhuang.hellominecraft.util.code.Charsets; /** * @@ -45,37 +47,27 @@ public class ProcessThread extends Thread { @Override public void run() { setName("ProcessMonitor"); - InputStreamReader br = null; + BufferedReader br = null; try { 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); - } + br = new BufferedReader(new InputStreamReader(in, Charsets.toCharset())); - int ch; - String line = ""; + String line; while (p.isRunning()) - while ((ch = br.read()) != -1) - if (ch == '\n') { - printlnEvent.execute(line); - System.out.println("Minecraft: " + line); - p.getStdOutLines().add(line); - line = ""; - } else - line += (char) ch; - while ((ch = br.read()) != -1) - if (ch == '\n') { + while ((line = br.readLine()) != null) { printlnEvent.execute(line); System.out.println("Minecraft: " + line); p.getStdOutLines().add(line); - line = ""; - } else - line += (char) ch; + } + while ((line = br.readLine()) != null) { + printlnEvent.execute(line); + System.out.println("Minecraft: " + line); + p.getStdOutLines().add(line); + } + if (p.getProcessManager() != null) + p.getProcessManager().onProcessStopped(p); stopEvent.execute(p); - } catch (Exception e) { + } catch (IOException e) { HMCLog.err("An error occured when reading process stdout/stderr.", e); } finally { IOUtils.closeQuietly(br); diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ZipEngine.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/ZipEngine.java similarity index 79% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ZipEngine.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/ZipEngine.java index aeab0c375..35b30c3a6 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ZipEngine.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/sys/ZipEngine.java @@ -15,14 +15,13 @@ * 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.system; +package org.jackhuang.hellominecraft.util.sys; -import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; +import java.io.Closeable; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashSet; @@ -35,25 +34,21 @@ import org.jackhuang.hellominecraft.util.func.BiFunction; * * @author huangyuhui */ -public class ZipEngine { +public class ZipEngine implements Closeable { byte[] buf = new byte[1024]; ZipOutputStream zos; public ZipEngine(File f) throws IOException { - FileOutputStream os = new FileOutputStream(f); - zos = new ZipOutputStream(new BufferedOutputStream(os)); + zos = new ZipOutputStream(new BufferedOutputStream(FileUtils.openOutputStream(f))); } - public void closeFile() throws IOException { + @Override + public void close() throws IOException { zos.closeEntry(); zos.close(); } - public void putDirectory(String sourceDir) throws IOException { - putDirectory(new File(sourceDir), null); - } - public void putDirectory(File sourceDir) throws IOException { putDirectory(sourceDir, null); } @@ -61,10 +56,9 @@ public class ZipEngine { /** * 功能:把 sourceDir 目录下的所有文件进行 zip 格式的压缩,保存为指定 zip 文件 * - * @param sourceDir 源文件夹 - * @param zipFile 压缩生成的zip文件路径。 + * @param sourceDir 源文件夹 * @param pathNameCallback callback(pathName, isDirectory) returns your - * modified pathName + * modified pathName * * @throws java.io.IOException 压缩失败或无法读取 */ @@ -75,11 +69,11 @@ public class ZipEngine { /** * 将文件压缩成zip文件 * - * @param source zip文件路径 - * @param basePath 待压缩文件根目录 - * @param zos zip文件的os + * @param source zip文件路径 + * @param basePath 待压缩文件根目录 + * @param zos zip文件的os * @param pathNameCallback callback(pathName, isDirectory) returns your - * modified pathName, null if you dont want this file zipped + * modified pathName, null if you dont want this file zipped */ private void putDirectoryImpl(File source, String basePath, BiFunction pathNameCallback) throws IOException { File[] files; @@ -95,7 +89,7 @@ public class ZipEngine { for (File file : files) if (file.isDirectory()) { pathName = file.getPath().substring(basePath.length() + 1) - + "/"; + + "/"; pathName = pathName.replace('\\', '/'); if (pathNameCallback != null) pathName = pathNameCallback.apply(pathName, true); @@ -117,14 +111,14 @@ public class ZipEngine { } public void putFile(File file, String pathName) throws IOException { - putStream(new FileInputStream(file), pathName); + try (FileInputStream fis = FileUtils.openInputStream(file)) { + putStream(fis, pathName); + } } public void putStream(InputStream is, String pathName) throws IOException { - try (BufferedInputStream bis = new BufferedInputStream(is)) { - put(new ZipEntry(pathName)); - IOUtils.copyStream(bis, zos, buf); - } + put(new ZipEntry(pathName)); + IOUtils.copyStream(is, zos, buf); } public void putTextFile(String text, String pathName) throws IOException { diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DeleteFileTask.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/DeleteFileTask.java similarity index 82% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DeleteFileTask.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/DeleteFileTask.java index b9422c766..8a30bde59 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DeleteFileTask.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/DeleteFileTask.java @@ -15,9 +15,10 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; import java.io.File; +import java.io.IOException; /** * @@ -32,8 +33,8 @@ public class DeleteFileTask extends Task { } @Override - public void executeTask() throws Throwable { - f.delete(); + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { + if (!f.delete()) throw new IOException("Failed to delete" + f); } @Override diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DoingDoneListener.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/DoingDoneListener.java similarity index 95% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DoingDoneListener.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/DoingDoneListener.java index 213855d0d..a2fd4adf8 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DoingDoneListener.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/DoingDoneListener.java @@ -15,7 +15,7 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; import java.util.Collection; diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DoubleTask.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/DoubleTask.java similarity index 83% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DoubleTask.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/DoubleTask.java index eb858c9bc..a6ebc5c95 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/DoubleTask.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/DoubleTask.java @@ -15,7 +15,7 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; import java.util.Arrays; import java.util.Collection; @@ -36,6 +36,7 @@ public class DoubleTask extends TaskInfo { super(info); this.a = a; this.b = b; + hidden = true; } @Override @@ -49,7 +50,9 @@ public class DoubleTask extends TaskInfo { } @Override - public void executeTask() throws Throwable { + public void executeTask(boolean areDependTasksSucceeded) throws Throwable { + if (!areDependTasksSucceeded) + throw new IllegalStateException("Depend tasks failed."); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/NoShownTaskException.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/NoShownTaskException.java similarity index 88% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/NoShownTaskException.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/NoShownTaskException.java index 5b3a76fb0..fe3f620a7 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/NoShownTaskException.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/NoShownTaskException.java @@ -15,13 +15,14 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; /** * * @author huangyuhui */ public class NoShownTaskException extends RuntimeException { + private static final long serialVersionUID = 4893571368018439312L; public NoShownTaskException(String msg) { super(msg); diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/ParallelTask.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/ParallelTask.java similarity index 78% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/ParallelTask.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/ParallelTask.java index 15793d200..be9bd8a22 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/ParallelTask.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/ParallelTask.java @@ -15,7 +15,7 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; import java.util.Collection; import java.util.HashSet; @@ -26,10 +26,14 @@ import java.util.HashSet; */ public class ParallelTask extends Task { - Collection dependsTask = new HashSet<>(); + Collection tasks = new HashSet<>(); + + public ParallelTask() { + hidden = true; + } @Override - public void executeTask() { + public void executeTask(boolean areDependTasksSucceeded) { } @Override @@ -39,11 +43,11 @@ public class ParallelTask extends Task { @Override public Collection getDependTasks() { - return dependsTask; + return tasks; } - public void addDependsTask(Task t) { - dependsTask.add(t); + public void addTask(Task t) { + tasks.add(t); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/ProgressProviderListener.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/ProgressProviderListener.java similarity index 95% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/ProgressProviderListener.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/ProgressProviderListener.java index 97a4969b1..af024d88a 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/ProgressProviderListener.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/ProgressProviderListener.java @@ -15,7 +15,7 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/Task.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/Task.java similarity index 66% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/Task.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/Task.java index e700229bd..5836a515e 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/Task.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/Task.java @@ -15,11 +15,9 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; -import java.util.ArrayList; import java.util.Collection; -import org.jackhuang.hellominecraft.util.logging.HMCLog; /** * @@ -29,8 +27,11 @@ public abstract class Task { /** * Run in a new thread(packed in TaskList). + * + * @param areDependTasksSucceeded Would be true if all of tasks which this task depends on have succeed. + * @throws java.lang.Throwable If a task throws an exception, this task will be marked as `failed`. */ - public abstract void executeTask() throws Throwable; + public abstract void executeTask(boolean areDependTasksSucceeded) throws Throwable; /** * if this func returns false, TaskList will force abort the thread. run in @@ -48,43 +49,41 @@ public abstract class Task { public boolean isAborted() { return aborted; } + + protected boolean hidden = false; + + public boolean isHidden() { + return hidden; + } public Throwable getFailReason() { return failReason; } protected Throwable failReason = null; + /** + * This method can be only invoked by TaskList. + * @param s what the `executeTask` throws. + */ protected void setFailReason(Throwable s) { failReason = s; } protected String tag; - protected boolean parallelExecuting; + /** + * For FileDownloadTask: info replacement. + * @return + */ + public String getTag() { + return tag; + } + public Task setTag(String tag) { this.tag = tag; return this; } - public boolean isParallelExecuting() { - return parallelExecuting; - } - - public void setParallelExecuting(boolean parallelExecuting) { - this.parallelExecuting = parallelExecuting; - } - - ArrayList> taskListener = new ArrayList(); - - public Task addTaskListener(DoingDoneListener l) { - taskListener.add(l); - return this; - } - - public ArrayList> getTaskListeners() { - return taskListener; - } - public abstract String getInfo(); public Collection getDependTasks() { @@ -95,8 +94,6 @@ public abstract class Task { return null; } - public boolean areDependTasksSucceeded; - protected ProgressProviderListener ppl; public Task setProgressProviderListener(ProgressProviderListener p) { @@ -104,33 +101,19 @@ public abstract class Task { return this; } - public Task after(Task t) { + public Task with(Task t) { return new DoubleTask(this, t); } - public Task before(Task t) { - return new DoubleTask(t, this); - } - public void runWithException() throws Throwable { Collection c = getDependTasks(); if (c != null) for (Task t : c) t.runWithException(); - executeTask(); + executeTask(true); c = getAfterTasks(); if (c != null) for (Task t : c) t.runWithException(); } - - public boolean run() { - try { - runWithException(); - return true; - } catch (Throwable t) { - HMCLog.err("Failed to execute task", t); - return false; - } - } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskInfo.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskInfo.java similarity index 88% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskInfo.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskInfo.java index 70a88be71..b01a04e25 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskInfo.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskInfo.java @@ -15,7 +15,7 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; /** * @@ -23,15 +23,13 @@ package org.jackhuang.hellominecraft.util.tasks; */ public abstract class TaskInfo extends Task { - String info; - public TaskInfo(String info) { - this.info = info; + this.tag = info; } @Override public String getInfo() { - return info; + return tag; } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskList.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskList.java similarity index 80% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskList.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskList.java index df318b254..f6a64a74c 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskList.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskList.java @@ -15,7 +15,7 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; import java.util.ArrayList; import java.util.Collection; @@ -29,7 +29,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.EventHandler; +import org.jackhuang.hellominecraft.util.log.HMCLog; /** * @@ -38,8 +39,8 @@ import org.jackhuang.hellominecraft.util.logging.HMCLog; public class TaskList extends Thread { List taskQueue = Collections.synchronizedList(new LinkedList<>()); - ArrayList allDone = new ArrayList(); - ArrayList> taskListener = new ArrayList(); + public final EventHandler doneEvent = new EventHandler<>(this); + ArrayList> taskListener = new ArrayList<>(); int totTask; boolean shouldContinue = true; @@ -48,15 +49,6 @@ public class TaskList extends Thread { setDaemon(true); } - public void clean() { - shouldContinue = true; - taskQueue.clear(); - } - - public void addAllDoneListener(Runnable l) { - allDone.add(l); - } - public void addTaskListener(DoingDoneListener l) { taskListener.add(l); } @@ -83,14 +75,17 @@ public class TaskList extends Thread { @Override public void run() { - if (!executeTask(task)) - bool.set(false); - latch.countDown(); + try { + if (!executeTask(task)) + bool.set(false); + } finally { + latch.countDown(); + } } } - ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(64); + ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(8); HashMap> futures = new HashMap<>(); HashSet invokers = new HashSet<>(); @@ -101,9 +96,10 @@ public class TaskList extends Thread { AtomicBoolean bool = new AtomicBoolean(true); CountDownLatch counter = new CountDownLatch(c.size()); for (Task t2 : c) { - if (t2 == null) + if (t2 == null) { + counter.countDown(); continue; - t2.setParallelExecuting(true); + } Invoker thread = new Invoker(t2, counter, bool); invokers.add(thread); if (!EXECUTOR_SERVICE.isShutdown() && !EXECUTOR_SERVICE.isTerminated()) @@ -111,9 +107,10 @@ public class TaskList extends Thread { } try { counter.await(); - } catch (InterruptedException ignore) { + return bool.get(); + } catch (InterruptedException ignore) { // this task is canceled, so failed. + return false; } - return bool.get(); } private boolean executeTask(Task t) { @@ -126,15 +123,13 @@ public class TaskList extends Thread { if (c == null) c = new HashSet<>(); HMCLog.log("Executing task: " + t.getInfo()); - for (DoingDoneListener d : t.getTaskListeners()) - d.onDoing(t, c); for (DoingDoneListener d : taskListener) d.onDoing(t, c); - t.areDependTasksSucceeded = processTasks(c); + boolean areDependTasksSucceeded = processTasks(c); boolean flag = true; try { - t.executeTask(); + t.executeTask(areDependTasksSucceeded); } catch (Throwable e) { t.setFailReason(e); flag = false; @@ -144,8 +139,6 @@ public class TaskList extends Thread { Collection at = t.getAfterTasks(); if (at == null) at = new HashSet<>(); - for (DoingDoneListener d : t.getTaskListeners()) - d.onDone(t, at); for (DoingDoneListener d : taskListener) d.onDone(t, at); processTasks(at); @@ -153,22 +146,21 @@ public class TaskList extends Thread { HMCLog.err("Task failed: " + t.getInfo(), t.getFailReason()); for (DoingDoneListener d : taskListener) d.onFailed(t); - for (DoingDoneListener d : t.getTaskListeners()) - d.onFailed(t); } return flag; } @Override public void run() { - Thread.currentThread().setName("TaskList"); + Thread.currentThread().setName("Task List"); totTask = taskQueue.size(); while (!taskQueue.isEmpty()) executeTask(taskQueue.remove(0)); - if (shouldContinue) - for (Runnable d : allDone) - d.run(); + if (shouldContinue) { + HMCLog.log("Tasks are successfully finished."); + doneEvent.execute(null); + } } public boolean isEmpty() { diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskRunnable.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskRunnable.java similarity index 90% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskRunnable.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskRunnable.java index 000cbacbc..b708f7944 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskRunnable.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskRunnable.java @@ -15,7 +15,7 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; /** * @@ -35,7 +35,7 @@ public class TaskRunnable extends TaskInfo { } @Override - public void executeTask() { + public void executeTask(boolean areDependTasksSucceeded) { r.run(); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskWindow.form b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskWindow.form similarity index 100% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskWindow.form rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskWindow.form diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskWindow.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskWindow.java similarity index 81% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskWindow.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskWindow.java index 83f3c4276..1b3a553f4 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/TaskWindow.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/TaskWindow.java @@ -15,14 +15,15 @@ * 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.tasks; +package org.jackhuang.hellominecraft.util.task; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import javax.swing.SwingUtilities; +import javax.swing.table.TableColumn; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.ui.SwingUtils; @@ -32,16 +33,9 @@ import org.jackhuang.hellominecraft.util.ui.SwingUtils; * @author huangyuhui */ public class TaskWindow extends javax.swing.JDialog - implements ProgressProviderListener, Runnable, DoingDoneListener { + implements ProgressProviderListener, DoingDoneListener { - private static volatile TaskWindow INSTANCE = null; - - private static synchronized TaskWindow instance() { - if (INSTANCE == null) - INSTANCE = new TaskWindow(); - INSTANCE.clean(); - return INSTANCE; - } + private static volatile TaskWindow INST = null; public static TaskWindowFactory factory() { return new TaskWindowFactory(); @@ -49,8 +43,8 @@ public class TaskWindow extends javax.swing.JDialog boolean suc = false; - private TaskList taskList; - private final ArrayList failReasons = new ArrayList(); + private transient TaskList taskList; + private final ArrayList failReasons = new ArrayList<>(); private String stackTrace = null, lastStackTrace = null; /** @@ -59,34 +53,32 @@ public class TaskWindow extends javax.swing.JDialog private TaskWindow() { initComponents(); - setLocationRelativeTo(null); - if (lstDownload.getColumnModel().getColumnCount() > 1) { int i = 35; - lstDownload.getColumnModel().getColumn(1).setMinWidth(i); - lstDownload.getColumnModel().getColumn(1).setMaxWidth(i); - lstDownload.getColumnModel().getColumn(1).setPreferredWidth(i); + TableColumn c = lstDownload.getColumnModel().getColumn(1); + c.setMinWidth(i); + c.setMaxWidth(i); + c.setPreferredWidth(i); } setModal(true); + setLocationRelativeTo(null); } - public TaskWindow addTask(Task task) { - taskList.addTask(task); - return this; - } - - public synchronized void clean() { + private synchronized void clean() { if (isVisible()) return; taskList = new TaskList(); taskList.addTaskListener(this); - taskList.addAllDoneListener(this); + taskList.doneEvent.register(SwingUtils.invokeLater(() -> { + dispose(); + suc = true; + })); } public static String downloadSource = ""; - public boolean start() { + private boolean start() { if (isVisible() || taskList == null || taskList.isAlive()) return false; pgsTotal.setValue(0); @@ -102,7 +94,7 @@ public class TaskWindow extends javax.swing.JDialog HMCLog.err(stackTrace); HMCLog.err("There's the stacktrace of the last invoking."); HMCLog.err(lastStackTrace); - MessageBox.Show(C.i18n("taskwindow.no_more_instance")); + MessageBox.show(C.i18n("taskwindow.no_more_instance")); return false; } setTitle(C.i18n("taskwindow.title") + " - " + C.i18n("download.source") + ": " + downloadSource); @@ -174,7 +166,7 @@ public class TaskWindow extends javax.swing.JDialog }// //GEN-END:initComponents private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed - if (MessageBox.Show(C.i18n("operation.confirm_stop"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) + if (MessageBox.show(C.i18n("operation.confirm_stop"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) this.dispose(); }//GEN-LAST:event_btnCancelActionPerformed @@ -185,13 +177,12 @@ public class TaskWindow extends javax.swing.JDialog if (!this.failReasons.isEmpty()) { String str = StrUtils.parseParams("", failReasons.toArray(), "\n"); - SwingUtilities.invokeLater(() -> MessageBox.Show(str, C.i18n("message.error"), MessageBox.ERROR_MESSAGE)); + SwingUtilities.invokeLater(() -> MessageBox.show(str, C.i18n("message.error"), MessageBox.ERROR_MESSAGE)); failReasons.clear(); } if (!suc) { - if (taskList != null) - SwingUtilities.invokeLater(taskList::abort); + SwingUtilities.invokeLater(taskList::abort); HMCLog.log("Tasks have been canceled by user."); } taskList = null; @@ -223,18 +214,9 @@ public class TaskWindow extends javax.swing.JDialog }); } - @Override - public void run() { - SwingUtilities.invokeLater(() -> { - dispose(); - suc = true; - HMCLog.log("Tasks are finished."); - }); - } - @Override public void onDoing(Task task, Collection taskCollection) { - if (task == null) + if (task == null || task.isHidden()) return; task.setProgressProviderListener(this); @@ -254,8 +236,10 @@ public class TaskWindow extends javax.swing.JDialog @Override public void onDone(Task task, Collection taskCollection) { + if (task == null || task.isHidden()) + return; SwingUtilities.invokeLater(() -> { - if (taskList == null || task == null) + if (taskList == null) return; pgsTotal.setMaximum(taskList.taskCount()); pgsTotal.setValue(pgsTotal.getValue() + 1); @@ -270,8 +254,10 @@ public class TaskWindow extends javax.swing.JDialog @Override public void onFailed(Task task) { + if (task == null || task.isHidden()) + return; SwingUtilities.invokeLater(() -> { - if (taskList == null || task == null) + if (taskList == null) return; String msg = null; if (task.getFailReason() != null && !(task.getFailReason() instanceof NoShownTaskException)) @@ -299,46 +285,43 @@ public class TaskWindow extends javax.swing.JDialog @Override public void setStatus(Task task, String sta) { + if (task == null || task.isHidden()) + return; SwingUtilities.invokeLater(() -> { - if (taskList == null || task == null) + if (taskList == null) return; int idx = tasks.indexOf(task); - if (idx == -1) - return; - SwingUtils.setValueAt(lstDownload, task.getInfo() + ": " + sta, idx, 0); + if (idx != -1) + SwingUtils.setValueAt(lstDownload, task.getInfo() + ": " + sta, idx, 0); }); } - public static boolean execute(Task... ts) { - TaskWindowFactory f = factory(); - for (Task t : ts) - f.append(t); - return f.create(); - } - public static class TaskWindowFactory { LinkedList ll = new LinkedList<>(); - boolean flag; - public TaskWindowFactory append(Task t) { - if (t != null) - ll.add(t); + public TaskWindowFactory append(Task ts) { + if (ts != null) + ll.add(ts); return this; } - public boolean create() { + public boolean execute(Task... ts) { + for (Task t : ts) + append(t); String stacktrace = StrUtils.getStackTrace(new Throwable()); return SwingUtils.invokeAndWait(() -> { - final TaskWindow tw = instance(); - synchronized (tw) { - if (tw.isVisible()) + if (INST == null) + INST = new TaskWindow(); + INST.clean(); + synchronized (INST) { + if (INST.isVisible()) return false; for (Task t : ll) - tw.addTask(t); - tw.lastStackTrace = tw.stackTrace; - tw.stackTrace = stacktrace; - return tw.start(); + INST.taskList.addTask(t); + INST.lastStackTrace = INST.stackTrace; + INST.stackTrace = stacktrace; + return INST.start(); } }); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/communication/PreviousResult.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/comm/PreviousResult.java similarity index 93% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/communication/PreviousResult.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/comm/PreviousResult.java index 4aa1ad85f..9fa6734b4 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/communication/PreviousResult.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/comm/PreviousResult.java @@ -15,7 +15,7 @@ * 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.tasks.communication; +package org.jackhuang.hellominecraft.util.task.comm; /** * diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/communication/PreviousResultRegistrar.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/comm/PreviousResultRegistrar.java similarity index 86% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/communication/PreviousResultRegistrar.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/comm/PreviousResultRegistrar.java index eed6be7ad..1849491f2 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/communication/PreviousResultRegistrar.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/task/comm/PreviousResultRegistrar.java @@ -15,9 +15,9 @@ * 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.tasks.communication; +package org.jackhuang.hellominecraft.util.task.comm; -import org.jackhuang.hellominecraft.util.tasks.Task; +import org.jackhuang.hellominecraft.util.task.Task; /** * @@ -30,7 +30,7 @@ public interface PreviousResultRegistrar { * * @param pr previous task handler * - * @return task self instance + * @return task self instance(factory mode!) */ Task registerPreviousResult(PreviousResult pr); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/DownloadListener.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/DownloadListener.java deleted file mode 100755 index 2d629a730..000000000 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/DownloadListener.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Hello Minecraft!. - * 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.tasks.download; - -import org.jackhuang.hellominecraft.util.tasks.ProgressProviderListener; - -/** - * - * @author huangyuhui - */ -public interface DownloadListener extends ProgressProviderListener { - - boolean OnFailed(); - - void OnFailedMoreThan5Times(String url); -} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/NetException.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/NetException.java deleted file mode 100755 index 5bfb496dc..000000000 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/NetException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Hello Minecraft!. - * 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.tasks.download; - -/** - * - * @author huangyuhui - */ -public class NetException extends RuntimeException { - - public NetException(Exception message) { - super(message); - } - - public NetException(String message) { - super(message); - } - - public NetException(String message, Exception e) { - super(message, e); - } - -} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/AbstractFilter.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/AbstractFilter.java index fe6d04d5f..af41c8145 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/AbstractFilter.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/AbstractFilter.java @@ -24,8 +24,6 @@ import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; -import java.awt.image.Raster; -import java.awt.image.WritableRaster; public abstract class AbstractFilter implements BufferedImageOp { @@ -55,36 +53,4 @@ public abstract class AbstractFilter public RenderingHints getRenderingHints() { return null; } - - protected int[] getPixels(BufferedImage img, int x, int y, int w, int h, int[] pixels) { - if ((w == 0) || (h == 0)) - return new int[0]; - - if (pixels == null) - pixels = new int[w * h]; - else if (pixels.length < w * h) - throw new IllegalArgumentException("pixels array must have a length >= w*h"); - - int imageType = img.getType(); - if ((imageType == 2) || (imageType == 1)) { - Raster raster = img.getRaster(); - return (int[]) (int[]) raster.getDataElements(x, y, w, h, pixels); - } - - return img.getRGB(x, y, w, h, pixels, 0, w); - } - - protected void setPixels(BufferedImage img, int x, int y, int w, int h, int[] pixels) { - if ((pixels == null) || (w == 0) || (h == 0)) - return; - if (pixels.length < w * h) - throw new IllegalArgumentException("pixels array must have a length >= w*h"); - - int imageType = img.getType(); - if ((imageType == 2) || (imageType == 1)) { - WritableRaster raster = img.getRaster(); - raster.setDataElements(x, y, w, h, pixels); - } else - img.setRGB(x, y, w, h, pixels, 0, w); - } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/BasicColors.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/BasicColors.java index b2977af5a..5031117fa 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/BasicColors.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/BasicColors.java @@ -23,8 +23,11 @@ import java.awt.Color; * * @author huangyuhui */ -public class BasicColors { +public final class BasicColors { + private BasicColors() { + } + private static Color getWebColor(String c) { return new Color( Integer.parseInt(c.substring(0, 2), 16), @@ -41,7 +44,7 @@ public class BasicColors { public static final Color COLOR_WHITE_TEXT = new Color(254, 254, 254); public static final Color COLOR_CENTRAL_BACK = new Color(25, 30, 34, 160); - public static final Color bgcolors[] = new Color[] { + public static final Color[] BG_COLORS = new Color[] { COLOR_BLUE, getWebColor("1ABC9C"), getWebColor("9B59B6"), @@ -49,7 +52,8 @@ public class BasicColors { getWebColor("E67E22"), getWebColor("E74C3C") }; - public static final Color bgcolors_darker[] = new Color[] { + + public static final Color[] BG_COLORS_DARKER = new Color[] { COLOR_BLUE_DARKER, getWebColor("16A085"), getWebColor("8E44AD"), diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/DropShadowBorder.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/DropShadowBorder.java index 98de6fd3a..75148c195 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/DropShadowBorder.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/DropShadowBorder.java @@ -37,10 +37,6 @@ public class DropShadowBorder extends AbstractBorder { private Insets insets = null; RenderingHints hints; - public DropShadowBorder(Color color) { - this(color, 3); - } - public DropShadowBorder(Color color, int thickness) { this.thickness = thickness; this.color = color; @@ -68,8 +64,9 @@ public class DropShadowBorder extends AbstractBorder { @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Pair pair = new Pair<>(width, height); - if (CACHE.containsKey(pair)) - g.drawImage(CACHE.get(pair), x, y, width, height, null); + BufferedImage list; + int border = this.thickness * 4; + if (CACHE.containsKey(pair)) list = CACHE.get(pair); else { BufferedImage shadow = new BufferedImage(width, height, 2); @@ -82,7 +79,6 @@ public class DropShadowBorder extends AbstractBorder { g2.fillRect(0, 0, width, height); g2.setComposite(oldComposite); g2.setColor(this.color); - int border = (int) (this.thickness * 4); g2.fillRect(border, border + border / 6, width - border * 2, height - border * 2); g2.dispose(); @@ -91,9 +87,8 @@ public class DropShadowBorder extends AbstractBorder { shadow = blur.filter(shadow, null); shadow = blur.filter(shadow, null); shadow = blur.filter(shadow, null); - - CACHE.put(pair, shadow); - g.drawImage(shadow, x, y, width, height, null); + CACHE.put(pair, list = shadow); } + g.drawImage(list, 0, 0, width, height, null); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/FastBlurFilter.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/FastBlurFilter.java index a69b749d1..93eae016b 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/FastBlurFilter.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/FastBlurFilter.java @@ -42,20 +42,22 @@ public class FastBlurFilter extends AbstractFilter { public BufferedImage filter(BufferedImage src, BufferedImage dst) { int width = src.getWidth(); int height = src.getHeight(); + return filter(src, new int[width * height], dst, new int[width * height]); + } + + public BufferedImage filter(BufferedImage src, int[] srcPixels, BufferedImage dst, int[] dstPixels) { + int width = src.getWidth(); + int height = src.getHeight(); if (dst == null) dst = createCompatibleDestImage(src, null); - int[] srcPixels = new int[width * height]; - int[] dstPixels = new int[width * height]; - - getPixels(src, 0, 0, width, height, srcPixels); + GraphicsUtils.getPixels(src, 0, 0, width, height, srcPixels); blur(srcPixels, dstPixels, width, height, this.radius); - blur(dstPixels, srcPixels, height, width, this.radius); - setPixels(dst, 0, 0, width, height, srcPixels); + GraphicsUtils.setPixels(dst, 0, 0, width, height, srcPixels); return dst; } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/GaussionPanel.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/GaussionPanel.java new file mode 100644 index 000000000..563c4905a --- /dev/null +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/GaussionPanel.java @@ -0,0 +1,90 @@ +/* + * 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.AlphaComposite; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; +import javax.swing.JPanel; + +/** + * This component will allow some area blured to provide better UI. + * @author huangyuhui + */ +public class GaussionPanel extends JPanel { + + private transient BufferedImage aeroBuffer; + private transient Image backgroundImage; + private final List aeroObject = new ArrayList<>(); + private transient Graphics2D aeroGraphics; + private static final int RADIUS = 10; + private transient final StackBlurFilter stackBlurFilter = new StackBlurFilter(RADIUS); + private transient BufferedImage cache = null; + + public void setBackgroundImage(Image backgroundImage) { + this.backgroundImage = backgroundImage; + } + + /** + * The background will be blured under the aero object. + * @param aeroObject just need its bounds, keep it not opaque. + */ + public void addAeroObject(JPanel aeroObject) { + this.aeroObject.add(aeroObject); + cache = null; + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + + if (backgroundImage == null) + return; + + // If we cache the processed background image, the CPU ratio will reduce 5%. + if (cache == null || getWidth() != cache.getWidth() || getHeight() != cache.getHeight()) { + cache = new BufferedImage(getWidth(), getHeight(), 2); + Graphics2D g2 = cache.createGraphics(); + g2.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), null); + for (JPanel panel : aeroObject) { + Rectangle aeroRect = panel.getBounds(); + if (aeroBuffer == null || aeroBuffer.getWidth() != aeroRect.width + RADIUS || aeroBuffer.getHeight() != aeroRect.height + RADIUS) { + if (aeroBuffer != null && aeroGraphics != null) { + aeroBuffer.flush(); + aeroGraphics.dispose(); + } + aeroBuffer = new BufferedImage(aeroRect.width + RADIUS, aeroRect.height + RADIUS, BufferedImage.TRANSLUCENT); + } + + aeroGraphics = aeroBuffer.createGraphics(); + aeroGraphics.setComposite(AlphaComposite.Src); + aeroGraphics.drawImage(backgroundImage, 0, 0, aeroBuffer.getWidth(), aeroBuffer.getHeight(), aeroRect.x, aeroRect.y, aeroRect.x + aeroRect.width, aeroRect.y + aeroRect.height, null); + aeroBuffer = stackBlurFilter.filter(aeroBuffer, null); + g2.drawImage(aeroBuffer, aeroRect.x, aeroRect.y, aeroRect.x + aeroRect.width, aeroRect.y + aeroRect.height, RADIUS / 2, RADIUS / 2, RADIUS / 2 + aeroRect.width, RADIUS / 2 + aeroRect.height, null); + } + g2.dispose(); + } + g.drawImage(cache, 0, 0, getWidth(), getHeight(), null); + } + +} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/GraphicsUtils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/GraphicsUtils.java index f2b328575..6593e56f0 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/GraphicsUtils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/GraphicsUtils.java @@ -6,6 +6,8 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.image.BufferedImage; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; import java.util.Map; import javax.imageio.ImageIO; import javax.swing.plaf.synth.SynthContext; @@ -203,5 +205,81 @@ public class GraphicsUtils extends SynthGraphicsUtils { int aMid = aTop + ((aBot - aTop) * percent / 100); return new Color(rMid, gMid, bMid, aMid); } + + /** + *

Returns an array of pixels, stored as integers, from a + * BufferedImage. The pixels are grabbed from a rectangular + * area defined by a location and two dimensions. Calling this method on + * an image of type different from BufferedImage.TYPE_INT_ARGB + * and BufferedImage.TYPE_INT_RGB will unmanage the image.

+ * + * @param img the source image + * @param x the x location at which to start grabbing pixels + * @param y the y location at which to start grabbing pixels + * @param w the width of the rectangle of pixels to grab + * @param h the height of the rectangle of pixels to grab + * @param pixels a pre-allocated array of pixels of size w*h; can be null + * @return pixels if non-null, a new array of integers + * otherwise + * @throws IllegalArgumentException is pixels is non-null and + * of length < w*h + */ + public static int[] getPixels(BufferedImage img, + int x, int y, int w, int h, int[] pixels) { + if (w == 0 || h == 0) { + return new int[0]; + } + if (pixels == null) { + pixels = new int[w * h]; + } else if (pixels.length < w * h) { + throw new IllegalArgumentException("pixels array must have a length" + + " >= w*h"); + } + + int imageType = img.getType(); + if (imageType == BufferedImage.TYPE_INT_ARGB || + imageType == BufferedImage.TYPE_INT_RGB) { + Raster raster = img.getRaster(); + return (int[]) raster.getDataElements(x, y, w, h, pixels); + } + + // Unmanages the image + return img.getRGB(x, y, w, h, pixels, 0, w); + } + + /** + *

Writes a rectangular area of pixels in the destination + * BufferedImage. Calling this method on + * an image of type different from BufferedImage.TYPE_INT_ARGB + * and BufferedImage.TYPE_INT_RGB will unmanage the image.

+ * + * @param img the destination image + * @param x the x location at which to start storing pixels + * @param y the y location at which to start storing pixels + * @param w the width of the rectangle of pixels to store + * @param h the height of the rectangle of pixels to store + * @param pixels an array of pixels, stored as integers + * @throws IllegalArgumentException is pixels is non-null and + * of length < w*h + */ + public static void setPixels(BufferedImage img, + int x, int y, int w, int h, int[] pixels) { + if (pixels == null || w == 0 || h == 0) { + return; + } else if (pixels.length < w * h) { + throw new IllegalArgumentException("pixels array must have a length" + + " >= w*h"); + } + + int imageType = img.getType(); + if (imageType == BufferedImage.TYPE_INT_ARGB || + imageType == BufferedImage.TYPE_INT_RGB) { + WritableRaster raster = img.getRaster(); + raster.setDataElements(x, y, w, h, pixels); + } else { + // Unmanages the image + img.setRGB(x, y, w, h, pixels, 0, w); + } + } } diff --git a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/ForgeOldInstaller.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/IRepaint.java old mode 100755 new mode 100644 similarity index 54% rename from HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/ForgeOldInstaller.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/IRepaint.java index 8a84e41ba..cb8952729 --- a/HMCL/src/core/java/org/jackhuang/hellominecraft/launcher/core/install/forge/ForgeOldInstaller.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/IRepaint.java @@ -1,7 +1,7 @@ /* * 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 @@ -15,24 +15,34 @@ * 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.install.forge; +package org.jackhuang.hellominecraft.util.ui; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import org.jackhuang.hellominecraft.launcher.core.install.PackMinecraftInstaller; +import java.awt.Rectangle; +import java.awt.Window; +import java.util.Collection; +import javax.swing.JComponent; /** * - * @author huangyuhui + * @author huang */ -public class ForgeOldInstaller { - - public static void install(String destMinecraftJar, String srcMinecraftJar, String forgeUniversal) throws IOException { - ArrayList al = new ArrayList<>(); - al.add(srcMinecraftJar); - al.add(forgeUniversal); - new PackMinecraftInstaller(al, new File(destMinecraftJar)).install(); - } - +public interface IRepaint { + + /** + * addDirtyRegion to? + * @return the component which needs repainting. + */ + JComponent getRepaintComponent(); + + /** + * addDirtyRegion to? + * @return the window which needs repainting. + */ + Window getRepaintWindow(); + + /** + * Repaint the component/window you want. + * @return the region where you want to repaint. + */ + Collection getRepaintRects(); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/JSystemFileChooser.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/JSystemFileChooser.java new file mode 100644 index 000000000..be74b8d71 --- /dev/null +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/JSystemFileChooser.java @@ -0,0 +1,63 @@ +/* + * 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.Color; +import java.io.File; +import javax.swing.JFileChooser; +import javax.swing.LookAndFeel; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +/** + * + * @author huangyuhui + */ +public class JSystemFileChooser extends JFileChooser { + + public JSystemFileChooser() { + super(); + } + + public JSystemFileChooser(File f) { + super(f); + } + + @Override + public void updateUI() { + LookAndFeel old = UIManager.getLookAndFeel(); + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException ignored) { + old = null; + } + + super.updateUI(); + + if (old != null) { + Color background = UIManager.getColor("Label.background"); + setBackground(background); + setOpaque(true); + + try { + UIManager.setLookAndFeel(old); + } catch (UnsupportedLookAndFeelException ignored) { + } + } + } +} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindow.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindow.java index 1377be174..dece70821 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindow.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindow.java @@ -17,15 +17,16 @@ */ package org.jackhuang.hellominecraft.util.ui; +import java.io.PrintStream; +import javax.swing.SwingUtilities; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; -import org.jackhuang.hellominecraft.util.logging.Level; +import org.jackhuang.hellominecraft.util.log.HMCLog; +import org.jackhuang.hellominecraft.util.log.Level; import org.jackhuang.hellominecraft.util.func.NonFunction; import org.jackhuang.hellominecraft.util.DoubleOutputStream; -import org.jackhuang.hellominecraft.util.LauncherPrintStream; import org.jackhuang.hellominecraft.util.Utils; /** @@ -33,7 +34,7 @@ import org.jackhuang.hellominecraft.util.Utils; * @author huangyuhui */ public class LogWindow extends javax.swing.JFrame { - + boolean movingEnd; NonFunction listener; Runnable terminateGameListener; @@ -43,17 +44,20 @@ public class LogWindow extends javax.swing.JFrame { */ public LogWindow() { initComponents(); - + movingEnd = true; - - setLocationRelativeTo(null); - txtLog.setEditable(false); + DoubleOutputStream out = new DoubleOutputStream(new LogWindowOutputStream(this, Level.INFO), System.out); - System.setOut(new LauncherPrintStream(out)); + System.setOut(new PrintStream(out)); DoubleOutputStream err = new DoubleOutputStream(new LogWindowOutputStream(this, Level.ERROR), System.err); - System.setErr(new LauncherPrintStream(err)); + System.setErr(new PrintStream(err)); + + SwingUtilities.invokeLater(() -> { + setLocationRelativeTo(null); + txtLog.setEditable(false); + }); } - + public static final LogWindow INSTANCE = new LogWindow(); /** @@ -202,7 +206,7 @@ public class LogWindow extends javax.swing.JFrame { }//GEN-LAST:event_btnCloseActionPerformed private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearActionPerformed - this.txtLog.setText(""); + clean(); }//GEN-LAST:event_btnClearActionPerformed private void btnCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCopyActionPerformed @@ -235,15 +239,7 @@ public class LogWindow extends javax.swing.JFrame { terminateGameListener.run(); SwingUtils.exitIfNoWindow(this); }//GEN-LAST:event_formWindowClosing - - public void log(String status) { - log(status, Level.INFO); - } - - public void warning(String status) { - log(status, Level.WARN); - } - + public synchronized void log(String status, Level c) { status = status.replace("\t", " "); Document d = txtLog.getStyledDocument(); @@ -254,33 +250,33 @@ public class LogWindow extends javax.swing.JFrame { } catch (Exception ex) { HMCLog.err("Failed to insert \"" + status + "\" to " + d.getLength(), ex); } - + if (movingEnd) { int position = d.getLength(); txtLog.setCaretPosition(position); } } - + public void setExit(NonFunction exit) { this.listener = exit; } - + public void setTerminateGame(Runnable l) { this.terminateGameListener = l; } - + public void clean() { txtLog.setText(""); } - + public boolean getMovingEnd() { return movingEnd; } - + public void setMovingEnd(boolean b) { movingEnd = b; } - + @Override public void setVisible(boolean b) { lblCrash.setVisible(false); @@ -289,7 +285,7 @@ public class LogWindow extends javax.swing.JFrame { btnMCF.setVisible(false); super.setVisible(b); } - + public void showAsCrashWindow(boolean out_date) { if (out_date) { lblCrash.setVisible(false); @@ -304,7 +300,7 @@ public class LogWindow extends javax.swing.JFrame { btnMCF.setVisible(true); lblCrash.setText(C.i18n("ui.label.crashing")); } - + super.setVisible(true); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindowOutputStream.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindowOutputStream.java index a400f150c..387fc1d76 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindowOutputStream.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/LogWindowOutputStream.java @@ -19,9 +19,9 @@ package org.jackhuang.hellominecraft.util.ui; import java.io.OutputStream; import java.util.Objects; -import java.util.Timer; import javax.swing.SwingUtilities; -import org.jackhuang.hellominecraft.util.logging.Level; +import org.jackhuang.hellominecraft.util.code.Charsets; +import org.jackhuang.hellominecraft.util.log.Level; /** * @@ -29,16 +29,12 @@ import org.jackhuang.hellominecraft.util.logging.Level; */ public class LogWindowOutputStream extends OutputStream { - private static final Timer TIMER = new Timer(); - private final LogWindow txt; private final Level sas; public LogWindowOutputStream(LogWindow logWindow, Level l) { - Objects.nonNull(logWindow); - Objects.nonNull(l); - txt = logWindow; - sas = l; + txt = Objects.requireNonNull(logWindow); + sas = Objects.requireNonNull(l); } @Override @@ -48,25 +44,17 @@ public class LogWindowOutputStream extends OutputStream { @Override public final void write(byte[] arr, int off, int len) { - append(new String(arr, off, len)); + append(new String(arr, off, len, Charsets.UTF_8)); } private void append(final String str) { - try { - SwingUtilities.invokeLater(() -> { - txt.log(str, Level.guessLevel(str, sas)); - }); - } catch (Throwable e) { - e.printStackTrace(); - } + SwingUtilities.invokeLater(() -> { + txt.log(str, Level.guessLevel(str, sas)); + }); } @Override public final void write(int i) { - append(new String(new byte[] { (byte) i })); - } - - public static void dispose() { - TIMER.cancel(); + append(new String(new byte[] { (byte) i }, Charsets.UTF_8)); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/MyRepaintManager.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/MyRepaintManager.java new file mode 100644 index 000000000..7a871ec9a --- /dev/null +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/MyRepaintManager.java @@ -0,0 +1,48 @@ +/* + * 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.Container; +import java.awt.Rectangle; +import java.awt.Window; +import javax.swing.JComponent; +import javax.swing.RepaintManager; + +/** + * + * @author huangyuhui + */ +public class MyRepaintManager extends RepaintManager { + + @Override + public void addDirtyRegion(JComponent c, int x, int y, int w, int h) { + super.addDirtyRegion(c, x, y, w, h); + + for (Container parent = c.getParent(); (parent instanceof JComponent || parent instanceof Window) && parent.isVisible(); parent = parent.getParent()) { + if (parent instanceof IRepaint) { + IRepaint d = (IRepaint) parent; + for (Rectangle r : d.getRepaintRects()) { + if (d.getRepaintComponent() != null) + super.addDirtyRegion(d.getRepaintComponent(), r.x, r.y, r.width, r.height); + if (d.getRepaintWindow() != null) + super.addDirtyRegion(d.getRepaintWindow(), r.x, r.y, r.width, r.height); + } + } + } + } +} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/StackBlurFilter.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/StackBlurFilter.java new file mode 100644 index 000000000..4156f6b07 --- /dev/null +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/StackBlurFilter.java @@ -0,0 +1,149 @@ +package org.jackhuang.hellominecraft.util.ui; + +/* + * Copyright (c) 2007, Romain Guy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the TimingFramework project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.awt.image.BufferedImage; + +/** + *

A stack blur filter can be used to create an approximation of a + * gaussian blur. The approximation is controlled by the number of times the + * {@link org.jdesktop.swingx.image.FastBlurFilter} is applied onto the source + * picture. The default number of iterations, 3, provides a decent compromise + * between speed and rendering quality.

+ *

The force of the blur can be controlled with a radius and the + * default radius is 3. Since the blur clamps values on the edges of the + * source picture, you might need to provide a picture with empty borders + * to avoid artifacts at the edges. The performance of this filter are + * independant from the radius.

+ * + * @author Romain Guy +*/ +public class StackBlurFilter extends AbstractFilter { + private final int radius; + private final int iterations; + + /** + *

Creates a new blur filter with a default radius of 3 and 3 iterations.

+ */ + public StackBlurFilter() { + this(3, 3); + } + + /** + *

Creates a new blur filter with the specified radius and 3 iterations. + * If the radius is lower than 1, a radius of 1 will be used automatically.

+ * + * @param radius the radius, in pixels, of the blur + */ + public StackBlurFilter(int radius) { + this(radius, 3); + } + + /** + *

Creates a new blur filter with the specified radius. If the radius + * is lower than 1, a radius of 1 will be used automatically. The number + * of iterations controls the approximation to a gaussian blur. If the + * number of iterations is lower than 1, one iteration will be used + * automatically.

+ * + * @param radius the radius, in pixels, of the blur + * @param iterations the number of iterations to approximate a gaussian blur + */ + public StackBlurFilter(int radius, int iterations) { + if (radius < 1) { + radius = 1; + } + if (iterations < 1) { + iterations = 1; + } + + this.radius = radius; + this.iterations = iterations; + } + + /** + *

Returns the effective radius of the stack blur. If the radius of the + * blur is 1 and the stack iterations count is 3, then the effective blur + * radius is 1 * 3 = 3.

+ * @return the number of iterations times the blur radius + */ + public int getEffectiveRadius() { + return getIterations() * getRadius(); + } + + /** + *

Returns the radius used by this filter, in pixels.

+ * + * @return the radius of the blur + */ + public int getRadius() { + return radius; + } + + /** + *

Returns the number of iterations used to approximate a gaussian + * blur.

+ * + * @return the number of iterations used by this blur + */ + public int getIterations() { + return iterations; + } + + /** + * {@inheritDoc} + */ + @Override + public BufferedImage filter(BufferedImage src, BufferedImage dst) { + int width = src.getWidth(); + int height = src.getHeight(); + + if (dst == null) { + dst = createCompatibleDestImage(src, null); + } + + int[] srcPixels = new int[width * height]; + int[] dstPixels = new int[width * height]; + + GraphicsUtils.getPixels(src, 0, 0, width, height, srcPixels); + for (int i = 0; i < iterations; i++) { + // horizontal pass + FastBlurFilter.blur(srcPixels, dstPixels, width, height, radius); + // vertical pass + FastBlurFilter.blur(dstPixels, srcPixels, height, width, radius); + } + // the result is now stored in srcPixels due to the 2nd pass + GraphicsUtils.setPixels(dst, 0, 0, width, height, srcPixels); + + return dst; + } +} diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/SwingUtils.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/SwingUtils.java index 32587df07..c79196291 100755 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/SwingUtils.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/SwingUtils.java @@ -40,70 +40,71 @@ import javax.swing.JOptionPane; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTable; -import javax.swing.JTextArea; +import javax.swing.SwingUtilities; import javax.swing.table.DefaultTableModel; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.Utils; import org.jackhuang.hellominecraft.util.func.NonFunction; -import org.jackhuang.hellominecraft.util.system.OS; +import org.jackhuang.hellominecraft.util.sys.OS; /** * * @author huang */ -public class SwingUtils { +public final class SwingUtils { + + private SwingUtils() { + } /** * Make DefaultTableModel by overriding getColumnClass and isCellEditable of * DefaultTableModel. * - * @param titleA The title of each column. - * @param typesA The type of each column value. + * @param titleA The title of each column. + * @param typesA The type of each column value. * @param canEditA Is column editable? * * @return */ - public static DefaultTableModel makeDefaultTableModel(String[] titleA, final Class[] typesA, final boolean[] canEditA) { - return new DefaultTableModel( - new Object[][] {}, - titleA) { - Class[] types = typesA; + public static DefaultTableModel makeDefaultTableModel(String[] titleA, final Class[] typesA, final boolean[] canEditA) { + return new DefaultTableModel(new Object[][] {}, titleA) { + Class[] types = typesA; boolean[] canEdit = canEditA; - + @Override - public Class getColumnClass(int columnIndex) { + public Class getColumnClass(int columnIndex) { return types[columnIndex]; } - + @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return canEdit[columnIndex]; } }; } - + public static void openFolder(File f) { f.mkdirs(); String path = f.getAbsolutePath(); switch (OS.os()) { - case OSX: - try { - Runtime.getRuntime().exec(new String[] { "/usr/bin/open", path }); - } catch (IOException ex) { - HMCLog.err("Failed to open " + path + " through /usr/bin/open", ex); - } - break; - default: - try { - java.awt.Desktop.getDesktop().open(f); - } catch (Throwable ex) { - MessageBox.Show(C.i18n("message.cannot_open_explorer") + ex.getMessage()); - HMCLog.warn("Failed to open " + path + " through java.awt.Desktop.getDesktop().open()", ex); - } - break; + case OSX: + try { + Runtime.getRuntime().exec(new String[] { "/usr/bin/open", path }); + } catch (IOException ex) { + HMCLog.err("Failed to open " + path + " through /usr/bin/open", ex); + } + break; + default: + try { + java.awt.Desktop.getDesktop().open(f); + } catch (Throwable ex) { + MessageBox.show(C.i18n("message.cannot_open_explorer") + ex.getMessage()); + HMCLog.warn("Failed to open " + path + " through java.awt.Desktop.getDesktop().open()", ex); + } + break; } } @@ -128,16 +129,6 @@ public class SwingUtils { } } - /** - * Move the cursor to the end of TextArea. - * - * @param tf the TextArea - */ - public static void moveEnd(JTextArea tf) { - int position = tf.getText().length(); - tf.setCaretPosition(position); - } - /** * Move the cursor to the end of ScrollPane. * @@ -155,27 +146,8 @@ public class SwingUtils { * * @return Forcely Type casted to DefaultListModel */ - public static DefaultListModel getDefaultListModel(JList list) { - return (DefaultListModel) list.getModel(); - } - - /** - * Append new element to JList - * - * @param list the JList - * @param element the Element - */ - public static void appendLast(JList list, Object element) { - getDefaultListModel(list).addElement(element); - } - - public static void replaceLast(JList list, Object element) { - DefaultListModel model = getDefaultListModel(list); - model.set(model.getSize() - 1, element); - } - - public static void clear(JList list) { - list.setModel(new DefaultListModel()); + public static DefaultListModel getDefaultListModel(JList list) { + return (DefaultListModel) list.getModel(); } /** @@ -191,17 +163,17 @@ public class SwingUtils { model.removeRow(0); return model; } - + public static void appendLast(JTable table, Object... elements) { DefaultTableModel model = (DefaultTableModel) table.getModel(); model.addRow(elements); } - + public static void setValueAt(JTable table, Object element, int row, int col) { DefaultTableModel model = (DefaultTableModel) table.getModel(); model.setValueAt(element, row, col); } - + public static Object[] getValueBySelectedRow(JTable table, int rows[], int col) { DefaultTableModel model = (DefaultTableModel) table.getModel(); Object[] ret = new Object[rows.length]; @@ -209,12 +181,12 @@ public class SwingUtils { ret[i] = model.getValueAt(rows[i], col); return ret; } - + public static void removeRow(JTable table, int row) { DefaultTableModel model = (DefaultTableModel) table.getModel(); model.removeRow(row); } - + public static String getParsedJPanelText(JLabel jLabel1, String longString) { if (StrUtils.isBlank(longString)) return longString; @@ -236,11 +208,11 @@ public class SwingUtils { } return builder.toString(); } - + private static final Map INVOKE_AND_WAIT_MAP = Collections.synchronizedMap(new HashMap<>()); private static int INVOKE_AND_WAIT_ID = 0; private static final Object INVOKE_AND_WAIT_LOCK = new Object(); - + public static T invokeAndWait(NonFunction x) { int id; synchronized (INVOKE_AND_WAIT_LOCK) { @@ -251,7 +223,7 @@ public class SwingUtils { invokeAndWait(r); return (T) INVOKE_AND_WAIT_MAP.remove(id); } - + public static void invokeAndWait(Runnable r) { if (EventQueue.isDispatchThread()) r.run(); @@ -263,17 +235,18 @@ public class SwingUtils { r.run(); } } - + public static int select(String[] selList, String msg) { + JComboBox box = new JComboBox<>(selList); Object msgs[] = new Object[2]; msgs[0] = msg; - msgs[1] = new JComboBox(selList); + msgs[1] = box; int result = JOptionPane.showOptionDialog(null, msgs, msg, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); if (result == JOptionPane.CANCEL_OPTION) return -1; - return ((JComboBox) msgs[1]).getSelectedIndex(); + return box.getSelectedIndex(); } - + public static void setEnabled(JComponent component, boolean t) { synchronized (component.getTreeLock()) { for (Component c : component.getComponents()) @@ -282,11 +255,11 @@ public class SwingUtils { } component.setEnabled(t); } - + public static void exitIfNoWindow(Window thisFrame) { exitIfNoWindow(thisFrame, false); } - + public static void exitIfNoWindow(Window thisFrame, boolean neededDispose) { boolean flag = false; for (Window f : Window.getWindows()) { @@ -299,17 +272,17 @@ public class SwingUtils { try { Utils.shutdownForcely(0); } catch (Exception e) { - MessageBox.Show(C.i18n("launcher.exit_failed")); + MessageBox.show(C.i18n("launcher.exit_failed")); HMCLog.err("Failed to shutdown forcely", e); } else thisFrame.dispose(); } - + public static ImageIcon scaleImage(ImageIcon i, int x, int y) { return new ImageIcon(i.getImage().getScaledInstance(x, y, Image.SCALE_SMOOTH)); } - + public static ImageIcon searchBackgroundImage(ImageIcon init, String bgpath, int width, int height) { Random r = new Random(); boolean loaded = false; @@ -359,9 +332,15 @@ public class SwingUtils { HMCLog.log("Prepared background image in background.jpg."); } } - + if (background == null) return init; return background; } + + public static Runnable invokeLater(Runnable r) { + return () -> { + SwingUtilities.invokeLater(r); + }; + } } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/ModpackUpdater.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/WideComboBox.java old mode 100755 new mode 100644 similarity index 53% rename from HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/ModpackUpdater.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/WideComboBox.java index fd4160e15..5204aa0ec --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/ModpackUpdater.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/WideComboBox.java @@ -1,7 +1,7 @@ /* * 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 @@ -15,48 +15,38 @@ * 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.util; +package org.jackhuang.hellominecraft.util.ui; -import java.io.File; -import java.util.ArrayList; +import java.awt.Dimension; +import javax.swing.JComboBox; /** - * + * Make the popup menu of combo boxes wider. * @author huangyuhui */ -public class ModpackUpdater { +public class WideComboBox extends JComboBox { - private ModpackInfo info; - - public ModpackUpdater(File baseFolder, ModpackInfo info) { - this.info = info; + public WideComboBox() { } - void update() { + private boolean layingOut = false; + public int customzedMinimumWidth = 300; - } - - public ModpackInfo getInfo() { - return info; - } - - public void setInfo(ModpackInfo info) { - this.info = info; - } - - public static class ModpackInfo { - - ArrayList folders; - ArrayList files; - - public static class ModpackFolder { - - String ext, name; + @Override + public void doLayout() { + try { + layingOut = true; + super.doLayout(); + } finally { + layingOut = false; } + } - public static class ModpackFile { - - String hash, loc; - } + @Override + public Dimension getSize() { + Dimension dim = super.getSize(); + if (!layingOut) + dim.width = Math.max(dim.width, customzedMinimumWidth); + return dim; } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/checktree/CheckBoxTreeCellRenderer.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/checktree/CheckBoxTreeCellRenderer.java index be0bed27f..f82ab5d0f 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/checktree/CheckBoxTreeCellRenderer.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/checktree/CheckBoxTreeCellRenderer.java @@ -27,7 +27,6 @@ import javax.swing.JTree; import javax.swing.UIManager; import javax.swing.plaf.ColorUIResource; import javax.swing.tree.TreeCellRenderer; -import org.jackhuang.hellominecraft.util.Pair; public class CheckBoxTreeCellRenderer extends JPanel implements TreeCellRenderer { diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/checktree/CheckBoxTreeNode.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/checktree/CheckBoxTreeNode.java index b6003fa3c..d231aa402 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/checktree/CheckBoxTreeNode.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/checktree/CheckBoxTreeNode.java @@ -44,7 +44,7 @@ public class CheckBoxTreeNode extends DefaultMutableTreeNode { @Override public String toString() { if (userObject instanceof Pair) - return "" + ((Pair) userObject).key + " - " + ((Pair) userObject).value + ""; + return "" + ((Pair) userObject).key + " - " + ((Pair) userObject).value + ""; else return userObject.toString(); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/WizardDisplayer.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/WizardDisplayer.java index aa9cf0180..dbf770c4d 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/WizardDisplayer.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/WizardDisplayer.java @@ -15,9 +15,9 @@ package org.jackhuang.hellominecraft.util.ui.wizard.api; import java.awt.Container; import java.awt.Rectangle; import java.util.Arrays; -import java.util.HashSet; import java.util.Map; import javax.swing.Action; +import org.jackhuang.hellominecraft.util.ArrayUtils; import org.jackhuang.hellominecraft.util.ui.wizard.api.displayer.WizardDisplayerImpl; import org.jackhuang.hellominecraft.util.ui.wizard.spi.Wizard; @@ -88,7 +88,6 @@ public abstract class WizardDisplayer { protected WizardDisplayer() { } - private static final String SYSPROP_KEY = "WizardDisplayer.default"; /** * Display a wizard in a dialog, using the default implementation of @@ -103,7 +102,7 @@ public abstract class WizardDisplayer { * shown * and entered in the wizard. May be null. */ - public static Object showWizard(Wizard wizard, Rectangle rect, Action help, Map initialProperties) { + public static Object showWizard(Wizard wizard, Rectangle rect, Action help, Map initialProperties) { // assert nonBuggyWizard (wizard); // validate it nonBuggyWizard(wizard); @@ -124,31 +123,6 @@ public abstract class WizardDisplayer { return showWizard(wizard, null, null, null); } - /** - * Show a wizard with default window placement, showing the help button, - * which will invoke the passed action. - * - * @param wizard The wizard to show - * @param help An action to invoke if the user presses the help button - * - * @return The result of Wizard.finish() - */ - public static Object showWizard(Wizard wizard, Action help) { - return showWizard(wizard, null, help, null); - } - - /** - * Show a wizard in the passed location on screen with no help button - * - * @param wizard The wizard to show - * @param r The rectangle on screen for the wizard - * - * @return The result of Wizard.finish() - */ - public static Object showWizard(Wizard wizard, Rectangle r) { - return showWizard(wizard, r, null, null); - } - /** * Show a wizard. * @@ -165,46 +139,19 @@ public abstract class WizardDisplayer { * @return Whatever object the wizard returns from its finish() * method, if the Wizard was completed by the user. */ - protected abstract Object show(Wizard wizard, Rectangle r, Action help, Map initialProperties); - - /** - * Install a panel representing a Wizard in a user-supplied container - * with a user-supplied layout constraint. - * - * @param c The container the wizard panel should be added - * to. May not - * be null. - * @param layoutConstraint The argument to use when adding the wizard's - * ui component to the container. May be null. - * @param helpAction An action that should be invoked when the help - * button - * is clicked (if null, no help button will be displayed) - * @param initialProperties A set of properties that should be pre-set upon - * entering the wizard. May be null. - * @param receiver An object which will be called when the Finish - * or - * Cancel buttons are pressed. May not be null. - */ - public static void installInContainer(Container c, Object layoutConstraint, - Wizard awizard, - Action helpAction, Map initialProperties, - WizardResultReceiver receiver) { - getDefault().install(c, layoutConstraint, awizard, helpAction, - initialProperties, receiver); - } + protected abstract Object show(Wizard wizard, Rectangle r, Action help, Map initialProperties); /** * Instance implementation of installInContainer(). */ protected abstract void install(Container c, Object layoutConstraint, - Wizard awizard, Action helpAction, Map initialProperties, + Wizard awizard, Action helpAction, Map initialProperties, WizardResultReceiver receiver); private static boolean nonBuggyWizard(Wizard wizard) { String[] s = wizard.getAllSteps(); - // assert new HashSet(Arrays.asList(s)).size() == s.length; // for JDK 1.4.2: replace assert with runtime exception - if (new HashSet(Arrays.asList(s)).size() != s.length) + if (ArrayUtils.hasDuplicateElements(s)) throw new RuntimeException("steps are duplicated: " + Arrays.asList(s)); if (s.length == 1 && Wizard.UNDETERMINED_STEP.equals(s[0])) // assert false : "Only ID may not be UNDETERMINED_ID"; diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/NavButtonManager.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/NavButtonManager.java index 94de57f21..30d5d7776 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/NavButtonManager.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/NavButtonManager.java @@ -125,6 +125,7 @@ public class NavButtonManager implements ActionListener { final boolean aqua = "Aqua".equals(UIManager.getLookAndFeel().getID()); buttons = new JPanel() { + @Override public void doLayout() { Insets ins = getInsets(); JButton b = aqua ? finish : cancel; @@ -221,6 +222,7 @@ public class NavButtonManager implements ActionListener { } + @Override public void actionPerformed(ActionEvent event) { JButton button = (JButton) event.getSource(); @@ -590,10 +592,12 @@ public class NavButtonManager implements ActionListener { boolean wasBusy = false; + @Override public void stepsChanged(Wizard wizard) { // do nothing } + @Override public void navigabilityChanged(final Wizard wizard) { final Runnable runnable = () -> { if (wizard.isBusy()) { @@ -618,6 +622,7 @@ public class NavButtonManager implements ActionListener { EventQueue.invokeLater(runnable); } + @Override public void selectionChanged(Wizard wizard) { // do nothing } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/NavProgress.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/NavProgress.java index df44ba0b8..f19defe4d 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/NavProgress.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/NavProgress.java @@ -8,7 +8,7 @@ import javax.swing.JLabel; import javax.swing.JProgressBar; import javax.swing.border.EmptyBorder; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.ui.wizard.spi.ResultProgressHandle; import org.jackhuang.hellominecraft.util.ui.wizard.spi.Summary; @@ -48,6 +48,7 @@ public class NavProgress implements ResultProgressHandle { this.parent = impl; } + @Override public void addProgressComponents(Container panel) { panel.add(lbl); panel.add(progressBar); @@ -55,6 +56,7 @@ public class NavProgress implements ResultProgressHandle { ipanel = panel; } + @Override public void setProgress(final String description, final int currentStep, final int totalSteps) { invoke(() -> { lbl.setText(description == null ? " " : description); @@ -62,6 +64,7 @@ public class NavProgress implements ResultProgressHandle { }); } + @Override public void setProgress(final int currentStep, final int totalSteps) { invoke(() -> { if (totalSteps == -1) { @@ -82,6 +85,7 @@ public class NavProgress implements ResultProgressHandle { }); } + @Override public void setBusy(final String description) { invoke(() -> { lbl.setText(description == null ? " " : description); @@ -101,6 +105,7 @@ public class NavProgress implements ResultProgressHandle { } } + @Override public void finished(final Object o) { isRunning = false; Runnable r = () -> { @@ -118,6 +123,7 @@ public class NavProgress implements ResultProgressHandle { invoke(r); } + @Override public void failed(final String message, final boolean canGoBack) { failMessage = message; isRunning = false; @@ -134,6 +140,7 @@ public class NavProgress implements ResultProgressHandle { invoke(r); } + @Override public boolean isRunning() { return isRunning; } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/WizardDisplayerImpl.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/WizardDisplayerImpl.java index 790f2b1d4..4e908c3eb 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/WizardDisplayerImpl.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/api/displayer/WizardDisplayerImpl.java @@ -50,7 +50,7 @@ import javax.swing.border.Border; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.ui.wizard.api.WizardDisplayer; import org.jackhuang.hellominecraft.util.ui.wizard.api.WizardResultReceiver; import org.jackhuang.hellominecraft.util.ui.wizard.modules.InstructionsPanelImpl; @@ -66,11 +66,10 @@ import org.jackhuang.hellominecraft.util.ui.wizard.spi.WizardPanel; * This class is NOT AN API CLASS. There is no * commitment that it will remain backward compatible or even exist in the * future. The API of this library is in the packages - * org.netbeans.api.wizard - * and org.netbeans.spi.wizard. + * org.netbeans.api.wizard and + * org.netbeans.spi.wizard. *

- * Use - * WizardDisplayer.showWizard() or its other static methods to + * Use WizardDisplayer.showWizard() or its other static methods to * display wizards in a way which will continue to work over time. * * @author stanley@StanleyKnutson.com @@ -122,9 +121,10 @@ public class WizardDisplayerImpl extends WizardDisplayer { protected void buildStepTitle() { ttlLabel = new JLabel(wizard.getStepDescription(wizard.getAllSteps()[0])); ttlLabel.setBorder(BorderFactory.createCompoundBorder(BorderFactory - .createEmptyBorder(5, 5, 12, 5), BorderFactory.createMatteBorder(0, 0, 1, 0, UIManager - .getColor("textText")))); + .createEmptyBorder(5, 5, 12, 5), BorderFactory.createMatteBorder(0, 0, 1, 0, UIManager + .getColor("textText")))); ttlPanel = new JPanel() { + @Override public void doLayout() { Dimension d = ttlLabel.getPreferredSize(); if (ttlLabel.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT) @@ -133,6 +133,7 @@ public class WizardDisplayerImpl extends WizardDisplayer { ttlLabel.setBounds(0, 0, getWidth(), d.height); } + @Override public Dimension getPreferredSize() { return ttlLabel.getPreferredSize(); } @@ -151,9 +152,8 @@ public class WizardDisplayerImpl extends WizardDisplayer { /** * Show a wizard * - * @param awizard is the wizard to be displayed - * @param bounds for display, may be null for default of - * 0,0,400,600. + * @param awizard is the wizard to be displayed + * @param bounds for display, may be null for default of 0,0,400,600. * @param helpAction * @param initialProperties - initial values for the map * @@ -164,7 +164,7 @@ public class WizardDisplayerImpl extends WizardDisplayer { * java.awt.Rectangle, javax.swing.Action, java.util.Map) */ private JPanel createOuterPanel(final Wizard awizard, Rectangle bounds, Action helpAction, - Map initialProperties) { + Map initialProperties) { this.wizard = awizard; @@ -181,6 +181,7 @@ public class WizardDisplayerImpl extends WizardDisplayer { outerPanel.setLayout(new BorderLayout()); Action kbdCancel = new AbstractAction() { + @Override public void actionPerformed(ActionEvent e) { JButton b = buttonManager.getCancel(); if (b.isEnabled()) @@ -188,7 +189,7 @@ public class WizardDisplayerImpl extends WizardDisplayer { } }; outerPanel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW).put( - KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel"); + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel"); outerPanel.getActionMap().put("cancel", kbdCancel); instructions = createInstructionsPanel(); @@ -232,8 +233,9 @@ public class WizardDisplayerImpl extends WizardDisplayer { return new InstructionsPanelImpl(wizard); } + @Override public void install(Container c, Object layoutConstraint, Wizard awizard, - Action helpAction, Map initialProperties, WizardResultReceiver receiver) { + Action helpAction, Map initialProperties, WizardResultReceiver receiver) { JPanel pnl = createOuterPanel(awizard, new Rectangle(), helpAction, initialProperties); if (layoutConstraint != null) if (c instanceof RootPaneContainer) @@ -249,12 +251,13 @@ public class WizardDisplayerImpl extends WizardDisplayer { private static boolean warned; + @Override public Object show(final Wizard awizard, Rectangle bounds, Action helpAction, - Map initialProperties) { + Map initialProperties) { if (!EventQueue.isDispatchThread() && !warned) { HMCLog.warn("WizardDisplayerImpl: show() should be called from the AWT Event Thread. This " - + "call may deadlock - c.f. " - + "http://java.net/jira/browse/WIZARD-33", new Throwable()); + + "call may deadlock - c.f. " + + "http://java.net/jira/browse/WIZARD-33", new Throwable()); warned = true; } createOuterPanel(awizard, bounds, helpAction, initialProperties); @@ -291,25 +294,26 @@ public class WizardDisplayerImpl extends WizardDisplayer { dlg.pack(); dlg.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); dlg.addWindowListener(new WindowAdapter() { + @Override public void windowClosing(WindowEvent e) { - if (!(e.getWindow() instanceof JDialog)) - return; - JDialog dlg = (JDialog) e.getWindow(); - boolean dontClose = false; - if (!wizard.isBusy()) { - DeferredWizardResult defResult; - synchronized (WizardDisplayerImpl.this) { - defResult = deferredResult; - } - try { - if (defResult != null && defResult.canAbort()) - defResult.abort(); - else if (defResult != null && !defResult.canAbort()) - dontClose = true; - } finally { - if (!dontClose && wizard.cancel(settings)) { - dlg.setVisible(false); - dlg.dispose(); + if (e.getWindow() instanceof JDialog) { + JDialog dlg = (JDialog) e.getWindow(); + boolean dontClose = false; + if (!wizard.isBusy()) { + DeferredWizardResult defResult; + synchronized (WizardDisplayerImpl.this) { + defResult = deferredResult; + } + try { + if (defResult != null && defResult.canAbort()) + defResult.abort(); + else if (defResult != null && !defResult.canAbort()) + dontClose = true; + } finally { + if (!dontClose && wizard.cancel(settings)) { + dlg.setVisible(false); + dlg.dispose(); + } } } } @@ -355,13 +359,13 @@ public class WizardDisplayerImpl extends WizardDisplayer { // available in the package only static void checkLegalNavMode(int i) { switch (i) { - case Wizard.MODE_CAN_CONTINUE: - case Wizard.MODE_CAN_CONTINUE_OR_FINISH: - case Wizard.MODE_CAN_FINISH: - return; - default: - throw new IllegalArgumentException("Illegal forward " - + "navigation mode: " + i); + case Wizard.MODE_CAN_CONTINUE: + case Wizard.MODE_CAN_CONTINUE_OR_FINISH: + case Wizard.MODE_CAN_FINISH: + return; + default: + throw new IllegalArgumentException("Illegal forward " + + "navigation mode: " + i); } } @@ -399,7 +403,7 @@ public class WizardDisplayerImpl extends WizardDisplayer { JComponent summaryComp = (JComponent) summary.getSummaryComponent(); // XXX if (summaryComp.getBorder() != null) { CompoundBorder b = new CompoundBorder(new EmptyBorder(5, 5, 5, 5), summaryComp - .getBorder()); + .getBorder()); summaryComp.setBorder(b); } setCurrentWizardPanel((JComponent) summaryComp); // XXX @@ -426,6 +430,7 @@ public class WizardDisplayerImpl extends WizardDisplayer { ((JComponent) inst).revalidate(); inst.repaint(); Runnable run = new Runnable() { + @Override public void run() { if (!EventQueue.isDispatchThread()) try { @@ -433,7 +438,7 @@ public class WizardDisplayerImpl extends WizardDisplayer { r.start(settings, progress); if (progress.isRunning()) progress.failed("Start method did not inidicate " - + "failure or finished in " + r, false); + + "failure or finished in " + r, false); } finally { try { @@ -538,8 +543,8 @@ public class WizardDisplayerImpl extends WizardDisplayer { /** * Will only be called if there is a WizardResultReceiver - i.e. if the - * wizard is being displayed in some kind of custom container. Return - * true to indicate we should not try to close the parent window. + * wizard is being displayed in some kind of custom container. Return true + * to indicate we should not try to close the parent window. */ boolean cancel() { boolean result = receiver != null; @@ -556,10 +561,10 @@ public class WizardDisplayerImpl extends WizardDisplayer { // showing the error line prob = null; Border b = prob == null ? BorderFactory.createEmptyBorder(1, 0, 0, 0) : BorderFactory - .createMatteBorder(1, 0, 0, 0, problem.getForeground()); + .createMatteBorder(1, 0, 0, 0, problem.getForeground()); Border b1 = BorderFactory.createCompoundBorder(BorderFactory - .createEmptyBorder(0, 12, 0, 12), b); + .createEmptyBorder(0, 12, 0, 12), b); problem.setBorder(b1); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/modules/InstructionsPanelImpl.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/modules/InstructionsPanelImpl.java index 2049e4a58..cad6733f5 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/modules/InstructionsPanelImpl.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/modules/InstructionsPanelImpl.java @@ -44,21 +44,21 @@ import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.UIManager; import org.jackhuang.hellominecraft.util.C; -import org.jackhuang.hellominecraft.util.logging.HMCLog; +import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.ui.wizard.api.displayer.InstructionsPanel; import org.jackhuang.hellominecraft.util.ui.wizard.spi.Wizard; import org.jackhuang.hellominecraft.util.ui.wizard.spi.WizardObserver; /** - * A panel that displays a background image and optionally instructions - * from a wizard, tracking the selected panel and showing that in bold. - *

+ * A panel that displays a background image and optionally instructions from a + * wizard, tracking the selected panel and showing that in bold. + *
* This class is NOT AN API CLASS. There is no * commitment that it will remain backward compatible or even exist in the * future. The API of this library is in the packages - * org.netbeans.api.wizard - * and org.netbeans.spi.wizard. - *

+ * org.netbeans.api.wizard and + * org.netbeans.spi.wizard. + *
* There is currently a single use-case for subclassing this - a navigation * panel that wants to display a different image for each step. * @@ -66,8 +66,8 @@ import org.jackhuang.hellominecraft.util.ui.wizard.spi.WizardObserver; */ public class InstructionsPanelImpl extends JComponent implements WizardObserver, Accessible, InstructionsPanel { - private final BufferedImage img; - private final Wizard wizard; + private transient final BufferedImage img; + private transient final Wizard wizard; private static final int MARGIN = 5; public InstructionsPanelImpl(Wizard wiz) { @@ -86,6 +86,7 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, return wizard; } + @Override public final Container getComponent() { return this; } @@ -93,6 +94,7 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, /** * Overridden to start listening to the wizard when added to a container */ + @Override public void addNotify() { super.addNotify(); wizard.addWizardObserver(this); @@ -101,16 +103,16 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, /** * Overridden to stop listening to the wizard when removed from a container */ + @Override public void removeNotify() { wizard.removeWizardObserver(this); super.removeNotify(); } /** - * Get the image to be displayed. Note that unpredictable behavior - * may result if all images returned from this method are not the - * same size. Override to display a different wizard depending on the - * step. + * Get the image to be displayed. Note that unpredictable behavior may + * result if all images returned from this method are not the same size. + * Override to display a different wizard depending on the step. * * @return */ @@ -122,7 +124,7 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, if (img == null) try { img = ImageIO.read(InstructionsPanelImpl.class.getResourceAsStream( - "/org/jackhuang/hellominecraft/wizard.jpg")); + "/org/jackhuang/hellominecraft/wizard.jpg")); } catch (IOException ioe) { HMCLog.err("Failed to load wizard.jpg, maybe you fucking modified the launcher", ioe); } @@ -130,13 +132,14 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, this.wizard = wizard; } + @Override public boolean isOpaque() { return img != null; } /** - * Paints the background image for this component, or fills the - * background with a color if no image present. + * Paints the background image for this component, or fills the background + * with a color if no image present. * * @param g A Graphic2D to paint into * @param x The x coordinate of the area that should contain the image @@ -158,6 +161,7 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, String[] steps = new String[0]; + @Override public final void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); @@ -193,10 +197,10 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, int underlineY = ins.top + MARGIN + fm.getAscent() + 3; g.drawLine(x, underlineY, x + (getWidth() - (x + ins.left + MARGIN)), - underlineY); + underlineY); int bottom = getComponentCount() == 0 ? getHeight() - getInsets().bottom - : getHeight() - getInsets().bottom - getComponents()[0].getPreferredSize().height; + : getHeight() - getInsets().bottom - getComponents()[0].getPreferredSize().height; y += h + 10; int first = 0; @@ -231,7 +235,7 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, for (int i = first; i < stop; i++) { boolean isUndetermined = Wizard.UNDETERMINED_STEP.equals(steps2[i]); boolean canOnlyFinish = wizard.getForwardNavigationMode() - == Wizard.MODE_CAN_FINISH; + == Wizard.MODE_CAN_FINISH; if (isUndetermined && canOnlyFinish) break; String curr; @@ -240,36 +244,35 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, curr = (i + 1) + ". " + steps2[i]; else curr = (i + 1) + ". " + (isUndetermined - ? elipsis - : steps2[i].equals(elipsis) ? elipsis - : wizard.getStepDescription(steps2[i])); + ? elipsis + : steps2[i].equals(elipsis) ? elipsis + : wizard.getStepDescription(steps2[i])); else curr = elipsis; - if (curr != null) { - boolean selected = (steps2[i].equals(currentStep) && !inSummaryPage) - || (inSummaryPage && i == steps2.length - 1); - if (selected) - g.setFont(boldFont); + boolean selected = (steps2[i].equals(currentStep) && !inSummaryPage) + || (inSummaryPage && i == steps2.length - 1); + if (selected) + g.setFont(boldFont); - int width = fm.stringWidth(curr); - while (width > getWidth() - (ins.left + ins.right) && curr.length() > 5) - curr = curr.substring(0, curr.length() - 5) + elipsis; + int width = fm.stringWidth(curr); + while (width > getWidth() - (ins.left + ins.right) && curr.length() > 5) + curr = curr.substring(0, curr.length() - 5) + elipsis; - g.drawString(curr, x, y); - if (selected) - g.setFont(f); - y += h; - } + g.drawString(curr, x, y); + if (selected) + g.setFont(f); + y += h; } } private int historicWidth = Integer.MIN_VALUE; - String elipsis = "..."; + private static final String elipsis = "..."; + @Override public final Dimension getPreferredSize() { Font f = getFont() != null ? getFont() - : UIManager.getFont("controlFont"); + : UIManager.getFont("controlFont"); Graphics g = getGraphics(); if (g == null) @@ -283,10 +286,9 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, int w = Integer.MIN_VALUE; for (int i = 0; i < steps2.length; i++) { String desc = i + ". " + (Wizard.UNDETERMINED_STEP.equals(steps2[i]) - ? elipsis - : wizard.getStepDescription(steps2[i])); - if (desc != null) - w = Math.max(w, fm.stringWidth(desc) + MARGIN); + ? elipsis + : wizard.getStepDescription(steps2[i])); + w = Math.max(w, fm.stringWidth(desc) + MARGIN); } if (Integer.MIN_VALUE == w) w = 250; @@ -301,27 +303,33 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, private boolean inSummaryPage; + @Override public void setInSummaryPage(boolean val) { this.inSummaryPage = val; repaint(); } + @Override public final Dimension getMinimumSize() { return getPreferredSize(); } + @Override public void stepsChanged(Wizard wizard) { repaint(); } + @Override public void navigabilityChanged(Wizard wizard) { //do nothing } + @Override public void selectionChanged(Wizard wizard) { repaint(); } + @Override public final void doLayout() { Component[] c = getComponents(); Insets ins = getInsets(); @@ -337,6 +345,7 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, } } + @Override public final AccessibleContext getAccessibleContext() { return new ACI(this); } @@ -355,6 +364,7 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, JEditorPane pane; + @Override public AccessibleText getAccessibleText() { if (pane == null) { //Cheat just a bit here - will do for now - the text is @@ -382,31 +392,37 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver, return sb.toString(); } + @Override public AccessibleRole getAccessibleRole() { return AccessibleRole.LIST; } + @Override public AccessibleStateSet getAccessibleStateSet() { - AccessibleState[] states = new AccessibleState[] { + AccessibleState[] states = new AccessibleState[]{ AccessibleState.VISIBLE, AccessibleState.OPAQUE, AccessibleState.SHOWING, - AccessibleState.MULTI_LINE, }; + AccessibleState.MULTI_LINE,}; return new AccessibleStateSet(states); } + @Override public int getAccessibleIndexInParent() { return -1; } + @Override public int getAccessibleChildrenCount() { return 0; } + @Override public Accessible getAccessibleChild(int i) { throw new IndexOutOfBoundsException("" + i); } + @Override public Locale getLocale() throws IllegalComponentStateException { return Locale.getDefault(); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/modules/MergeMap.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/modules/MergeMap.java index 31dcf03e4..238fb1145 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/modules/MergeMap.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/modules/MergeMap.java @@ -50,10 +50,10 @@ import java.util.Stack; * * @author Tim Boudreau */ -public class MergeMap implements Map { +public class MergeMap implements Map { - private final Stack order = new Stack(); - private final Map id2map = new HashMap(); + private final Stack order = new Stack<>(); + private final Map> id2map = new HashMap<>(); /** * Creates a new instance of MergeMap @@ -71,7 +71,7 @@ public class MergeMap implements Map { * have a first panel that gathered some settings using the old APIs * framework, and we need to inject them here. */ - public MergeMap(String currId, Map everpresent) { + public MergeMap(String currId, Map everpresent) { order.push(BASE); id2map.put(BASE, everpresent); push(currId); @@ -81,16 +81,16 @@ public class MergeMap implements Map { * Move to a different ID (meaning add a new named map to proxy which can be * calved off if necessary). */ - public Map push(String id) { + public Map push(String id) { // assert !order.contains(id) : id + " already present"; if (order.contains(id)) throw new RuntimeException(id + " already present"); // assert !order.contains(id) : id + " already present"; if (!order.isEmpty() && id.equals(order.peek())) - return (Map) id2map.get(id); - Map result = (Map) id2map.get(id); + return (Map) id2map.get(id); + Map result = (Map) id2map.get(id); if (result == null) { - result = new HashMap(); + result = new HashMap<>(); id2map.put(id, result); } order.push(id); @@ -115,7 +115,7 @@ public class MergeMap implements Map { + "entry"); //Get the current map String result = (String) order.peek(); - Map curr = (Map) id2map.get(result); + Map curr = (Map) id2map.get(result); order.pop(); //Though unlikely, it is possible that a later step in a wizard @@ -124,89 +124,95 @@ public class MergeMap implements Map { //we're removing, and if any of them are in steps lower on the //stack, change those lower steps values to whatever was written //into the map we're calving off - Set keysForCurr = curr.keySet(); - for (Iterator i = orderIterator(); i.hasNext();) { - Map other = (Map) id2map.get(i.next()); - for (Iterator j = curr.keySet().iterator(); j.hasNext();) { - Object key = j.next(); + for (Iterator i = orderIterator(); i.hasNext();) { + Map other = (Map) id2map.get(i.next()); + for (K key : curr.keySet()) if (other.containsKey(key)) other.put(key, curr.get(key)); - } } return result; } + @Override public void clear() { throw new UnsupportedOperationException(); } + @Override public boolean containsKey(Object obj) { - for (Iterator i = orderIterator(); i.hasNext();) { - Map curr = (Map) id2map.get(i.next()); + for (Iterator i = orderIterator(); i.hasNext();) { + Map curr = (Map) id2map.get(i.next()); if (curr.containsKey(obj)) return true; } return false; } + @Override public boolean containsValue(Object obj) { - for (Iterator i = orderIterator(); i.hasNext();) { - Map curr = (Map) id2map.get(i.next()); + for (Iterator i = orderIterator(); i.hasNext();) { + Map curr = (Map) id2map.get(i.next()); if (curr.containsValue(obj)) return true; } return false; } - public java.util.Set entrySet() { - HashSet result = new HashSet(); - for (Iterator i = orderIterator(); i.hasNext();) { - Map curr = (Map) id2map.get(i.next()); + @Override + public java.util.Set> entrySet() { + HashSet> result = new HashSet<>(); + for (Iterator i = orderIterator(); i.hasNext();) { + Map curr = (Map) id2map.get(i.next()); result.addAll(curr.entrySet()); } return result; } - public Object get(Object obj) { - for (Iterator i = orderIterator(); i.hasNext();) { + @Override + public V get(Object obj) { + for (Iterator i = orderIterator(); i.hasNext();) { String id = (String) i.next(); - Map curr = (Map) id2map.get(id); - Object result = curr.get(obj); + Map curr = (Map) id2map.get(id); + V result = curr.get(obj); if (result != null) return result; } return null; } + @Override public boolean isEmpty() { return size() == 0; } - public Set keySet() { - HashSet result = new HashSet(); - for (Iterator i = orderIterator(); i.hasNext();) { - Map curr = (Map) id2map.get(i.next()); + @Override + public Set keySet() { + HashSet result = new HashSet<>(); + for (Iterator i = orderIterator(); i.hasNext();) { + Map curr = (Map) id2map.get(i.next()); result.addAll(curr.keySet()); } return result; } - public Object put(Object obj, Object obj1) { - Map curr = (Map) id2map.get(order.peek()); + @Override + public V put(K obj, V obj1) { + Map curr = (Map) id2map.get(order.peek()); return curr.put(obj, obj1); } - public void putAll(Map map) { - Map curr = (Map) id2map.get(order.peek()); + @Override + public void putAll(Map map) { + Map curr = (Map) id2map.get(order.peek()); curr.putAll(map); } - private Object doRemove(Object obj) { - Map curr = (Map) id2map.get(order.peek()); - Object result = curr.remove(obj); + private V doRemove(Object obj) { + Map curr = (Map) id2map.get(order.peek()); + V result = curr.remove(obj); if (result == null) - for (Iterator i = orderIterator(); i.hasNext();) { - curr = (Map) id2map.get(i.next()); + for (Iterator i = orderIterator(); i.hasNext();) { + curr = (Map) id2map.get(i.next()); result = curr.remove(obj); if (result != null) break; @@ -214,53 +220,59 @@ public class MergeMap implements Map { return result; } - public Object remove(Object obj) { + @Override + public V remove(Object obj) { //Ensure we remove any duplicates in upper arrays - Object result = get(obj); + V result = get(obj); while (get(obj) != null) doRemove(obj); return result; } + @Override public int size() { //using keySet() prunes duplicates return keySet().size(); } - public Collection values() { - HashSet result = new HashSet(); - Set keys = keySet(); - for (Iterator i = keys.iterator(); i.hasNext();) + @Override + public Collection values() { + HashSet result = new HashSet<>(); + Set keys = keySet(); + for (Iterator i = keys.iterator(); i.hasNext();) result.add(get(i.next())); return result; } - private Iterator orderIterator() { + private Iterator orderIterator() { return new ReverseIterator(order); } - private static final class ReverseIterator implements Iterator { + private static final class ReverseIterator implements Iterator { private int pos; - private final List l; + private final List l; - public ReverseIterator(Stack s) { + public ReverseIterator(Stack s) { pos = s.size() - 1; - l = new ArrayList(s); + l = new ArrayList<>(s); } + @Override public boolean hasNext() { return pos != -1; } - public Object next() { + @Override + public String next() { if (pos < 0) throw new NoSuchElementException(); - Object result = l.get(pos); + String result = l.get(pos); pos--; return result; } + @Override public void remove() { throw new UnsupportedOperationException(); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ThreadExecutor.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/AbstractWizard.java old mode 100755 new mode 100644 similarity index 54% rename from HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ThreadExecutor.java rename to HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/AbstractWizard.java index ee76ae85d..809cb5556 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/system/ThreadExecutor.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/AbstractWizard.java @@ -1,7 +1,7 @@ /* - * Hello Minecraft!. + * 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 @@ -15,33 +15,27 @@ * 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.system; +package org.jackhuang.hellominecraft.util.ui.wizard.spi; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import org.jackhuang.hellominecraft.util.func.Consumer; /** * - * @author huangyuhui + * @author huang */ -public class ThreadExecutor extends Thread { +public abstract class AbstractWizard implements WizardImplementation { - public final Consumer c; - public final Runnable r; + protected final List listenerList = Collections.synchronizedList(new LinkedList<>()); + + protected void fireChanged(Consumer r) { + WizardObserver[] listeners = listenerList.toArray(new WizardObserver[listenerList.size()]); - public ThreadExecutor(Consumer c, Runnable r) { - super(); - this.c = c; - this.r = r; - } - - @Override - public void run() { - try { - r.run(); - c.accept(null); - } catch (Throwable t) { - c.accept(t); + for (int i = listeners.length - 1; i >= 0; i--) { + WizardObserver l = (WizardObserver) listeners[i]; + r.accept(l); } } - } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/BranchingWizard.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/BranchingWizard.java index a79607d49..ffeaedd8b 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/BranchingWizard.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/BranchingWizard.java @@ -18,28 +18,23 @@ package org.jackhuang.hellominecraft.util.ui.wizard.spi; import javax.swing.*; import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; import java.util.Map; +import java.util.Objects; /** - * A Wizard with indeterminate branches. The actual branch decision-making - * is done by the WizardBranchController passed to the constructor. + * A Wizard with indeterminate branches. The actual branch decision-making is + * done by the WizardBranchController passed to the constructor. *

* Wizards with arbitrary numbers of branches can be handled by a - * WizardBranchController by returning wizards created by - * another WizardBranchController's createWizard() method. + * WizardBranchController by returning wizards created by another + * WizardBranchController's createWizard() method. *

- * One important point: There should be no duplicate IDs between steps of - * this wizard. + * One important point: There should be no duplicate IDs between steps of this + * wizard. * * @author Tim Boudreau */ -final class BranchingWizard implements WizardImplementation { - - private final List listenerList = Collections.synchronizedList( - new LinkedList()); +final class BranchingWizard extends AbstractWizard { private final WizardBranchController brancher; final WizardImplementation initialSteps; @@ -89,8 +84,8 @@ final class BranchingWizard implements WizardImplementation { private void setSecondary(WizardImplementation newSecondary) { /* johnflournoy added additional condition: secondary != this */ if ((((subsequentSteps == null) != (newSecondary == null)) - || (subsequentSteps != null && !subsequentSteps.equals(newSecondary))) - && !this.equals(newSecondary)) + || (subsequentSteps != null && !subsequentSteps.equals(newSecondary))) + && !this.equals(newSecondary)) /* * johnflournoy: only set the subsequent steps if it @@ -102,6 +97,7 @@ final class BranchingWizard implements WizardImplementation { } } + @Override public int getForwardNavigationMode() { return activeWizard.getForwardNavigationMode(); } @@ -110,8 +106,7 @@ final class BranchingWizard implements WizardImplementation { if (activeWizard == wizard) return; - if (wizard == null) - throw new NullPointerException("Can't set current wizard to null"); + Objects.requireNonNull(wizard, "Can't set current wizard to null"); if ((activeWizard != null) && (wl != null)) activeWizard.removeWizardObserver(wl); @@ -124,10 +119,12 @@ final class BranchingWizard implements WizardImplementation { activeWizard.addWizardObserver(wl); } + @Override public final boolean isBusy() { return activeWizard.isBusy(); } + @Override public final Object finish(Map settings) throws WizardException { try { Object result = activeWizard.finish(settings); @@ -147,6 +144,7 @@ final class BranchingWizard implements WizardImplementation { } } + @Override public final String[] getAllSteps() { String[] result; if (subsequentSteps == null) { @@ -164,10 +162,12 @@ final class BranchingWizard implements WizardImplementation { return result; } + @Override public String getCurrentStep() { return currStep; } + @Override public final String getNextStep() { String result; if (currStep == null) @@ -177,8 +177,8 @@ final class BranchingWizard implements WizardImplementation { int idx = Arrays.asList(steps).indexOf(currStep); if (idx == -1) throw new IllegalStateException("Current step not in" - + " available steps: " + currStep + " not in " - + Arrays.asList(steps)); + + " available steps: " + currStep + " not in " + + Arrays.asList(steps)); else if (idx == steps.length - 1) if (subsequentSteps == null) result = UNDETERMINED_STEP; @@ -199,6 +199,7 @@ final class BranchingWizard implements WizardImplementation { return getProblem() == null ? result : UNDETERMINED_STEP.equals(result) ? result : null; } + @Override public final String getPreviousStep() { if (activeWizard == subsequentSteps && subsequentSteps.getAllSteps()[0].equals(currStep)) return initialSteps.getAllSteps()[initialSteps.getAllSteps().length - 1]; @@ -206,10 +207,12 @@ final class BranchingWizard implements WizardImplementation { return activeWizard.getPreviousStep(); } + @Override public final String getProblem() { return activeWizard.getProblem(); } + @Override public final String getStepDescription(String id) { WizardImplementation w = ownerOf(id); if (w == null) @@ -217,6 +220,7 @@ final class BranchingWizard implements WizardImplementation { return w.getStepDescription(id); } + @Override public final String getLongDescription(String id) { WizardImplementation w = ownerOf(id); if (w == null) @@ -249,76 +253,63 @@ final class BranchingWizard implements WizardImplementation { } } + @Override public final String getTitle() { return activeWizard.getTitle(); } + @Override public final JComponent navigatingTo(String id, Map settings) { - if (id == null) - throw new NullPointerException(); - currStep = id; + currStep = Objects.requireNonNull(id); wizardData = settings; - WizardImplementation impl = ownerOf(id); - if (impl == null) - throw new NullPointerException("No owning WizardImplementation for" - + " id " + id); + WizardImplementation impl = Objects.requireNonNull(ownerOf(id), "No owning WizardImplementation for id " + id); setCurrent(impl); return activeWizard.navigatingTo(id, settings); } + @Override public final void removeWizardObserver(WizardObserver observer) { listenerList.remove(observer); } + @Override public final void addWizardObserver(WizardObserver observer) { listenerList.add(observer); } private void fireStepsChanged() { - WizardObserver[] listeners = (WizardObserver[]) listenerList.toArray(new WizardObserver[0]); - - for (int i = listeners.length - 1; i >= 0; i--) { - WizardObserver l = (WizardObserver) listeners[i]; - l.stepsChanged(null); - } + fireChanged(l -> l.stepsChanged(null)); } private void fireNavigabilityChanged() { checkForSecondary(); - - WizardObserver[] listeners = (WizardObserver[]) listenerList.toArray(new WizardObserver[0]); - - for (int i = listeners.length - 1; i >= 0; i--) { - WizardObserver l = (WizardObserver) listeners[i]; - l.navigabilityChanged(null); - } + fireChanged(l -> l.navigabilityChanged(null)); } private void fireSelectionChanged() { - WizardObserver[] listeners = (WizardObserver[]) listenerList.toArray(new WizardObserver[0]); - - for (int i = listeners.length - 1; i >= 0; i--) { - WizardObserver l = (WizardObserver) listeners[i]; - l.selectionChanged(null); - } + fireChanged(l -> l.selectionChanged(null)); } + @Override public boolean cancel(Map settings) { return activeWizard == null ? true : activeWizard.cancel(settings); } private class WL implements WizardObserver { + @Override public void stepsChanged(Wizard wizard) { fireStepsChanged(); } + @Override public void navigabilityChanged(Wizard wizard) { fireNavigabilityChanged(); } + @Override public void selectionChanged(Wizard wizard) { fireSelectionChanged(); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/GenericListener.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/GenericListener.java index b4f51f85d..171211176 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/GenericListener.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/GenericListener.java @@ -27,7 +27,6 @@ import java.beans.PropertyChangeListener; import java.util.Arrays; import java.util.EventObject; import java.util.HashSet; -import java.util.Iterator; import java.util.Set; import javax.swing.*; import javax.swing.table.*; @@ -71,7 +70,7 @@ final class GenericListener * Set of components that we're listening to models of, so we can look * up the component from the model as needed */ - private final Set listenedTo = new HashSet(); + private final Set listenedTo = new HashSet<>(); private final WizardPage.CustomComponentListener extListener; private final WizardPage.CustomComponentNotifier extNotifier; @@ -150,9 +149,9 @@ final class GenericListener attachToHierarchyOf((Container) jc); else if (jc instanceof JList) { listenedTo.add(jc); - ((JList) jc).addListSelectionListener(this); + ((JList) jc).addListSelectionListener(this); } else if (jc instanceof JComboBox) - ((JComboBox) jc).addActionListener(this); + ((JComboBox) jc).addActionListener(this); else if (jc instanceof JTree) { listenedTo.add(jc); ((JTree) jc).getSelectionModel().addTreeSelectionListener(this); @@ -189,9 +188,9 @@ final class GenericListener if (isProbablyAContainer(jc)) detachFromHierarchyOf((Container) jc); else if (jc instanceof JList) - ((JList) jc).removeListSelectionListener(this); + ((JList) jc).removeListSelectionListener(this); else if (jc instanceof JComboBox) - ((JComboBox) jc).removeActionListener(this); + ((JComboBox) jc).removeActionListener(this); else if (jc instanceof JTree) ((JTree) jc).getSelectionModel().removeTreeSelectionListener(this); else if (jc instanceof JToggleButton) @@ -271,34 +270,28 @@ final class GenericListener wizardPage.userInputReceived((Component) ((EventObject) e).getSource(), e); else if (e instanceof TreeSelectionEvent) { TreeSelectionModel mdl = (TreeSelectionModel) ((TreeSelectionEvent) e).getSource(); - for (Iterator i = listenedTo.iterator(); i.hasNext();) { - Object o = i.next(); + for (Object o : listenedTo) if (o instanceof JTree && ((JTree) o).getSelectionModel() == mdl) { wizardPage.userInputReceived((Component) o, e); break; } - } } else if (e instanceof DocumentEvent) { Document document = ((DocumentEvent) e).getDocument(); - for (Iterator i = listenedTo.iterator(); i.hasNext();) { - Object o = i.next(); + for (Component o : listenedTo) if (o instanceof JTextComponent && ((JTextComponent) o).getDocument() == document) { wizardPage.userInputReceived((Component) o, e); break; } - } } else if (e instanceof ListSelectionEvent) { ListSelectionModel model = (ListSelectionModel) ((ListSelectionEvent) e).getSource(); - for (Iterator i = listenedTo.iterator(); i.hasNext();) { - Object o = i.next(); - if (o instanceof JList && ((JList) o).getSelectionModel() == model) { + for (Object o : listenedTo) + if (o instanceof JList && ((JList) o).getSelectionModel() == model) { wizardPage.userInputReceived((Component) o, e); break; } else if (o instanceof JTable && ((JTable) o).getSelectionModel() == model) { wizardPage.userInputReceived((Component) o, e); break; } - } } else wizardPage.userInputReceived(null, e); } finally { @@ -307,10 +300,12 @@ final class GenericListener } } + @Override public void actionPerformed(ActionEvent e) { fire(e); } + @Override public void propertyChange(PropertyChangeEvent e) { if (e.getSource() instanceof JComponent && "name".equals(e.getPropertyName())) { // Note - most components do NOT fire a property change on @@ -324,10 +319,12 @@ final class GenericListener } } + @Override public void itemStateChanged(ItemEvent e) { fire(e); } + @Override public void componentAdded(ContainerEvent e) { // if (extListener != null && extListener.accept(e.getChild())) { // extListener.startListeningTo(e.getChild(), extNotifier); @@ -337,6 +334,7 @@ final class GenericListener attachTo(e.getChild()); } + @Override public void componentRemoved(ContainerEvent e) { if (extListener != null && extListener.accept(e.getChild())) { extListener.stopListeningTo(e.getChild()); @@ -345,30 +343,37 @@ final class GenericListener detachFrom(e.getChild()); } + @Override public void insertUpdate(DocumentEvent e) { fire(e); } + @Override public void changedUpdate(DocumentEvent e) { fire(e); } + @Override public void removeUpdate(DocumentEvent e) { fire(e); } + @Override public void stateChanged(ChangeEvent e) { fire(e); } + @Override public void valueChanged(ListSelectionEvent e) { fire(e); } + @Override public void valueChanged(TreeSelectionEvent e) { fire(e); } + @Override public void tableChanged(TableModelEvent e) { fire(e); } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/SimpleWizard.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/SimpleWizard.java index e6c0f0379..d71ee6f45 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/SimpleWizard.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/SimpleWizard.java @@ -18,10 +18,7 @@ package org.jackhuang.hellominecraft.util.ui.wizard.spi; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import javax.swing.JComponent; @@ -33,11 +30,9 @@ import javax.swing.JComponent; * @see SimpleWizardInfo * @author Tim Boudreau */ -final class SimpleWizard implements WizardImplementation { +final class SimpleWizard extends AbstractWizard { - private final List listenerList - = Collections.synchronizedList(new LinkedList()); - private final Map ids2panels = new HashMap(); + private final Map ids2panels = new HashMap<>(); final SimpleWizardInfo info; @@ -65,14 +60,17 @@ final class SimpleWizard implements WizardImplementation { info.setWizard(this); } + @Override public void addWizardObserver(WizardObserver observer) { listenerList.add(observer); } + @Override public void removeWizardObserver(WizardObserver observer) { listenerList.remove(observer); } + @Override public int getForwardNavigationMode() { int result = info.getFwdNavMode(); if (!subwizard && ((result & WizardController.MODE_CAN_CONTINUE) != 0) && isLastStep()) @@ -85,6 +83,7 @@ final class SimpleWizard implements WizardImplementation { return currID != null && steps.length > 0 && currID.equals(steps[steps.length - 1]); } + @Override public String[] getAllSteps() { String[] allSteps = info.getSteps(); String[] result = new String[allSteps.length]; @@ -93,6 +92,7 @@ final class SimpleWizard implements WizardImplementation { return result; } + @Override public String getStepDescription(String id) { int idx = Arrays.asList(info.getSteps()).indexOf(id); if (idx == -1) @@ -100,10 +100,12 @@ final class SimpleWizard implements WizardImplementation { return info.getDescriptions()[idx]; } + @Override public String getLongDescription(String id) { return info.getLongDescription(id); } + @Override public JComponent navigatingTo(String id, Map settings) { // assert SwingUtilities.isEventDispatchThread(); @@ -121,10 +123,12 @@ final class SimpleWizard implements WizardImplementation { return result; } + @Override public String getCurrentStep() { return currID; } + @Override public String getNextStep() { if (!info.isValid()) return null; @@ -138,6 +142,7 @@ final class SimpleWizard implements WizardImplementation { return null; } + @Override public String getPreviousStep() { int idx = currentStepIndex(); if (idx < info.getSteps().length && idx > 0) @@ -154,47 +159,44 @@ final class SimpleWizard implements WizardImplementation { } void fireNavigability() { - WizardObserver[] listeners = (WizardObserver[]) listenerList.toArray(new WizardObserver[0]); - - for (int i = listeners.length - 1; i >= 0; i--) { - WizardObserver l = (WizardObserver) listeners[i]; - l.navigabilityChanged(null); - } + fireChanged(l -> l.navigabilityChanged(null)); } private void fireSelectionChanged() { - WizardObserver[] listeners = (WizardObserver[]) listenerList.toArray(new WizardObserver[0]); - - for (int i = listeners.length - 1; i >= 0; i--) { - WizardObserver l = (WizardObserver) listeners[i]; - l.selectionChanged(null); - } + fireChanged(l -> l.selectionChanged(null)); } + @Override public Object finish(Map settings) throws WizardException { return info.finish(settings); } + @Override public boolean cancel(Map settings) { return info.cancel(settings); } + @Override public String getTitle() { return info.getTitle(); } + @Override public String getProblem() { return info.getProblem(); } + @Override public boolean isBusy() { return info.isBusy(); } + @Override public int hashCode() { return info.hashCode() ^ 17; } + @Override public boolean equals(Object o) { if (o instanceof SimpleWizard) return ((SimpleWizard) o).info.equals(info); @@ -202,6 +204,7 @@ final class SimpleWizard implements WizardImplementation { return false; } + @Override public String toString() { return "SimpleWizard for " + info; } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/SimpleWizardInfo.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/SimpleWizardInfo.java index 507e150fa..5ed354cf1 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/SimpleWizardInfo.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/SimpleWizardInfo.java @@ -23,12 +23,15 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.lang.ref.WeakReference; import java.util.Arrays; -import java.util.HashSet; import java.util.Map; +import java.util.Objects; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JScrollPane; import javax.swing.JTextArea; +import org.jackhuang.hellominecraft.util.ArrayUtils; +import org.jackhuang.hellominecraft.util.code.Charsets; +import org.jackhuang.hellominecraft.util.sys.IOUtils; /** * Provides information about a simple wizard. Wraps a @@ -57,13 +60,9 @@ public final class SimpleWizardInfo implements WizardControllerImplementation { * and descriptions. */ protected SimpleWizardInfo(String title, String[] steps, String[] descriptions, WizardPanelProvider provider) { - if (steps == null) - throw new NullPointerException("Null steps"); - if (descriptions == null) - throw new NullPointerException("Null descriptions"); - this.steps = steps; - this.descriptions = descriptions; - if (new HashSet(Arrays.asList(steps)).size() < steps.length) + this.steps = Objects.requireNonNull(steps, "Null steps"); + this.descriptions = Objects.requireNonNull(descriptions, "Null descriptions"); + if (ArrayUtils.hasDuplicateElements(steps)) throw new IllegalArgumentException("Duplicate ID: " + Arrays.asList(steps)); if (descriptions.length != steps.length) if (steps.length != descriptions.length + 1 && !WizardImplementation.UNDETERMINED_STEP.equals(steps[steps.length - 1])) @@ -77,17 +76,13 @@ public final class SimpleWizardInfo implements WizardControllerImplementation { } final void setWizard(SimpleWizard wizard) { - this.wizard = new WeakReference(wizard); + this.wizard = new WeakReference<>(wizard); } final SimpleWizard getWizard() { return wizard != null ? (SimpleWizard) wizard.get() : null; } - final SimpleWizard createWizard() { - return new SimpleWizard(this); - } - //pkg private for unit tests final WizardController controller = new WizardController(this); @@ -117,9 +112,9 @@ public final class SimpleWizardInfo implements WizardControllerImplementation { JTextArea jta = new JTextArea(); jta.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.RED)); ByteArrayOutputStream buf = new ByteArrayOutputStream(); - PrintStream str = new PrintStream(buf); + PrintStream str = IOUtils.createPrintStream(buf, Charsets.UTF_8); re.printStackTrace(str); - jta.setText(new String(buf.toByteArray())); + jta.setText(new String(buf.toByteArray(), Charsets.UTF_8)); setProblem(re.getLocalizedMessage()); return new JScrollPane(jta); } @@ -130,16 +125,6 @@ public final class SimpleWizardInfo implements WizardControllerImplementation { * gathered data. */ protected Object finish(Map settings) throws WizardException { - //XXX fixme -// assert canFinish(); - - // SKNUTSON: the "canFinish" behavior is not working - // instead, panels must implement the WizardPanel interface - // and have allowFinish return false -// if ( ! canFinish()) -// { -// throw new RuntimeException ("Can't finish right now"); -// } return provider.finish(settings); } @@ -176,6 +161,7 @@ public final class SimpleWizardInfo implements WizardControllerImplementation { return a == null ? 0 : a.currentStepIndex(); } + @Override public final void setBusy(boolean value) { if (value != busy) { busy = value; @@ -188,6 +174,7 @@ public final class SimpleWizardInfo implements WizardControllerImplementation { * user-entered information in a panel changes, call this method as * appropriate. */ + @Override public final void setProblem(String value) { this.problem = value; int idx = index(); @@ -215,6 +202,7 @@ public final class SimpleWizardInfo implements WizardControllerImplementation { * * @see setProblem */ + @Override public final void setForwardNavigationMode(int value) { switch (value) { case WizardController.MODE_CAN_CONTINUE: @@ -292,6 +280,7 @@ public final class SimpleWizardInfo implements WizardControllerImplementation { return busy; } + @Override public boolean equals(Object o) { if (o != null && o.getClass() == getClass()) { SimpleWizardInfo info = (SimpleWizardInfo) o; @@ -308,6 +297,7 @@ public final class SimpleWizardInfo implements WizardControllerImplementation { return false; } + @Override public int hashCode() { int result = 0; for (int i = 0; i < steps.length; i++) diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Summary.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Summary.java index 9b31872a5..5e25a7cf8 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Summary.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Summary.java @@ -20,10 +20,13 @@ package org.jackhuang.hellominecraft.util.ui.wizard.spi; import java.awt.Component; import java.awt.Font; +import java.util.Objects; import javax.swing.JList; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.UIManager; +import org.jackhuang.hellominecraft.util.ArrayUtils; +import org.jackhuang.hellominecraft.util.StrUtils; /** * Object which may be returned from @@ -56,9 +59,7 @@ public class Summary { public Summary(String text, Object result) { //XXX this is creating components off the AWT thread - needs to change //to use invokeAndWait where appropriate - if (text == null) - throw new NullPointerException("Text is null"); - if (text.trim().length() == 0) + if (StrUtils.isBlank(text)) throw new IllegalArgumentException("Text is empty or all whitespace"); this.result = result; JTextArea jta = new JTextArea(); @@ -85,12 +86,10 @@ public class Summary { * @return the requested Summary object */ public Summary(String[] items, Object result) { - if (items == null) - throw new NullPointerException("Items array null"); - if (items.length == 0) + if (ArrayUtils.isEmpty(items)) throw new IllegalArgumentException("Items array empty"); this.result = result; - JList list = new JList(items); + JList list = new JList<>(items); comp = new JScrollPane(list); } @@ -108,9 +107,7 @@ public class Summary { */ public Summary(Component comp, Object result) { this.result = result; - this.comp = comp; - if (comp == null) - throw new NullPointerException("Null component"); + this.comp = Objects.requireNonNull(comp, "Null component"); } /** diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Util.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Util.java index bf812ecb1..8c08f6865 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Util.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Util.java @@ -7,7 +7,10 @@ package org.jackhuang.hellominecraft.util.ui.wizard.spi; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.HashSet; +import java.util.Objects; import java.util.Set; /** @@ -25,12 +28,12 @@ final class Util { static String[] getSteps(WizardPage[] pages) { String[] result = new String[pages.length]; - Set uniqueNames = new HashSet(pages.length); + Set uniqueNames = new HashSet<>(pages.length); for (int i = 0; i < pages.length; i++) { result[i] = pages[i].id(); if (result[i] == null || uniqueNames.contains(result[i])) { result[i] = uniquify(getIDFromStaticMethod(pages[i].getClass()), - uniqueNames); + uniqueNames); pages[i].id = result[i]; } uniqueNames.add(result[i]); @@ -38,7 +41,7 @@ final class Util { return result; } - static String uniquify(String s, Set /* */ used) { + static String uniquify(String s, Set used) { String test = s; if (test != null) { int ix = 0; @@ -63,15 +66,13 @@ final class Util { return result; } - static String getIDFromStaticMethod(Class clazz) { + static String getIDFromStaticMethod(Class clazz) { // System.err.println("GetID by method for " + clazz); String result = null; try { - Method m = clazz.getDeclaredMethod("getStep", new Class[] {}); + Method m = clazz.getDeclaredMethod("getStep", new Class[]{}); // assert m.getReturnType() == String.class; - result = (String) m.invoke(clazz, (Object[]) null); - if (result == null) - throw new NullPointerException("getStep may not return null"); + result = Objects.requireNonNull((String) m.invoke(clazz, (Object[]) null), "getStep may not return null"); } catch (Exception ex) { //do nothing } @@ -82,21 +83,18 @@ final class Util { * Get an array of steps by looking for a static method getID() on each * class object passed */ - static String[] getSteps(Class[] pages) { - if (pages == null) - throw new NullPointerException("Null array of classes"); + static String[] getSteps(Class[] pages) { + Objects.requireNonNull(pages, "Null array of classes"); String[] result = new String[pages.length]; - Set used = new HashSet(pages.length); + Set used = new HashSet<>(pages.length); for (int i = 0; i < pages.length; i++) { - if (pages[i] == null) - throw new NullPointerException("Null at " + i + " in array " - + "of panel classes"); + Objects.requireNonNull(pages[i], "Null at " + i + " in array of panel classes"); if (!WizardPage.class.isAssignableFrom(pages[i])) throw new IllegalArgumentException(pages[i] - + " is not a subclass of WizardPage"); + + " is not a subclass of WizardPage"); result[i] = uniquify(getIDFromStaticMethod(pages[i]), used); if (result[i] == null) result[i] = pages[i].getName(); @@ -118,7 +116,7 @@ final class Util { * Get an array of descriptions by looking for the static method * getDescription() on each passed class object */ - static String[] getDescriptions(Class[] pages) { + static String[] getDescriptions(Class[] pages) { String[] result = new String[pages.length]; for (int i = 0; i < pages.length; i++) @@ -127,34 +125,34 @@ final class Util { return result; } - static String getDescriptionFromStaticMethod(Class clazz) { - String result = null; + static String getDescriptionFromStaticMethod(Class clazz) { Method m; try { m = clazz.getDeclaredMethod("getDescription", (Class[]) null); - } catch (Exception e) { + } catch (NoSuchMethodException | SecurityException e) { throw new IllegalArgumentException("Could not find or access " - + "public static String " + clazz.getName() - + ".getDescription() - make sure it exists"); + + "public static String " + clazz.getName() + + ".getDescription() - make sure it exists"); } if (m.getReturnType() != String.class) throw new IllegalArgumentException("getStep has wrong " - + " return type: " + m.getReturnType() + " on " - + clazz); + + " return type: " + m.getReturnType() + " on " + + clazz); if (!Modifier.isStatic(m.getModifiers())) throw new IllegalArgumentException("getStep is not " - + "static on " + clazz); + + "static on " + clazz); - try { - m.setAccessible(true); - result = (String) m.invoke(null, (Object[]) null); - } catch (InvocationTargetException | IllegalAccessException ite) { - throw new IllegalArgumentException("Could not invoke " - + "public static String " + clazz.getName() - + ".getDescription() - make sure it exists.", ite); - } - return result; + return AccessController.doPrivileged((PrivilegedAction) () -> { + try { + m.setAccessible(true); + return (String) m.invoke(null, (Object[]) null); + } catch (InvocationTargetException | IllegalAccessException ite) { + throw new IllegalArgumentException("Could not invoke " + + "public static String " + clazz.getName() + + ".getDescription() - make sure it exists.", ite); + } + }); } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Wizard.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Wizard.java index 7f4e76e8d..d463305f9 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Wizard.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/Wizard.java @@ -10,14 +10,12 @@ enclosed by brackets [] replaced by your own identifying information: "Portions Copyrighted [year] [name of copyright owner]" */ package org.jackhuang.hellominecraft.util.ui.wizard.spi; -import java.awt.Rectangle; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; -import javax.swing.Action; +import java.util.Objects; import javax.swing.JComponent; -import org.jackhuang.hellominecraft.util.ui.wizard.api.WizardDisplayer; /** * Encapsulates the logic and state of a Wizard. A Wizard gathers information @@ -121,9 +119,7 @@ public final class Wizard { * Creates a new instance of Wizard */ Wizard(WizardImplementation impl) { - this.impl = impl; - if (impl == null) - throw new NullPointerException(); + this.impl = Objects.requireNonNull(impl); } /** @@ -285,8 +281,8 @@ public final class Wizard { } private volatile boolean listeningToImpl = false; - private final List listeners = Collections.synchronizedList( - new LinkedList()); + private final List listeners = Collections.synchronizedList( + new LinkedList<>()); private WizardObserver l = null; @@ -321,6 +317,7 @@ public final class Wizard { private class ImplL implements WizardObserver { + @Override public void stepsChanged(Wizard wizard) { WizardObserver[] l = (WizardObserver[]) listeners.toArray( new WizardObserver[listeners.size()]); @@ -328,6 +325,7 @@ public final class Wizard { l1.stepsChanged(Wizard.this); } + @Override public void navigabilityChanged(Wizard wizard) { WizardObserver[] l = (WizardObserver[]) listeners.toArray( new WizardObserver[listeners.size()]); @@ -335,6 +333,7 @@ public final class Wizard { l1.navigabilityChanged(Wizard.this); } + @Override public void selectionChanged(Wizard wizard) { WizardObserver[] l = (WizardObserver[]) listeners.toArray( new WizardObserver[listeners.size()]); @@ -343,10 +342,12 @@ public final class Wizard { } } + @Override public int hashCode() { return impl.hashCode() * 17; } + @Override public boolean equals(Object o) { if (o == this) return true; @@ -356,31 +357,4 @@ public final class Wizard { return false; } - /** - * Delegates to WizardDisplayer.showWizard() - */ - public void show() { - WizardDisplayer.showWizard(this); - } - - /** - * Delegates to WizardDisplayer.showWizard() - */ - public Object show(Wizard wizard, Action help) { - return WizardDisplayer.showWizard(wizard, help); - } - - /** - * Delegates to WizardDisplayer.showWizard() - */ - public Object show(Wizard wizard, Rectangle r) { - return WizardDisplayer.showWizard(wizard, r); - } - - /** - * Delegates to WizardDisplayer.showWizard() - */ - public Object show(Wizard wizard, Rectangle r, Action help) { - return WizardDisplayer.showWizard(wizard, r, help, null); - } } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardBranchController.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardBranchController.java index ebc1598a9..25bb2e010 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardBranchController.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardBranchController.java @@ -16,6 +16,7 @@ enclosed by brackets [] replaced by your own identifying information: package org.jackhuang.hellominecraft.util.ui.wizard.spi; import java.util.Map; +import java.util.Objects; /** * Extend this class to create wizards which have branch points in them - @@ -93,9 +94,7 @@ public abstract class WizardBranchController { * for the initial panes of the wizard. */ WizardBranchController(SimpleWizardInfo base) { - if (base == null) - throw new NullPointerException("No base"); - this.base = base; + this.base = Objects.requireNonNull(base, "No base"); } /** diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardPage.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardPage.java index 7cdd1937f..bd1b3d177 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardPage.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardPage.java @@ -23,9 +23,10 @@ import java.awt.Color; import java.awt.Component; import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; import java.util.Map; +import java.util.Objects; +import java.util.Set; +import org.jackhuang.hellominecraft.util.ArrayUtils; /** * A convenience JPanel subclass that makes it easy to create wizard panels. @@ -33,14 +34,13 @@ import java.util.Map; *

* Automatic listening to child components
* If you add an editable component (all standard Swing controls are supported) - * to a WizardPage or a child JPanel inside it, - * a listener is automatically attached to it. If user input occurs, the - * following things happen, in order: + * to a WizardPage or a child JPanel inside it, a listener is automatically + * attached to it. If user input occurs, the following things happen, in order: *

    - *
  • If the name property of the component has been set, then - * the value from the component (i.e. Boolean for checkboxes, selected item(s) - * for lists/combo boxes/trees, etc.) will automatically be added to the - * wizard settings map, with the component name as the key.
  • + *
  • If the name property of the component has been set, then the + * value from the component (i.e. Boolean for checkboxes, selected item(s) for + * lists/combo boxes/trees, etc.) will automatically be added to the wizard + * settings map, with the component name as the key.
  • *
  • Regardless of whether the name property is set, * validateContents() will be called. You can override that method * to enable/disable the finish button, call setProblem() to @@ -51,21 +51,21 @@ import java.util.Map; * appropriate constructor. In that case, validateContents will * never be called automatically. *

    - * If you have custom components that WizardPage will not know how to listen - * to automatically, attach an appropriate listener to them and optionally - * call userInputReceived() with the component and the event if - * you want to run your automatic validation code. + * If you have custom components that WizardPage will not know how to listen to + * automatically, attach an appropriate listener to them and optionally call + * userInputReceived() with the component and the event if you want + * to run your automatic validation code. *

    - * For convenience, this class implements the relevant methods for accessing - * the WizardController and the settings map for the wizard that - * the panel is a part of. + * For convenience, this class implements the relevant methods for accessing the + * WizardController and the settings map for the wizard that the + * panel is a part of. *

    * Instances of WizardPage can be returned from a WizardPanelProvider; this * class also offers two methods for conveniently assembling a wizard: *

      *
    • Pass an array of already instantiated WizardPages to - * createWizard(). Note that for large wizards, it is preferable - * to construct the panels on demand rather than at construction time.
    • + * createWizard(). Note that for large wizards, it is preferable to + * construct the panels on demand rather than at construction time. *
    • Construct a wizard out of WizardPages, instantiating the panels as * needed: Pass an array of classes all of which *
        @@ -80,20 +80,19 @@ import java.util.Map; *

        * Note that during development of a wizard, it is worthwhile to test/run with * assertions enabled, as there is quite a bit of validity checking via - * assertions - * that can help find problems early. + * assertions that can help find problems early. *

        Using Custom Components

        * If the autoListen constructor argument is true, a WizardPage * will automatically listen to components which have a name, if they are - * standard Swing components it knows how to listen to. If you are using - * custom components, implement WizardPage.CustomComponentListener and return - * it from createCustomComponentListener() to add supplementary - * listening code for custom components. + * standard Swing components it knows how to listen to. If you are using custom + * components, implement WizardPage.CustomComponentListener and return it from + * createCustomComponentListener() to add supplementary listening + * code for custom components. *

        * Note: Swing components do not fire property changes when setName() is called. * If your component's values are not being propagated into the settings map, - * make sure you are calling setName() before adding the component - * to the hierarchy. + * make sure you are calling setName() before adding the component to the + * hierarchy. *

        * Also note that cell editors in tables and lists and so forth are always * ignored by the automatic listening code. @@ -127,23 +126,23 @@ public class WizardPage extends JPanel implements WizardPanel { * behavior. * * @param stepDescription the localized description of this step - * @param autoListen if true, components added will automatically be - * listened to for user input + * @param autoListen if true, components added will automatically be + * listened to for user input */ public WizardPage(String stepDescription, boolean autoListen) { this(null, stepDescription, autoListen); } /** - * Construct a new WizardPage with the passed step id and description. - * Use this constructor for WizardPages which will be constructed ahead - * of time and passed in an array to createWizard. + * Construct a new WizardPage with the passed step id and description. Use + * this constructor for WizardPages which will be constructed ahead of time + * and passed in an array to createWizard. * - * @param stepId the unique ID for the step represented. If null, - * the class name or a variant of it will be used + * @param stepId the unique ID for the step represented. If null, the class + * name or a variant of it will be used * @param stepDescription the localized description of this step - * @param autoListen if true, components added will automatically be - * listened to for user input + * @param autoListen if true, components added will automatically be + * listened to for user input * * @see #validateContents */ @@ -161,16 +160,12 @@ public class WizardPage extends JPanel implements WizardPanel { if (autoListen) { //It will attach itself GenericListener gl = new GenericListener(this, ccl = createCustomComponentListener(), - ccl == null ? null : new CustomComponentNotifierImpl(this)); + ccl == null ? null : new CustomComponentNotifierImpl(this)); gl.attachToHierarchyOf(this); } else if ((ccl = createCustomComponentListener()) != null) throw new IllegalStateException("CustomComponentListener " - + "will never be called if the autoListen parameter is " - + "false"); -// if (getClass() == WizardPage.class && stepId == null || -// description == null) { -// throw new NullPointerException ("Step or ID is null"); -// } + + "will never be called if the autoListen parameter is " + + "false"); setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); //XXX } @@ -186,8 +181,8 @@ public class WizardPage extends JPanel implements WizardPanel { /** * Create an auto-listening WizardPage with the passed description * - * @param stepId The unique id for the step. If null, an id will be - * generated + * @param stepId The unique id for the step. If null, an id will be + * generated * @param stepDescription the localized description of this step * */ @@ -196,8 +191,8 @@ public class WizardPage extends JPanel implements WizardPanel { } /** - * Use this constructor or the default constructor if you intend to - * pass an array of Class objects to lazily create WizardPanels. + * Use this constructor or the default constructor if you intend to pass an + * array of Class objects to lazily create WizardPanels. */ protected WizardPage(boolean autoListen) { this(null, null, autoListen); @@ -211,10 +206,9 @@ public class WizardPage extends JPanel implements WizardPanel { } /** - * If you are using custom Swing or AWT components which the - * WizardPage will not know how to automatically listen to, you - * may want to override this method, implement CustomComponentListener - * and return an instance of it. + * If you are using custom Swing or AWT components which the WizardPage will + * not know how to automatically listen to, you may want to override this + * method, implement CustomComponentListener and return an instance of it. * * @return A CustomComponentListener implementation, or null (the default). */ @@ -223,8 +217,8 @@ public class WizardPage extends JPanel implements WizardPanel { } /** - * Implement this class if you are using custom Swing or AWT components, - * and return an instance of it from + * Implement this class if you are using custom Swing or AWT components, and + * return an instance of it from * WizardPage.createCustomComponentListener(). */ public static abstract class CustomComponentListener { @@ -232,21 +226,20 @@ public class WizardPage extends JPanel implements WizardPanel { /** * Indicates that this CustomComponentListener will take responsibility * for noticing events from the passed component, and that the - * WizardPage should not try to automatically listen on it (which it - * can only do for standard Swing components and their children). + * WizardPage should not try to automatically listen on it (which it can + * only do for standard Swing components and their children). *

        - * Note that this method may be called frequently and any test it - * does should be fast. + * Note that this method may be called frequently and any test it does + * should be fast. *

        - * Important: The return value from this method should always - * be the same for any given component, for the lifetime of the - * WizardPage. + * Important: The return value from this method should always be + * the same for any given component, for the lifetime of the WizardPage. * * @param c A component * - * @return Whether or not this CustomComponentListener will listen - * on the passed component. If true, the component will later be - * passed to startListeningTo() + * @return Whether or not this CustomComponentListener will listen on + * the passed component. If true, the component will later be passed to + * startListeningTo() */ public abstract boolean accept(Component c); @@ -256,8 +249,8 @@ public class WizardPage extends JPanel implements WizardPanel { * CustomComponentNotifier. * * @param c The component to start listening to - * @param n An object that can be called to update the settings map - * when an interesting event occurs on the component + * @param n An object that can be called to update the settings map when + * an interesting event occurs on the component */ public abstract void startListeningTo(Component c, CustomComponentNotifier n); @@ -269,8 +262,8 @@ public class WizardPage extends JPanel implements WizardPanel { public abstract void stopListeningTo(Component c); /** - * Determine if the passed component is a container whose children - * may need to be listened on. Returns false by default. + * Determine if the passed component is a container whose children may + * need to be listened on. Returns false by default. * * @param c A component which might be a container */ @@ -279,47 +272,44 @@ public class WizardPage extends JPanel implements WizardPanel { } /** - * Get the map key for this component's value. By default, returns - * the component's name. Will only - * be passed components which the accept() method - * returned true for. + * Get the map key for this component's value. By default, returns the + * component's name. Will only be passed components which the + * accept() method returned true for. *

        - * Important: The return value from this method should always - * be the same for any given component, for the lifetime of the - * WizardPage. + * Important: The return value from this method should always be + * the same for any given component, for the lifetime of the WizardPage. * - * @param c the component, which the accept method earlier returned - * true for + * @param c the component, which the accept method earlier returned true + * for * - * @return A string key that should be used in the Wizard's settings - * map for the name of this component's value + * @return A string key that should be used in the Wizard's settings map + * for the name of this component's value */ public String keyFor(Component c) { return c.getName(); } /** - * Get the value currently set on the passed component. Will only - * be passed components which the accept() method - * returned true for, and which keyFor() returned non-null. + * Get the value currently set on the passed component. Will only be + * passed components which the accept() method returned + * true for, and which keyFor() returned non-null. * * @param c the component * * @return An object representing the current value of this component. - * For example, if it were a JTextComponent, the value - * would likely - * be the return value of JTextComponent.getText() + * For example, if it were a JTextComponent, the value + * would likely be the return value of + * JTextComponent.getText() */ public abstract Object valueFor(Component c); } /** * Object which is passed to - * CustomComponentListener.startListeningTo(), - * which can be called when an event has occurred on a custom component the + * CustomComponentListener.startListeningTo(), which can be + * called when an event has occurred on a custom component the * CustomComponentListener has claimed (by returning - * true - * from its accept() method). + * true from its accept() method). */ public static abstract class CustomComponentNotifier { @@ -330,10 +320,10 @@ public class WizardPage extends JPanel implements WizardPanel { * Method which may be called when an event occurred on a custom * component. * - * @param c the component + * @param c the component * @param eventObject the event object from the component, or null (with - * the exception of javax.swing.text.DocumentEvent, it - * will likely be a subclass of java.util.EventObject). + * the exception of javax.swing.text.DocumentEvent, it will + * likely be a subclass of java.util.EventObject). */ public abstract void userInputReceived(Component c, Object eventObject); } @@ -346,6 +336,7 @@ public class WizardPage extends JPanel implements WizardPanel { this.page = page; //Slightly smaller footprint a nested, not inner class } + @Override public void userInputReceived(Component c, Object event) { if (!page.ccl.accept(c)) return; @@ -369,6 +360,7 @@ public class WizardPage extends JPanel implements WizardPanel { return description; } + @Override public void addNotify() { super.addNotify(); if (!listening) @@ -383,14 +375,17 @@ public class WizardPage extends JPanel implements WizardPanel { } } + @Override public WizardPanelNavResult allowBack(String stepName, Map settings, Wizard wizard) { return WizardPanelNavResult.PROCEED; } + @Override public WizardPanelNavResult allowFinish(String stepName, Map settings, Wizard wizard) { return WizardPanelNavResult.PROCEED; } + @Override public WizardPanelNavResult allowNext(String stepName, Map settings, Wizard wizard) { return WizardPanelNavResult.PROCEED; } @@ -398,9 +393,8 @@ public class WizardPage extends JPanel implements WizardPanel { private boolean inValidateContents = false; /** - * Called whenever the page is rendered. - * This can be used by the page as a notification - * to load page-specific information in its fields. + * Called whenever the page is rendered. This can be used by the page as a + * notification to load page-specific information in its fields. *

        * By default, this method does nothing. */ @@ -424,68 +418,65 @@ public class WizardPage extends JPanel implements WizardPanel { } /** - * Create a simple Wizard from an array of WizardPages, with a - * no-op WizardResultProducer. + * Create a simple Wizard from an array of WizardPages, with a no-op + * WizardResultProducer. */ public static Wizard createWizard(WizardPage[] contents) { return createWizard(contents, WizardResultProducer.NO_OP); } /** - * Create simple Wizard from an array of classes, each of which is a - * unique subclass of WizardPage. + * Create simple Wizard from an array of classes, each of which is a unique + * subclass of WizardPage. */ - public static Wizard createWizard(Class[] wizardPageClasses, WizardResultProducer finisher) { + public static Wizard createWizard(Class[] wizardPageClasses, WizardResultProducer finisher) { return new CWPP(wizardPageClasses, finisher).createWizard(); } /** - * Create simple Wizard from an array of classes, each of which is a - * unique subclass of WizardPage. + * Create simple Wizard from an array of classes, each of which is a unique + * subclass of WizardPage. */ - public static Wizard createWizard(String title, Class[] wizardPageClasses, WizardResultProducer finisher) { + public static Wizard createWizard(String title, Class[] wizardPageClasses, WizardResultProducer finisher) { return new CWPP(title, wizardPageClasses, finisher).createWizard(); } /** - * Create simple Wizard from an array of classes, each of which is a - * unique subclass of WizardPage. + * Create simple Wizard from an array of classes, each of which is a unique + * subclass of WizardPage. */ - public static Wizard createWizard(String title, Class[] wizardPageClasses) { + public static Wizard createWizard(String title, Class[] wizardPageClasses) { return new CWPP(title, wizardPageClasses, - WizardResultProducer.NO_OP).createWizard(); + WizardResultProducer.NO_OP).createWizard(); } /** * Create a simple Wizard from an array of classes, each of which is a - * unique subclass of WizardPage, with a - * no-op WizardResultProducer. + * unique subclass of WizardPage, with a no-op WizardResultProducer. */ - public static Wizard createWizard(Class[] wizardPageClasses) { + public static Wizard createWizard(Class[] wizardPageClasses) { return createWizard(wizardPageClasses, WizardResultProducer.NO_OP); } /** - * Called by createPanelForStep, with whatever map is passed. In the - * current impl this is always the same Map, but that is not guaranteed. - * If any content was added by calls to putWizardData() during the - * constructor, etc., such data is copied to the settings map the first - * time this method is called. + * Called by createPanelForStep, with whatever map is passed. In the current + * impl this is always the same Map, but that is not guaranteed. If any + * content was added by calls to putWizardData() during the constructor, + * etc., such data is copied to the settings map the first time this method + * is called. * - * Subclasses do NOT need to override this method, - * they can override renderPage which is always called AFTER the map has - * been made valid. + * Subclasses do NOT need to override this method, they can override + * renderPage which is always called AFTER the map has been made valid. */ void setWizardDataMap(Map m) { if (m == null) - wizardData = new HashMap(); + wizardData = new HashMap<>(); else { if (wizardData instanceof HashMap) // our initial map has keys for all of our components // but with dummy empty values // So make sure we don't override data that was put in as part of the initialProperties - for (Iterator iter = wizardData.entrySet().iterator(); iter.hasNext();) { - Map.Entry entry = (Map.Entry) iter.next(); + for (Map.Entry entry : (Set) wizardData.entrySet()) { Object key = entry.getKey(); if (!m.containsKey(key)) m.put(key, entry.getValue()); @@ -497,8 +488,8 @@ public class WizardPage extends JPanel implements WizardPanel { /** * Set the WizardController. In the current impl, this is always the same * object, but the API does not guarantee that. The first time this is - * called, it will update the state of the passed controller to match - * any state that was set by components during the construction of this + * called, it will update the state of the passed controller to match any + * state that was set by components during the construction of this * component */ void setController(WizardController controller) { @@ -509,9 +500,8 @@ public class WizardPage extends JPanel implements WizardPanel { } /** - * Get the WizardController for interacting with the Wizard that - * contains this panel. - * Return value will never be null. + * Get the WizardController for interacting with the Wizard that contains + * this panel. Return value will never be null. */ private WizardController getController() { return controller; @@ -519,29 +509,29 @@ public class WizardPage extends JPanel implements WizardPanel { /** * Set the problem string. Call this method if next/finish should be - * disabled. The passed string will be visible to the user, and should - * be a short, localized description of what is wrong. + * disabled. The passed string will be visible to the user, and should be a + * short, localized description of what is wrong. */ protected final void setProblem(String value) { getController().setProblem(value); } /** - * Set whether the finish, next or both buttons should be enabled, - * assuming no problem string is set. + * Set whether the finish, next or both buttons should be enabled, assuming + * no problem string is set. * * @param value WizardController.MODE_CAN_CONTINUE, - * WizardController.MODE_CAN_FINISH or - * WizardController.MODE_CAN_CONTINUE_OR_FINISH; + * WizardController.MODE_CAN_FINISH or + * WizardController.MODE_CAN_CONTINUE_OR_FINISH; */ protected final void setForwardNavigationMode(int value) { getController().setForwardNavigationMode(value); } /** - * Disable all navigation. Useful if some background task is being - * completed during which no navigation should be allowed. Use with care, - * as it disables the cancel button as well. + * Disable all navigation. Useful if some background task is being completed + * during which no navigation should be allowed. Use with care, as it + * disables the cancel button as well. */ protected final void setBusy(boolean busy) { getController().setBusy(busy); @@ -572,8 +562,7 @@ public class WizardPage extends JPanel implements WizardPanel { /** * Retrieve a value stored in the wizard map, which may have been * putWizardData there by this panel or any previous panel in the wizard - * which - * contains this panel. + * which contains this panel. */ protected final Object getWizardData(Object key) { return getWizardDataMap().get(key); @@ -587,21 +576,20 @@ public class WizardPage extends JPanel implements WizardPanel { } /** - * Called when an event is received from one of the components in the - * panel that indicates user input. Typically you won't need to touch this - * method, unless your panel contains custom components which are not - * subclasses of any standard Swing component, which the framework won't - * know how to listen for changes on. For such cases, attach a listener - * to the custom component, and call this method with the event if you want - * validation to run when input happens. Automatic updating of the - * settings map will not work for such custom components, for obvious - * reasons, so update the settings map, if needed, in validateContents - * for this case. + * Called when an event is received from one of the components in the panel + * that indicates user input. Typically you won't need to touch this method, + * unless your panel contains custom components which are not subclasses of + * any standard Swing component, which the framework won't know how to + * listen for changes on. For such cases, attach a listener to the custom + * component, and call this method with the event if you want validation to + * run when input happens. Automatic updating of the settings map will not + * work for such custom components, for obvious reasons, so update the + * settings map, if needed, in validateContents for this case. * - * @param source The component that the user interacted with (if it can - * be determined from the event) or null - * @param event Usually an instance of EventObject, except in the case of - * DocumentEvent. + * @param source The component that the user interacted with (if it can be + * determined from the event) or null + * @param event Usually an instance of EventObject, except in the case of + * DocumentEvent. */ protected final void userInputReceived(Component source, Object event) { if (inBeginUIChanged) @@ -633,8 +621,8 @@ public class WizardPage extends JPanel implements WizardPanel { } /** - * Puts the value from the component in the settings map if the - * component's name property is not null + * Puts the value from the component in the settings map if the component's + * name property is not null */ void maybeUpdateMap(Component comp) { Object mapKey = getMapKeyFor(comp); @@ -657,8 +645,8 @@ public class WizardPage extends JPanel implements WizardPanel { * Given an ad-hoc swing component, fetch the likely value based on its * state. The default implementation handles most common swing components. * If you are using custom components and have assigned them names, override - * this method to handle getting an appropriate value out of your - * custom component and call super for the others. + * this method to handle getting an appropriate value out of your custom + * component and call super for the others. */ protected Object valueFrom(Component comp) { if (ccl != null && ccl.accept(comp)) @@ -672,16 +660,15 @@ public class WizardPage extends JPanel implements WizardPanel { } else if (comp instanceof JFormattedTextField) return ((JFormattedTextField) comp).getValue(); else if (comp instanceof JList) { - Object[] o = ((JList) comp).getSelectedValues(); - if (o != null) - if (o.length > 1) - return o; - else if (o.length == 1) - return o[0]; + Object[] o = ((JList) comp).getSelectedValues(); + if (o.length > 1) + return o; + else if (o.length == 1) + return o[0]; } else if (comp instanceof JTextComponent) return ((JTextComponent) comp).getText(); else if (comp instanceof JComboBox) - return ((JComboBox) comp).getSelectedItem(); + return ((JComboBox) comp).getSelectedItem(); else if (comp instanceof JColorChooser) return ((JColorChooser) comp).getSelectionModel().getSelectedColor(); else if (comp instanceof JSpinner) @@ -693,12 +680,11 @@ public class WizardPage extends JPanel implements WizardPanel { } /** - * Given an ad-hoc swing component, set the value as the property - * from the settings. The default implementation handles most common swing - * components. - * If you are using custom components and have assigned them names, override - * this method to handle getting an appropriate value out of your - * custom component and call super for the others. + * Given an ad-hoc swing component, set the value as the property from the + * settings. The default implementation handles most common swing + * components. If you are using custom components and have assigned them + * names, override this method to handle getting an appropriate value out of + * your custom component and call super for the others. */ protected void valueTo(Map settings, Component comp) { String name = comp.getName(); @@ -716,7 +702,7 @@ public class WizardPage extends JPanel implements WizardPanel { else if (comp instanceof JList) { if (value instanceof Object[]) throw new IllegalArgumentException("can't handle multi-select lists"); - ((JList) comp).setSelectedValue(value, true); + ((JList) comp).setSelectedValue(value, true); } else if (comp instanceof JTextComponent) ((JTextComponent) comp).setText((String) value); else if (comp instanceof JComboBox) @@ -734,14 +720,13 @@ public class WizardPage extends JPanel implements WizardPanel { * represented by this component into the wizard data map. *

        * The default implementation returns the result of - * c.getName(), - * which is almost always sufficient and convenient - just set the - * component names in a GUI builder and everything will be handled. + * c.getName(), which is almost always sufficient and + * convenient - just set the component names in a GUI builder and everything + * will be handled. * - * @return null if the component's value should not be automatically - * written to the wizard data map, or an object which is the key that - * later code will use to find this value. By default, it returns the - * component's name. + * @return null if the component's value should not be automatically written + * to the wizard data map, or an object which is the key that later code + * will use to find this value. By default, it returns the component's name. */ protected Object getMapKeyFor(Component c) { if (ccl != null && ccl.accept(c)) @@ -752,55 +737,54 @@ public class WizardPage extends JPanel implements WizardPanel { /** * Called when user interaction has occurred on a component contained by - * this - * panel or one of its children. Override this method to check if all of - * the values are legal, such that the Next/Finish button should be enabled, - * optionally calling setForwardNavigationMode() if warranted. + * this panel or one of its children. Override this method to check if all + * of the values are legal, such that the Next/Finish button should be + * enabled, optionally calling setForwardNavigationMode() if + * warranted. *

        - * This method also may be called with a null argument an effect of - * calling putWizardData() from someplace other than within - * this method. + * This method also may be called with a null argument an effect of calling + * putWizardData() from someplace other than within this + * method. *

        * Note that this method may be called very frequently, so it is important * that validation code be fast. For cases such as - * DocumentEvents, - * it may be desirable to delay validation with a timer, if the - * implementation - * of this method is too expensive to call on each keystroke. + * DocumentEvents, it may be desirable to delay validation with + * a timer, if the implementation of this method is too expensive to call on + * each keystroke. *

        - * Either the component, or the event, or both may be null on some calls - * to this method (such as when it is called because the settings map - * has been written to). + * Either the component, or the event, or both may be null on some calls to + * this method (such as when it is called because the settings map has been + * written to). *

        * The default implementation returns null. * * @param component The component the user interacted with, if it can be - * determined. The infrastructure does track the owners of list models - * and such, and can find the associated component, so this will usually - * (but not necessarily) be non-null. - * @param event The event object (if any) that triggered this call to - * validateContents. For most cases this will be an instance of - * EventObject, and can be used to directly detect what component - * the user interacted with. Since javax.swing.text.DocumentEvent is - * not a subclass of EventObject, the type of the argument is Object, - * so these events may be passed. + * determined. The infrastructure does track the owners of list models and + * such, and can find the associated component, so this will usually (but + * not necessarily) be non-null. + * @param event The event object (if any) that triggered this call to + * validateContents. For most cases this will be an instance of EventObject, + * and can be used to directly detect what component the user interacted + * with. Since javax.swing.text.DocumentEvent is not a subclass of + * EventObject, the type of the argument is Object, so these events may be + * passed. * * @return A localized string describing why navigation should be disabled, - * or null if the state of the components is valid and forward navigation - * should be enabled. + * or null if the state of the components is valid and forward navigation + * should be enabled. */ protected String validateContents(Component component, Object event) { return null; } /** - * Called if the user is navigating into this panel when it has already - * been displayed at least once - the user has navigated back to this - * panel, or back past this panel and is now navigating forward again. + * Called if the user is navigating into this panel when it has already been + * displayed at least once - the user has navigated back to this panel, or + * back past this panel and is now navigating forward again. *

        - * If some of the UI needs to be set up based on values from earlier - * pages that may have changed, do that here, fetching values from the - * settings map by calling getWizardData(). + * If some of the UI needs to be set up based on values from earlier pages + * that may have changed, do that here, fetching values from the settings + * map by calling getWizardData(). *

        * The default implementation simply calls * validateContents (null, null). @@ -810,8 +794,8 @@ public class WizardPage extends JPanel implements WizardPanel { } /** - * Get the settings map into which the wizard gathers settings. - * Return value will never be null. + * Get the settings map into which the wizard gathers settings. Return value + * will never be null. */ // the map is empty during construction, then later set to the map from the containing WizardController protected Map getWizardDataMap() { @@ -823,22 +807,22 @@ public class WizardPage extends JPanel implements WizardPanel { private String longDescription; /** - * Set the long description of this page. This method may be called - * only once and should be called from within the constructor. + * Set the long description of this page. This method may be called only + * once and should be called from within the constructor. * * @param desc The long description for this step */ protected void setLongDescription(String desc) { if (!Beans.isDesignTime() && this.longDescription != null) throw new IllegalStateException("Long description already set to" - + " " + desc); + + " " + desc); this.longDescription = desc; } /** * Get the long description of this page, which should be used in the title - * area of the wizard's UI if non-null. To use, call setLongDescription() - * in your WizardPage's constructor. It may be set only once. + * area of the wizard's UI if non-null. To use, call setLongDescription() in + * your WizardPage's constructor. It may be set only once. * * @return the description */ @@ -896,8 +880,9 @@ public class WizardPage extends JPanel implements WizardPanel { this.finish = finish; } + @Override protected JComponent createPanel(WizardController controller, String id, - Map wizardData) { + Map wizardData) { int idx = indexOfStep(id); // assert idx != -1 : "Bad ID passed to createPanel: " + id; @@ -913,9 +898,9 @@ public class WizardPage extends JPanel implements WizardPanel { * Make sure we haven't been passed bogus data */ private String valid(WizardPage[] pages) { - if (new HashSet(Arrays.asList(pages)).size() != pages.length) + if (ArrayUtils.hasDuplicateElements(pages)) return "Duplicate entry in array: " - + Arrays.asList(pages); + + Arrays.asList(pages); for (int i = 0; i < pages.length; i++) if (pages[i] == null) @@ -924,14 +909,17 @@ public class WizardPage extends JPanel implements WizardPanel { return null; } + @Override protected Object finish(Map settings) throws WizardException { return finish.finish(settings); } + @Override public boolean cancel(Map settings) { return finish.cancel(settings); } + @Override public String getLongDescription(String stepId) { for (WizardPage wizardPage : pages) if (stepId.equals(wizardPage.getID())) @@ -946,44 +934,27 @@ public class WizardPage extends JPanel implements WizardPanel { */ private static final class CWPP extends WizardPanelProvider { - private final Class[] classes; + private final Class[] classes; private final WizardResultProducer finish; private final String[] longDescriptions; - CWPP(String title, Class[] classes, WizardResultProducer finish) { + CWPP(String title, Class[] classes, WizardResultProducer finish) { super(title, Util.getSteps(classes), Util.getDescriptions(classes)); -// assert classes != null : "Class array may not be null"; -// assert new HashSet(Arrays.asList(classes)).size() == classes.length : -// "Duplicate entries in class array"; -// assert finish != null : "WizardResultProducer may not be null"; - _validateArgs(classes, finish); this.finish = finish; this.classes = classes; longDescriptions = new String[classes.length]; } - private void _validateArgs(Class[] classes, WizardResultProducer finish) { -// assert classes != null : "Class array may not be null"; -// assert new HashSet(Arrays.asList(classes)).size() == classes.length : -// "Duplicate entries in class array"; -// assert finish != null : "WizardResultProducer may not be null"; - - if (classes == null) - throw new RuntimeException("Class array may not be null"); - if (new HashSet(Arrays.asList(classes)).size() != classes.length) + private void _validateArgs(Class[] classes, WizardResultProducer finish) { + Objects.requireNonNull(classes, "Class array may not be null"); + Objects.requireNonNull(finish, "WizardResultProducer may not be null"); + if (ArrayUtils.hasDuplicateElements(classes)) throw new RuntimeException("Duplicate entries in class array"); - if (finish == null) - throw new RuntimeException("WizardResultProducer may not be null"); } - CWPP(Class[] classes, WizardResultProducer finish) { + CWPP(Class[] classes, WizardResultProducer finish) { super(Util.getSteps(classes), Util.getDescriptions(classes)); - -// assert classes != null : "Class array may not be null"; -// assert new HashSet(Arrays.asList(classes)).size() == classes.length : -// "Duplicate entries in class array"; -// assert finish != null : "WizardResultProducer may not be null"; longDescriptions = new String[classes.length]; _validateArgs(classes, finish); @@ -991,6 +962,7 @@ public class WizardPage extends JPanel implements WizardPanel { this.finish = finish; } + @Override protected JComponent createPanel(WizardController controller, String id, Map wizardData) { int idx = indexOfStep(id); @@ -1005,38 +977,42 @@ public class WizardPage extends JPanel implements WizardPanel { result.setWizardDataMap(wizardData); return result; - } catch (Exception e) { + } catch (IllegalAccessException | InstantiationException e) { // really IllegalArgumentException, but we need to have the "cause" get shown in stack trace throw new RuntimeException("Could not instantiate " - + classes[idx], e); + + classes[idx], e); } } + @Override protected Object finish(Map settings) throws WizardException { return finish.finish(settings); } + @Override public boolean cancel(Map settings) { return finish.cancel(settings); } + @Override public String toString() { return super.toString() + " for " + finish; } + @Override public String getLongDescription(String stepId) { int idx = indexOfStep(stepId); if (idx != -1) return longDescriptions[idx] == null ? descriptions[idx] - : longDescriptions[idx]; + : longDescriptions[idx]; return null; } } /** - * A dummy wizard controller which is used until the panel has actually - * been put into use; so state can be set during the constructor, etc. - * Its state will be dumped into the real one once there is a real one. + * A dummy wizard controller which is used until the panel has actually been + * put into use; so state can be set during the constructor, etc. Its state + * will be dumped into the real one once there is a real one. */ private static final class WC implements WizardControllerImplementation { @@ -1044,23 +1020,26 @@ public class WizardPage extends JPanel implements WizardPanel { private int canFinish = -1; private Boolean busy = null; + @Override public void setProblem(String value) { this.problem = value; } + @Override public void setForwardNavigationMode(int value) { switch (value) { - case WizardController.MODE_CAN_CONTINUE: - case WizardController.MODE_CAN_FINISH: - case WizardController.MODE_CAN_CONTINUE_OR_FINISH: - break; - default: - throw new IllegalArgumentException(Integer.toString(value)); + case WizardController.MODE_CAN_CONTINUE: + case WizardController.MODE_CAN_FINISH: + case WizardController.MODE_CAN_CONTINUE_OR_FINISH: + break; + default: + throw new IllegalArgumentException(Integer.toString(value)); } canFinish = value; } + @Override public void setBusy(boolean busy) { this.busy = busy ? Boolean.TRUE : Boolean.FALSE; } @@ -1082,9 +1061,9 @@ public class WizardPage extends JPanel implements WizardPanel { /** * Interface that is passed to WizardPage.createWizard(). For wizards - * created from a set of WizardPages or WizardPage subclasses, this is - * the object that whose code will be run to create or do whatever the - * wizard does when the user clicks the Finish button. + * created from a set of WizardPages or WizardPage subclasses, this is the + * object that whose code will be run to create or do whatever the wizard + * does when the user clicks the Finish button. */ public static interface WizardResultProducer { @@ -1093,30 +1072,23 @@ public class WizardPage extends JPanel implements WizardPanel { * gathered into the map on the various panels. *

        * If an instance of Summary is returned from this method, - * the - * UI shall display it on a final page and disable all navigation - * buttons - * except the Close/Cancel button. + * the UI shall display it on a final page and disable all navigation + * buttons except the Close/Cancel button. *

        * If an instance of DeferredWizardResult is returned from - * this - * method, the UI shall display some sort of progress bar while the - * result - * is computed in the background. If that - * DeferredWizardResult - * produces a Summary object, that summary shall be - * displayed - * as described above. + * this method, the UI shall display some sort of progress bar while the + * result is computed in the background. If that + * DeferredWizardResult produces a Summary + * object, that summary shall be displayed as described above. * * @param wizardData the map with key-value pairs which has been - * populated by the UI as the user progressed through the wizard + * populated by the UI as the user progressed through the wizard * * @return an object composed based on what the user entered in the - * wizard - - * somethingmeaningful to whatever code invoked the wizard, or null. - * Note - * special handling if an instance of DeferredWizardResult - * or Summary is returned from this method. + * wizard - somethingmeaningful to whatever code invoked the wizard, or + * null. Note special handling if an instance of + * DeferredWizardResult or Summary is returned + * from this method. */ Object finish(Map wizardData) throws WizardException; @@ -1130,14 +1102,17 @@ public class WizardPage extends JPanel implements WizardPanel { * A no-op WizardResultProducer that returns null. */ WizardResultProducer NO_OP = new WizardResultProducer() { + @Override public Object finish(Map wizardData) { return wizardData; } + @Override public boolean cancel(Map settings) { return true; } + @Override public String toString() { return "NO_OP WizardResultProducer"; } diff --git a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardPanelProvider.java b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardPanelProvider.java index 88dd4e8b5..724b98cd8 100644 --- a/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardPanelProvider.java +++ b/HMCUtils/src/main/java/org/jackhuang/hellominecraft/util/ui/wizard/spi/WizardPanelProvider.java @@ -8,44 +8,44 @@ and include the License file at http://www.netbeans.org/cddl.txt. If applicable, add the following below the CDDL Header, with the fields enclosed by brackets [] replaced by your own identifying information: "Portions Copyrighted [year] [name of copyright owner]" */ -/* + /* * PanelProvider.java * * Created on March 5, 2005, 7:25 PM */ - package org.jackhuang.hellominecraft.util.ui.wizard.spi; import java.util.Arrays; -import java.util.HashSet; import java.util.Map; +import java.util.Objects; import javax.swing.JComponent; +import org.jackhuang.hellominecraft.util.ArrayUtils; /** * (Note: WizardPage offers somewhat simpler functionality for - * creating a wizard than does WizardPanelProvider; the only advantage of - * WizardPanelProvider is that it does not require one to - * subclass a panel component). + * creating a wizard than does WizardPanelProvider; the only advantage of + * WizardPanelProvider is that it does not require one to subclass + * a panel component). *

        - * A simple interface for providing a fixed set of panels for a wizard. - * To use, simply implement createPanel() to create the - * appropriate UI component for a given step (a unique String ID - one of the ones passed - * in the constructor in the steps array), and implement + * A simple interface for providing a fixed set of panels for a wizard. To use, + * simply implement createPanel() to create the appropriate UI + * component for a given step (a unique String ID - one of the ones passed in + * the constructor in the steps array), and implement * finish() to do whatever should be done when the wizard is * finished. *

        - * To control whether the Next/Finish buttons are enabled, components - * created in createPanel() should call methods on the - * WizardController passed. The created panels should listen on the - * UI components they create, updating the settings Map when the user changes - * their input. + * To control whether the Next/Finish buttons are enabled, components created in + * createPanel() should call methods on the + * WizardController passed. The created panels should listen on the UI + * components they create, updating the settings Map when the user changes their + * input. *

        * Super-simple one-pane wizard example - if the checkbox is checked, the user * can continue: *

          * public class MyProvider extends WizardPanelProvider {
          *    public MyProvider() {
        - *       //here we pass a localized title for the wizard, 
        + *       //here we pass a localized title for the wizard,
          *       //the ID of the one step it will have, and a localized description
          *       //the wizard can show for that one step
          *       super ("Click the box", "click", "Click the checkbox");
        @@ -57,7 +57,7 @@ import javax.swing.JComponent;
          *       final JCheckBox result = new JCheckBox();
          *       result.addActionListener (new ActionListener() {
          *          public void actionPerformed (ActionEvent ae) {
        - *             //Typically you want to write the result of some user 
        + *             //Typically you want to write the result of some user
          *             //action into the settings map as soon as they do it 
          *             settings.put ("boxSelected", result.isSelected() ? Boolean.TRUE : Boolean.FALSE);
          *             if (result.isSelected()) {
        @@ -72,7 +72,7 @@ import javax.swing.JComponent;
          *    }
          *
          *    protected Object finish (Map settings) throws WizardException {
        - *       //if we had some interesting information (Strings a user put in a 
        + *       //if we had some interesting information (Strings a user put in a
          *       //text field or something, we'd generate some interesting object or
          *       //create some files or something here
          *       return null;
        @@ -83,240 +83,229 @@ import javax.swing.JComponent;
          * @author Tim Boudreau
          */
         public abstract class WizardPanelProvider {
        +
             final String title;
             final String[] descriptions;
             final String[] steps;
             final String[] knownProblems;
        -    
        +
             /**
        -     * Create a WizardPanelProvider.  The passed array of steps and descriptions
        +     * Create a WizardPanelProvider. The passed array of steps and descriptions
              * will be used as IDs and localized descriptions of the various steps in
        -     * the wizard.  Use this constructor (which passes not title) for sub-wizards
        -     * used in a WizardBranchController, where the first pane 
        -     * will determine the title, and the titles of the sub-wizards will never be 
        +     * the wizard. Use this constructor (which passes not title) for sub-wizards
        +     * used in a WizardBranchController, where the first pane will
        +     * determine the title, and the titles of the sub-wizards will never be
              * shown.
        -     * @param steps A set of unique IDs identifying each step of this wizard.  Each
        -     *   ID must occur only once in the array of steps.
        -     *   
        +     *
        +     * @param steps A set of unique IDs identifying each step of this wizard.
        +     * Each ID must occur only once in the array of steps.
        +     *
              * @param descriptions A set of human-readable descriptions corresponding
        -     *  1:1 with the unique IDs passed as the steps parameter
        +     * 1:1 with the unique IDs passed as the steps parameter
              */
        -    protected WizardPanelProvider (String[] steps, String[] descriptions) {
        -        this (null, steps, descriptions);
        +    protected WizardPanelProvider(String[] steps, String[] descriptions) {
        +        this(null, steps, descriptions);
             }
        -    
        +
             /**
        -     * Create a WizardPanelProvider with the provided title, steps and 
        -     * descriptions.  The steps parameter are unique IDs of 
        -     * panels, which will be passed to createPanel to create
        -     * panels for various steps in the wizard, as the user navigates it.
        -     * The descriptions parameter is a set of localized descriptions
        +     * Create a WizardPanelProvider with the provided title, steps and
        +     * descriptions. The steps parameter are unique IDs of panels,
        +     * which will be passed to createPanel to create panels for
        +     * various steps in the wizard, as the user navigates it. The
        +     * descriptions parameter is a set of localized descriptions
              * that can appear in the Wizard to describe each step.
        +     *
              * @param title A human readable title for the wizard dialog
        -     * @param steps An array of unique IDs for the various panels of this 
        -     *  wizard
        +     * @param steps An array of unique IDs for the various panels of this wizard
              * @param descriptions An array of descriptions corresponding 1:1 with the
        -     *  unique IDs.  These must be human readable, localized strings.
        +     * unique IDs. These must be human readable, localized strings.
              */
        -    protected WizardPanelProvider (String title, String[] steps, String[] descriptions) {
        +    protected WizardPanelProvider(String title, String[] steps, String[] descriptions) {
                 this.title = title;
                 this.steps = steps;
                 this.descriptions = descriptions;
                 knownProblems = new String[steps.length];
        -        if (steps.length != descriptions.length) {
        -            throw new IllegalArgumentException ("Length of steps and" +
        -                    " descriptions arrays do not match");
        -        }
        +        if (steps.length != descriptions.length)
        +            throw new IllegalArgumentException("Length of steps and"
        +                    + " descriptions arrays do not match");
                 // assert validData (steps, descriptions) == null : validData (steps, descriptions);
        -        String v = validData (steps, descriptions);
        +        String v = validData(steps, descriptions);
                 if (v != null)
        -        {
        -            throw new RuntimeException (v);
        -        }
        +            throw new RuntimeException(v);
             }
        -    
        -    
        -    private String validData (String[] steps, String[] descriptions) {
        -        if (steps.length != descriptions.length) {
        -            return steps.length + " steps but " + descriptions.length + 
        -                    " descriptions";
        +
        +    private String validData(String[] steps, String[] descriptions) {
        +        if (steps.length != descriptions.length)
        +            return steps.length + " steps but " + descriptions.length
        +                    + " descriptions";
        +        for (int i = 0; i < steps.length; i++) {
        +            Objects.requireNonNull(steps[i], "Step id " + i + " is null");
        +            Objects.requireNonNull(descriptions[i], "Description " + i + " is null");
                 }
        -        for (int i=0; i < steps.length; i++) {
        -            if (steps[i] == null) {
        -                throw new NullPointerException ("Step id " + i + " is null");
        -            }
        -            if (descriptions[i] == null) {
        -                throw new NullPointerException ("Description " + i + " is null");
        -            }
        -        }
        -        if (new HashSet(Arrays.asList(steps)).size() != steps.length) {
        +        if (ArrayUtils.hasDuplicateElements(steps))
                     return "Duplicate step ids: " + Arrays.asList(steps);
        -        }
                 return null;
             }
        -    
        +
             /**
              * Convenience constructor to create a WizardPanelProvider which has only
        -     * one step to it.  Mainly useful for initial steps in a WizardBranchController.
        +     * one step to it. Mainly useful for initial steps in a
        +     * WizardBranchController.
        +     *
              * @param title A human readable title for the wizard dialog
              * @param singleStep The unique ID of the only step this wizard has
              * @param singleDescription The human-readable description of what the user
        -     *  should do in the one step of this one-step wizard or sub-wizard
        +     * should do in the one step of this one-step wizard or sub-wizard
              */
        -    protected WizardPanelProvider (String title, String singleStep, String singleDescription) {
        -        this (title, new String[] {singleStep}, new String[] {singleDescription});
        +    protected WizardPanelProvider(String title, String singleStep, String singleDescription) {
        +        this(title, new String[] { singleStep }, new String[] { singleDescription });
             }
        -    
        +
             /**
        -     * Create a panel that represents a named step in the wizard.
        -     * This method will be called exactly once in the life of 
        -     * a wizard.  The panel should retain the passed settings Map, and
        -     * add/remove values from it as the user enters information, calling
        -     * setProblem() and setCanFinish() as
        -     * appropriate in response to user input.
        -     * 
        -     * @param controller - the object which controls whether the
        -     *  Next/Finish buttons in the wizard are enabled, and what instructions
        -     *  are displayed to the user if they are not
        -     * @param id The name of the step, one of the array of steps passed in
        -     *  the constructor
        -     * @param settings A Map containing settings from earlier steps in
        -     *   the wizard.  It is safe to retain a reference to this map and put
        -     *   values in it as the user manipulates the UI;  the reference should
        -     *   be refreshed whenever this method is called again.
        -     * @return A JComponent that should be displayed in the center of the
        -     *  wizard
        +     * Create a panel that represents a named step in the wizard. This method
        +     * will be called exactly once in the life of a wizard. The panel
        +     * should retain the passed settings Map, and add/remove values from it as
        +     * the user enters information, calling setProblem() and
        +     * setCanFinish() as appropriate in response to user input.
        +     *
        +     * @param controller - the object which controls whether the Next/Finish
        +     * buttons in the wizard are enabled, and what instructions are displayed to
        +     * the user if they are not
        +     * @param id The name of the step, one of the array of steps passed in the
        +     * constructor
        +     * @param settings A Map containing settings from earlier steps in the
        +     * wizard. It is safe to retain a reference to this map and put values in it
        +     * as the user manipulates the UI; the reference should be refreshed
        +     * whenever this method is called again.
        +     * @return A JComponent that should be displayed in the center of the wizard
              */
        -    protected abstract JComponent createPanel (WizardController controller, String id, Map settings);
        -    
        +    protected abstract JComponent createPanel(WizardController controller, String id, Map settings);
        +
             /**
        -     * Instantiate whatever object (if any) the wizard creates from its
        -     * gathered data.  The default implementation is a no-op that returns
        -     * null.
        +     * Instantiate whatever object (if any) the wizard creates from its gathered
        +     * data. The default implementation is a no-op that returns null.
              * 

        * If an instance of Summary is returned from this method, the * UI shall display it on a final page and disable all navigation buttons * except the Close/Cancel button. *

        * If an instance of DeferredWizardResult is returned from this - * method, the UI shall display some sort of progress bar while the result - * is computed in the background. If that DeferredWizardResult + * method, the UI shall display some sort of progress bar while the result + * is computed in the background. If that DeferredWizardResult * produces a Summary object, that summary shall be displayed * as described above. *

        * The default implementation returns the settings map it is passed. * - * @param settings The settings map, now fully populated with all settings needed - * to complete the wizard (this method will only be called if - * setProblem(null) and setCanFinish(true) have - * been called on the WizardController passed to - * createPanel(). - * @return an object composed based on what the user entered in the wizard - - * somethingmeaningful to whatever code invoked the wizard, or null. Note - * special handling if an instance of DeferredWizardResult - * or Summary is returned from this method. + * @param settings The settings map, now fully populated with all settings + * needed to complete the wizard (this method will only be called if + * setProblem(null) and setCanFinish(true) have + * been called on the WizardController passed to + * createPanel(). + * @return an object composed based on what the user entered in the wizard - + * somethingmeaningful to whatever code invoked the wizard, or null. Note + * special handling if an instance of DeferredWizardResult or + * Summary is returned from this method. */ - protected Object finish (Map settings) throws WizardException { + protected Object finish(Map settings) throws WizardException { return settings; } /** * The method provides a chance to call setProblem() or setCanFinish() when - * the user re-navigates to a panel they've already seen - in the case - * that the user pressed the Previous button and then the Next button. + * the user re-navigates to a panel they've already seen - in the case that + * the user pressed the Previous button and then the Next button. *

        * The default implementation does nothing, which is sufficient for most - * cases. - * If whether this panel is valid or not could - * have changed because of changed data from a previous panel, or it - * displays data entered on previous panes which may have changed, - * you may want to override this method to ensure validity and canFinish - * are set correctly, and that the components have the correct text. + * cases. If whether this panel is valid or not could have changed because + * of changed data from a previous panel, or it displays data entered on + * previous panes which may have changed, you may want to override this + * method to ensure validity and canFinish are set correctly, and that the + * components have the correct text. *

        - * This method will not be called when a panel is first instantiated - - * createPanel() is expected to set validity and canFinish + * This method will not be called when a panel is first instantiated + * - createPanel() is expected to set validity and canFinish * appropriately. *

        - * The settings Map passed to this method will always be the same - * Settings map instance that was passed to createPanel() - * when the panel was created. + * The settings Map passed to this method will always be the same Settings + * map instance that was passed to createPanel() when the panel + * was created. *

        * If you are implementing WizardPanelProvider and some of the pages are - * WizardPages, you should call the super implementation if - * you override this method. + * WizardPages, you should call the super implementation if you + * override this method. */ - protected void recycleExistingPanel (String id, WizardController controller, Map wizardData, JComponent panel) { + protected void recycleExistingPanel(String id, WizardController controller, Map wizardData, JComponent panel) { //do nothing } - void recycle (String id, WizardController controller, Map wizardData, JComponent panel) { + void recycle(String id, WizardController controller, Map wizardData, JComponent panel) { if (panel instanceof WizardPage) { WizardPage page = (WizardPage) panel; page.setController(controller); page.setWizardDataMap(wizardData); page.recycle(); } - recycleExistingPanel (id, controller, wizardData, panel); + recycleExistingPanel(id, controller, wizardData, panel); } - + private Wizard wizard; + /** - * Create a Wizard for this PanelProvider. The instance created by this + * Create a Wizard for this PanelProvider. The instance created by this * method is cached and the same instance will be returned on subsequent * calls. */ public final Wizard createWizard() { - if (wizard == null) { - wizard = new Wizard (new SimpleWizard (this)); - } + if (wizard == null) + wizard = new Wizard(new SimpleWizard(this)); return wizard; } - + /** - * This method can optionally be overridden to provide a longer - * description of a step to be shown in the top of its panel. - * The default implementation returns null, indicating that the - * short description should be used. - * + * This method can optionally be overridden to provide a longer description + * of a step to be shown in the top of its panel. The default implementation + * returns null, indicating that the short description should be used. + * * @param stepId a unique id for one step of the wizard - * @return An alternate description for use in the top of the wizard - * page when this page is the current one, or null - */ - public String getLongDescription (String stepId) { + * @return An alternate description for use in the top of the wizard page + * when this page is the current one, or null + */ + public String getLongDescription(String stepId) { return null; } - + /** - * Convenience method to get the index into the array of steps passed to - * the constructor of a specific step id. + * Convenience method to get the index into the array of steps passed to the + * constructor of a specific step id. */ - protected final int indexOfStep (String id) { + protected final int indexOfStep(String id) { return Arrays.asList(steps).indexOf(id); } - - void setKnownProblem (String problem, int idx) { + + void setKnownProblem(String problem, int idx) { //Record a problem message so we can put it back if the user does //prev and then next - if (idx >= 0) { //setProblem() can be called during initialization + if (idx >= 0) //setProblem() can be called during initialization knownProblems[idx] = problem; - } } - + String getKnownProblem(int idx) { return knownProblems[idx]; } /** - * Called if the user invokes cancel. The default impl returns - * true. - * @return false to abort cancellation (almost all implementations will - * want to return true - this is really only applicable in cases such - * as an OS installer or such). + * Called if the user invokes cancel. The default impl returns true. + * + * @return false to abort cancellation (almost all implementations will want + * to return true - this is really only applicable in cases such as an OS + * installer or such). */ public boolean cancel(Map settings) { return true; } - + + @Override public String toString() { return super.toString() + " with wizard " + wizard; } diff --git a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N.lang b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N.lang index c57982610..0ad6ed310 100755 --- a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N.lang +++ b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N.lang @@ -13,404 +13,408 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see {http://www.gnu.org/licenses/}. -launch.failed=启动失败 -launch.failed_creating_process=启动失败,在创建新进程时发生错误,可能是Java路径错误。 -launch.failed_sh_permission=为启动文件添加权限时发生错误 -launch.failed_packing_jar=在打包jar时发生错误 -launch.unsupported_launcher_version=对不起,本启动器现在可能不能启动这个版本的Minecraft,但启动器还是会尝试启动,请尽快将此问题报告给作者。 -launch.too_big_memory_alloc_64bit=您设置的内存大小过大,由于可能超过了32位Java的内存分配限制,所以可能无法启动游戏,请将内存调至1024MB或更小,启动器仍会尝试启动。 -launch.too_big_memory_alloc_free_space_too_low=您设置的内存大小过大,由于超过了系统内存大小%dMB,所以可能影响游戏体验或无法启动游戏,启动器仍会尝试启动。 -launch.cannot_create_jvm=截获到无法创建Java虚拟机,可能是Java参数有问题,可以在设置中开启无参数模式启动 -launch.circular_dependency_versions=发现游戏版本循环引用,请确认您的客户端未被修改或修改导致出现此问题。 -launch.not_finished_downloading_libraries=未完成游戏依赖库的下载,还要继续启动游戏吗? -launch.not_finished_decompressing_natives=未能解压游戏本地库,还要继续启动游戏吗? -launch.wrong_javadir=错误的Java路径,将自动重置为默认Java路径。 -launch.exited_abnormally=游戏非正常退出,请查看日志文件,或联系他人寻求帮助。 +# +#author: huangyuhui, dxNeil +launch.failed=Failed to launch. +launch.failed_creating_process=Failed to create process, maybe your java path is wrong, please modify your java path. +launch.failed_sh_permission=Failed to add permission to the launch script. +launch.failed_packing_jar=Failed to pack the jar. +launch.unsupported_launcher_version=Sorry, the launcher cannot launch minecraft, but will retry launching it. +launch.too_big_memory_alloc_64bit=You have allocated too much memory, because of your 32-Bit Java Runtime Environment, your game probably crash. The maximum memory is 1024MB. The launcher will try to launch it. +launch.too_big_memory_alloc_free_space_too_low=You have allocated too much memory, because the physical memory size is %dMB, your game probably crash. The launcher will try to launch it. +launch.cannot_create_jvm=We find that it cannot create java virutal machine. The Java argements may have problems. You can enable the no args mode in the settings. +launch.circular_dependency_versions=Found circular dependency versions, please check if your client has been modified. +launch.not_finished_downloading_libraries=Did not finish downloading libraries, continue launching game? +launch.not_finished_decompressing_natives=Did not finish decompressing native libraries, continue launching game? +launch.wrong_javadir=Incorrect Java directory, will reset to default Java directory. +launch.exited_abnormally=Game exited abnormally, please visit the log, or ask someone for help. -launch.state.logging_in=登录中 -launch.state.generating_launching_codes=正在生成启动代码 -launch.state.downloading_libraries=正在下载必要文件 -launch.state.decompressing_natives=正在释放本地文件 +launch.state.logging_in=Logging In +launch.state.generating_launching_codes=Generating Launching Codes +launch.state.downloading_libraries=Downloading dependencies +launch.state.decompressing_natives=Decompressing natives -install.no_version=未找到要安装的对应MC版本 -install.no_version_if_intall=未找到要安装的对应MC版本,是否自动安装需要的MC版本? -install.not_refreshed=未刷新列表 -install.download_list=下载列表 +install.no_version=The version is not found. +install.no_version_if_intall=The required version is not found, do you wish to install the version automatically? +install.not_refreshed=The installer list is not refreshed. +install.download_list=Download List -install.liteloader.get_list=获取LiteLoader列表 -install.liteloader.install=安装LiteLoader +install.liteloader.get_list=Get LiteLoader List +install.liteloader.install=Install LiteLoader -install.forge.get_list=获取Forge列表 -install.forge.install=安装Forge -install.forge.get_changelogs=获取Forge更新记录 +install.forge.get_list=Get Forge List +install.forge.install=Install Forge +install.forge.get_changelogs=Get Forge Changelogs -install.optifine.install=安装OptiFine -install.optifine.get_list=获取OptiFine列表 -install.optifine.get_download_link=获取OptiFine下载地址 +install.optifine.install=Install OptiFine +install.optifine.get_list=Get OptiFine Download List +install.optifine.get_download_link=Get the Download Link of OptiFine -install.failed_forge=安装Forge失败 -install.failed_optifine=安装OptiFine失败 -install.failed_liteloader=安装LiteLoader失败 -install.failed_download_forge=下载Forge失败 -install.failed_download_optifine=下载OptiFine失败 -install.failed=安装失败 -install.success=安装成功 -install.no_forge=没有安装Forge -install.choose_forge=选择你安装的Forge版本 -install.version=版本 -install.mcversion=游戏版本 -install.time=时间 -install.release_time=释放时间 -install.type=类型 -install.please_refresh=如需使用自动安装请点击右侧刷新按钮 +install.failed_forge=Failed to install 'Forge'. +install.failed_optifine=Failed to install 'OptiFine'. +install.failed_liteloader=Failed to install 'LiteLoader'. +install.failed_download_forge=Failed to download 'Forge'. +install.failed_download_optifine=Failed to download 'OptiFine'. +install.failed=Failed to install +install.success=Install successfully +install.no_forge=No Forge +install.choose_forge=Choose the version you want to install Forge +install.version=Version +install.mcversion=Game Version +install.time=Time +install.release_time=Release Time +install.type=Type +install.please_refresh=If you want to install something please click "Refresh" button. -crash.launcher=启动器崩溃了! -crash.minecraft=Minecraft崩溃了!请认真阅读建议。 +crash.launcher=Launcher has crashed! +crash.minecraft=Minecraft has crashed! -login.choose_charactor=请选择您要使用的角色 -login.no_charactor=该帐号没有角色 -login.your_password=您的密码 -login.failed=登录失败: -login.no_Player007=你还未设置用户名! -login.wrong_password=可能是您的用户名或密码错误 -login.invalid_username=无效的用户名 -login.invalid_uuid_and_username=无效的UUID和用户名 -login.invalid_password=无效的密码 -login.invalid_access_token=无效的访问令牌 -login.changed_client_token=服务器回应已经修改客户端令牌 -login.not_email=用户名必须是邮箱 -login.type=登录 -login.username=名字 -login.account=邮箱 -login.invalid_token=请尝试登出并重新输入密码登录 -login.no_valid_character=无有效的角色,自行到skinme.cc登陆并创建角色 +login.choose_charactor=Please choose the character you want +login.no_charactor=No character in this account. +login.your_password=Your password +login.failed=Failed to login +login.no_Player007=You have not set a username! +login.wrong_password=Incorrect password or username +login.invalid_username=Invalid username +login.invalid_uuid_and_username=Invalid UUID and username +login.invalid_password=Invalid password +login.invalid_access_token=Invalid Access Token +login.changed_client_token=The server response has changed the client token. +login.not_email=The username must be a e-mail. +login.type=Login +login.username=Name +login.account=Email +login.invalid_token=Please log out and re-input your password to log in. +login.no_valid_character=No valid character, please visit skinme.cc and create your own character. -proxy.username=账户 -proxy.password=密码 -proxy.host=主机 -proxy.port=端口 +proxy.username=Account +proxy.password=Password +proxy.host=Host +proxy.port=Port -login.failed.connect_authentication_server=无法连接认证服务器,可能是网络问题 +login.failed.connect_authentication_server=Cannot connect the authentication server. Check your network. -login.profile.not_logged_in=无法修改游戏资料同时未登录 -login.profile.selected=无法修改游戏资料. 你必须登出再返回. +login.profile.not_logged_in=You are not logged in, you can't modify the profile! +login.profile.selected=Can't modify the profile, logout and go retry. -login.methods.yggdrasil=正版登录 -login.methods.offline=离线模式 -login.methods.no_method=没有登入方式... +login.methods.yggdrasil=Mojang +login.methods.offline=Offline +login.methods.no_method=No login method -log.playername_null=玩家名为空,这代表着登录方法出现问题 +log.playername_null=The player name is empty. -minecraft.no_selected_version=没有选择任何一个Minecraft版本 -minecraft.wrong_path=错误的Minecraft路径,启动器未找到设定的Minecraft路径,请检查。 +minecraft.no_selected_version=No selected Minecraft version +minecraft.wrong_path=Wrong Minecraft path, the launcher could not find the path. -operation.stopped=操作被强行终止 -operation.confirm_stop=真的要终止操作吗? +operation.stopped=The operation was aborted. +operation.confirm_stop=Terminate the operations? -ui.login.password=密码 -ui.more=更多 +ui.login.password=Password +ui.more=More -crash.advice.UnsupportedClassVersionError=这可能是因为您的Java版本过于老旧,可以尝试更换最新Java并在版本设置的Java路径中设置. -crash.advice.ConcurrentModificationException=这可能是因为您的Java版本高于Java 1.8.0_11导致的,可以尝试卸载Java8安装Java7。 -crash.advice.ClassNotFoundException=Minecraft不完整或Mod冲突,如果有未能下载的文件请下载成功后重试或是客户端损坏请重试请重新制作客户端或下载整合包解决问题,另可尝试游戏设置->(版本)管理->删除库文件解决问题 -crash.advice.NoSuchFieldError=Minecraft不完整或Mod冲突,如果有未能下载的文件请下载成功后重试或是客户端损坏请重试请重新制作客户端或下载整合包解决问题。 -crash.advice.LWJGLException=您的电脑不正常,可能需要使用驱动精灵或其他安装器更新显卡驱动。 -crash.advice.SecurityException=可能是您修改了minecraft.jar但未删除META-INF文件夹的原因。请通过压缩软件删除jar中的META-INF文件夹。 -crash.advice.OutOfMemoryError=内存溢出,您设置的Minecraft最大内存过小,请调大! -crash.advice.otherwise=可能是Mod或其他问题。 +crash.advice.UnsupportedClassVersionError=Maybe your java is too old, try to update the java. +crash.advice.ConcurrentModificationException=Maybe your Java is newer than 1.8.0_11, you could downgrade to Java 7. +crash.advice.ClassNotFoundException=Minecraft or mods are incomplete. Retry if there are some libraries that have not downloaded or update your game and mods! Or you can try Game Settings -> Manage (Version) -> Delete library files to solve the problem. +crash.advice.NoSuchFieldError=Minecraft or mods are incomplete. Retry if there are some libraries that have not downloaded or update your game and mods! +crash.advice.LWJGLException=Maybe your video driver does not work well, please update your video driver. +crash.advice.SecurityException=Maybe you have modified minecraft.jar but have not removed the META-INF. +crash.advice.OutOfMemoryError=The maximum memory of JVM is too small, please modify it. +crash.advice.otherwise=Maybe mods caused problems. -crash.advice.OpenGL=可能是显卡/声卡驱动问题,也可能是Mod导致的问题。 -crash.advice.no_lwjgl=可能是游戏依赖库不完整或解压依赖库时出错。可以通过下载整合包解决问题。 +crash.advice.OpenGL=Maybe drivers caused problems. +crash.advice.no_lwjgl=Maybe drivers caused problems. -crash.advice.no=无建议。 +crash.advice.no=No advice. -crash.user_fault=您的系统或Java环境可能安装不当导致本软件崩溃,请检查您的Java环境或您的电脑!可以尝试重新安装Java。 -crash.headless=如果您的操作系统是Linux,请注意不要使用OpenJDK,务必使用Oracle JDK,或尝试添加-Djava.awt.headless=false参数,或检查您的Xserver是否正常 -crash.NoClassDefFound=请确认HMCL本体是否完整 +crash.user_fault=Your OS or Java environment may not be properly installed resulting in crashing of this software, please check your Java Environment or your computer! +crash.headless=If your OS is Linux, please use Oracle JDK instead of OpenJDK, or add "-Djava.awt.headless=false" JVM argument, or check if your Xserver works normally. +crash.NoClassDefFound=Please check "HMCL" software is complete. -crash.error=您的Minecraft崩溃了。 -crash.main_class_not_found=找不到主类,可能是您的JSON文件填写错误。无法启动游戏。可以通过下载整合包解决问题。 -crash.class_path_wrong=解析Class Path时出现错误,此错误本不应该发生。可能是启动脚本错误,请仔细检查启动脚本。 +crash.error=Minecraft has crashed. +crash.main_class_not_found=Main Class is not found, may be your mc has been broken. +crash.class_path_wrong=Maybe the launch script is malformed. -ui.label.newProfileWindow.new_profile_name=新配置名: -ui.label.newProfileWindow.copy_from=复制配置: -ui.newProfileWindow.title=新建配置 +ui.label.newProfileWindow.new_profile_name=New Profile Name: +ui.label.newProfileWindow.copy_from=Copy From: +ui.newProfileWindow.title=New Config -ui.button.ok=确认 -ui.button.refresh=刷新 -ui.button.run=启动Minecraft -ui.button.settings= -ui.button.about=关于 -ui.button.others=其他 -ui.button.logout=登出 -ui.button.download=下载 -ui.button.retry=重试 -ui.button.delete=删除 -ui.button.install=安装 -ui.button.info=信息 -ui.button.save=保存 -ui.button.copy=复制 -ui.button.clear=清除 -ui.button.close=关闭 -ui.button.explore=浏览 -ui.button.test=测试 -ui.button.preview=预览 -button.cancel=取消 -button.ok=确定 +ui.button.ok=OK +ui.button.refresh=Refresh +ui.button.run=Play +ui.button.settings=Settings +ui.button.about=About +ui.button.others=Others +ui.button.logout=Log Out +ui.button.download=Download +ui.button.retry=Retry +ui.button.delete=Delete +ui.button.install=Install +ui.button.info=Info +ui.button.save=Save +ui.button.copy=Copy +ui.button.clear=Clear +ui.button.close=Close +ui.button.explore=Explore +ui.button.test=Test +ui.button.preview=Preview +button.cancel=Cancel +button.ok=OK -ui.label.version=版本 -ui.label.password=密码 -ui.label.profile=配置 +ui.label.version=Version +ui.label.password=Password +ui.label.profile=Profile -ui.message.first_load=请在左边输入您的账号 -ui.message.enter_password=请在左边输入您的密码 -ui.message.launching=启动中 -ui.message.making=生成中 -ui.message.sure_remove=真的要删除配置%s吗? -ui.message.update_java=请更新您的Java +ui.message.first_load=Please enter your name. +ui.message.enter_password=Please enter your password. +ui.message.launching=Launching... +ui.message.making=Generating... +ui.message.sure_remove=Sure to remove profile %s? +ui.message.update_java=Please upgrade your Java. -ui.label.settings=选项 -ui.label.crashing=Hello Minecraft!遇到了无法处理的错误,请复制下列内容并通过mcbbs、贴吧、Github或Minecraft Forum反馈bug。 -ui.label.crashing_out_dated=Hello Minecraft! Launcher遇到了无法处理的错误,已检测到您的启动器不是最新版本,请更新后再试! -ui.label.failed_set=设置失败: +ui.label.settings=Settings +ui.label.crashing=Hello Minecraft! Launcher has crashed! +ui.label.crashing_out_dated=Hello Minecraft! Launcher has crashed! Your launcher is outdated. Update it! +ui.label.failed_set=Failed to set: -download=下载 -download.mojang=官方 +download=Download +download.mojang=Mojang download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/) -download.rapid_data=RapidData (锐网云计算, https://www.rapiddata.org/) -download.not_200=下载失败,回复码 -download.failed=下载失败 -download.successfully=下载完成 -download.source=下载源 +download.rapid_data=RapidData (https://www.rapiddata.org/) +download.not_200=Failed to download, the response code +download.failed=Failed to download +download.successfully=Downloaded successfully +download.source=Download Source -message.error=错误 -message.cannot_open_explorer=无法打开文件管理器: -message.cancelled=已取消 -message.info=提示 +message.error=Error +message.cannot_open_explorer=Cannot open explorer: +message.cancelled=Cancelled +message.info=Info +message.loading=Loading... -folder.game=游戏文件夹 -folder.mod=MOD文件夹 -folder.coremod=核心MOD文件夹 -folder.config=配置文件夹 -folder.resourcepacks=资源包文件夹 -folder.screenshots=截图文件夹 -folder.saves=存档文件夹 +folder.game=Game Dir +folder.mod=Mod +folder.coremod=Core Mod +folder.config=Configs +folder.resourcepacks=Resourcepacks +folder.screenshots=Screenshots +folder.saves=Saves -settings.tabs.game_download=游戏下载 -settings.tabs.installers=自动安装 -settings.tabs.assets_downloads=资源下载 +settings.tabs.game_download=Games +settings.tabs.installers=Installers +settings.tabs.assets_downloads=Assets -settings=普通设置 -settings.explore=浏览 -settings.manage=管理 -settings.cannot_remove_default_config=不能删除默认配置 -settings.max_memory=最大内存/MB -settings.java_dir=Java路径 -settings.game_directory=游戏路径 -settings.dimension=游戏窗口分辨率 -settings.fullscreen=全屏 -settings.update_version=更新版本文件 -settings.run_directory=运行路径(版本隔离) -settings.physical_memory=物理内存大小 -settings.choose_javapath=选择Java路径 -settings.default=默认 -settings.custom=自定义 -settings.choose_gamedir=选择游戏路径 -settings.failed_load=设置文件加载失败,可能是升级了启动器或被人工修改造成错误,是否清除? -settings.test_game=测试游戏 +settings=Settings +settings.explore=Explore +settings.manage=Manage +settings.cannot_remove_default_config=Cannot remove the default configution. +settings.max_memory=Max Memory/MB +settings.java_dir=Java Dir +settings.game_directory=Game Directory +settings.dimension=Game Window Dimension +settings.fullscreen=Fullscreen +settings.update_version=Update version json. +settings.run_directory=Run Directory(Version Isolation) +settings.physical_memory=Physical Memory Size +settings.choose_javapath=Choose Java Directory. +settings.default=Default +settings.custom=Custom +settings.choose_gamedir=Choose Game Directory +settings.failed_load=Failed to load settings file. Remove it? +settings.test_game=Test game -modpack=整合包 -modpack.choose=选择要导入的游戏整合包文件,如果您希望更新整合包,请输入要更新的版本名 -modpack.export_error=导出失败,可能是您的游戏文件夹格式不正确或操作文件失败 -modpack.export_finished=整合包导出完成,参见 -modpack.included_launcher=整合包已包含启动器,可直接发布 -modpack.not_included_launcher=整合包未包含启动器,可使用本软件的导入整合包功能导入整合包 -modpack.enter_name=给游戏起个你喜欢的名字 +modpack=Mod pack +modpack.choose=Choose a modpack zip file which you want to import. If you want to update the modpack, please enter the version you want to update. +modpack.export_error=Failed to export the modpack, maybe the format of your game directory is incorrect or failed to manage files. +modpack.export_finished=Exporting the modpack finished. See +modpack.included_launcher=The modpack is included the launcher, you can publish it directly. +modpack.not_included_launcher=You can use the modpack by clicking the "Import Modpack" button. +modpack.enter_name=Enter your desired name for this game. -modpack.task.save=导出整合包 -modpack.task.install=导入整合包 -modpack.task.install.error=安装失败,可能是整合包格式不正确或操作文件失败 -modpack.task.install.will=将会安装整合包: +modpack.task.save=Export Modpack +modpack.task.install=Import Modpack +modpack.task.install.error=Failed to install the modpack. Maybe the files is incorrect, or a management issue occurred. +modpack.task.install.will=Install the modpack: -modpack.wizard=导出整合包向导 -modpack.wizard.step.1=基本设置 -modpack.wizard.step.1.title=设置整合包的主要信息 -modpack.wizard.step.initialization.include_launcher=包含启动器 -modpack.wizard.step.initialization.exported_version=要导出的游戏版本 -modpack.wizard.step.initialization.save=选择要导出到的游戏整合包位置 -modpack.wizard.step.initialization.warning=在制作整合包前,请您确认您选择的版本可以正常启动,
        并保证您的Minecraft是正式版而非快照版,
        而且不应当将不允许非官方途径传播的Mod、材质包等纳入整合包。
        整合包会保存您目前的下载源设置 -modpack.wizard.step.2=文件选择 -modpack.wizard.step.2.title=选中你不想加到整合包中的文件(夹) -modpack.wizard.step.3=整合包描述 -modpack.wizard.step.3.title=描述你要制作的整合包 +modpack.wizard=Exporting the modpack wizard +modpack.wizard.step.1=Basic options +modpack.wizard.step.1.title=Set the basic options to the modpack. +modpack.wizard.step.initialization.include_launcher=Include the launcher +modpack.wizard.step.initialization.exported_version=The exported game version +modpack.wizard.step.initialization.save=Choose a location to export the game files to +modpack.wizard.step.initialization.warning=Before making modpack, you should ensure that your game can launch successfully,
        and that your Minecraft is release, not snapshot.
        and that it is not allowed to add mods which is not allowed to distribute to the modpack. +modpack.wizard.step.2=Files selection +modpack.wizard.step.2.title=Choose the files you do not want to put in the modpack. +modpack.wizard.step.3=Description +modpack.wizard.step.3.title=Describe your modpack. -modpack.desc=描述你要制作的整合包,比如整合包注意事项和更新记录,支持Markdown(图片请用网络图片)。 -modpack.incorrect_format.no_json=整合包格式错误,pack.json丢失 -modpack.incorrect_format.no_jar=整合包格式错误,pack.json丢失jar字段 -modpack.cannot_read_version=读取游戏版本失败 -modpack.not_a_valid_location=不是一个有效整合包位置 -modpack.name=整合包名称 -modpack.not_a_valid_name=不是一个有效的整合包名称 +modpack.desc=Describe your modpack, including precautions, changlog, supporting Markdown(also supporting online pictures). +modpack.incorrect_format.no_json=The format of the modpack is incorrect, pack.json is missing. +modpack.incorrect_format.no_jar=The format of the modpack is incorrect, pack.json does not have attribute 'jar' +modpack.cannot_read_version=Failed to gather the game version +modpack.not_a_valid_location=Not a valid modpack location +modpack.name=Modpack Name +modpack.not_a_valid_name=Not a valid modpack name -modpack.files.servers_dat=多人游戏服务器列表 -modpack.files.saves=游戏存档 -modpack.files.mods=Mod -modpack.files.config=Mod配置文件 -modpack.files.liteconfig=Mod配置文件 -modpack.files.resourcepacks=资源包(材质包) -modpack.files.options_txt=游戏设定 -modpack.files.optionsshaders_txt=光影设定 -modpack.files.mods.voxelmods=VoxelMods配置,如小地图 -modpack.files.dumps=NEI调试输出 -modpack.files.scripts=MineTweaker配置 -modpack.files.blueprints=BuildCraft蓝图 +modpack.files.servers_dat=Multiplayer servers list +modpack.files.saves=Saved games +modpack.files.mods=Mods +modpack.files.config=Mod configs +modpack.files.liteconfig=Mod configurations +modpack.files.resourcepacks=Resource(Texture) packs +modpack.files.options_txt=Game options +modpack.files.optionsshaders_txt=Shaders options +modpack.files.mods.voxelmods=VoxelMods (including VoxelMap) options +modpack.files.dumps=NEI debug output +modpack.files.scripts=MineTweaker configuration +modpack.files.blueprints=BuildCraft blueprints -mods=Mod管理 -mods.choose_mod=选择模组 -mods.failed=添加失败 -mods.add=添加 -mods.remove=删除 -mods.default_information=安装Mod前你需要确保已安装Forge或LiteLoader!
        您可以从资源管理器拖动mod文件到列表中来添加mod,同时使用删除键可快速删除选中mod
        点掉mod前面的勾可禁用mod,不会加载;选择mod可以获取mod信息
        +mods=Mods +mods.choose_mod=Choose your mods +mods.failed=Failed to add mods +mods.add=Add +mods.remove=Remove +mods.default_information=Please ensure that you have installed Forge or LiteLoader before installing mods!
        You can drop your mod files from explorer/finder, and delete mods by the delete button.
        Disable a mod by leaving the check box unchecked; Choose an item to get the information.
        -advancedsettings=高级设置 -advancedsettings.launcher_visible=启动器可见性 -advancedsettings.debug_mode=调试模式 -advancedsettings.java_permanent_generation_space=内存永久保存区域(不必填写,MB) -advancedsettings.jvm_args=Java虚拟机参数(不必填写) -advancedsettings.Minecraft_arguments=Minecraft额外参数(不必填写) -advancedsettings.launcher_visibility.close=游戏启动后结束启动器 -advancedsettings.launcher_visibility.hide=游戏启动后隐藏启动器 -advancedsettings.launcher_visibility.keep=保持启动器可见 -advancedsettings.game_dir.default=默认(.minecraft/) -advancedsettings.game_dir.independent=各版本独立(.minecraft/versions/<版本名>/,除assets,libraries) -advancedsettings.no_jvm_args=不添加默认的JVM参数(使用Java9时必勾) -advancedsettings.java_args_default=启动器默认添加的参数(请不要重复添加):-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -XX:MaxPermSize=???m -Xmx???m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true -advancedsettings.wrapper_launcher=前置指令(不必填写,如optirun) -advancedsettings.precall_command=启动前执行命令(不必填写,将在游戏启动前调用) -advancedsettings.server_ip=直入服务器ip地址(不必填写,启动游戏后直接进入对应服务器) -advancedsettings.cancel_wrapper_launcher=取消包裹启动器(出现奇怪问题时可尝试使用,与调试模式冲突) -advancedsettings.dont_check_game_completeness=不检查游戏完整性 +advancedsettings=Advanced +advancedsettings.launcher_visible=Launcher Visibility +advancedsettings.debug_mode=Debug Mode +advancedsettings.java_permanent_generation_space=PermGen Space/MB +advancedsettings.jvm_args=Java VM Arguments +advancedsettings.Minecraft_arguments=Minecraft Arguments +advancedsettings.launcher_visibility.close=Close the launcher when the game launched. +advancedsettings.launcher_visibility.hide=Hide the launcher when the game launched. +advancedsettings.launcher_visibility.keep=Keep the launcher visible. +advancedsettings.game_dir.default=Default (.minecraft/) +advancedsettings.game_dir.independent=Independent (.minecraft/versions//, except assets,libraries) +advancedsettings.no_jvm_args=No Default JVM Args +advancedsettings.java_args_default=Default java args: -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -XX:MaxPermSize=???m -Xmx???m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true +advancedsettings.wrapper_launcher=Wrapper Launcher(like optirun...) +advancedsettings.precall_command=Precalling command(will be executed before game launching) +advancedsettings.server_ip=Server Host +advancedsettings.cancel_wrapper_launcher=Cancel Wrapper Launcher +advancedsettings.dont_check_game_completeness=Don't check game completeness -mainwindow.show_log=查看日志 -mainwindow.make_launch_script=生成启动脚本 -mainwindow.make_launch_script_failed=生成启动脚本失败 -mainwindow.enter_script_name=输入要生成脚本的文件名 -mainwindow.make_launch_succeed=启动脚本已生成完毕: -mainwindow.no_version=未找到任何版本,是否进入游戏下载? +mainwindow.show_log=Show Logs +mainwindow.make_launch_script=Make Launching Script. +mainwindow.make_launch_script_failed=Failed to make script. +mainwindow.enter_script_name=Enter the script name. +mainwindow.make_launch_succeed=Finished script creation. +mainwindow.no_version=No version found. Switch to Game Downloads Tab? -launcher.about=默认背景图感谢gamerteam提供。
        如果您希望本软件继续发展,请赞助
        关于作者:
        百度ID:huanghongxun20
        mcbbs:huanghongxun
        邮箱:huanghongxun2008@126.com
        Minecraft Forum ID: klkl6523
        欢迎提交Bug哦
        Copyright (c) 2013-2016 huangyuhui.
        免责声明:Minecraft软件版权归Mojang AB所有,使用本软件产生的版权问题本软件制作方概不负责。
        本启动器在GPLv3协议下开源:https://github.com/huanghongxun/HMCL/ ,感谢issues和pull requests贡献者
        本软件使用了基于Apache License 2.0的Gson项目,感谢贡献者。 -launcher.download_source=下载源 -launcher.background_location=背景地址 -launcher.exit_failed=强制退出失败,可能是Forge 1.7.10及更高版本导致的,无法解决。 -launcher.versions_json_not_matched=版本%s格式不规范!该版本文件夹下有json:%s,是否更名这个文件来规范格式? -launcher.versions_json_not_matched_cannot_auto_completion=版本%s缺失必要的版本信息文件,是否删除该版本? -launcher.versions_json_not_formatted=版本%s信息文件格式错误,是否重新下载? -launcher.choose_bgpath=选择背景路径 -launcher.background_tooltip=启动器默认使用自带的背景
        如果当前目录有background.png,则会使用该文件作为背景
        如果当前目录有bg子目录,则会随机使用里面的一张图作为背景
        如果该背景地址被修改,则会使用背景地址里的一张图作为背景
        背景地址允许有多个地址,使用半角分号";"(不包含双引号)分隔 -launcher.update_launcher=检查更新 -launcher.enable_shadow=启用窗口阴影 -launcher.theme=主题 -launcher.proxy=代理 -launcher.decorated=启用窗口边框(Linux下可解决程序界面全灰问题) -launcher.modpack=整合包作者帮助 -launcher.enable_animation=启用动态效果 -launcher.lang=语言 -launcher.restart=本界面选项需要重启本启动器生效 +launcher.about=About Author
        Minecraft Forum ID: klkl6523
        Copyright (c) 2013 huangyuhui
        Opened source under GPL v3 license:http://github.com/huanghongxun/HMCL/
        This software used project Gson which is under Apache License 2.0, thanks contributors. +launcher.download_source=Download Source +launcher.background_location=Background Location +launcher.exit_failed=Failed to shutdown. +launcher.versions_json_not_matched=The version %s is malformed! There are a json:%s in this version. Do you want to fix this problem? +launcher.versions_json_not_matched_cannot_auto_completion=The version %s lost version information file, delete it? +launcher.versions_json_not_formatted=The version information of %s is malformed! Redownload it? +launcher.choose_bgpath=Choose background path. +launcher.background_tooltip=The laucher uses a default background.
        If you use custom background.png, link it and it will be used.
        If there is "bg" subdirectory, this app will chooses one picture in "bgskin" randomly.
        If you set the background setting, this app will use it. +launcher.update_launcher=Check for update +launcher.enable_shadow=Enable Window Shadow +launcher.enable_animation=Enable Animation +launcher.enable_blur=Enable Blur +launcher.theme=Theme +launcher.proxy=Proxy +launcher.decorated=Enable system window border(in order to fix the problem that the ui become all gray in Linux OS) +launcher.modpack=Documentations for modpacks. +launcher.lang=Language +launcher.restart=Options will be in operations only if restart this app. -launcher.title.game=游戏设置 -launcher.title.main=主页 -launcher.title.launcher=启动器设置 +launcher.title.game=Games +launcher.title.main=Home +launcher.title.launcher=Launcher -versions.release=稳定版 -versions.snapshot=快照版 -versions.old_beta=测试版 -versions.old_alpha=远古版 +versions.release=Release +versions.snapshot=Snapshot +versions.old_beta=Beta +versions.old_alpha=Old Alpha -versions.manage.rename=重命名该版本 -versions.manage.rename.message=请输入要改成的名字 -versions.manage.remove=删除该版本 -versions.manage.remove.confirm=真的要删除版本 -versions.manage.redownload_json=重新下载版本配置(minecraft.json) -versions.manage.redownload_assets_index=重新下载资源配置(assets_index.json) -versions.mamage.remove_libraries=删除所有库文件 +versions.manage.rename=Rename this version +versions.manage.rename.message=Please enter the new name +versions.manage.remove=Delete this version +versions.manage.remove.confirm=Sure to remove the version +versions.manage.redownload_json=Redownload Minecraft Configuration(minecraft.json) +versions.manage.redownload_assets_index=Redownload Assets Index +versions.mamage.remove_libraries=Delete library files -advice.os64butjdk32=您的系统是64位的但是Java是32位的,推荐您安装64位Java. +advice.os64butjdk32=Your OS is 64-Bit but your Java is 32-Bit. The 64-Bit Java is recommended. -assets.download_all=下载资源文件 -assets.not_refreshed=资源列表未刷新,请刷新一次。 -assets.failed=获取列表失败,请刷新重试。 -assets.list.1_7_3_after=1.7.3及以后 +assets.download_all=Download Assets Files +assets.not_refreshed=The assets list is not refreshed, please refresh it once. +assets.failed=Failed to get the list, try again. +assets.list.1_7_3_after=1.7.3 And higher assets.list.1_6=1.6(BMCLAPI) -assets.unkown_type_select_one=无法解析游戏版本:%s,请选择一种资源类型下载。 -assets.type=资源类型 -assets.download=下载资源 -assets.no_assets=资源文件不完整,是否补全? -assets.failed_download=下载资源文件失败,可能导致没有中文和声音。 +assets.unkown_type_select_one=Unknown game version: %s, please choose an asset type. +assets.type=Asset Type +assets.download=Download Assets +assets.no_assets=Assets are not complete, complete them? +assets.failed_download=Failed to download assets, may cause no sounds and language files. -gamedownload.not_refreshed=游戏下载列表未刷新,请再刷新一次。 +gamedownload.not_refreshed=The game list is not refreshed, please refresh it once. -taskwindow.title=任务 -taskwindow.single_progress=单项进度 -taskwindow.total_progress=总进度 -taskwindow.cancel=取消 -taskwindow.no_more_instance=可能同时打开了多个任务窗口,请不要多次打开! -taskwindow.file_name=任务 -taskwindow.download_progress=进度 +taskwindow.title=Tasks +taskwindow.single_progress=Single progress +taskwindow.total_progress=Total progress +taskwindow.cancel=Cancel +taskwindow.no_more_instance=Maybe you opened more than one task window, don't open it again! +taskwindow.file_name=Task +taskwindow.download_progress=Pgs. -setupwindow.include_minecraft=导入游戏文件夹 -setupwindow.find_in_configurations=导入完成,快到配置下拉框中找新游戏路径吧! -setupwindow.give_a_name=给新游戏路径起个名字吧 -setupwindow.new=新建 -setupwindow.no_empty_name=名字不可为空 -setupwindow.clean=清理游戏文件 +setupwindow.include_minecraft=Import game +setupwindow.find_in_configurations=Finished importing. You can find it in the configuration selection bar. +setupwindow.give_a_name=Give a name to the new game. +setupwindow.new=New +setupwindow.no_empty_name=Version name cannot be empty. +setupwindow.clean=Clean game files -update.no_browser=无法打开浏览器,网址已经复制到剪贴板了,您可以手动粘贴网址打开页面 -update.should_open_link=是否更新? -update.newest_version=最新版本为: -update.failed=检查更新失败 -update.found=(发现更新!) +update.no_browser=Cannot open any browser. The link has been copied to the clipboard. Paste it to a browser address bar to update. +update.should_open_link=Are you willing to update the launcher? +update.newest_version=Newest version: +update.failed=Failed to check for updates. +update.found=(Found Update!) -logwindow.terminate_game=结束游戏进程 -logwindow.tieba=贴吧 -logwindow.title=日志 +logwindow.terminate_game=Terminate Game +logwindow.tieba=Baidu Tieba +logwindow.title=Log -selector.choose=选择 +selector.choose=Choose -serverlistview.title=选择服务器 -serverlistview.name=名称 -serverlistview.type=类型 -serverlistview.version=版本 -serverlistview.info=信息 +serverlistview.title=Choose a server +serverlistview.name=Name +serverlistview.type=Type +serverlistview.version=Version +serverlistview.info=Information -minecraft.invalid=无效的 -minecraft.invalid_jar=无效的jar包 -minecraft.not_a_file=不是文件 -minecraft.not_found=找不到minecraft.jar -minecraft.not_readable=minecraft.jar不可读 -minecraft.modified=(修改的!) +minecraft.invalid=Invalid +minecraft.invalid_jar=Invalid Jar +minecraft.not_a_file=Not a file +minecraft.not_found=Not found +minecraft.not_readable=Not readable +minecraft.modified=(Modified!) -color.red=红色 -color.blue=蓝色 -color.green=绿色 -color.orange=橙色 -color.dark_blue=深蓝色 -color.purple=紫色 +color.red=Red +color.blue=Blue +color.green=Green +color.orange=Orange +color.dark_blue=Dark Blue +color.purple=Purple -wizard.next_>=下一步 > -wizard.next_mnemonic=下 -wizard.<_prev=< 上一步 -wizard.prev_mnemonic=上 -wizard.finish=完成 -wizard.finish_mnemonic=完 -wizard.cancel=取消 -wizard.cancel_mnemonic=取 -wizard.help=帮助 -wizard.help_mnemonic=帮 -wizard.close=关闭 -wizard.close_mnemonic=关 -wizard.summary=概要 -wizard.failed=失败 -wizard.steps=步骤 +wizard.next_>=Next > +wizard.next_mnemonic=N +wizard.<_prev=< Prev +wizard.prev_mnemonic=P +wizard.finish=Finish +wizard.finish_mnemonic=F +wizard.cancel=Cancel +wizard.cancel_mnemonic=C +wizard.help=Help +wizard.help_mnemonic=H +wizard.close=Close +wizard.close_mnemonic=C +wizard.summary=Summary +wizard.failed=Failed +wizard.steps=Steps -lang=简体中文 -lang.default=跟随系统语言 +lang=English +lang.default=Belong to OS language. diff --git a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N.properties b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N.properties index 642388d74..0ad6ed310 100755 --- a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N.properties +++ b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N.properties @@ -13,404 +13,408 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see {http://www.gnu.org/licenses/}. -launch.failed=\u542f\u52a8\u5931\u8d25 -launch.failed_creating_process=\u542f\u52a8\u5931\u8d25\uff0c\u5728\u521b\u5efa\u65b0\u8fdb\u7a0b\u65f6\u53d1\u751f\u9519\u8bef\uff0c\u53ef\u80fd\u662fJava\u8def\u5f84\u9519\u8bef\u3002 -launch.failed_sh_permission=\u4e3a\u542f\u52a8\u6587\u4ef6\u6dfb\u52a0\u6743\u9650\u65f6\u53d1\u751f\u9519\u8bef -launch.failed_packing_jar=\u5728\u6253\u5305jar\u65f6\u53d1\u751f\u9519\u8bef -launch.unsupported_launcher_version=\u5bf9\u4e0d\u8d77\uff0c\u672c\u542f\u52a8\u5668\u73b0\u5728\u53ef\u80fd\u4e0d\u80fd\u542f\u52a8\u8fd9\u4e2a\u7248\u672c\u7684Minecraft\uff0c\u4f46\u542f\u52a8\u5668\u8fd8\u662f\u4f1a\u5c1d\u8bd5\u542f\u52a8\uff0c\u8bf7\u5c3d\u5feb\u5c06\u6b64\u95ee\u9898\u62a5\u544a\u7ed9\u4f5c\u8005\u3002 -launch.too_big_memory_alloc_64bit=\u60a8\u8bbe\u7f6e\u7684\u5185\u5b58\u5927\u5c0f\u8fc7\u5927\uff0c\u7531\u4e8e\u53ef\u80fd\u8d85\u8fc7\u4e8632\u4f4dJava\u7684\u5185\u5b58\u5206\u914d\u9650\u5236\uff0c\u6240\u4ee5\u53ef\u80fd\u65e0\u6cd5\u542f\u52a8\u6e38\u620f\uff0c\u8bf7\u5c06\u5185\u5b58\u8c03\u81f31024MB\u6216\u66f4\u5c0f\uff0c\u542f\u52a8\u5668\u4ecd\u4f1a\u5c1d\u8bd5\u542f\u52a8\u3002 -launch.too_big_memory_alloc_free_space_too_low=\u60a8\u8bbe\u7f6e\u7684\u5185\u5b58\u5927\u5c0f\u8fc7\u5927\uff0c\u7531\u4e8e\u8d85\u8fc7\u4e86\u7cfb\u7edf\u5185\u5b58\u5927\u5c0f%dMB\uff0c\u6240\u4ee5\u53ef\u80fd\u5f71\u54cd\u6e38\u620f\u4f53\u9a8c\u6216\u65e0\u6cd5\u542f\u52a8\u6e38\u620f\uff0c\u542f\u52a8\u5668\u4ecd\u4f1a\u5c1d\u8bd5\u542f\u52a8\u3002 -launch.cannot_create_jvm=\u622a\u83b7\u5230\u65e0\u6cd5\u521b\u5efaJava\u865a\u62df\u673a\uff0c\u53ef\u80fd\u662fJava\u53c2\u6570\u6709\u95ee\u9898\uff0c\u53ef\u4ee5\u5728\u8bbe\u7f6e\u4e2d\u5f00\u542f\u65e0\u53c2\u6570\u6a21\u5f0f\u542f\u52a8 -launch.circular_dependency_versions=\u53d1\u73b0\u6e38\u620f\u7248\u672c\u5faa\u73af\u5f15\u7528\uff0c\u8bf7\u786e\u8ba4\u60a8\u7684\u5ba2\u6237\u7aef\u672a\u88ab\u4fee\u6539\u6216\u4fee\u6539\u5bfc\u81f4\u51fa\u73b0\u6b64\u95ee\u9898\u3002 -launch.not_finished_downloading_libraries=\u672a\u5b8c\u6210\u6e38\u620f\u4f9d\u8d56\u5e93\u7684\u4e0b\u8f7d\uff0c\u8fd8\u8981\u7ee7\u7eed\u542f\u52a8\u6e38\u620f\u5417\uff1f -launch.not_finished_decompressing_natives=\u672a\u80fd\u89e3\u538b\u6e38\u620f\u672c\u5730\u5e93\uff0c\u8fd8\u8981\u7ee7\u7eed\u542f\u52a8\u6e38\u620f\u5417\uff1f -launch.wrong_javadir=\u9519\u8bef\u7684Java\u8def\u5f84\uff0c\u5c06\u81ea\u52a8\u91cd\u7f6e\u4e3a\u9ed8\u8ba4Java\u8def\u5f84\u3002 -launch.exited_abnormally=\u6e38\u620f\u975e\u6b63\u5e38\u9000\u51fa\uff0c\u8bf7\u67e5\u770b\u65e5\u5fd7\u6587\u4ef6\uff0c\u6216\u8054\u7cfb\u4ed6\u4eba\u5bfb\u6c42\u5e2e\u52a9\u3002 +# +#author: huangyuhui, dxNeil +launch.failed=Failed to launch. +launch.failed_creating_process=Failed to create process, maybe your java path is wrong, please modify your java path. +launch.failed_sh_permission=Failed to add permission to the launch script. +launch.failed_packing_jar=Failed to pack the jar. +launch.unsupported_launcher_version=Sorry, the launcher cannot launch minecraft, but will retry launching it. +launch.too_big_memory_alloc_64bit=You have allocated too much memory, because of your 32-Bit Java Runtime Environment, your game probably crash. The maximum memory is 1024MB. The launcher will try to launch it. +launch.too_big_memory_alloc_free_space_too_low=You have allocated too much memory, because the physical memory size is %dMB, your game probably crash. The launcher will try to launch it. +launch.cannot_create_jvm=We find that it cannot create java virutal machine. The Java argements may have problems. You can enable the no args mode in the settings. +launch.circular_dependency_versions=Found circular dependency versions, please check if your client has been modified. +launch.not_finished_downloading_libraries=Did not finish downloading libraries, continue launching game? +launch.not_finished_decompressing_natives=Did not finish decompressing native libraries, continue launching game? +launch.wrong_javadir=Incorrect Java directory, will reset to default Java directory. +launch.exited_abnormally=Game exited abnormally, please visit the log, or ask someone for help. -launch.state.logging_in=\u767b\u5f55\u4e2d -launch.state.generating_launching_codes=\u6b63\u5728\u751f\u6210\u542f\u52a8\u4ee3\u7801 -launch.state.downloading_libraries=\u6b63\u5728\u4e0b\u8f7d\u5fc5\u8981\u6587\u4ef6 -launch.state.decompressing_natives=\u6b63\u5728\u91ca\u653e\u672c\u5730\u6587\u4ef6 +launch.state.logging_in=Logging In +launch.state.generating_launching_codes=Generating Launching Codes +launch.state.downloading_libraries=Downloading dependencies +launch.state.decompressing_natives=Decompressing natives -install.no_version=\u672a\u627e\u5230\u8981\u5b89\u88c5\u7684\u5bf9\u5e94MC\u7248\u672c -install.no_version_if_intall=\u672a\u627e\u5230\u8981\u5b89\u88c5\u7684\u5bf9\u5e94MC\u7248\u672c\uff0c\u662f\u5426\u81ea\u52a8\u5b89\u88c5\u9700\u8981\u7684MC\u7248\u672c\uff1f -install.not_refreshed=\u672a\u5237\u65b0\u5217\u8868 -install.download_list=\u4e0b\u8f7d\u5217\u8868 +install.no_version=The version is not found. +install.no_version_if_intall=The required version is not found, do you wish to install the version automatically? +install.not_refreshed=The installer list is not refreshed. +install.download_list=Download List -install.liteloader.get_list=\u83b7\u53d6LiteLoader\u5217\u8868 -install.liteloader.install=\u5b89\u88c5LiteLoader +install.liteloader.get_list=Get LiteLoader List +install.liteloader.install=Install LiteLoader -install.forge.get_list=\u83b7\u53d6Forge\u5217\u8868 -install.forge.install=\u5b89\u88c5Forge -install.forge.get_changelogs=\u83b7\u53d6Forge\u66f4\u65b0\u8bb0\u5f55 +install.forge.get_list=Get Forge List +install.forge.install=Install Forge +install.forge.get_changelogs=Get Forge Changelogs -install.optifine.install=\u5b89\u88c5OptiFine -install.optifine.get_list=\u83b7\u53d6OptiFine\u5217\u8868 -install.optifine.get_download_link=\u83b7\u53d6OptiFine\u4e0b\u8f7d\u5730\u5740 +install.optifine.install=Install OptiFine +install.optifine.get_list=Get OptiFine Download List +install.optifine.get_download_link=Get the Download Link of OptiFine -install.failed_forge=\u5b89\u88c5Forge\u5931\u8d25 -install.failed_optifine=\u5b89\u88c5OptiFine\u5931\u8d25 -install.failed_liteloader=\u5b89\u88c5LiteLoader\u5931\u8d25 -install.failed_download_forge=\u4e0b\u8f7dForge\u5931\u8d25 -install.failed_download_optifine=\u4e0b\u8f7dOptiFine\u5931\u8d25 -install.failed=\u5b89\u88c5\u5931\u8d25 -install.success=\u5b89\u88c5\u6210\u529f -install.no_forge=\u6ca1\u6709\u5b89\u88c5Forge -install.choose_forge=\u9009\u62e9\u4f60\u5b89\u88c5\u7684Forge\u7248\u672c -install.version=\u7248\u672c -install.mcversion=\u6e38\u620f\u7248\u672c -install.time=\u65f6\u95f4 -install.release_time=\u91ca\u653e\u65f6\u95f4 -install.type=\u7c7b\u578b -install.please_refresh=\u5982\u9700\u4f7f\u7528\u81ea\u52a8\u5b89\u88c5\u8bf7\u70b9\u51fb\u53f3\u4fa7\u5237\u65b0\u6309\u94ae +install.failed_forge=Failed to install 'Forge'. +install.failed_optifine=Failed to install 'OptiFine'. +install.failed_liteloader=Failed to install 'LiteLoader'. +install.failed_download_forge=Failed to download 'Forge'. +install.failed_download_optifine=Failed to download 'OptiFine'. +install.failed=Failed to install +install.success=Install successfully +install.no_forge=No Forge +install.choose_forge=Choose the version you want to install Forge +install.version=Version +install.mcversion=Game Version +install.time=Time +install.release_time=Release Time +install.type=Type +install.please_refresh=If you want to install something please click "Refresh" button. -crash.launcher=\u542f\u52a8\u5668\u5d29\u6e83\u4e86\uff01 -crash.minecraft=Minecraft\u5d29\u6e83\u4e86\uff01\u8bf7\u8ba4\u771f\u9605\u8bfb\u5efa\u8bae\u3002 +crash.launcher=Launcher has crashed! +crash.minecraft=Minecraft has crashed! -login.choose_charactor=\u8bf7\u9009\u62e9\u60a8\u8981\u4f7f\u7528\u7684\u89d2\u8272 -login.no_charactor=\u8be5\u5e10\u53f7\u6ca1\u6709\u89d2\u8272 -login.your_password=\u60a8\u7684\u5bc6\u7801 -login.failed=\u767b\u5f55\u5931\u8d25\uff1a -login.no_Player007=\u4f60\u8fd8\u672a\u8bbe\u7f6e\u7528\u6237\u540d\uff01 -login.wrong_password=\u53ef\u80fd\u662f\u60a8\u7684\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef -login.invalid_username=\u65e0\u6548\u7684\u7528\u6237\u540d -login.invalid_uuid_and_username=\u65e0\u6548\u7684UUID\u548c\u7528\u6237\u540d -login.invalid_password=\u65e0\u6548\u7684\u5bc6\u7801 -login.invalid_access_token=\u65e0\u6548\u7684\u8bbf\u95ee\u4ee4\u724c -login.changed_client_token=\u670d\u52a1\u5668\u56de\u5e94\u5df2\u7ecf\u4fee\u6539\u5ba2\u6237\u7aef\u4ee4\u724c -login.not_email=\u7528\u6237\u540d\u5fc5\u987b\u662f\u90ae\u7bb1 -login.type=\u767b\u5f55 -login.username=\u540d\u5b57 -login.account=\u90ae\u7bb1 -login.invalid_token=\u8bf7\u5c1d\u8bd5\u767b\u51fa\u5e76\u91cd\u65b0\u8f93\u5165\u5bc6\u7801\u767b\u5f55 -login.no_valid_character=\u65e0\u6709\u6548\u7684\u89d2\u8272\uff0c\u81ea\u884c\u5230skinme.cc\u767b\u9646\u5e76\u521b\u5efa\u89d2\u8272 +login.choose_charactor=Please choose the character you want +login.no_charactor=No character in this account. +login.your_password=Your password +login.failed=Failed to login +login.no_Player007=You have not set a username! +login.wrong_password=Incorrect password or username +login.invalid_username=Invalid username +login.invalid_uuid_and_username=Invalid UUID and username +login.invalid_password=Invalid password +login.invalid_access_token=Invalid Access Token +login.changed_client_token=The server response has changed the client token. +login.not_email=The username must be a e-mail. +login.type=Login +login.username=Name +login.account=Email +login.invalid_token=Please log out and re-input your password to log in. +login.no_valid_character=No valid character, please visit skinme.cc and create your own character. -proxy.username=\u8d26\u6237 -proxy.password=\u5bc6\u7801 -proxy.host=\u4e3b\u673a -proxy.port=\u7aef\u53e3 +proxy.username=Account +proxy.password=Password +proxy.host=Host +proxy.port=Port -login.failed.connect_authentication_server=\u65e0\u6cd5\u8fde\u63a5\u8ba4\u8bc1\u670d\u52a1\u5668,\u53ef\u80fd\u662f\u7f51\u7edc\u95ee\u9898 +login.failed.connect_authentication_server=Cannot connect the authentication server. Check your network. -login.profile.not_logged_in=\u65e0\u6cd5\u4fee\u6539\u6e38\u620f\u8d44\u6599\u540c\u65f6\u672a\u767b\u5f55 -login.profile.selected=\u65e0\u6cd5\u4fee\u6539\u6e38\u620f\u8d44\u6599. \u4f60\u5fc5\u987b\u767b\u51fa\u518d\u8fd4\u56de. +login.profile.not_logged_in=You are not logged in, you can't modify the profile! +login.profile.selected=Can't modify the profile, logout and go retry. -login.methods.yggdrasil=\u6b63\u7248\u767b\u5f55 -login.methods.offline=\u79bb\u7ebf\u6a21\u5f0f -login.methods.no_method=\u6ca1\u6709\u767b\u5165\u65b9\u5f0f... +login.methods.yggdrasil=Mojang +login.methods.offline=Offline +login.methods.no_method=No login method -log.playername_null=\u73a9\u5bb6\u540d\u4e3a\u7a7a\uff0c\u8fd9\u4ee3\u8868\u7740\u767b\u5f55\u65b9\u6cd5\u51fa\u73b0\u95ee\u9898 +log.playername_null=The player name is empty. -minecraft.no_selected_version=\u6ca1\u6709\u9009\u62e9\u4efb\u4f55\u4e00\u4e2aMinecraft\u7248\u672c -minecraft.wrong_path=\u9519\u8bef\u7684Minecraft\u8def\u5f84\uff0c\u542f\u52a8\u5668\u672a\u627e\u5230\u8bbe\u5b9a\u7684Minecraft\u8def\u5f84\uff0c\u8bf7\u68c0\u67e5\u3002 +minecraft.no_selected_version=No selected Minecraft version +minecraft.wrong_path=Wrong Minecraft path, the launcher could not find the path. -operation.stopped=\u64cd\u4f5c\u88ab\u5f3a\u884c\u7ec8\u6b62 -operation.confirm_stop=\u771f\u7684\u8981\u7ec8\u6b62\u64cd\u4f5c\u5417\uff1f +operation.stopped=The operation was aborted. +operation.confirm_stop=Terminate the operations? -ui.login.password=\u5bc6\u7801 -ui.more=\u66f4\u591a +ui.login.password=Password +ui.more=More -crash.advice.UnsupportedClassVersionError=\u8fd9\u53ef\u80fd\u662f\u56e0\u4e3a\u60a8\u7684Java\u7248\u672c\u8fc7\u4e8e\u8001\u65e7\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u66f4\u6362\u6700\u65b0Java\u5e76\u5728\u7248\u672c\u8bbe\u7f6e\u7684Java\u8def\u5f84\u4e2d\u8bbe\u7f6e. -crash.advice.ConcurrentModificationException=\u8fd9\u53ef\u80fd\u662f\u56e0\u4e3a\u60a8\u7684Java\u7248\u672c\u9ad8\u4e8eJava 1.8.0_11\u5bfc\u81f4\u7684,\u53ef\u4ee5\u5c1d\u8bd5\u5378\u8f7dJava8\u5b89\u88c5Java7\u3002 -crash.advice.ClassNotFoundException=Minecraft\u4e0d\u5b8c\u6574\u6216Mod\u51b2\u7a81\uff0c\u5982\u679c\u6709\u672a\u80fd\u4e0b\u8f7d\u7684\u6587\u4ef6\u8bf7\u4e0b\u8f7d\u6210\u529f\u540e\u91cd\u8bd5\u6216\u662f\u5ba2\u6237\u7aef\u635f\u574f\u8bf7\u91cd\u8bd5\u8bf7\u91cd\u65b0\u5236\u4f5c\u5ba2\u6237\u7aef\u6216\u4e0b\u8f7d\u6574\u5408\u5305\u89e3\u51b3\u95ee\u9898\uff0c\u53e6\u53ef\u5c1d\u8bd5\u6e38\u620f\u8bbe\u7f6e->\uff08\u7248\u672c\uff09\u7ba1\u7406->\u5220\u9664\u5e93\u6587\u4ef6\u89e3\u51b3\u95ee\u9898 -crash.advice.NoSuchFieldError=Minecraft\u4e0d\u5b8c\u6574\u6216Mod\u51b2\u7a81\uff0c\u5982\u679c\u6709\u672a\u80fd\u4e0b\u8f7d\u7684\u6587\u4ef6\u8bf7\u4e0b\u8f7d\u6210\u529f\u540e\u91cd\u8bd5\u6216\u662f\u5ba2\u6237\u7aef\u635f\u574f\u8bf7\u91cd\u8bd5\u8bf7\u91cd\u65b0\u5236\u4f5c\u5ba2\u6237\u7aef\u6216\u4e0b\u8f7d\u6574\u5408\u5305\u89e3\u51b3\u95ee\u9898\u3002 -crash.advice.LWJGLException=\u60a8\u7684\u7535\u8111\u4e0d\u6b63\u5e38\uff0c\u53ef\u80fd\u9700\u8981\u4f7f\u7528\u9a71\u52a8\u7cbe\u7075\u6216\u5176\u4ed6\u5b89\u88c5\u5668\u66f4\u65b0\u663e\u5361\u9a71\u52a8\u3002 -crash.advice.SecurityException=\u53ef\u80fd\u662f\u60a8\u4fee\u6539\u4e86minecraft.jar\u4f46\u672a\u5220\u9664META-INF\u6587\u4ef6\u5939\u7684\u539f\u56e0\u3002\u8bf7\u901a\u8fc7\u538b\u7f29\u8f6f\u4ef6\u5220\u9664jar\u4e2d\u7684META-INF\u6587\u4ef6\u5939\u3002 -crash.advice.OutOfMemoryError=\u5185\u5b58\u6ea2\u51fa\uff0c\u60a8\u8bbe\u7f6e\u7684Minecraft\u6700\u5927\u5185\u5b58\u8fc7\u5c0f\uff0c\u8bf7\u8c03\u5927\uff01 -crash.advice.otherwise=\u53ef\u80fd\u662fMod\u6216\u5176\u4ed6\u95ee\u9898\u3002 +crash.advice.UnsupportedClassVersionError=Maybe your java is too old, try to update the java. +crash.advice.ConcurrentModificationException=Maybe your Java is newer than 1.8.0_11, you could downgrade to Java 7. +crash.advice.ClassNotFoundException=Minecraft or mods are incomplete. Retry if there are some libraries that have not downloaded or update your game and mods! Or you can try Game Settings -> Manage (Version) -> Delete library files to solve the problem. +crash.advice.NoSuchFieldError=Minecraft or mods are incomplete. Retry if there are some libraries that have not downloaded or update your game and mods! +crash.advice.LWJGLException=Maybe your video driver does not work well, please update your video driver. +crash.advice.SecurityException=Maybe you have modified minecraft.jar but have not removed the META-INF. +crash.advice.OutOfMemoryError=The maximum memory of JVM is too small, please modify it. +crash.advice.otherwise=Maybe mods caused problems. -crash.advice.OpenGL=\u53ef\u80fd\u662f\u663e\u5361/\u58f0\u5361\u9a71\u52a8\u95ee\u9898\uff0c\u4e5f\u53ef\u80fd\u662fMod\u5bfc\u81f4\u7684\u95ee\u9898\u3002 -crash.advice.no_lwjgl=\u53ef\u80fd\u662f\u6e38\u620f\u4f9d\u8d56\u5e93\u4e0d\u5b8c\u6574\u6216\u89e3\u538b\u4f9d\u8d56\u5e93\u65f6\u51fa\u9519\u3002\u53ef\u4ee5\u901a\u8fc7\u4e0b\u8f7d\u6574\u5408\u5305\u89e3\u51b3\u95ee\u9898\u3002 +crash.advice.OpenGL=Maybe drivers caused problems. +crash.advice.no_lwjgl=Maybe drivers caused problems. -crash.advice.no=\u65e0\u5efa\u8bae\u3002 +crash.advice.no=No advice. -crash.user_fault=\u60a8\u7684\u7cfb\u7edf\u6216Java\u73af\u5883\u53ef\u80fd\u5b89\u88c5\u4e0d\u5f53\u5bfc\u81f4\u672c\u8f6f\u4ef6\u5d29\u6e83\uff0c\u8bf7\u68c0\u67e5\u60a8\u7684Java\u73af\u5883\u6216\u60a8\u7684\u7535\u8111\uff01\u53ef\u4ee5\u5c1d\u8bd5\u91cd\u65b0\u5b89\u88c5Java\u3002 -crash.headless=\u5982\u679c\u60a8\u7684\u64cd\u4f5c\u7cfb\u7edf\u662fLinux\uff0c\u8bf7\u6ce8\u610f\u4e0d\u8981\u4f7f\u7528OpenJDK\uff0c\u52a1\u5fc5\u4f7f\u7528Oracle JDK\uff0c\u6216\u5c1d\u8bd5\u6dfb\u52a0-Djava.awt.headless=false\u53c2\u6570\uff0c\u6216\u68c0\u67e5\u60a8\u7684Xserver\u662f\u5426\u6b63\u5e38 -crash.NoClassDefFound=\u8bf7\u786e\u8ba4HMCL\u672c\u4f53\u662f\u5426\u5b8c\u6574 +crash.user_fault=Your OS or Java environment may not be properly installed resulting in crashing of this software, please check your Java Environment or your computer! +crash.headless=If your OS is Linux, please use Oracle JDK instead of OpenJDK, or add "-Djava.awt.headless=false" JVM argument, or check if your Xserver works normally. +crash.NoClassDefFound=Please check "HMCL" software is complete. -crash.error=\u60a8\u7684Minecraft\u5d29\u6e83\u4e86\u3002 -crash.main_class_not_found=\u627e\u4e0d\u5230\u4e3b\u7c7b\uff0c\u53ef\u80fd\u662f\u60a8\u7684JSON\u6587\u4ef6\u586b\u5199\u9519\u8bef\u3002\u65e0\u6cd5\u542f\u52a8\u6e38\u620f\u3002\u53ef\u4ee5\u901a\u8fc7\u4e0b\u8f7d\u6574\u5408\u5305\u89e3\u51b3\u95ee\u9898\u3002 -crash.class_path_wrong=\u89e3\u6790Class Path\u65f6\u51fa\u73b0\u9519\u8bef\uff0c\u6b64\u9519\u8bef\u672c\u4e0d\u5e94\u8be5\u53d1\u751f\u3002\u53ef\u80fd\u662f\u542f\u52a8\u811a\u672c\u9519\u8bef\uff0c\u8bf7\u4ed4\u7ec6\u68c0\u67e5\u542f\u52a8\u811a\u672c\u3002 +crash.error=Minecraft has crashed. +crash.main_class_not_found=Main Class is not found, may be your mc has been broken. +crash.class_path_wrong=Maybe the launch script is malformed. -ui.label.newProfileWindow.new_profile_name=\u65b0\u914d\u7f6e\u540d: -ui.label.newProfileWindow.copy_from=\u590d\u5236\u914d\u7f6e: -ui.newProfileWindow.title=\u65b0\u5efa\u914d\u7f6e +ui.label.newProfileWindow.new_profile_name=New Profile Name: +ui.label.newProfileWindow.copy_from=Copy From: +ui.newProfileWindow.title=New Config -ui.button.ok=\u786e\u8ba4 -ui.button.refresh=\u5237\u65b0 -ui.button.run=\u542f\u52a8Minecraft -ui.button.settings= -ui.button.about=\u5173\u4e8e -ui.button.others=\u5176\u4ed6 -ui.button.logout=\u767b\u51fa -ui.button.download=\u4e0b\u8f7d -ui.button.retry=\u91cd\u8bd5 -ui.button.delete=\u5220\u9664 -ui.button.install=\u5b89\u88c5 -ui.button.info=\u4fe1\u606f -ui.button.save=\u4fdd\u5b58 -ui.button.copy=\u590d\u5236 -ui.button.clear=\u6e05\u9664 -ui.button.close=\u5173\u95ed -ui.button.explore=\u6d4f\u89c8 -ui.button.test=\u6d4b\u8bd5 -ui.button.preview=\u9884\u89c8 -button.cancel=\u53d6\u6d88 -button.ok=\u786e\u5b9a +ui.button.ok=OK +ui.button.refresh=Refresh +ui.button.run=Play +ui.button.settings=Settings +ui.button.about=About +ui.button.others=Others +ui.button.logout=Log Out +ui.button.download=Download +ui.button.retry=Retry +ui.button.delete=Delete +ui.button.install=Install +ui.button.info=Info +ui.button.save=Save +ui.button.copy=Copy +ui.button.clear=Clear +ui.button.close=Close +ui.button.explore=Explore +ui.button.test=Test +ui.button.preview=Preview +button.cancel=Cancel +button.ok=OK -ui.label.version=\u7248\u672c -ui.label.password=\u5bc6\u7801 -ui.label.profile=\u914d\u7f6e +ui.label.version=Version +ui.label.password=Password +ui.label.profile=Profile -ui.message.first_load=\u8bf7\u5728\u5de6\u8fb9\u8f93\u5165\u60a8\u7684\u8d26\u53f7 -ui.message.enter_password=\u8bf7\u5728\u5de6\u8fb9\u8f93\u5165\u60a8\u7684\u5bc6\u7801 -ui.message.launching=\u542f\u52a8\u4e2d -ui.message.making=\u751f\u6210\u4e2d -ui.message.sure_remove=\u771f\u7684\u8981\u5220\u9664\u914d\u7f6e%s\u5417\uff1f -ui.message.update_java=\u8bf7\u66f4\u65b0\u60a8\u7684Java +ui.message.first_load=Please enter your name. +ui.message.enter_password=Please enter your password. +ui.message.launching=Launching... +ui.message.making=Generating... +ui.message.sure_remove=Sure to remove profile %s? +ui.message.update_java=Please upgrade your Java. -ui.label.settings=\u9009\u9879 -ui.label.crashing=Hello Minecraft!\u9047\u5230\u4e86\u65e0\u6cd5\u5904\u7406\u7684\u9519\u8bef\uff0c\u8bf7\u590d\u5236\u4e0b\u5217\u5185\u5bb9\u5e76\u901a\u8fc7mcbbs\u3001\u8d34\u5427\u3001Github\u6216Minecraft Forum\u53cd\u9988bug\u3002 -ui.label.crashing_out_dated=Hello Minecraft! Launcher\u9047\u5230\u4e86\u65e0\u6cd5\u5904\u7406\u7684\u9519\u8bef\uff0c\u5df2\u68c0\u6d4b\u5230\u60a8\u7684\u542f\u52a8\u5668\u4e0d\u662f\u6700\u65b0\u7248\u672c\uff0c\u8bf7\u66f4\u65b0\u540e\u518d\u8bd5\uff01 -ui.label.failed_set=\u8bbe\u7f6e\u5931\u8d25\uff1a +ui.label.settings=Settings +ui.label.crashing=Hello Minecraft! Launcher has crashed! +ui.label.crashing_out_dated=Hello Minecraft! Launcher has crashed! Your launcher is outdated. Update it! +ui.label.failed_set=Failed to set: -download=\u4e0b\u8f7d -download.mojang=\u5b98\u65b9 +download=Download +download.mojang=Mojang download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/) -download.rapid_data=RapidData (\u9510\u7f51\u4e91\u8ba1\u7b97, https://www.rapiddata.org/) -download.not_200=\u4e0b\u8f7d\u5931\u8d25\uff0c\u56de\u590d\u7801 -download.failed=\u4e0b\u8f7d\u5931\u8d25 -download.successfully=\u4e0b\u8f7d\u5b8c\u6210 -download.source=\u4e0b\u8f7d\u6e90 +download.rapid_data=RapidData (https://www.rapiddata.org/) +download.not_200=Failed to download, the response code +download.failed=Failed to download +download.successfully=Downloaded successfully +download.source=Download Source -message.error=\u9519\u8bef -message.cannot_open_explorer=\u65e0\u6cd5\u6253\u5f00\u6587\u4ef6\u7ba1\u7406\u5668: -message.cancelled=\u5df2\u53d6\u6d88 -message.info=\u63d0\u793a +message.error=Error +message.cannot_open_explorer=Cannot open explorer: +message.cancelled=Cancelled +message.info=Info +message.loading=Loading... -folder.game=\u6e38\u620f\u6587\u4ef6\u5939 -folder.mod=MOD\u6587\u4ef6\u5939 -folder.coremod=\u6838\u5fc3MOD\u6587\u4ef6\u5939 -folder.config=\u914d\u7f6e\u6587\u4ef6\u5939 -folder.resourcepacks=\u8d44\u6e90\u5305\u6587\u4ef6\u5939 -folder.screenshots=\u622a\u56fe\u6587\u4ef6\u5939 -folder.saves=\u5b58\u6863\u6587\u4ef6\u5939 +folder.game=Game Dir +folder.mod=Mod +folder.coremod=Core Mod +folder.config=Configs +folder.resourcepacks=Resourcepacks +folder.screenshots=Screenshots +folder.saves=Saves -settings.tabs.game_download=\u6e38\u620f\u4e0b\u8f7d -settings.tabs.installers=\u81ea\u52a8\u5b89\u88c5 -settings.tabs.assets_downloads=\u8d44\u6e90\u4e0b\u8f7d +settings.tabs.game_download=Games +settings.tabs.installers=Installers +settings.tabs.assets_downloads=Assets -settings=\u666e\u901a\u8bbe\u7f6e -settings.explore=\u6d4f\u89c8 -settings.manage=\u7ba1\u7406 -settings.cannot_remove_default_config=\u4e0d\u80fd\u5220\u9664\u9ed8\u8ba4\u914d\u7f6e -settings.max_memory=\u6700\u5927\u5185\u5b58/MB -settings.java_dir=Java\u8def\u5f84 -settings.game_directory=\u6e38\u620f\u8def\u5f84 -settings.dimension=\u6e38\u620f\u7a97\u53e3\u5206\u8fa8\u7387 -settings.fullscreen=\u5168\u5c4f -settings.update_version=\u66f4\u65b0\u7248\u672c\u6587\u4ef6 -settings.run_directory=\u8fd0\u884c\u8def\u5f84(\u7248\u672c\u9694\u79bb) -settings.physical_memory=\u7269\u7406\u5185\u5b58\u5927\u5c0f -settings.choose_javapath=\u9009\u62e9Java\u8def\u5f84 -settings.default=\u9ed8\u8ba4 -settings.custom=\u81ea\u5b9a\u4e49 -settings.choose_gamedir=\u9009\u62e9\u6e38\u620f\u8def\u5f84 -settings.failed_load=\u8bbe\u7f6e\u6587\u4ef6\u52a0\u8f7d\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u5347\u7ea7\u4e86\u542f\u52a8\u5668\u6216\u88ab\u4eba\u5de5\u4fee\u6539\u9020\u6210\u9519\u8bef\uff0c\u662f\u5426\u6e05\u9664\uff1f -settings.test_game=\u6d4b\u8bd5\u6e38\u620f +settings=Settings +settings.explore=Explore +settings.manage=Manage +settings.cannot_remove_default_config=Cannot remove the default configution. +settings.max_memory=Max Memory/MB +settings.java_dir=Java Dir +settings.game_directory=Game Directory +settings.dimension=Game Window Dimension +settings.fullscreen=Fullscreen +settings.update_version=Update version json. +settings.run_directory=Run Directory(Version Isolation) +settings.physical_memory=Physical Memory Size +settings.choose_javapath=Choose Java Directory. +settings.default=Default +settings.custom=Custom +settings.choose_gamedir=Choose Game Directory +settings.failed_load=Failed to load settings file. Remove it? +settings.test_game=Test game -modpack=\u6574\u5408\u5305 -modpack.choose=\u9009\u62e9\u8981\u5bfc\u5165\u7684\u6e38\u620f\u6574\u5408\u5305\u6587\u4ef6\uff0c\u5982\u679c\u60a8\u5e0c\u671b\u66f4\u65b0\u6574\u5408\u5305\uff0c\u8bf7\u8f93\u5165\u8981\u66f4\u65b0\u7684\u7248\u672c\u540d -modpack.export_error=\u5bfc\u51fa\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u60a8\u7684\u6e38\u620f\u6587\u4ef6\u5939\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u64cd\u4f5c\u6587\u4ef6\u5931\u8d25 -modpack.export_finished=\u6574\u5408\u5305\u5bfc\u51fa\u5b8c\u6210\uff0c\u53c2\u89c1 -modpack.included_launcher=\u6574\u5408\u5305\u5df2\u5305\u542b\u542f\u52a8\u5668\uff0c\u53ef\u76f4\u63a5\u53d1\u5e03 -modpack.not_included_launcher=\u6574\u5408\u5305\u672a\u5305\u542b\u542f\u52a8\u5668\uff0c\u53ef\u4f7f\u7528\u672c\u8f6f\u4ef6\u7684\u5bfc\u5165\u6574\u5408\u5305\u529f\u80fd\u5bfc\u5165\u6574\u5408\u5305 -modpack.enter_name=\u7ed9\u6e38\u620f\u8d77\u4e2a\u4f60\u559c\u6b22\u7684\u540d\u5b57 +modpack=Mod pack +modpack.choose=Choose a modpack zip file which you want to import. If you want to update the modpack, please enter the version you want to update. +modpack.export_error=Failed to export the modpack, maybe the format of your game directory is incorrect or failed to manage files. +modpack.export_finished=Exporting the modpack finished. See +modpack.included_launcher=The modpack is included the launcher, you can publish it directly. +modpack.not_included_launcher=You can use the modpack by clicking the "Import Modpack" button. +modpack.enter_name=Enter your desired name for this game. -modpack.task.save=\u5bfc\u51fa\u6574\u5408\u5305 -modpack.task.install=\u5bfc\u5165\u6574\u5408\u5305 -modpack.task.install.error=\u5b89\u88c5\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6574\u5408\u5305\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u64cd\u4f5c\u6587\u4ef6\u5931\u8d25 -modpack.task.install.will=\u5c06\u4f1a\u5b89\u88c5\u6574\u5408\u5305\uff1a +modpack.task.save=Export Modpack +modpack.task.install=Import Modpack +modpack.task.install.error=Failed to install the modpack. Maybe the files is incorrect, or a management issue occurred. +modpack.task.install.will=Install the modpack: -modpack.wizard=\u5bfc\u51fa\u6574\u5408\u5305\u5411\u5bfc -modpack.wizard.step.1=\u57fa\u672c\u8bbe\u7f6e -modpack.wizard.step.1.title=\u8bbe\u7f6e\u6574\u5408\u5305\u7684\u4e3b\u8981\u4fe1\u606f -modpack.wizard.step.initialization.include_launcher=\u5305\u542b\u542f\u52a8\u5668 -modpack.wizard.step.initialization.exported_version=\u8981\u5bfc\u51fa\u7684\u6e38\u620f\u7248\u672c -modpack.wizard.step.initialization.save=\u9009\u62e9\u8981\u5bfc\u51fa\u5230\u7684\u6e38\u620f\u6574\u5408\u5305\u4f4d\u7f6e -modpack.wizard.step.initialization.warning=\u5728\u5236\u4f5c\u6574\u5408\u5305\u524d\uff0c\u8bf7\u60a8\u786e\u8ba4\u60a8\u9009\u62e9\u7684\u7248\u672c\u53ef\u4ee5\u6b63\u5e38\u542f\u52a8\uff0c
        \u5e76\u4fdd\u8bc1\u60a8\u7684Minecraft\u662f\u6b63\u5f0f\u7248\u800c\u975e\u5feb\u7167\u7248\uff0c
        \u800c\u4e14\u4e0d\u5e94\u5f53\u5c06\u4e0d\u5141\u8bb8\u975e\u5b98\u65b9\u9014\u5f84\u4f20\u64ad\u7684Mod\u3001\u6750\u8d28\u5305\u7b49\u7eb3\u5165\u6574\u5408\u5305\u3002
        \u6574\u5408\u5305\u4f1a\u4fdd\u5b58\u60a8\u76ee\u524d\u7684\u4e0b\u8f7d\u6e90\u8bbe\u7f6e -modpack.wizard.step.2=\u6587\u4ef6\u9009\u62e9 -modpack.wizard.step.2.title=\u9009\u4e2d\u4f60\u4e0d\u60f3\u52a0\u5230\u6574\u5408\u5305\u4e2d\u7684\u6587\u4ef6(\u5939) -modpack.wizard.step.3=\u6574\u5408\u5305\u63cf\u8ff0 -modpack.wizard.step.3.title=\u63cf\u8ff0\u4f60\u8981\u5236\u4f5c\u7684\u6574\u5408\u5305 +modpack.wizard=Exporting the modpack wizard +modpack.wizard.step.1=Basic options +modpack.wizard.step.1.title=Set the basic options to the modpack. +modpack.wizard.step.initialization.include_launcher=Include the launcher +modpack.wizard.step.initialization.exported_version=The exported game version +modpack.wizard.step.initialization.save=Choose a location to export the game files to +modpack.wizard.step.initialization.warning=Before making modpack, you should ensure that your game can launch successfully,
        and that your Minecraft is release, not snapshot.
        and that it is not allowed to add mods which is not allowed to distribute to the modpack. +modpack.wizard.step.2=Files selection +modpack.wizard.step.2.title=Choose the files you do not want to put in the modpack. +modpack.wizard.step.3=Description +modpack.wizard.step.3.title=Describe your modpack. -modpack.desc=\u63cf\u8ff0\u4f60\u8981\u5236\u4f5c\u7684\u6574\u5408\u5305\uff0c\u6bd4\u5982\u6574\u5408\u5305\u6ce8\u610f\u4e8b\u9879\u548c\u66f4\u65b0\u8bb0\u5f55\uff0c\u652f\u6301Markdown(\u56fe\u7247\u8bf7\u7528\u7f51\u7edc\u56fe\u7247)\u3002 -modpack.incorrect_format.no_json=\u6574\u5408\u5305\u683c\u5f0f\u9519\u8bef\uff0cpack.json\u4e22\u5931 -modpack.incorrect_format.no_jar=\u6574\u5408\u5305\u683c\u5f0f\u9519\u8bef\uff0cpack.json\u4e22\u5931jar\u5b57\u6bb5 -modpack.cannot_read_version=\u8bfb\u53d6\u6e38\u620f\u7248\u672c\u5931\u8d25 -modpack.not_a_valid_location=\u4e0d\u662f\u4e00\u4e2a\u6709\u6548\u6574\u5408\u5305\u4f4d\u7f6e -modpack.name=\u6574\u5408\u5305\u540d\u79f0 -modpack.not_a_valid_name=\u4e0d\u662f\u4e00\u4e2a\u6709\u6548\u7684\u6574\u5408\u5305\u540d\u79f0 +modpack.desc=Describe your modpack, including precautions, changlog, supporting Markdown(also supporting online pictures). +modpack.incorrect_format.no_json=The format of the modpack is incorrect, pack.json is missing. +modpack.incorrect_format.no_jar=The format of the modpack is incorrect, pack.json does not have attribute 'jar' +modpack.cannot_read_version=Failed to gather the game version +modpack.not_a_valid_location=Not a valid modpack location +modpack.name=Modpack Name +modpack.not_a_valid_name=Not a valid modpack name -modpack.files.servers_dat=\u591a\u4eba\u6e38\u620f\u670d\u52a1\u5668\u5217\u8868 -modpack.files.saves=\u6e38\u620f\u5b58\u6863 -modpack.files.mods=Mod -modpack.files.config=Mod\u914d\u7f6e\u6587\u4ef6 -modpack.files.liteconfig=Mod\u914d\u7f6e\u6587\u4ef6 -modpack.files.resourcepacks=\u8d44\u6e90\u5305(\u6750\u8d28\u5305) -modpack.files.options_txt=\u6e38\u620f\u8bbe\u5b9a -modpack.files.optionsshaders_txt=\u5149\u5f71\u8bbe\u5b9a -modpack.files.mods.voxelmods=VoxelMods\u914d\u7f6e\uff0c\u5982\u5c0f\u5730\u56fe -modpack.files.dumps=NEI\u8c03\u8bd5\u8f93\u51fa -modpack.files.scripts=MineTweaker\u914d\u7f6e -modpack.files.blueprints=BuildCraft\u84dd\u56fe +modpack.files.servers_dat=Multiplayer servers list +modpack.files.saves=Saved games +modpack.files.mods=Mods +modpack.files.config=Mod configs +modpack.files.liteconfig=Mod configurations +modpack.files.resourcepacks=Resource(Texture) packs +modpack.files.options_txt=Game options +modpack.files.optionsshaders_txt=Shaders options +modpack.files.mods.voxelmods=VoxelMods (including VoxelMap) options +modpack.files.dumps=NEI debug output +modpack.files.scripts=MineTweaker configuration +modpack.files.blueprints=BuildCraft blueprints -mods=Mod\u7ba1\u7406 -mods.choose_mod=\u9009\u62e9\u6a21\u7ec4 -mods.failed=\u6dfb\u52a0\u5931\u8d25 -mods.add=\u6dfb\u52a0 -mods.remove=\u5220\u9664 -mods.default_information=\u5b89\u88c5Mod\u524d\u4f60\u9700\u8981\u786e\u4fdd\u5df2\u5b89\u88c5Forge\u6216LiteLoader!
        \u60a8\u53ef\u4ee5\u4ece\u8d44\u6e90\u7ba1\u7406\u5668\u62d6\u52a8mod\u6587\u4ef6\u5230\u5217\u8868\u4e2d\u6765\u6dfb\u52a0mod\uff0c\u540c\u65f6\u4f7f\u7528\u5220\u9664\u952e\u53ef\u5feb\u901f\u5220\u9664\u9009\u4e2dmod
        \u70b9\u6389mod\u524d\u9762\u7684\u52fe\u53ef\u7981\u7528mod\uff0c\u4e0d\u4f1a\u52a0\u8f7d\uff1b\u9009\u62e9mod\u53ef\u4ee5\u83b7\u53d6mod\u4fe1\u606f
        +mods=Mods +mods.choose_mod=Choose your mods +mods.failed=Failed to add mods +mods.add=Add +mods.remove=Remove +mods.default_information=Please ensure that you have installed Forge or LiteLoader before installing mods!
        You can drop your mod files from explorer/finder, and delete mods by the delete button.
        Disable a mod by leaving the check box unchecked; Choose an item to get the information.
        -advancedsettings=\u9ad8\u7ea7\u8bbe\u7f6e -advancedsettings.launcher_visible=\u542f\u52a8\u5668\u53ef\u89c1\u6027 -advancedsettings.debug_mode=\u8c03\u8bd5\u6a21\u5f0f -advancedsettings.java_permanent_generation_space=\u5185\u5b58\u6c38\u4e45\u4fdd\u5b58\u533a\u57df(\u4e0d\u5fc5\u586b\u5199,MB) -advancedsettings.jvm_args=Java\u865a\u62df\u673a\u53c2\u6570(\u4e0d\u5fc5\u586b\u5199) -advancedsettings.Minecraft_arguments=Minecraft\u989d\u5916\u53c2\u6570(\u4e0d\u5fc5\u586b\u5199) -advancedsettings.launcher_visibility.close=\u6e38\u620f\u542f\u52a8\u540e\u7ed3\u675f\u542f\u52a8\u5668 -advancedsettings.launcher_visibility.hide=\u6e38\u620f\u542f\u52a8\u540e\u9690\u85cf\u542f\u52a8\u5668 -advancedsettings.launcher_visibility.keep=\u4fdd\u6301\u542f\u52a8\u5668\u53ef\u89c1 -advancedsettings.game_dir.default=\u9ed8\u8ba4(.minecraft/) -advancedsettings.game_dir.independent=\u5404\u7248\u672c\u72ec\u7acb(.minecraft/versions/<\u7248\u672c\u540d>/,\u9664assets,libraries) -advancedsettings.no_jvm_args=\u4e0d\u6dfb\u52a0\u9ed8\u8ba4\u7684JVM\u53c2\u6570(\u4f7f\u7528Java9\u65f6\u5fc5\u52fe) -advancedsettings.java_args_default=\u542f\u52a8\u5668\u9ed8\u8ba4\u6dfb\u52a0\u7684\u53c2\u6570\uff08\u8bf7\u4e0d\u8981\u91cd\u590d\u6dfb\u52a0\uff09\uff1a-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -XX:MaxPermSize=???m -Xmx???m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true -advancedsettings.wrapper_launcher=\u524d\u7f6e\u6307\u4ee4(\u4e0d\u5fc5\u586b\u5199,\u5982optirun) -advancedsettings.precall_command=\u542f\u52a8\u524d\u6267\u884c\u547d\u4ee4(\u4e0d\u5fc5\u586b\u5199\uff0c\u5c06\u5728\u6e38\u620f\u542f\u52a8\u524d\u8c03\u7528) -advancedsettings.server_ip=\u76f4\u5165\u670d\u52a1\u5668ip\u5730\u5740(\u4e0d\u5fc5\u586b\u5199\uff0c\u542f\u52a8\u6e38\u620f\u540e\u76f4\u63a5\u8fdb\u5165\u5bf9\u5e94\u670d\u52a1\u5668) -advancedsettings.cancel_wrapper_launcher=\u53d6\u6d88\u5305\u88f9\u542f\u52a8\u5668\uff08\u51fa\u73b0\u5947\u602a\u95ee\u9898\u65f6\u53ef\u5c1d\u8bd5\u4f7f\u7528,\u4e0e\u8c03\u8bd5\u6a21\u5f0f\u51b2\u7a81\uff09 -advancedsettings.dont_check_game_completeness=\u4e0d\u68c0\u67e5\u6e38\u620f\u5b8c\u6574\u6027 +advancedsettings=Advanced +advancedsettings.launcher_visible=Launcher Visibility +advancedsettings.debug_mode=Debug Mode +advancedsettings.java_permanent_generation_space=PermGen Space/MB +advancedsettings.jvm_args=Java VM Arguments +advancedsettings.Minecraft_arguments=Minecraft Arguments +advancedsettings.launcher_visibility.close=Close the launcher when the game launched. +advancedsettings.launcher_visibility.hide=Hide the launcher when the game launched. +advancedsettings.launcher_visibility.keep=Keep the launcher visible. +advancedsettings.game_dir.default=Default (.minecraft/) +advancedsettings.game_dir.independent=Independent (.minecraft/versions//, except assets,libraries) +advancedsettings.no_jvm_args=No Default JVM Args +advancedsettings.java_args_default=Default java args: -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -XX:MaxPermSize=???m -Xmx???m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true +advancedsettings.wrapper_launcher=Wrapper Launcher(like optirun...) +advancedsettings.precall_command=Precalling command(will be executed before game launching) +advancedsettings.server_ip=Server Host +advancedsettings.cancel_wrapper_launcher=Cancel Wrapper Launcher +advancedsettings.dont_check_game_completeness=Don't check game completeness -mainwindow.show_log=\u67e5\u770b\u65e5\u5fd7 -mainwindow.make_launch_script=\u751f\u6210\u542f\u52a8\u811a\u672c -mainwindow.make_launch_script_failed=\u751f\u6210\u542f\u52a8\u811a\u672c\u5931\u8d25 -mainwindow.enter_script_name=\u8f93\u5165\u8981\u751f\u6210\u811a\u672c\u7684\u6587\u4ef6\u540d -mainwindow.make_launch_succeed=\u542f\u52a8\u811a\u672c\u5df2\u751f\u6210\u5b8c\u6bd5: -mainwindow.no_version=\u672a\u627e\u5230\u4efb\u4f55\u7248\u672c\uff0c\u662f\u5426\u8fdb\u5165\u6e38\u620f\u4e0b\u8f7d\uff1f +mainwindow.show_log=Show Logs +mainwindow.make_launch_script=Make Launching Script. +mainwindow.make_launch_script_failed=Failed to make script. +mainwindow.enter_script_name=Enter the script name. +mainwindow.make_launch_succeed=Finished script creation. +mainwindow.no_version=No version found. Switch to Game Downloads Tab? -launcher.about=\u9ed8\u8ba4\u80cc\u666f\u56fe\u611f\u8c22gamerteam\u63d0\u4f9b\u3002
        \u5982\u679c\u60a8\u5e0c\u671b\u672c\u8f6f\u4ef6\u7ee7\u7eed\u53d1\u5c55\uff0c\u8bf7\u8d5e\u52a9
        \u5173\u4e8e\u4f5c\u8005\uff1a
        \u767e\u5ea6ID\uff1ahuanghongxun20
        mcbbs\uff1ahuanghongxun
        \u90ae\u7bb1\uff1ahuanghongxun2008@126.com
        Minecraft Forum ID: klkl6523
        \u6b22\u8fce\u63d0\u4ea4Bug\u54e6
        Copyright (c) 2013-2016 huangyuhui.
        \u514d\u8d23\u58f0\u660e\uff1aMinecraft\u8f6f\u4ef6\u7248\u6743\u5f52Mojang AB\u6240\u6709\uff0c\u4f7f\u7528\u672c\u8f6f\u4ef6\u4ea7\u751f\u7684\u7248\u6743\u95ee\u9898\u672c\u8f6f\u4ef6\u5236\u4f5c\u65b9\u6982\u4e0d\u8d1f\u8d23\u3002
        \u672c\u542f\u52a8\u5668\u5728GPLv3\u534f\u8bae\u4e0b\u5f00\u6e90:https://github.com/huanghongxun/HMCL/ ,\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005
        \u672c\u8f6f\u4ef6\u4f7f\u7528\u4e86\u57fa\u4e8eApache License 2.0\u7684Gson\u9879\u76ee\uff0c\u611f\u8c22\u8d21\u732e\u8005\u3002 -launcher.download_source=\u4e0b\u8f7d\u6e90 -launcher.background_location=\u80cc\u666f\u5730\u5740 -launcher.exit_failed=\u5f3a\u5236\u9000\u51fa\u5931\u8d25\uff0c\u53ef\u80fd\u662fForge 1.7.10\u53ca\u66f4\u9ad8\u7248\u672c\u5bfc\u81f4\u7684\uff0c\u65e0\u6cd5\u89e3\u51b3\u3002 -launcher.versions_json_not_matched=\u7248\u672c%s\u683c\u5f0f\u4e0d\u89c4\u8303\uff01\u8be5\u7248\u672c\u6587\u4ef6\u5939\u4e0b\u6709json:%s\uff0c\u662f\u5426\u66f4\u540d\u8fd9\u4e2a\u6587\u4ef6\u6765\u89c4\u8303\u683c\u5f0f\uff1f -launcher.versions_json_not_matched_cannot_auto_completion=\u7248\u672c%s\u7f3a\u5931\u5fc5\u8981\u7684\u7248\u672c\u4fe1\u606f\u6587\u4ef6\uff0c\u662f\u5426\u5220\u9664\u8be5\u7248\u672c\uff1f -launcher.versions_json_not_formatted=\u7248\u672c%s\u4fe1\u606f\u6587\u4ef6\u683c\u5f0f\u9519\u8bef\uff0c\u662f\u5426\u91cd\u65b0\u4e0b\u8f7d\uff1f -launcher.choose_bgpath=\u9009\u62e9\u80cc\u666f\u8def\u5f84 -launcher.background_tooltip=\u542f\u52a8\u5668\u9ed8\u8ba4\u4f7f\u7528\u81ea\u5e26\u7684\u80cc\u666f
        \u5982\u679c\u5f53\u524d\u76ee\u5f55\u6709background.png\uff0c\u5219\u4f1a\u4f7f\u7528\u8be5\u6587\u4ef6\u4f5c\u4e3a\u80cc\u666f
        \u5982\u679c\u5f53\u524d\u76ee\u5f55\u6709bg\u5b50\u76ee\u5f55\uff0c\u5219\u4f1a\u968f\u673a\u4f7f\u7528\u91cc\u9762\u7684\u4e00\u5f20\u56fe\u4f5c\u4e3a\u80cc\u666f
        \u5982\u679c\u8be5\u80cc\u666f\u5730\u5740\u88ab\u4fee\u6539\uff0c\u5219\u4f1a\u4f7f\u7528\u80cc\u666f\u5730\u5740\u91cc\u7684\u4e00\u5f20\u56fe\u4f5c\u4e3a\u80cc\u666f
        \u80cc\u666f\u5730\u5740\u5141\u8bb8\u6709\u591a\u4e2a\u5730\u5740\uff0c\u4f7f\u7528\u534a\u89d2\u5206\u53f7";"(\u4e0d\u5305\u542b\u53cc\u5f15\u53f7)\u5206\u9694 -launcher.update_launcher=\u68c0\u67e5\u66f4\u65b0 -launcher.enable_shadow=\u542f\u7528\u7a97\u53e3\u9634\u5f71 -launcher.theme=\u4e3b\u9898 -launcher.proxy=\u4ee3\u7406 -launcher.decorated=\u542f\u7528\u7a97\u53e3\u8fb9\u6846(Linux\u4e0b\u53ef\u89e3\u51b3\u7a0b\u5e8f\u754c\u9762\u5168\u7070\u95ee\u9898) -launcher.modpack=\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9 -launcher.enable_animation=\u542f\u7528\u52a8\u6001\u6548\u679c -launcher.lang=\u8bed\u8a00 -launcher.restart=\u672c\u754c\u9762\u9009\u9879\u9700\u8981\u91cd\u542f\u672c\u542f\u52a8\u5668\u751f\u6548 +launcher.about=About Author
        Minecraft Forum ID: klkl6523
        Copyright (c) 2013 huangyuhui
        Opened source under GPL v3 license:http://github.com/huanghongxun/HMCL/
        This software used project Gson which is under Apache License 2.0, thanks contributors. +launcher.download_source=Download Source +launcher.background_location=Background Location +launcher.exit_failed=Failed to shutdown. +launcher.versions_json_not_matched=The version %s is malformed! There are a json:%s in this version. Do you want to fix this problem? +launcher.versions_json_not_matched_cannot_auto_completion=The version %s lost version information file, delete it? +launcher.versions_json_not_formatted=The version information of %s is malformed! Redownload it? +launcher.choose_bgpath=Choose background path. +launcher.background_tooltip=The laucher uses a default background.
        If you use custom background.png, link it and it will be used.
        If there is "bg" subdirectory, this app will chooses one picture in "bgskin" randomly.
        If you set the background setting, this app will use it. +launcher.update_launcher=Check for update +launcher.enable_shadow=Enable Window Shadow +launcher.enable_animation=Enable Animation +launcher.enable_blur=Enable Blur +launcher.theme=Theme +launcher.proxy=Proxy +launcher.decorated=Enable system window border(in order to fix the problem that the ui become all gray in Linux OS) +launcher.modpack=Documentations for modpacks. +launcher.lang=Language +launcher.restart=Options will be in operations only if restart this app. -launcher.title.game=\u6e38\u620f\u8bbe\u7f6e -launcher.title.main=\u4e3b\u9875 -launcher.title.launcher=\u542f\u52a8\u5668\u8bbe\u7f6e +launcher.title.game=Games +launcher.title.main=Home +launcher.title.launcher=Launcher -versions.release=\u7a33\u5b9a\u7248 -versions.snapshot=\u5feb\u7167\u7248 -versions.old_beta=\u6d4b\u8bd5\u7248 -versions.old_alpha=\u8fdc\u53e4\u7248 +versions.release=Release +versions.snapshot=Snapshot +versions.old_beta=Beta +versions.old_alpha=Old Alpha -versions.manage.rename=\u91cd\u547d\u540d\u8be5\u7248\u672c -versions.manage.rename.message=\u8bf7\u8f93\u5165\u8981\u6539\u6210\u7684\u540d\u5b57 -versions.manage.remove=\u5220\u9664\u8be5\u7248\u672c -versions.manage.remove.confirm=\u771f\u7684\u8981\u5220\u9664\u7248\u672c -versions.manage.redownload_json=\u91cd\u65b0\u4e0b\u8f7d\u7248\u672c\u914d\u7f6e(minecraft.json) -versions.manage.redownload_assets_index=\u91cd\u65b0\u4e0b\u8f7d\u8d44\u6e90\u914d\u7f6e(assets_index.json) -versions.mamage.remove_libraries=\u5220\u9664\u6240\u6709\u5e93\u6587\u4ef6 +versions.manage.rename=Rename this version +versions.manage.rename.message=Please enter the new name +versions.manage.remove=Delete this version +versions.manage.remove.confirm=Sure to remove the version +versions.manage.redownload_json=Redownload Minecraft Configuration(minecraft.json) +versions.manage.redownload_assets_index=Redownload Assets Index +versions.mamage.remove_libraries=Delete library files -advice.os64butjdk32=\u60a8\u7684\u7cfb\u7edf\u662f64\u4f4d\u7684\u4f46\u662fJava\u662f32\u4f4d\u7684\uff0c\u63a8\u8350\u60a8\u5b89\u88c564\u4f4dJava. +advice.os64butjdk32=Your OS is 64-Bit but your Java is 32-Bit. The 64-Bit Java is recommended. -assets.download_all=\u4e0b\u8f7d\u8d44\u6e90\u6587\u4ef6 -assets.not_refreshed=\u8d44\u6e90\u5217\u8868\u672a\u5237\u65b0\uff0c\u8bf7\u5237\u65b0\u4e00\u6b21\u3002 -assets.failed=\u83b7\u53d6\u5217\u8868\u5931\u8d25\uff0c\u8bf7\u5237\u65b0\u91cd\u8bd5\u3002 -assets.list.1_7_3_after=1.7.3\u53ca\u4ee5\u540e +assets.download_all=Download Assets Files +assets.not_refreshed=The assets list is not refreshed, please refresh it once. +assets.failed=Failed to get the list, try again. +assets.list.1_7_3_after=1.7.3 And higher assets.list.1_6=1.6(BMCLAPI) -assets.unkown_type_select_one=\u65e0\u6cd5\u89e3\u6790\u6e38\u620f\u7248\u672c\uff1a%s\uff0c\u8bf7\u9009\u62e9\u4e00\u79cd\u8d44\u6e90\u7c7b\u578b\u4e0b\u8f7d\u3002 -assets.type=\u8d44\u6e90\u7c7b\u578b -assets.download=\u4e0b\u8f7d\u8d44\u6e90 -assets.no_assets=\u8d44\u6e90\u6587\u4ef6\u4e0d\u5b8c\u6574\uff0c\u662f\u5426\u8865\u5168\uff1f -assets.failed_download=\u4e0b\u8f7d\u8d44\u6e90\u6587\u4ef6\u5931\u8d25\uff0c\u53ef\u80fd\u5bfc\u81f4\u6ca1\u6709\u4e2d\u6587\u548c\u58f0\u97f3\u3002 +assets.unkown_type_select_one=Unknown game version: %s, please choose an asset type. +assets.type=Asset Type +assets.download=Download Assets +assets.no_assets=Assets are not complete, complete them? +assets.failed_download=Failed to download assets, may cause no sounds and language files. -gamedownload.not_refreshed=\u6e38\u620f\u4e0b\u8f7d\u5217\u8868\u672a\u5237\u65b0\uff0c\u8bf7\u518d\u5237\u65b0\u4e00\u6b21\u3002 +gamedownload.not_refreshed=The game list is not refreshed, please refresh it once. -taskwindow.title=\u4efb\u52a1 -taskwindow.single_progress=\u5355\u9879\u8fdb\u5ea6 -taskwindow.total_progress=\u603b\u8fdb\u5ea6 -taskwindow.cancel=\u53d6\u6d88 -taskwindow.no_more_instance=\u53ef\u80fd\u540c\u65f6\u6253\u5f00\u4e86\u591a\u4e2a\u4efb\u52a1\u7a97\u53e3\uff0c\u8bf7\u4e0d\u8981\u591a\u6b21\u6253\u5f00\uff01 -taskwindow.file_name=\u4efb\u52a1 -taskwindow.download_progress=\u8fdb\u5ea6 +taskwindow.title=Tasks +taskwindow.single_progress=Single progress +taskwindow.total_progress=Total progress +taskwindow.cancel=Cancel +taskwindow.no_more_instance=Maybe you opened more than one task window, don't open it again! +taskwindow.file_name=Task +taskwindow.download_progress=Pgs. -setupwindow.include_minecraft=\u5bfc\u5165\u6e38\u620f\u6587\u4ef6\u5939 -setupwindow.find_in_configurations=\u5bfc\u5165\u5b8c\u6210\uff0c\u5feb\u5230\u914d\u7f6e\u4e0b\u62c9\u6846\u4e2d\u627e\u65b0\u6e38\u620f\u8def\u5f84\u5427\uff01 -setupwindow.give_a_name=\u7ed9\u65b0\u6e38\u620f\u8def\u5f84\u8d77\u4e2a\u540d\u5b57\u5427 -setupwindow.new=\u65b0\u5efa -setupwindow.no_empty_name=\u540d\u5b57\u4e0d\u53ef\u4e3a\u7a7a -setupwindow.clean=\u6e05\u7406\u6e38\u620f\u6587\u4ef6 +setupwindow.include_minecraft=Import game +setupwindow.find_in_configurations=Finished importing. You can find it in the configuration selection bar. +setupwindow.give_a_name=Give a name to the new game. +setupwindow.new=New +setupwindow.no_empty_name=Version name cannot be empty. +setupwindow.clean=Clean game files -update.no_browser=\u65e0\u6cd5\u6253\u5f00\u6d4f\u89c8\u5668\uff0c\u7f51\u5740\u5df2\u7ecf\u590d\u5236\u5230\u526a\u8d34\u677f\u4e86\uff0c\u60a8\u53ef\u4ee5\u624b\u52a8\u7c98\u8d34\u7f51\u5740\u6253\u5f00\u9875\u9762 -update.should_open_link=\u662f\u5426\u66f4\u65b0\uff1f -update.newest_version=\u6700\u65b0\u7248\u672c\u4e3a\uff1a -update.failed=\u68c0\u67e5\u66f4\u65b0\u5931\u8d25 -update.found=(\u53d1\u73b0\u66f4\u65b0!) +update.no_browser=Cannot open any browser. The link has been copied to the clipboard. Paste it to a browser address bar to update. +update.should_open_link=Are you willing to update the launcher? +update.newest_version=Newest version: +update.failed=Failed to check for updates. +update.found=(Found Update!) -logwindow.terminate_game=\u7ed3\u675f\u6e38\u620f\u8fdb\u7a0b -logwindow.tieba=\u8d34\u5427 -logwindow.title=\u65e5\u5fd7 +logwindow.terminate_game=Terminate Game +logwindow.tieba=Baidu Tieba +logwindow.title=Log -selector.choose=\u9009\u62e9 +selector.choose=Choose -serverlistview.title=\u9009\u62e9\u670d\u52a1\u5668 -serverlistview.name=\u540d\u79f0 -serverlistview.type=\u7c7b\u578b -serverlistview.version=\u7248\u672c -serverlistview.info=\u4fe1\u606f +serverlistview.title=Choose a server +serverlistview.name=Name +serverlistview.type=Type +serverlistview.version=Version +serverlistview.info=Information -minecraft.invalid=\u65e0\u6548\u7684 -minecraft.invalid_jar=\u65e0\u6548\u7684jar\u5305 -minecraft.not_a_file=\u4e0d\u662f\u6587\u4ef6 -minecraft.not_found=\u627e\u4e0d\u5230minecraft.jar -minecraft.not_readable=minecraft.jar\u4e0d\u53ef\u8bfb -minecraft.modified=(\u4fee\u6539\u7684!) +minecraft.invalid=Invalid +minecraft.invalid_jar=Invalid Jar +minecraft.not_a_file=Not a file +minecraft.not_found=Not found +minecraft.not_readable=Not readable +minecraft.modified=(Modified!) -color.red=\u7ea2\u8272 -color.blue=\u84dd\u8272 -color.green=\u7eff\u8272 -color.orange=\u6a59\u8272 -color.dark_blue=\u6df1\u84dd\u8272 -color.purple=\u7d2b\u8272 +color.red=Red +color.blue=Blue +color.green=Green +color.orange=Orange +color.dark_blue=Dark Blue +color.purple=Purple -wizard.next_>=\u4e0b\u4e00\u6b65 > -wizard.next_mnemonic=\u4e0b -wizard.<_prev=< \u4e0a\u4e00\u6b65 -wizard.prev_mnemonic=\u4e0a -wizard.finish=\u5b8c\u6210 -wizard.finish_mnemonic=\u5b8c -wizard.cancel=\u53d6\u6d88 -wizard.cancel_mnemonic=\u53d6 -wizard.help=\u5e2e\u52a9 -wizard.help_mnemonic=\u5e2e -wizard.close=\u5173\u95ed -wizard.close_mnemonic=\u5173 -wizard.summary=\u6982\u8981 -wizard.failed=\u5931\u8d25 -wizard.steps=\u6b65\u9aa4 +wizard.next_>=Next > +wizard.next_mnemonic=N +wizard.<_prev=< Prev +wizard.prev_mnemonic=P +wizard.finish=Finish +wizard.finish_mnemonic=F +wizard.cancel=Cancel +wizard.cancel_mnemonic=C +wizard.help=Help +wizard.help_mnemonic=H +wizard.close=Close +wizard.close_mnemonic=C +wizard.summary=Summary +wizard.failed=Failed +wizard.steps=Steps -lang=\u7b80\u4f53\u4e2d\u6587 -lang.default=\u8ddf\u968f\u7cfb\u7edf\u8bed\u8a00 +lang=English +lang.default=Belong to OS language. diff --git a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_en.lang b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_en.lang deleted file mode 100755 index 9d746d0e1..000000000 --- a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_en.lang +++ /dev/null @@ -1,416 +0,0 @@ -# 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/}. -launch.failed=Failed to launch -launch.failed_creating_process=Failed to create process, maybe your java path is wrong, please modify your java path. -launch.failed_sh_permission=Failed to add permission to the launch script -launch.failed_packing_jar=Failed to pack jar -launch.unsupported_launcher_version=Sorry, this launcher cannot launch this minecraft, but the launcher will try to launch it. -launch.too_big_memory_alloc_64bit=You have allocated too much memory, because of your 32-Bit Java Runtime Environment, your game probably crash. The maximum memory is 1024MB. The launcher will try to launch it. -launch.too_big_memory_alloc_free_space_too_low=You have allocated too much memory, because the physical memory size is %dMB, your game probably crash. The launcher will try to launch it. -launch.cannot_create_jvm=We find that it cannot create java virutal machine. The Java argements may have problems. You can enable the no args mode in the settings. -launch.circular_dependency_versions=Found circular dependency versions, please check if your client has been modified. -launch.not_finished_downloading_libraries=Did not finish downloading libraries, continue launching game? -launch.not_finished_decompressing_natives=Did not finish decompressing native libraries, continue launching game? -launch.wrong_javadir=Wrong Java Dir, will reset to default Java dir. -launch.exited_abnormally=Game exited abnormally, please visit the log, or ask someone for help. - -launch.state.logging_in=Logging In -launch.state.generating_launching_codes=Generating Launching Codes -launch.state.downloading_libraries=Downloading dependencies -launch.state.decompressing_natives=Decompressing natives - -install.no_version=The version is not found. -install.no_version_if_intall=The needed version is not found, should install the version automatically? -install.not_refreshed=The installer list is not refreshed. -install.download_list=Download List - -install.liteloader.get_list=Get LiteLoader List -install.liteloader.install=Install LiteLoader - -install.forge.get_list=Get Forge List -install.forge.install=Install Forge -install.forge.get_changelogs=Get Forge Changelogs - -install.optifine.install=Install OptiFine -install.optifine.get_list=Get OptiFine Download List -install.optifine.get_download_link=Get the Download Link of OptiFine - -install.failed_forge=Failed to Install Forge -install.failed_optifine=Failed to Install OptiFine -install.failed_liteloader=Failed to Install LiteLoader -install.failed_download_forge=Failed to Download Forge -install.failed_download_optifine=Failed to Download OptiFine -install.failed=Failed to install -install.success=Install successfully -install.no_forge=No Forge -install.choose_forge=Choose the version you want to install Forge -install.version=Version -install.mcversion=Game Version -install.time=Time -install.release_time=Release Time -install.type=Type -install.please_refresh=If you want to install something, please click "Refresh" button. - -crash.launcher=Launcher has crashed! -crash.minecraft=Minecraft has crashed! - -login.choose_charactor=Please choose the charactor you want -login.no_charactor=No charactor in this account. -login.your_password=Your password -login.failed=Failed to login -login.no_Player007=You have not set username! -login.wrong_password=Wrong password or username -login.invalid_username=Invalid username -login.invalid_uuid_and_username=Invalid UUID and username -login.invalid_password=Invalid password -login.invalid_access_token=Invalid Access Token -login.changed_client_token=The server response has changed the client token. -login.not_email=The username must be a e-mail. -login.type=Login -login.username=Name -login.account=Email -login.invalid_token=Please log out and reinput your password to log in. -login.no_valid_character=No Valid Character, please visit skinme.cc and create your own character. - -proxy.username=Account -proxy.password=Password -proxy.host=Host -proxy.port=Port - -login.failed.connect_authentication_server=Cannot connect the authentication server. Check your network. - -login.profile.not_logged_in=Not Logged In and Cannot modify the profile. -login.profile.selected=Cannot modify the profile, you must logout and go back. - -login.methods.yggdrasil=Mojang -login.methods.offline=Offline -login.methods.no_method=No login method - -log.playername_null=The player name is empty. - -minecraft.no_selected_version=No selected Minecraft version -minecraft.wrong_path=Wrong Minecraft path, the launcher could not find the path. - -operation.stopped=The operation was aborted. -operation.confirm_stop=Terminate the operations? - -ui.login.password=Password -ui.more=More - -crash.advice.UnsupportedClassVersionError=Maybe your java is too old, try to update the java. -crash.advice.ConcurrentModificationException=Maybe your Java is newer than 1.8.0_11, you could downgrade to Java 7. -crash.advice.ClassNotFoundException=Minecraft or mods are incomplete. Retry if there are some libraries that have not downloaded or update your game and mods! Or you can try Game Settings -> Manage (Version) -> Delete library files to solve the problem. -crash.advice.NoSuchFieldError=Minecraft or mods are incomplete. Retry if there are some libraries that have not downloaded or update your game and mods! -crash.advice.LWJGLException=Maybe your video driver does not work well, please update your video driver. -crash.advice.SecurityException=Maybe you have modified minecraft.jar but have not removed the META-INF. -crash.advice.OutOfMemoryError=The maximum memory of JVM is too small, please modify it. -crash.advice.otherwise=Maybe mods caused problems. - -crash.advice.OpenGL=Maybe drivers caused problems. -crash.advice.no_lwjgl=Maybe drivers caused problems. - -crash.advice.no=No advice. - -crash.user_fault=Your OS or Java environment may not be properly installed resulting in crashing of this software, please check your Java Environment or your computer! -crash.headless=If your OS is Linux, please use Oracle JDK instead of OpenJDK, or add "-Djava.awt.headless=false" JVM argument, or check if your Xserver works normally. -crash.NoClassDefFound=Please check "HMCL" software is complete. - -crash.error=Minecraft has crashed. -crash.main_class_not_found=Main Class is not found, may be your mc has been broken. -crash.class_path_wrong=Maybe the launch script is malformed. - -ui.label.newProfileWindow.new_profile_name=New Profile Name: -ui.label.newProfileWindow.copy_from=Copy From: -ui.newProfileWindow.title=New Config - -ui.button.ok=OK -ui.button.refresh=Refresh -ui.button.run=Play -ui.button.settings=Settings -ui.button.about=About -ui.button.others=Others -ui.button.logout=Log Out -ui.button.download=Download -ui.button.retry=Retry -ui.button.delete=Delete -ui.button.install=Install -ui.button.info=Info -ui.button.save=Save -ui.button.copy=Copy -ui.button.clear=Clear -ui.button.close=Close -ui.button.explore=Explore -ui.button.test=Test -ui.button.preview=Preview -button.cancel=Cancel -button.ok=OK - -ui.label.version=Version -ui.label.password=Password -ui.label.profile=Profile - -ui.message.first_load=Please enter your name. -ui.message.enter_password=Please enter your password. -ui.message.launching=Launching... -ui.message.making=Generating... -ui.message.sure_remove=Sure to remove profile %s? -ui.message.update_java=Please upgrade your Java. - -ui.label.settings=Settings -ui.label.crashing=Hello Minecraft! Launcher has crashed! -ui.label.crashing_out_dated=Hello Minecraft! Launcher has crashed! And your launcher is not the latest version. Update it! -ui.label.failed_set=Failed to set: - -download=Download -download.mojang=Mojang -download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/) -download.rapid_data=RapidData (https://www.rapiddata.org/) -download.not_200=Failed to download, the response code -download.failed=Failed to download -download.successfully=Download Successfully -download.source=Download Source - -message.error=Error -message.cannot_open_explorer=Cannot open explorer: -message.cancelled=Cancelled -message.info=Info - -folder.game=Game Dir -folder.mod=Mod -folder.coremod=Core Mod -folder.config=Configs -folder.resourcepacks=Resourcepacks -folder.screenshots=Screenshots -folder.saves=Saves - -settings.tabs.game_download=Games -settings.tabs.installers=Installers -settings.tabs.assets_downloads=Assets - -settings=Settings -settings.explore=Explore -settings.manage=Manage -settings.cannot_remove_default_config=Cannot remove the default configution. -settings.max_memory=Max Memory/MB -settings.java_dir=Java Dir -settings.game_directory=Game Directory -settings.dimension=Game Window Dimension -settings.fullscreen=Fullscreen -settings.update_version=Update version json. -settings.run_directory=Run Directory(Version Isolation) -settings.physical_memory=Physical Memory Size -settings.choose_javapath=Choose Java Directory. -settings.default=Default -settings.custom=Custom -settings.choose_gamedir=Choose Game Directory -settings.failed_load=Failed to load settings file. Remove it? -settings.test_game=Test game - -modpack=Mod pack -modpack.choose=Choose a modpack zip file which you want to import. If you want to update the modpack, please enter the version you want to update. -modpack.export_error=Failed to export the modpack, maybe the format of your game directory is incorrect or failed to manage files. -modpack.export_finished=Exporting the modpack finished. See -modpack.included_launcher=The modpack has already included the launcher, you can publish it directly. -modpack.not_included_launcher=Use the modpack by "import modpack". -modpack.enter_name=Give this game a name which is your favorite. - -modpack.task.save=Export the modpack -modpack.task.install=Import the modpack -modpack.task.install.error=Failed to install the modpack, maybe the modpack file is incorrect or failed to manage files. -modpack.task.install.will=Will install the modpack: - -modpack.wizard=Exporting the modpack wizard -modpack.wizard.step.1=Basic options -modpack.wizard.step.1.title=Set the basic options to the modpack. -modpack.wizard.step.initialization.include_launcher=Include the launcher -modpack.wizard.step.initialization.exported_version=The exported game version -modpack.wizard.step.initialization.save=Choose a location which you want to export the game files to -modpack.wizard.step.initialization.warning=Before making modpack, you should ensure that your game can launch successfully,
        and that your Minecraft is release, not snapshot.
        and that it is not allowed to add mods which is not allowed to distribute to the modpack. -modpack.wizard.step.2=Files selection -modpack.wizard.step.2.title=Choose the files you do not want to put in the modpack. -modpack.wizard.step.3=Description -modpack.wizard.step.3.title=Describe your modpack. - -modpack.desc=Describe your modpack, including precautions, changlog, supporting Markdown(also supporting online pictures). -modpack.incorrect_format.no_json=The format of the modpack is incorrect, pack.json is missing. -modpack.incorrect_format.no_jar=The format of the modpack is incorrect, pack.json does not have attribute 'jar' -modpack.cannot_read_version=Failed to gather the game version -modpack.not_a_valid_location=Not a valid modpack location -modpack.name=Modpack Name -modpack.not_a_valid_name=Not a valid modpack name - -modpack.files.servers_dat=Multiplayer servers list -modpack.files.saves=Saved games -modpack.files.mods=Mods -modpack.files.config=Mod configs -modpack.files.liteconfig=Mod configurations -modpack.files.resourcepacks=Resource(Texutre) packs -modpack.files.options_txt=Game options -modpack.files.optionsshaders_txt=Shaders options -modpack.files.mods.voxelmods=VoxelMods(including VoxelMap) options -modpack.files.dumps=NEI debug output -modpack.files.scripts=MineTweaker configs -modpack.files.blueprints=BuildCraft blueprints - -mods=Mods -mods.choose_mod=Choose your mods -mods.failed=Failed to add mods -mods.add=Add -mods.remove=Remove -mods.default_information=Please ensure that you have installed Forge or LiteLoader before installing mods!
        You can drop your mod files from explorer/finder, and delete mods by the delete button.
        Disable a mod by leaving the check box unchecked; Choose an item to get the information.
        - -advancedsettings=Advanced -advancedsettings.launcher_visible=Launcher Visibility -advancedsettings.debug_mode=Debug Mode -advancedsettings.java_permanent_generation_space=PermGen Space/MB -advancedsettings.jvm_args=Java VM Arguments -advancedsettings.Minecraft_arguments=Minecraft Arguments -advancedsettings.launcher_visibility.close=Close the launcher when the game launched. -advancedsettings.launcher_visibility.hide=Hide the launcher when the game launched. -advancedsettings.launcher_visibility.keep=Keep the launcher visible. -advancedsettings.game_dir.default=Default (.minecraft/) -advancedsettings.game_dir.independent=Independent (.minecraft/versions//, except assets,libraries) -advancedsettings.no_jvm_args=No Default JVM Args -advancedsettings.java_args_default=Default java args: -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -XX:MaxPermSize=???m -Xmx???m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true -advancedsettings.wrapper_launcher=Wrapper Launcher(like optirun...) -advancedsettings.precall_command=Precalling command(will be executed before game launching) -advancedsettings.server_ip=Server Host -advancedsettings.cancel_wrapper_launcher=Cancel Wrapper Launcher -advancedsettings.dont_check_game_completeness=Dont check game completeness - -mainwindow.show_log=Show Logs -mainwindow.make_launch_script=Make Launching Script. -mainwindow.make_launch_script_failed=Failed to make script. -mainwindow.enter_script_name=Enter the script name. -mainwindow.make_launch_succeed=Finished script creation. -mainwindow.no_version=No version found. Switch to Game Downloads Tab? - -launcher.about=About Author
        Email:huanghongxun2008@126.com
        Minecraft Forum ID: klkl6523
        Copyright (c) 2013 huangyuhui
        Opened source under GPL v3 license:http://github.com/huanghongxun/HMCL/
        This software used project Gson which is under Apache License 2.0, thanks contributors. -launcher.download_source=Download Source -launcher.background_location=Background Location -launcher.exit_failed=Failed to shutdown. -launcher.versions_json_not_matched=The version %s is malformed! There are a json:%s in this version. Do you want to fix this problem? -launcher.versions_json_not_matched_cannot_auto_completion=The version %s lost version information file, delete it? -launcher.versions_json_not_formatted=The version information of %s is malformed! Redownload it? -launcher.choose_bgpath=Choose background path. -launcher.background_tooltip=This app uses the default background at first.
        If there is background.png in the directory, it will be used.
        If there is "bg" subdirectory, this app will chooses one picture in "bgskin" randomly.
        If you set the background setting, this app will use it. -launcher.update_launcher=Check for update -launcher.enable_shadow=Enable Window Shadow -launcher.theme=Theme -launcher.proxy=Proxy -launcher.decorated=Enable system window border(in order to fix the problem that the ui become all gray in Linux OS) -launcher.modpack=Documentations for modpacks. -launcher.enable_animation=Enable Animation -launcher.lang=Language -launcher.restart=Options will be in operations only if restart this app. - -launcher.title.game=Games -launcher.title.main=Home -launcher.title.launcher=Launcher - -versions.release=Release -versions.snapshot=Snapshot -versions.old_beta=Beta -versions.old_alpha=Old Alpha - -versions.manage.rename=Rename this version -versions.manage.rename.message=Please enter the new name -versions.manage.remove=Delete this version -versions.manage.remove.confirm=Sure to remove the version -versions.manage.redownload_json=Redownload Minecraft Configuration(minecraft.json) -versions.manage.redownload_assets_index=Redownload Assets Index -versions.mamage.remove_libraries=Delete library files - -advice.os64butjdk32=Your OS is 64-Bit but your Java is 32-Bit. The 64-Bit Java is recommended. - -assets.download_all=Download Assets Files -assets.not_refreshed=The assets list is not refreshed, please refresh it once. -assets.failed=Failed to get the list, try again. -assets.list.1_7_3_after=1.7.3 And Higher -assets.list.1_6=1.6(BMCLAPI) -assets.unkown_type_select_one=Unknown game version: %s, please choose an asset type. -assets.type=Asset Type -assets.download=Download Assets -assets.no_assets=Assets are not complete, complete them? -assets.failed_download=Failed to download assets, may cause no sounds and language files. - -gamedownload.not_refreshed=The game list is not refreshed, please refresh it once. - -taskwindow.title=Tasks -taskwindow.single_progress=Single progress -taskwindow.total_progress=Total progress -taskwindow.cancel=Cancel -taskwindow.no_more_instance=Maybe you opened more than one task window, dont open it again! -taskwindow.file_name=Task -taskwindow.download_progress=Pgs. - -setupwindow.include_minecraft=Import game -setupwindow.find_in_configurations=Finished importing. You can find it in the configuration selection bar. -setupwindow.give_a_name=Give a name to the new game. -setupwindow.new=New -setupwindow.no_empty_name=Version name cannot be empty. -setupwindow.clean=Clean game files - -update.no_browser=Cannot open any browser. The link has been copied to the clipboard. You can paste it to the address bar. -update.should_open_link=Are you willing to upgrade this app? -update.newest_version=Newest version: -update.failed=Failed to check for updates. -update.found=(Found Update!) - -logwindow.terminate_game=Terminate Game -logwindow.tieba=Baidu Tieba -logwindow.title=Log - -selector.choose=Choose - -serverlistview.title=Choose a server -serverlistview.name=Name -serverlistview.type=Type -serverlistview.version=Version -serverlistview.info=Information - -minecraft.invalid=Invalid -minecraft.invalid_jar=Invalid Jar -minecraft.not_a_file=Not a file -minecraft.not_found=Not found -minecraft.not_readable=Not readable -minecraft.modified=(Modified!) - -color.red=Red -color.blue=Blue -color.green=Green -color.orange=Orange -color.dark_blue=Dark Blue -color.purple=Purple - -wizard.next_>=Next > -wizard.next_mnemonic=N -wizard.<_prev=< Prev -wizard.prev_mnemonic=P -wizard.finish=Finish -wizard.finish_mnemonic=F -wizard.cancel=Cancel -wizard.cancel_mnemonic=C -wizard.help=Help -wizard.help_mnemonic=H -wizard.close=Close -wizard.close_mnemonic=C -wizard.summary=Summary -wizard.failed=Failed -wizard.steps=Steps - -lang=English -lang.default=Belong to OS language. \ No newline at end of file diff --git a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_en.properties b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_en.properties deleted file mode 100755 index c1ed34126..000000000 --- a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_en.properties +++ /dev/null @@ -1,416 +0,0 @@ -# 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/}. -launch.failed=Failed to launch -launch.failed_creating_process=Failed to create process, maybe your java path is wrong, please modify your java path. -launch.failed_sh_permission=Failed to add permission to the launch script -launch.failed_packing_jar=Failed to pack jar -launch.unsupported_launcher_version=Sorry, this launcher cannot launch this minecraft, but the launcher will try to launch it. -launch.too_big_memory_alloc_64bit=You have allocated too much memory, because of your 32-Bit Java Runtime Environment, your game probably crash. The maximum memory is 1024MB. The launcher will try to launch it. -launch.too_big_memory_alloc_free_space_too_low=You have allocated too much memory, because the physical memory size is %dMB, your game probably crash. The launcher will try to launch it. -launch.cannot_create_jvm=We find that it cannot create java virutal machine. The Java argements may have problems. You can enable the no args mode in the settings. -launch.circular_dependency_versions=Found circular dependency versions, please check if your client has been modified. -launch.not_finished_downloading_libraries=Did not finish downloading libraries, continue launching game? -launch.not_finished_decompressing_natives=Did not finish decompressing native libraries, continue launching game? -launch.wrong_javadir=Wrong Java Dir, will reset to default Java dir. -launch.exited_abnormally=Game exited abnormally, please visit the log, or ask someone for help. - -launch.state.logging_in=Logging In -launch.state.generating_launching_codes=Generating Launching Codes -launch.state.downloading_libraries=Downloading dependencies -launch.state.decompressing_natives=Decompressing natives - -install.no_version=The version is not found. -install.no_version_if_intall=The needed version is not found, should install the version automatically? -install.not_refreshed=The installer list is not refreshed. -install.download_list=Download List - -install.liteloader.get_list=Get LiteLoader List -install.liteloader.install=Install LiteLoader - -install.forge.get_list=Get Forge List -install.forge.install=Install Forge -install.forge.get_changelogs=Get Forge Changelogs - -install.optifine.install=Install OptiFine -install.optifine.get_list=Get OptiFine Download List -install.optifine.get_download_link=Get the Download Link of OptiFine - -install.failed_forge=Failed to Install Forge -install.failed_optifine=Failed to Install OptiFine -install.failed_liteloader=Failed to Install LiteLoader -install.failed_download_forge=Failed to Download Forge -install.failed_download_optifine=Failed to Download OptiFine -install.failed=Failed to install -install.success=Install successfully -install.no_forge=No Forge -install.choose_forge=Choose the version you want to install Forge -install.version=Version -install.mcversion=Game Version -install.time=Time -install.release_time=Release Time -install.type=Type -install.please_refresh=If you want to install something, please click "Refresh" button. - -crash.launcher=Launcher has crashed! -crash.minecraft=Minecraft has crashed! - -login.choose_charactor=Please choose the charactor you want -login.no_charactor=No charactor in this account. -login.your_password=Your password -login.failed=Failed to login -login.no_Player007=You have not set username! -login.wrong_password=Wrong password or username -login.invalid_username=Invalid username -login.invalid_uuid_and_username=Invalid UUID and username -login.invalid_password=Invalid password -login.invalid_access_token=Invalid Access Token -login.changed_client_token=The server response has changed the client token. -login.not_email=The username must be a e-mail. -login.type=Login -login.username=Name -login.account=Email -login.invalid_token=Please log out and reinput your password to log in. -login.no_valid_character=No Valid Character, please visit skinme.cc and create your own character. - -proxy.username=Account -proxy.password=Password -proxy.host=Host -proxy.port=Port - -login.failed.connect_authentication_server=Cannot connect the authentication server. Check your network. - -login.profile.not_logged_in=Not Logged In and Cannot modify the profile. -login.profile.selected=Cannot modify the profile, you must logout and go back. - -login.methods.yggdrasil=Mojang -login.methods.offline=Offline -login.methods.no_method=No login method - -log.playername_null=The player name is empty. - -minecraft.no_selected_version=No selected Minecraft version -minecraft.wrong_path=Wrong Minecraft path, the launcher could not find the path. - -operation.stopped=The operation was aborted. -operation.confirm_stop=Terminate the operations? - -ui.login.password=Password -ui.more=More - -crash.advice.UnsupportedClassVersionError=Maybe your java is too old, try to update the java. -crash.advice.ConcurrentModificationException=Maybe your Java is newer than 1.8.0_11, you could downgrade to Java 7. -crash.advice.ClassNotFoundException=Minecraft or mods are incomplete. Retry if there are some libraries that have not downloaded or update your game and mods! Or you can try Game Settings -> Manage (Version) -> Delete library files to solve the problem. -crash.advice.NoSuchFieldError=Minecraft or mods are incomplete. Retry if there are some libraries that have not downloaded or update your game and mods! -crash.advice.LWJGLException=Maybe your video driver does not work well, please update your video driver. -crash.advice.SecurityException=Maybe you have modified minecraft.jar but have not removed the META-INF. -crash.advice.OutOfMemoryError=The maximum memory of JVM is too small, please modify it. -crash.advice.otherwise=Maybe mods caused problems. - -crash.advice.OpenGL=Maybe drivers caused problems. -crash.advice.no_lwjgl=Maybe drivers caused problems. - -crash.advice.no=No advice. - -crash.user_fault=Your OS or Java environment may not be properly installed resulting in crashing of this software, please check your Java Environment or your computer! -crash.headless=If your OS is Linux, please use Oracle JDK instead of OpenJDK, or add "-Djava.awt.headless=false" JVM argument, or check if your Xserver works normally. -crash.NoClassDefFound=Please check "HMCL" software is complete. - -crash.error=Minecraft has crashed. -crash.main_class_not_found=Main Class is not found, may be your mc has been broken. -crash.class_path_wrong=Maybe the launch script is malformed. - -ui.label.newProfileWindow.new_profile_name=New Profile Name: -ui.label.newProfileWindow.copy_from=Copy From: -ui.newProfileWindow.title=New Config - -ui.button.ok=OK -ui.button.refresh=Refresh -ui.button.run=Play -ui.button.settings=Settings -ui.button.about=About -ui.button.others=Others -ui.button.logout=Log Out -ui.button.download=Download -ui.button.retry=Retry -ui.button.delete=Delete -ui.button.install=Install -ui.button.info=Info -ui.button.save=Save -ui.button.copy=Copy -ui.button.clear=Clear -ui.button.close=Close -ui.button.explore=Explore -ui.button.test=Test -ui.button.preview=Preview -button.cancel=Cancel -button.ok=OK - -ui.label.version=Version -ui.label.password=Password -ui.label.profile=Profile - -ui.message.first_load=Please enter your name. -ui.message.enter_password=Please enter your password. -ui.message.launching=Launching... -ui.message.making=Generating... -ui.message.sure_remove=Sure to remove profile %s? -ui.message.update_java=Please upgrade your Java. - -ui.label.settings=Settings -ui.label.crashing=Hello Minecraft! Launcher has crashed! -ui.label.crashing_out_dated=Hello Minecraft! Launcher has crashed! And your launcher is not the latest version. Update it! -ui.label.failed_set=Failed to set: - -download=Download -download.mojang=Mojang -download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/) -download.rapid_data=RapidData (https://www.rapiddata.org/) -download.not_200=Failed to download, the response code -download.failed=Failed to download -download.successfully=Download Successfully -download.source=Download Source - -message.error=Error -message.cannot_open_explorer=Cannot open explorer: -message.cancelled=Cancelled -message.info=Info - -folder.game=Game Dir -folder.mod=Mod -folder.coremod=Core Mod -folder.config=Configs -folder.resourcepacks=Resourcepacks -folder.screenshots=Screenshots -folder.saves=Saves - -settings.tabs.game_download=Games -settings.tabs.installers=Installers -settings.tabs.assets_downloads=Assets - -settings=Settings -settings.explore=Explore -settings.manage=Manage -settings.cannot_remove_default_config=Cannot remove the default configution. -settings.max_memory=Max Memory/MB -settings.java_dir=Java Dir -settings.game_directory=Game Directory -settings.dimension=Game Window Dimension -settings.fullscreen=Fullscreen -settings.update_version=Update version json. -settings.run_directory=Run Directory(Version Isolation) -settings.physical_memory=Physical Memory Size -settings.choose_javapath=Choose Java Directory. -settings.default=Default -settings.custom=Custom -settings.choose_gamedir=Choose Game Directory -settings.failed_load=Failed to load settings file. Remove it? -settings.test_game=Test game - -modpack=Mod pack -modpack.choose=Choose a modpack zip file which you want to import. If you want to update the modpack, please enter the version you want to update. -modpack.export_error=Failed to export the modpack, maybe the format of your game directory is incorrect or failed to manage files. -modpack.export_finished=Exporting the modpack finished. See -modpack.included_launcher=The modpack has already included the launcher, you can publish it directly. -modpack.not_included_launcher=Use the modpack by "import modpack". -modpack.enter_name=Give this game a name which is your favorite. - -modpack.task.save=Export the modpack -modpack.task.install=Import the modpack -modpack.task.install.error=Failed to install the modpack, maybe the modpack file is incorrect or failed to manage files. -modpack.task.install.will=Will install the modpack: - -modpack.wizard=Exporting the modpack wizard -modpack.wizard.step.1=Basic options -modpack.wizard.step.1.title=Set the basic options to the modpack. -modpack.wizard.step.initialization.include_launcher=Include the launcher -modpack.wizard.step.initialization.exported_version=The exported game version -modpack.wizard.step.initialization.save=Choose a location which you want to export the game files to -modpack.wizard.step.initialization.warning=Before making modpack, you should ensure that your game can launch successfully,
        and that your Minecraft is release, not snapshot.
        and that it is not allowed to add mods which is not allowed to distribute to the modpack. -modpack.wizard.step.2=Files selection -modpack.wizard.step.2.title=Choose the files you do not want to put in the modpack. -modpack.wizard.step.3=Description -modpack.wizard.step.3.title=Describe your modpack. - -modpack.desc=Describe your modpack, including precautions, changlog, supporting Markdown(also supporting online pictures). -modpack.incorrect_format.no_json=The format of the modpack is incorrect, pack.json is missing. -modpack.incorrect_format.no_jar=The format of the modpack is incorrect, pack.json does not have attribute 'jar' -modpack.cannot_read_version=Failed to gather the game version -modpack.not_a_valid_location=Not a valid modpack location -modpack.name=Modpack Name -modpack.not_a_valid_name=Not a valid modpack name - -modpack.files.servers_dat=Multiplayer servers list -modpack.files.saves=Saved games -modpack.files.mods=Mods -modpack.files.config=Mod configs -modpack.files.liteconfig=Mod configurations -modpack.files.resourcepacks=Resource(Texutre) packs -modpack.files.options_txt=Game options -modpack.files.optionsshaders_txt=Shaders options -modpack.files.mods.voxelmods=VoxelMods(including VoxelMap) options -modpack.files.dumps=NEI debug output -modpack.files.scripts=MineTweaker configs -modpack.files.blueprints=BuildCraft blueprints - -mods=Mods -mods.choose_mod=Choose your mods -mods.failed=Failed to add mods -mods.add=Add -mods.remove=Remove -mods.default_information=Please ensure that you have installed Forge or LiteLoader before installing mods!
        You can drop your mod files from explorer/finder, and delete mods by the delete button.
        Disable a mod by leaving the check box unchecked; Choose an item to get the information.
        - -advancedsettings=Advanced -advancedsettings.launcher_visible=Launcher Visibility -advancedsettings.debug_mode=Debug Mode -advancedsettings.java_permanent_generation_space=PermGen Space/MB -advancedsettings.jvm_args=Java VM Arguments -advancedsettings.Minecraft_arguments=Minecraft Arguments -advancedsettings.launcher_visibility.close=Close the launcher when the game launched. -advancedsettings.launcher_visibility.hide=Hide the launcher when the game launched. -advancedsettings.launcher_visibility.keep=Keep the launcher visible. -advancedsettings.game_dir.default=Default (.minecraft/) -advancedsettings.game_dir.independent=Independent (.minecraft/versions//, except assets,libraries) -advancedsettings.no_jvm_args=No Default JVM Args -advancedsettings.java_args_default=Default java args: -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -XX:MaxPermSize=???m -Xmx???m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true -advancedsettings.wrapper_launcher=Wrapper Launcher(like optirun...) -advancedsettings.precall_command=Precalling command(will be executed before game launching) -advancedsettings.server_ip=Server Host -advancedsettings.cancel_wrapper_launcher=Cancel Wrapper Launcher -advancedsettings.dont_check_game_completeness=Dont check game completeness - -mainwindow.show_log=Show Logs -mainwindow.make_launch_script=Make Launching Script. -mainwindow.make_launch_script_failed=Failed to make script. -mainwindow.enter_script_name=Enter the script name. -mainwindow.make_launch_succeed=Finished script creation. -mainwindow.no_version=No version found. Switch to Game Downloads Tab? - -launcher.about=About Author
        Email\uff1ahuanghongxun2008@126.com
        Minecraft Forum ID: klkl6523
        Copyright (c) 2013 huangyuhui
        Opened source under GPL v3 license:http://github.com/huanghongxun/HMCL/
        This software used project Gson which is under Apache License 2.0, thanks contributors. -launcher.download_source=Download Source -launcher.background_location=Background Location -launcher.exit_failed=Failed to shutdown. -launcher.versions_json_not_matched=The version %s is malformed! There are a json:%s in this version. Do you want to fix this problem? -launcher.versions_json_not_matched_cannot_auto_completion=The version %s lost version information file, delete it? -launcher.versions_json_not_formatted=The version information of %s is malformed! Redownload it? -launcher.choose_bgpath=Choose background path. -launcher.background_tooltip=This app uses the default background at first.
        If there is background.png in the directory, it will be used.
        If there is "bg" subdirectory, this app will chooses one picture in "bgskin" randomly.
        If you set the background setting, this app will use it. -launcher.update_launcher=Check for update -launcher.enable_shadow=Enable Window Shadow -launcher.theme=Theme -launcher.proxy=Proxy -launcher.decorated=Enable system window border(in order to fix the problem that the ui become all gray in Linux OS) -launcher.modpack=Documentations for modpacks. -launcher.enable_animation=Enable Animation -launcher.lang=Language -launcher.restart=Options will be in operations only if restart this app. - -launcher.title.game=Games -launcher.title.main=Home -launcher.title.launcher=Launcher - -versions.release=Release -versions.snapshot=Snapshot -versions.old_beta=Beta -versions.old_alpha=Old Alpha - -versions.manage.rename=Rename this version -versions.manage.rename.message=Please enter the new name -versions.manage.remove=Delete this version -versions.manage.remove.confirm=Sure to remove the version -versions.manage.redownload_json=Redownload Minecraft Configuration(minecraft.json) -versions.manage.redownload_assets_index=Redownload Assets Index -versions.mamage.remove_libraries=Delete library files - -advice.os64butjdk32=Your OS is 64-Bit but your Java is 32-Bit. The 64-Bit Java is recommended. - -assets.download_all=Download Assets Files -assets.not_refreshed=The assets list is not refreshed, please refresh it once. -assets.failed=Failed to get the list, try again. -assets.list.1_7_3_after=1.7.3 And Higher -assets.list.1_6=1.6(BMCLAPI) -assets.unkown_type_select_one=Unknown game version: %s, please choose an asset type. -assets.type=Asset Type -assets.download=Download Assets -assets.no_assets=Assets are not complete, complete them? -assets.failed_download=Failed to download assets, may cause no sounds and language files. - -gamedownload.not_refreshed=The game list is not refreshed, please refresh it once. - -taskwindow.title=Tasks -taskwindow.single_progress=Single progress -taskwindow.total_progress=Total progress -taskwindow.cancel=Cancel -taskwindow.no_more_instance=Maybe you opened more than one task window, dont open it again! -taskwindow.file_name=Task -taskwindow.download_progress=Pgs. - -setupwindow.include_minecraft=Import game -setupwindow.find_in_configurations=Finished importing. You can find it in the configuration selection bar. -setupwindow.give_a_name=Give a name to the new game. -setupwindow.new=New -setupwindow.no_empty_name=Version name cannot be empty. -setupwindow.clean=Clean game files - -update.no_browser=Cannot open any browser. The link has been copied to the clipboard. You can paste it to the address bar. -update.should_open_link=Are you willing to upgrade this app? -update.newest_version=Newest version: -update.failed=Failed to check for updates. -update.found=(Found Update!) - -logwindow.terminate_game=Terminate Game -logwindow.tieba=Baidu Tieba -logwindow.title=Log - -selector.choose=Choose - -serverlistview.title=Choose a server -serverlistview.name=Name -serverlistview.type=Type -serverlistview.version=Version -serverlistview.info=Information - -minecraft.invalid=Invalid -minecraft.invalid_jar=Invalid Jar -minecraft.not_a_file=Not a file -minecraft.not_found=Not found -minecraft.not_readable=Not readable -minecraft.modified=(Modified!) - -color.red=Red -color.blue=Blue -color.green=Green -color.orange=Orange -color.dark_blue=Dark Blue -color.purple=Purple - -wizard.next_>=Next > -wizard.next_mnemonic=N -wizard.<_prev=< Prev -wizard.prev_mnemonic=P -wizard.finish=Finish -wizard.finish_mnemonic=F -wizard.cancel=Cancel -wizard.cancel_mnemonic=C -wizard.help=Help -wizard.help_mnemonic=H -wizard.close=Close -wizard.close_mnemonic=C -wizard.summary=Summary -wizard.failed=Failed -wizard.steps=Steps - -lang=English -lang.default=Belong to OS language. \ No newline at end of file diff --git a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_vi.lang b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_vi.lang new file mode 100644 index 000000000..1ad102ddb --- /dev/null +++ b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_vi.lang @@ -0,0 +1,418 @@ +# 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/}. +# +#author: LADBOSSHOSS +launch.failed=Mở minecraft không thành công. +launch.failed_creating_process=Tạo tiến trình chạy thất bại, có thể nơi bạn cài java đã bị sai, vui lòng hãy chỉnh sửa lại đường dẫn cài java. +launch.failed_sh_permission=Thêm quyền vào đoạn mã chạy launcher thất bại. +launch.failed_packing_jar=Đóng gói file jar thất bại +launch.unsupported_launcher_version=Xin lỗi, launcher không mở được minecraft, nhưng launcher sẽ cố gắng để chạy. +launch.too_big_memory_alloc_64bit=Bạn đã cho minecraft dùng quá nhiều RAM, vì máy bạn dùng 32-Bit Java Runtime Environment, Minecraft có thể bị crash. Mức RAM cho minecraft dùng cao nhất là 1024MB. Launcher sẽ thử để chạy mnecraft +launch.too_big_memory_alloc_free_space_too_low=Bạn đã cho minecraft dùng quá nhiều RAM, vì ram của bạn chỉ có %dMB, minecraft có thể bị crash. Launcher sẽ thử để chạy +launch.cannot_create_jvm=Launcher không tạo được máy ảo java để chạy minecraft. Java argument có thể có vấn đề, bạn có thể bật chế độ no args trong cài đặt +launch.circular_dependency_versions=Đã tìm thấy phiên bản minecraft không phù hợp, xin hãy xem phiên bản minecraft đã được chỉnh sửa hay không. +launch.not_finished_downloading_libraries=Không download được libraries cho minecraft, có tiếp tục mở game không? +launch.not_finished_decompressing_natives=Không giải nén được libraries cho minecraft, có tiếp tục mở game không? +launch.wrong_javadir=Đường dẫn cài java bị sai, launcher sẽ reset lại đường dẫn java đúng +launch.exited_abnormally=Minecraft đã bị thoát bất thường, hãy xem file log, hoặc nói với người khác giúp. + +launch.state.logging_in=Đang đăng nhập... +launch.state.generating_launching_codes=Đang tạo code chạy minecraft +launch.state.downloading_libraries=Downloading... +launch.state.decompressing_natives=Giải nén... + +install.no_version=Không tìm thấy phiên bản minecraft. +install.no_version_if_intall=Phiên bản cần thiết không thấy, có nên cài đặt phiên bản tự động không? +install.not_refreshed=Danh sách cài chưa được làm mới +install.download_list=Danh sách download + +install.liteloader.get_list=Lấy LiteLoader List +install.liteloader.install=Cài LiteLoader + +install.forge.get_list=Get Forge List +install.forge.install=Cài Forge +install.forge.get_changelogs=Lấy Forge Changelogs + +install.optifine.install=Cài OptiFine +install.optifine.get_list=Lấy OptiFine Download List +install.optifine.get_download_link=Lấy download link của Optifine + +install.failed_forge=Không cài được Forge +install.failed_optifine=Không cài được Optifine +install.failed_liteloader=Không cài được LiteLoader +install.failed_download_forge=Failed to Download Forge +install.failed_download_optifine=Failed to Download OptiFine +install.failed=Không cài được +install.success=Cài đặt thành công +install.no_forge=No Forge +install.choose_forge=Chọn phiên bản bạn muốn cài Forge +install.version=Phiên bản +install.mcversion=Game Version +install.time=Time +install.release_time=Thời gian phát hành +install.type=Type +install.please_refresh=Nếu bạn muốn cài một thứ gì đó, hãy ấn nút "Tải lại". + +crash.launcher=Launcher bị crash rồi! +crash.minecraft=Minecraft bị crash rồi! + +login.choose_charactor=Xin hãy chọn nhân vật bạn muốn +login.no_charactor=Không có nhân vật trong tài khoản này. +login.your_password=Mật khẩu của bạn +login.failed=Không đăng nhập được +login.no_Player007=You have not set username! +login.wrong_password=Mật khẩu hoặc username đã sai. +login.invalid_username=Username không đúng +login.invalid_uuid_and_username=UUID và username không đúng +login.invalid_password=Mật khẩu không đúng +login.invalid_access_token=Access Token bị sai +login.changed_client_token=Server đã thay đổi client token. +login.not_email=Username phải là email +login.type=Login +login.username=Username: +login.account=Email: +login.invalid_token=Hãy đăng xuất và đăng nhập lại. +login.no_valid_character=Không có nhân vật hợp lệ, hãy vào trang web skinme.cc và tạo một nhân vật cho bạn. + +proxy.username=Tài khoản +proxy.password=Mật khẩu +proxy.host=Host +proxy.port=Số cổng + +login.failed.connect_authentication_server=Không thể kết nối đến máy chủ xác thực, hãy xem lại kết nối mạng của bạn + +login.profile.not_logged_in=Không đăng nhập vào được và không thể chính sửa cấu hình. +login.profile.selected=Không chỉnh sửa được cấu hình, bạn phải đăng xuất ra rồi làm lại. + +login.methods.yggdrasil=Mojang +login.methods.offline=Offline +login.methods.no_method=Không có chế độ nào + +log.playername_null=Tên của người chơi trống. + +minecraft.no_selected_version=Bạn chưa chọn phiên bản minecraft! +minecraft.wrong_path=Đường dẫn minecraft bị sai, launcher không tìm thấy được đường dẫn + +operation.stopped=Quá trình đã được dừng lại. +operation.confirm_stop=Dừng lại quá trình không? + +ui.login.password=Mật khẩu +ui.more=Xem thêm + +crash.advice.UnsupportedClassVersionError=Phiên bản java của bạn quá cũ, hãy thử cập nhật phiên bản java +crash.advice.ConcurrentModificationException=Có thể phiên bản java của bạn mới hơn phiên bản 1.8.0_11, Bạn có thể hạ cấp java xuông phiên bản 7. +crash.advice.ClassNotFoundException=Minecraft hoặc mod chưa được hoàn thành. Hãy thử lại nếu có một số libraries chưa được tải về hoặc cập nhật phiên bản minecraft và mod. Hoặc bạn có thể chọn Game Settings -> Manage (Version) -> Xóa libraries để sửa lỗi. +crash.advice.NoSuchFieldError=Minecraft hoặc mod chưa được hoàn thành. Hãy thử lại nếu có một số libraries chưa được tải về hoặc cập nhật phiên bản minecraft và mod. +crash.advice.LWJGLException=Có thể video driver của bạn không hoạt động tốt cho lắm, hãy thử cập nhật video driver của bạn. +crash.advice.SecurityException=Có thể bạn đã chỉnh sửa file minecraft.jar nhưng bạn chưa xóa file META-INF +crash.advice.OutOfMemoryError=Lượng RAM cao nhất của máy áo java quá nhỏ, hãy chỉnh sửa nó. +crash.advice.otherwise=Có thể mods đã làm ra lỗi. +crash.advice.OpenGL=Có thể drivers đã làm ra lỗi +crash.advice.no_lwjgl=Có thể drivers đã làm ra lỗi +crash.advice.no=Không có lời khuyên. + +crash.user_fault=Hệ điều hành hoặc java của bạn có thể đã cài đặt không đúng cách dẫn đến sự crash của launcher, hãy cài lại java và xem lại máy tính của bạn! +crash.headless=Nếu hệ điều hành của bạn là Linux, hãy dùng Oracle JDK thay cho OpenJDK, hoặc thêm vào "-Djava.awt.headless=false" vào argument của máy ảo java, hoặc xem nếu Xserver có hoạt động hay không +crash.NoClassDefFound=Hãy kiểm tra phần mềm "HMCL" đã hoàn thành + +crash.error=Minecraft đã bị crash. +crash.main_class_not_found=Class chính của minecraft không tìm thấy, có lẽ phiên bản minecraft đã bị lỗi. +crash.class_path_wrong=Có lẽ đoạn mã chạy launcher đã bị lỗi + +ui.label.newProfileWindow.new_profile_name=Tên cấu hình mới: +ui.label.newProfileWindow.copy_from=Copy từ: +ui.newProfileWindow.title=Cấu hình mới + +ui.button.ok=OK +ui.button.refresh=Tải lại +ui.button.run=Play +ui.button.settings=Cài đặt +ui.button.about=About +ui.button.others=Khác +ui.button.logout=Đăng xuất +ui.button.download=Tải về +ui.button.retry=Thử lại +ui.button.delete=Xóa +ui.button.install=Cài +ui.button.info=Thông tin +ui.button.save=Lưu +ui.button.copy=Copy +ui.button.clear=Xóa +ui.button.close=Đóng +ui.button.explore=Explore +ui.button.test=Test +ui.button.preview=Xem trước +button.cancel=Thoát +button.ok=OK + +ui.label.version=Phiên bản +ui.label.password=Mật khẩu +ui.label.profile=Cấu hình + +ui.message.first_load=Hãy nhập username của bạn vào. +ui.message.enter_password=Hãy nhập mật khẩu của bạn +ui.message.launching=Launching... +ui.message.making=Generating... +ui.message.sure_remove=Bạn có chắc chắn xóa cấu hình %s không? +ui.message.update_java=Hãy cập nhật phiên bản java của bạn. + +ui.label.settings=Cài đặt +ui.label.crashing=HMCL Minecraft Launcher đã bị crash! +ui.label.crashing_out_dated=HL Minecraft Launcher đã bị crash! Và launcher của bạn không phải là phiên bản mới nhất. cập nhật nó đi! +ui.label.failed_set=Failed to set: + +download=Download +download.mojang=Mojang +download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/) +download.rapid_data=RapidData (https://www.rapiddata.org/) +download.not_200=Download không thành công, the response code +download.failed=Download không thành công. +download.successfully=Download thành công. +download.source=Download Source + +message.error=Lỗi +message.cannot_open_explorer=Cannot open explorer: +message.cancelled=Đã thoảt +message.info=Thông tin +message.loading=Loading... + +folder.game=Thư mục minecraft +folder.mod=Mod +folder.coremod=Core Mod +folder.config=Cấu hình +folder.resourcepacks=Resourcepacks +folder.screenshots=Ảnh chụp màn hình +folder.saves=Thế giới + +settings.tabs.game_download=Games +settings.tabs.installers=Trình cài đặt +settings.tabs.assets_downloads=Assets + +settings=Settings +settings.explore=Explore +settings.manage=Manage +settings.cannot_remove_default_config=Không thể xóa cấu hình mặc định +settings.max_memory=RAM cao nhất(MB) +settings.java_dir=Thư mục Java +settings.game_directory=Thư mục minecraft +settings.dimension=Khu vực cửa sổ của game +settings.fullscreen=Toàn màn hình +settings.update_version=Update version json. +settings.run_directory=Run Directory(Version Isolation) +settings.physical_memory=Dung lượgg RAM vật lý +settings.choose_javapath=Chọn thư mục java +settings.default=Mặc định +settings.custom=Tùy chỉnh +settings.choose_gamedir=Chọn thư mục game +settings.failed_load=Đọc file cấu hình thất bại. Xóa nó không? +settings.test_game=Chạy thử game + +modpack=Mod pack +modpack.choose=Chọn modpack zip file mà bạn muốn nhập vào. Nếu bạn muốn cập nhật phiên bản của modpack, Hãy nhập vào phiên bản bạn muốn cập nhật. +modpack.export_error=Xuất modpack ra thất bại, có thể định dạng của thư mục chứa dữ liệu bị sai hoặc không thể quản lý file. +modpack.export_finished=Xuất modpack ra thành công. Xem +modpack.included_launcher=Modpack đã được tích hợp trong launcher, Bạn có thể publish nó. +modpack.not_included_launcher=Dùng nút "Cài Modpack" để cài modpack. +modpack.enter_name=Hãy cho một cái tên mà bạn thích. + +modpack.task.save=Xuất Modpack +modpack.task.install=Cài Modpack +modpack.task.install.error=Cài modpack không thành công, có lẽ file modpack không đúng hoặc là không thể quản lý file +modpack.task.install.will=Launcher sẽ cài modpack: + +modpack.wizard=Công cụ xuất modpack +modpack.wizard.step.1=Tùy chọn cơ bản +modpack.wizard.step.1.title=Chọn các tùy chọn cơ bản cho modpack. +modpack.wizard.step.initialization.include_launcher=Include the launcher +modpack.wizard.step.initialization.exported_version=Phiên bản đã được xuất +modpack.wizard.step.initialization.save=Chọn một thư mục mà bạn muốn xuất game data +modpack.wizard.step.initialization.warning=Trước khi tạo modpack, bạn phải chắc chắn rằng minecraft có thể chạy,
        và phiên bản minecraft là chính thức, không phải là snapshot.
        và nó không cho thêm mods mà không có quyền để tạo modpack. +modpack.wizard.step.2=Chọn file +modpack.wizard.step.2.title=Chọn file bạn không muốn thêm vào modpack +modpack.wizard.step.3=Miêu tả +modpack.wizard.step.3.title=Miêu tả modpack của bạn. + +modpack.desc=Miêu tả modpack của bạn, bao gồm đề phòng, sự thay đổi, dấu gạch xuống(và một số hình ảnh). +modpack.incorrect_format.no_json=Định dạng của modpack không đúng, file pack.json bị thiếu +modpack.incorrect_format.no_jar=Định dạng của modpack không đúng, file pack.json không có đặc tính jar +modpack.cannot_read_version=Lấy phiên bản của minecraft thất bại +modpack.not_a_valid_location=Nơi chứa modpack không đúng +modpack.name=Tên của modpack +modpack.not_a_valid_name=Tên của modpack không đúng + +modpack.files.servers_dat=Danh sách server +modpack.files.saves=Thư mục chứa dữ liệu thế giới +modpack.files.mods=Mods +modpack.files.config=Cấu hình của mod +modpack.files.liteconfig=Cấu hình của LiteLoader +modpack.files.resourcepacks=Resource(Texutre) packs +modpack.files.options_txt=Tùy chọn của game +modpack.files.optionsshaders_txt=Tùy chọn của shaders +modpack.files.mods.voxelmods=Tùy chọn của VoxelMod(tính cả VoxelMap) +modpack.files.dumps=NEI debug output +modpack.files.scripts=Cấu hình của MineTweaker +modpack.files.blueprints=Bản thiết kế cho BuildCraft + +mods=Mods +mods.choose_mod=Chọn mods +mods.failed=Tải mods thất bại +mods.add=Thêm +mods.remove=Xóa +mods.default_information=Bạn hãy chắc chắn rằng bạn đã cài Forge hoặc LiteLoader trước khi cài mods!
        Bạn có thể kéo file mods vào trong cửa sổ này để thêm, và xóa mods bằng cách ấn nút xóa.
        Tắt mods bằng cách bỏ dấu v ở chỗ hộp kiểm; Chọn một mục để biết thêm thông tin.
        + +advancedsettings=Nâng cao +advancedsettings.launcher_visible=Sự hiển thị của launcher +advancedsettings.debug_mode=Chế độ gỡ lỗi +advancedsettings.java_permanent_generation_space=Dung lượng PermGen/MB +advancedsettings.jvm_args=Arguments của máy ảo java +advancedsettings.Minecraft_arguments=Arguments của minecraft +advancedsettings.launcher_visibility.close=Đóng launcher sau khi minecraft được mở. +advancedsettings.launcher_visibility.hide=Ẩn launcher sau khi minecraft được mở. +advancedsettings.launcher_visibility.keep=Để cho launcher hiển thị. +advancedsettings.game_dir.default=Mặc định (.minecraft/) +advancedsettings.game_dir.independent=Independent (.minecraft/versions//, trừ thư mục assets,libraries) +advancedsettings.no_jvm_args=Không có arguments mặc định cho máy ảo java +advancedsettings.java_args_default=Java arguments mặc định: -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -XX:MaxPermSize=???m -Xmx???m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true +advancedsettings.wrapper_launcher=Wrapper Launcher(dạng như optirun...) +advancedsettings.precall_command=Câu lệnh được chạy trước khi game mở +advancedsettings.server_ip=Máy chủ +advancedsettings.cancel_wrapper_launcher=Hủy bỏ Wrapper Launcher +advancedsettings.dont_check_game_completeness=Không kiểm tra game có đầy đủ không. + +mainwindow.show_log=Xem logs +mainwindow.make_launch_script=Tạo đoạn mã launching +mainwindow.make_launch_script_failed=Tạo đoạn mã thất bại +mainwindow.enter_script_name=Nhập tên của đoạn mã. +mainwindow.make_launch_succeed=Đã tạo đoạn mã. +mainwindow.no_version=Không có phiên bản minecraft nào được tìm thấy. Chuyển sang tab Game Download? + +launcher.about=Về tác giả
        Minecraft Forum ID: klkl6523
        Copyright (c) 2013 huangyuhui
        http://github.com/huanghongxun/HMCL/
        Phần mềm này dùng project Gson, cảm ơn người đóng góp. +launcher.download_source=Download Source +launcher.background_location=Background Location +launcher.exit_failed=Tắt launcher thất bại. +launcher.versions_json_not_matched=The version %s is malformed! There are a json:%s in this version. Do you want to fix this problem? +launcher.versions_json_not_matched_cannot_auto_completion=The version %s lost version information file, delete it? +launcher.versions_json_not_formatted=The version information of %s is malformed! Redownload it? +launcher.choose_bgpath=Choose background path. +launcher.background_tooltip=This app uses the default background at first.
        If there is background.png in the directory, it will be used.
        If there is "bg" subdirectory, this app will chooses one picture in "bgskin" randomly.
        If you set the background setting, this app will use it. +launcher.update_launcher=Check for update +launcher.enable_shadow=Enable Window Shadow +launcher.enable_animation=Enable Animation +launcher.enable_blur=Enable Blur +launcher.theme=Theme +launcher.proxy=Proxy +launcher.decorated=Enable system window border(in order to fix the problem that the ui become all gray in Linux OS) +launcher.modpack=Documentations for modpacks. +launcher.lang=Language +launcher.restart=Options will be in operations only if restart this app. + +launcher.title.game=Phiên bản & Mods +launcher.title.main=HMCL Main +launcher.title.launcher=Launcher + +versions.release=Chính thức +versions.snapshot=Snapshot +versions.old_beta=Beta +versions.old_alpha=Old Alpha + +versions.manage.rename=Đổi tên phiên bản này +versions.manage.rename.message=Nhập tên mới +versions.manage.remove=Xóa phiên bản này +versions.manage.remove.confirm=Bạn có chắc để xóa phiên bản này không? +versions.manage.redownload_json=Download lại cấu hình của minecraft(minecraft.json) +versions.manage.redownload_assets_index=Download lại Assets Index +versions.mamage.remove_libraries=Xóa libraries file + +advice.os64butjdk32=Hệ điều hành của bạn là 64-Bit nhưng phiên bản Java của bạn là 32-Bit. Khuyên bạn nên dùng Java 64-Bit. + +assets.download_all=Download file assets +assets.not_refreshed=Danh sách assets chưa được load lại, bạn hãy ấn nút Tải lại. +assets.failed=Lấy danh sách thất bại, hãy thử lại. +assets.list.1_7_3_after=1.7.3 và cao hơn +assets.list.1_6=1.6(BMCLAPI) +assets.unkown_type_select_one=Phiên bản minecraft chưa được biết: %s, hãy chọn một loại asset. +assets.type=Loại asset +assets.download=Download Assets +assets.no_assets=Assets chưa được hoàn thành, hoàn thành nó không? +assets.failed_download=Download asset thất bại, có thể sẽ không có âm thanh và ngôn ngữ. + +gamedownload.not_refreshed=Danh sách phiên bản chưa được load lại, bạn hãy ấn nút Tải lại. + +taskwindow.title=Tasks +taskwindow.single_progress=Single progress +taskwindow.total_progress=Total progress +taskwindow.cancel=Cancel +taskwindow.no_more_instance=Maybe you opened more than one task window, dont open it again! +taskwindow.file_name=Task +taskwindow.download_progress=Pgs. + +setupwindow.include_minecraft=Import game +setupwindow.find_in_configurations=Finished importing. You can find it in the configuration selection bar. +setupwindow.give_a_name=Give a name to the new game. +setupwindow.new=New +setupwindow.no_empty_name=Version name cannot be empty. +setupwindow.clean=Clean game files + +update.no_browser=Không thể mở trình duyệt. Đường link đã được copy vào clipboard. Bạn có thể paste nó vào thanh đường link. +update.should_open_link=Bạn có muốn cập nhật launcher không? +update.newest_version=Phiên bản mới nhất: +update.failed=Kiểm tra cập nhật thất bại. +update.found=(Đã tìm thấy bản cập nhật!) + +logwindow.terminate_game=Tắt Game +logwindow.tieba=Baidu Tieba +logwindow.title=HMCL Error Log (Hãy đăng cái này lên forum!) + +selector.choose=Chọn + +serverlistview.title=Chọn máy chủ +serverlistview.name=Tên +serverlistview.type=Lọai +serverlistview.version=Phiên bản +serverlistview.info=Thông tin + +minecraft.invalid=Không hợp lệ +minecraft.invalid_jar=File jar không hợp lệ +minecraft.not_a_file=Not a file +minecraft.not_found=Không tìm thấy +minecraft.not_readable=Không đọc được +minecraft.modified=(Đã sửa đổi!) + +color.red=Đỏ +color.blue=Xanh da trời +color.green=Xanh lục +color.orange=Cam +color.dark_blue=Xanh da trời tối +color.purple=Tím + +wizard.next_>=Next > +wizard.next_mnemonic=N +wizard.<_prev=< Prev +wizard.prev_mnemonic=P +wizard.finish=Finish +wizard.finish_mnemonic=F +wizard.cancel=Cancel +wizard.cancel_mnemonic=C +wizard.help=Help +wizard.help_mnemonic=H +wizard.close=Close +wizard.close_mnemonic=C +wizard.summary=Summary +wizard.failed=Failed +wizard.steps=Steps + +lang=Vietnamese +lang.default=Thuộc về ngôn ngữ của hệ điều hành \ No newline at end of file diff --git a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_vi.properties b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_vi.properties new file mode 100644 index 000000000..e56190d3d --- /dev/null +++ b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_vi.properties @@ -0,0 +1,418 @@ +# 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/}. +# +#author: LADBOSSHOSS +launch.failed=M\u1edf minecraft kh\u00f4ng th\u00e0nh c\u00f4ng. +launch.failed_creating_process=T\u1ea1o ti\u1ebfn tr\u00ecnh ch\u1ea1y th\u1ea5t b\u1ea1i, c\u00f3 th\u1ec3 n\u01a1i b\u1ea1n c\u00e0i java \u0111\u00e3 b\u1ecb sai, vui l\u00f2ng h\u00e3y ch\u1ec9nh s\u1eeda l\u1ea1i \u0111\u01b0\u1eddng d\u1eabn c\u00e0i java. +launch.failed_sh_permission=Th\u00eam quy\u1ec1n v\u00e0o \u0111o\u1ea1n m\u00e3 ch\u1ea1y launcher th\u1ea5t b\u1ea1i. +launch.failed_packing_jar=\u0110\u00f3ng g\u00f3i file jar th\u1ea5t b\u1ea1i +launch.unsupported_launcher_version=Xin l\u1ed7i, launcher kh\u00f4ng m\u1edf \u0111\u01b0\u1ee3c minecraft, nh\u01b0ng launcher s\u1ebd c\u1ed1 g\u1eafng \u0111\u1ec3 ch\u1ea1y. +launch.too_big_memory_alloc_64bit=B\u1ea1n \u0111\u00e3 cho minecraft d\u00f9ng qu\u00e1 nhi\u1ec1u RAM, v\u00ec m\u00e1y b\u1ea1n d\u00f9ng 32-Bit Java Runtime Environment, Minecraft c\u00f3 th\u1ec3 b\u1ecb crash. M\u1ee9c RAM cho minecraft d\u00f9ng cao nh\u1ea5t l\u00e0 1024MB. Launcher s\u1ebd th\u1eed \u0111\u1ec3 ch\u1ea1y mnecraft +launch.too_big_memory_alloc_free_space_too_low=B\u1ea1n \u0111\u00e3 cho minecraft d\u00f9ng qu\u00e1 nhi\u1ec1u RAM, v\u00ec ram c\u1ee7a b\u1ea1n ch\u1ec9 c\u00f3 %dMB, minecraft c\u00f3 th\u1ec3 b\u1ecb crash. Launcher s\u1ebd th\u1eed \u0111\u1ec3 ch\u1ea1y +launch.cannot_create_jvm=Launcher kh\u00f4ng t\u1ea1o \u0111\u01b0\u1ee3c m\u00e1y \u1ea3o java \u0111\u1ec3 ch\u1ea1y minecraft. Java argument c\u00f3 th\u1ec3 c\u00f3 v\u1ea5n \u0111\u1ec1, b\u1ea1n c\u00f3 th\u1ec3 b\u1eadt ch\u1ebf \u0111\u1ed9 no args trong c\u00e0i \u0111\u1eb7t +launch.circular_dependency_versions=\u0110\u00e3 t\u00ecm th\u1ea5y phi\u00ean b\u1ea3n minecraft kh\u00f4ng ph\u00f9 h\u1ee3p, xin h\u00e3y xem phi\u00ean b\u1ea3n minecraft \u0111\u00e3 \u0111\u01b0\u1ee3c ch\u1ec9nh s\u1eeda hay kh\u00f4ng. +launch.not_finished_downloading_libraries=Kh\u00f4ng download \u0111\u01b0\u1ee3c libraries cho minecraft, c\u00f3 ti\u1ebfp t\u1ee5c m\u1edf game kh\u00f4ng? +launch.not_finished_decompressing_natives=Kh\u00f4ng gi\u1ea3i n\u00e9n \u0111\u01b0\u1ee3c libraries cho minecraft, c\u00f3 ti\u1ebfp t\u1ee5c m\u1edf game kh\u00f4ng? +launch.wrong_javadir=\u0110\u01b0\u1eddng d\u1eabn c\u00e0i java b\u1ecb sai, launcher s\u1ebd reset l\u1ea1i \u0111\u01b0\u1eddng d\u1eabn java \u0111\u00fang +launch.exited_abnormally=Minecraft \u0111\u00e3 b\u1ecb tho\u00e1t b\u1ea5t th\u01b0\u1eddng, h\u00e3y xem file log, ho\u1eb7c n\u00f3i v\u1edbi ng\u01b0\u1eddi kh\u00e1c gi\u00fap. + +launch.state.logging_in=\u0110ang \u0111\u0103ng nh\u1eadp... +launch.state.generating_launching_codes=\u0110ang t\u1ea1o code ch\u1ea1y minecraft +launch.state.downloading_libraries=Downloading... +launch.state.decompressing_natives=Gi\u1ea3i n\u00e9n... + +install.no_version=Kh\u00f4ng t\u00ecm th\u1ea5y phi\u00ean b\u1ea3n minecraft. +install.no_version_if_intall=Phi\u00ean b\u1ea3n c\u1ea7n thi\u1ebft kh\u00f4ng th\u1ea5y, c\u00f3 n\u00ean c\u00e0i \u0111\u1eb7t phi\u00ean b\u1ea3n t\u1ef1 \u0111\u1ed9ng kh\u00f4ng? +install.not_refreshed=Danh s\u00e1ch c\u00e0i ch\u01b0a \u0111\u01b0\u1ee3c l\u00e0m m\u1edbi +install.download_list=Danh s\u00e1ch download + +install.liteloader.get_list=L\u1ea5y LiteLoader List +install.liteloader.install=C\u00e0i LiteLoader + +install.forge.get_list=Get Forge List +install.forge.install=C\u00e0i Forge +install.forge.get_changelogs=L\u1ea5y Forge Changelogs + +install.optifine.install=C\u00e0i OptiFine +install.optifine.get_list=L\u1ea5y OptiFine Download List +install.optifine.get_download_link=L\u1ea5y download link c\u1ee7a Optifine + +install.failed_forge=Kh\u00f4ng c\u00e0i \u0111\u01b0\u1ee3c Forge +install.failed_optifine=Kh\u00f4ng c\u00e0i \u0111\u01b0\u1ee3c Optifine +install.failed_liteloader=Kh\u00f4ng c\u00e0i \u0111\u01b0\u1ee3c LiteLoader +install.failed_download_forge=Failed to Download Forge +install.failed_download_optifine=Failed to Download OptiFine +install.failed=Kh\u00f4ng c\u00e0i \u0111\u01b0\u1ee3c +install.success=C\u00e0i \u0111\u1eb7t th\u00e0nh c\u00f4ng +install.no_forge=No Forge +install.choose_forge=Ch\u1ecdn phi\u00ean b\u1ea3n b\u1ea1n mu\u1ed1n c\u00e0i Forge +install.version=Phi\u00ean b\u1ea3n +install.mcversion=Game Version +install.time=Time +install.release_time=Th\u1eddi gian ph\u00e1t h\u00e0nh +install.type=Type +install.please_refresh=N\u1ebfu b\u1ea1n mu\u1ed1n c\u00e0i m\u1ed9t th\u1ee9 g\u00ec \u0111\u00f3, h\u00e3y \u1ea5n n\u00fat "T\u1ea3i l\u1ea1i". + +crash.launcher=Launcher b\u1ecb crash r\u1ed3i! +crash.minecraft=Minecraft b\u1ecb crash r\u1ed3i! + +login.choose_charactor=Xin h\u00e3y ch\u1ecdn nh\u00e2n v\u1eadt b\u1ea1n mu\u1ed1n +login.no_charactor=Kh\u00f4ng c\u00f3 nh\u00e2n v\u1eadt trong t\u00e0i kho\u1ea3n n\u00e0y. +login.your_password=M\u1eadt kh\u1ea9u c\u1ee7a b\u1ea1n +login.failed=Kh\u00f4ng \u0111\u0103ng nh\u1eadp \u0111\u01b0\u1ee3c +login.no_Player007=You have not set username! +login.wrong_password=M\u1eadt kh\u1ea9u ho\u1eb7c username \u0111\u00e3 sai. +login.invalid_username=Username kh\u00f4ng \u0111\u00fang +login.invalid_uuid_and_username=UUID v\u00e0 username kh\u00f4ng \u0111\u00fang +login.invalid_password=M\u1eadt kh\u1ea9u kh\u00f4ng \u0111\u00fang +login.invalid_access_token=Access Token b\u1ecb sai +login.changed_client_token=Server \u0111\u00e3 thay \u0111\u1ed5i client token. +login.not_email=Username ph\u1ea3i l\u00e0 email +login.type=Login +login.username=Username: +login.account=Email: +login.invalid_token=H\u00e3y \u0111\u0103ng xu\u1ea5t v\u00e0 \u0111\u0103ng nh\u1eadp l\u1ea1i. +login.no_valid_character=Kh\u00f4ng c\u00f3 nh\u00e2n v\u1eadt h\u1ee3p l\u1ec7, h\u00e3y v\u00e0o trang web skinme.cc v\u00e0 t\u1ea1o m\u1ed9t nh\u00e2n v\u1eadt cho b\u1ea1n. + +proxy.username=T\u00e0i kho\u1ea3n +proxy.password=M\u1eadt kh\u1ea9u +proxy.host=Host +proxy.port=S\u1ed1 c\u1ed5ng + +login.failed.connect_authentication_server=Kh\u00f4ng th\u1ec3 k\u1ebft n\u1ed1i \u0111\u1ebfn m\u00e1y ch\u1ee7 x\u00e1c th\u1ef1c, h\u00e3y xem l\u1ea1i k\u1ebft n\u1ed1i m\u1ea1ng c\u1ee7a b\u1ea1n + +login.profile.not_logged_in=Kh\u00f4ng \u0111\u0103ng nh\u1eadp v\u00e0o \u0111\u01b0\u1ee3c v\u00e0 kh\u00f4ng th\u1ec3 ch\u00ednh s\u1eeda c\u1ea5u h\u00ecnh. +login.profile.selected=Kh\u00f4ng ch\u1ec9nh s\u1eeda \u0111\u01b0\u1ee3c c\u1ea5u h\u00ecnh, b\u1ea1n ph\u1ea3i \u0111\u0103ng xu\u1ea5t ra r\u1ed3i l\u00e0m l\u1ea1i. + +login.methods.yggdrasil=Mojang +login.methods.offline=Offline +login.methods.no_method=Kh\u00f4ng c\u00f3 ch\u1ebf \u0111\u1ed9 n\u00e0o + +log.playername_null=T\u00ean c\u1ee7a ng\u01b0\u1eddi ch\u01a1i tr\u1ed1ng. + +minecraft.no_selected_version=B\u1ea1n ch\u01b0a ch\u1ecdn phi\u00ean b\u1ea3n minecraft! +minecraft.wrong_path=\u0110\u01b0\u1eddng d\u1eabn minecraft b\u1ecb sai, launcher kh\u00f4ng t\u00ecm th\u1ea5y \u0111\u01b0\u1ee3c \u0111\u01b0\u1eddng d\u1eabn + +operation.stopped=Qu\u00e1 tr\u00ecnh \u0111\u00e3 \u0111\u01b0\u1ee3c d\u1eebng l\u1ea1i. +operation.confirm_stop=D\u1eebng l\u1ea1i qu\u00e1 tr\u00ecnh kh\u00f4ng? + +ui.login.password=M\u1eadt kh\u1ea9u +ui.more=Xem th\u00eam + +crash.advice.UnsupportedClassVersionError=Phi\u00ean b\u1ea3n java c\u1ee7a b\u1ea1n qu\u00e1 c\u0169, h\u00e3y th\u1eed c\u1eadp nh\u1eadt phi\u00ean b\u1ea3n java +crash.advice.ConcurrentModificationException=C\u00f3 th\u1ec3 phi\u00ean b\u1ea3n java c\u1ee7a b\u1ea1n m\u1edbi h\u01a1n phi\u00ean b\u1ea3n 1.8.0_11, B\u1ea1n c\u00f3 th\u1ec3 h\u1ea1 c\u1ea5p java xu\u00f4ng phi\u00ean b\u1ea3n 7. +crash.advice.ClassNotFoundException=Minecraft ho\u1eb7c mod ch\u01b0a \u0111\u01b0\u1ee3c ho\u00e0n th\u00e0nh. H\u00e3y th\u1eed l\u1ea1i n\u1ebfu c\u00f3 m\u1ed9t s\u1ed1 libraries ch\u01b0a \u0111\u01b0\u1ee3c t\u1ea3i v\u1ec1 ho\u1eb7c c\u1eadp nh\u1eadt phi\u00ean b\u1ea3n minecraft v\u00e0 mod. Ho\u1eb7c b\u1ea1n c\u00f3 th\u1ec3 ch\u1ecdn Game Settings -> Manage (Version) -> X\u00f3a libraries \u0111\u1ec3 s\u1eeda l\u1ed7i. +crash.advice.NoSuchFieldError=Minecraft ho\u1eb7c mod ch\u01b0a \u0111\u01b0\u1ee3c ho\u00e0n th\u00e0nh. H\u00e3y th\u1eed l\u1ea1i n\u1ebfu c\u00f3 m\u1ed9t s\u1ed1 libraries ch\u01b0a \u0111\u01b0\u1ee3c t\u1ea3i v\u1ec1 ho\u1eb7c c\u1eadp nh\u1eadt phi\u00ean b\u1ea3n minecraft v\u00e0 mod. +crash.advice.LWJGLException=C\u00f3 th\u1ec3 video driver c\u1ee7a b\u1ea1n kh\u00f4ng ho\u1ea1t \u0111\u1ed9ng t\u1ed1t cho l\u1eafm, h\u00e3y th\u1eed c\u1eadp nh\u1eadt video driver c\u1ee7a b\u1ea1n. +crash.advice.SecurityException=C\u00f3 th\u1ec3 b\u1ea1n \u0111\u00e3 ch\u1ec9nh s\u1eeda file minecraft.jar nh\u01b0ng b\u1ea1n ch\u01b0a x\u00f3a file META-INF +crash.advice.OutOfMemoryError=L\u01b0\u1ee3ng RAM cao nh\u1ea5t c\u1ee7a m\u00e1y \u00e1o java qu\u00e1 nh\u1ecf, h\u00e3y ch\u1ec9nh s\u1eeda n\u00f3. +crash.advice.otherwise=C\u00f3 th\u1ec3 mods \u0111\u00e3 l\u00e0m ra l\u1ed7i. +crash.advice.OpenGL=C\u00f3 th\u1ec3 drivers \u0111\u00e3 l\u00e0m ra l\u1ed7i +crash.advice.no_lwjgl=C\u00f3 th\u1ec3 drivers \u0111\u00e3 l\u00e0m ra l\u1ed7i +crash.advice.no=Kh\u00f4ng c\u00f3 l\u1eddi khuy\u00ean. + +crash.user_fault=H\u1ec7 \u0111i\u1ec1u h\u00e0nh ho\u1eb7c java c\u1ee7a b\u1ea1n c\u00f3 th\u1ec3 \u0111\u00e3 c\u00e0i \u0111\u1eb7t kh\u00f4ng \u0111\u00fang c\u00e1ch d\u1eabn \u0111\u1ebfn s\u1ef1 crash c\u1ee7a launcher, h\u00e3y c\u00e0i l\u1ea1i java v\u00e0 xem l\u1ea1i m\u00e1y t\u00ednh c\u1ee7a b\u1ea1n! +crash.headless=N\u1ebfu h\u1ec7 \u0111i\u1ec1u h\u00e0nh c\u1ee7a b\u1ea1n l\u00e0 Linux, h\u00e3y d\u00f9ng Oracle JDK thay cho OpenJDK, ho\u1eb7c th\u00eam v\u00e0o "-Djava.awt.headless=false" v\u00e0o argument c\u1ee7a m\u00e1y \u1ea3o java, ho\u1eb7c xem n\u1ebfu Xserver c\u00f3 ho\u1ea1t \u0111\u1ed9ng hay kh\u00f4ng +crash.NoClassDefFound=H\u00e3y ki\u1ec3m tra ph\u1ea7n m\u1ec1m "HMCL" \u0111\u00e3 ho\u00e0n th\u00e0nh + +crash.error=Minecraft \u0111\u00e3 b\u1ecb crash. +crash.main_class_not_found=Class ch\u00ednh c\u1ee7a minecraft kh\u00f4ng t\u00ecm th\u1ea5y, c\u00f3 l\u1ebd phi\u00ean b\u1ea3n minecraft \u0111\u00e3 b\u1ecb l\u1ed7i. +crash.class_path_wrong=C\u00f3 l\u1ebd \u0111o\u1ea1n m\u00e3 ch\u1ea1y launcher \u0111\u00e3 b\u1ecb l\u1ed7i + +ui.label.newProfileWindow.new_profile_name=T\u00ean c\u1ea5u h\u00ecnh m\u1edbi: +ui.label.newProfileWindow.copy_from=Copy t\u1eeb: +ui.newProfileWindow.title=C\u1ea5u h\u00ecnh m\u1edbi + +ui.button.ok=OK +ui.button.refresh=T\u1ea3i l\u1ea1i +ui.button.run=Play +ui.button.settings=C\u00e0i \u0111\u1eb7t +ui.button.about=About +ui.button.others=Kh\u00e1c +ui.button.logout=\u0110\u0103ng xu\u1ea5t +ui.button.download=T\u1ea3i v\u1ec1 +ui.button.retry=Th\u1eed l\u1ea1i +ui.button.delete=X\u00f3a +ui.button.install=C\u00e0i +ui.button.info=Th\u00f4ng tin +ui.button.save=L\u01b0u +ui.button.copy=Copy +ui.button.clear=X\u00f3a +ui.button.close=\u0110\u00f3ng +ui.button.explore=Explore +ui.button.test=Test +ui.button.preview=Xem tr\u01b0\u1edbc +button.cancel=Tho\u00e1t +button.ok=OK + +ui.label.version=Phi\u00ean b\u1ea3n +ui.label.password=M\u1eadt kh\u1ea9u +ui.label.profile=C\u1ea5u h\u00ecnh + +ui.message.first_load=H\u00e3y nh\u1eadp username c\u1ee7a b\u1ea1n v\u00e0o. +ui.message.enter_password=H\u00e3y nh\u1eadp m\u1eadt kh\u1ea9u c\u1ee7a b\u1ea1n +ui.message.launching=Launching... +ui.message.making=Generating... +ui.message.sure_remove=B\u1ea1n c\u00f3 ch\u1eafc ch\u1eafn x\u00f3a c\u1ea5u h\u00ecnh %s kh\u00f4ng? +ui.message.update_java=H\u00e3y c\u1eadp nh\u1eadt phi\u00ean b\u1ea3n java c\u1ee7a b\u1ea1n. + +ui.label.settings=C\u00e0i \u0111\u1eb7t +ui.label.crashing=HMCL Minecraft Launcher \u0111\u00e3 b\u1ecb crash! +ui.label.crashing_out_dated=HL Minecraft Launcher \u0111\u00e3 b\u1ecb crash! V\u00e0 launcher c\u1ee7a b\u1ea1n kh\u00f4ng ph\u1ea3i l\u00e0 phi\u00ean b\u1ea3n m\u1edbi nh\u1ea5t. c\u1eadp nh\u1eadt n\u00f3 \u0111i! +ui.label.failed_set=Failed to set: + +download=Download +download.mojang=Mojang +download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/) +download.rapid_data=RapidData (https://www.rapiddata.org/) +download.not_200=Download kh\u00f4ng th\u00e0nh c\u00f4ng, the response code +download.failed=Download kh\u00f4ng th\u00e0nh c\u00f4ng. +download.successfully=Download th\u00e0nh c\u00f4ng. +download.source=Download Source + +message.error=L\u1ed7i +message.cannot_open_explorer=Cannot open explorer: +message.cancelled=\u0110\u00e3 tho\u1ea3t +message.info=Th\u00f4ng tin +message.loading=Loading... + +folder.game=Th\u01b0 m\u1ee5c minecraft +folder.mod=Mod +folder.coremod=Core Mod +folder.config=C\u1ea5u h\u00ecnh +folder.resourcepacks=Resourcepacks +folder.screenshots=\u1ea2nh ch\u1ee5p m\u00e0n h\u00ecnh +folder.saves=Th\u1ebf gi\u1edbi + +settings.tabs.game_download=Games +settings.tabs.installers=Tr\u00ecnh c\u00e0i \u0111\u1eb7t +settings.tabs.assets_downloads=Assets + +settings=Settings +settings.explore=Explore +settings.manage=Manage +settings.cannot_remove_default_config=Kh\u00f4ng th\u1ec3 x\u00f3a c\u1ea5u h\u00ecnh m\u1eb7c \u0111\u1ecbnh +settings.max_memory=RAM cao nh\u1ea5t(MB) +settings.java_dir=Th\u01b0 m\u1ee5c Java +settings.game_directory=Th\u01b0 m\u1ee5c minecraft +settings.dimension=Khu v\u1ef1c c\u1eeda s\u1ed5 c\u1ee7a game +settings.fullscreen=To\u00e0n m\u00e0n h\u00ecnh +settings.update_version=Update version json. +settings.run_directory=Run Directory(Version Isolation) +settings.physical_memory=Dung l\u01b0\u1ee3gg RAM v\u1eadt l\u00fd +settings.choose_javapath=Ch\u1ecdn th\u01b0 m\u1ee5c java +settings.default=M\u1eb7c \u0111\u1ecbnh +settings.custom=T\u00f9y ch\u1ec9nh +settings.choose_gamedir=Ch\u1ecdn th\u01b0 m\u1ee5c game +settings.failed_load=\u0110\u1ecdc file c\u1ea5u h\u00ecnh th\u1ea5t b\u1ea1i. X\u00f3a n\u00f3 kh\u00f4ng? +settings.test_game=Ch\u1ea1y th\u1eed game + +modpack=Mod pack +modpack.choose=Ch\u1ecdn modpack zip file m\u00e0 b\u1ea1n mu\u1ed1n nh\u1eadp v\u00e0o. N\u1ebfu b\u1ea1n mu\u1ed1n c\u1eadp nh\u1eadt phi\u00ean b\u1ea3n c\u1ee7a modpack, H\u00e3y nh\u1eadp v\u00e0o phi\u00ean b\u1ea3n b\u1ea1n mu\u1ed1n c\u1eadp nh\u1eadt. +modpack.export_error=Xu\u1ea5t modpack ra th\u1ea5t b\u1ea1i, c\u00f3 th\u1ec3 \u0111\u1ecbnh d\u1ea1ng c\u1ee7a th\u01b0 m\u1ee5c ch\u1ee9a d\u1eef li\u1ec7u b\u1ecb sai ho\u1eb7c kh\u00f4ng th\u1ec3 qu\u1ea3n l\u00fd file. +modpack.export_finished=Xu\u1ea5t modpack ra th\u00e0nh c\u00f4ng. Xem +modpack.included_launcher=Modpack \u0111\u00e3 \u0111\u01b0\u1ee3c t\u00edch h\u1ee3p trong launcher, B\u1ea1n c\u00f3 th\u1ec3 publish n\u00f3. +modpack.not_included_launcher=D\u00f9ng n\u00fat "C\u00e0i Modpack" \u0111\u1ec3 c\u00e0i modpack. +modpack.enter_name=H\u00e3y cho m\u1ed9t c\u00e1i t\u00ean m\u00e0 b\u1ea1n th\u00edch. + +modpack.task.save=Xu\u1ea5t Modpack +modpack.task.install=C\u00e0i Modpack +modpack.task.install.error=C\u00e0i modpack kh\u00f4ng th\u00e0nh c\u00f4ng, c\u00f3 l\u1ebd file modpack kh\u00f4ng \u0111\u00fang ho\u1eb7c l\u00e0 kh\u00f4ng th\u1ec3 qu\u1ea3n l\u00fd file +modpack.task.install.will=Launcher s\u1ebd c\u00e0i modpack: + +modpack.wizard=C\u00f4ng c\u1ee5 xu\u1ea5t modpack +modpack.wizard.step.1=T\u00f9y ch\u1ecdn c\u01a1 b\u1ea3n +modpack.wizard.step.1.title=Ch\u1ecdn c\u00e1c t\u00f9y ch\u1ecdn c\u01a1 b\u1ea3n cho modpack. +modpack.wizard.step.initialization.include_launcher=Include the launcher +modpack.wizard.step.initialization.exported_version=Phi\u00ean b\u1ea3n \u0111\u00e3 \u0111\u01b0\u1ee3c xu\u1ea5t +modpack.wizard.step.initialization.save=Ch\u1ecdn m\u1ed9t th\u01b0 m\u1ee5c m\u00e0 b\u1ea1n mu\u1ed1n xu\u1ea5t game data +modpack.wizard.step.initialization.warning=Tr\u01b0\u1edbc khi t\u1ea1o modpack, b\u1ea1n ph\u1ea3i ch\u1eafc ch\u1eafn r\u1eb1ng minecraft c\u00f3 th\u1ec3 ch\u1ea1y,
        v\u00e0 phi\u00ean b\u1ea3n minecraft l\u00e0 ch\u00ednh th\u1ee9c, kh\u00f4ng ph\u1ea3i l\u00e0 snapshot.
        v\u00e0 n\u00f3 kh\u00f4ng cho th\u00eam mods m\u00e0 kh\u00f4ng c\u00f3 quy\u1ec1n \u0111\u1ec3 t\u1ea1o modpack. +modpack.wizard.step.2=Ch\u1ecdn file +modpack.wizard.step.2.title=Ch\u1ecdn file b\u1ea1n kh\u00f4ng mu\u1ed1n th\u00eam v\u00e0o modpack +modpack.wizard.step.3=Mi\u00eau t\u1ea3 +modpack.wizard.step.3.title=Mi\u00eau t\u1ea3 modpack c\u1ee7a b\u1ea1n. + +modpack.desc=Mi\u00eau t\u1ea3 modpack c\u1ee7a b\u1ea1n, bao g\u1ed3m \u0111\u1ec1 ph\u00f2ng, s\u1ef1 thay \u0111\u1ed5i, d\u1ea5u g\u1ea1ch xu\u1ed1ng(v\u00e0 m\u1ed9t s\u1ed1 h\u00ecnh \u1ea3nh). +modpack.incorrect_format.no_json=\u0110\u1ecbnh d\u1ea1ng c\u1ee7a modpack kh\u00f4ng \u0111\u00fang, file pack.json b\u1ecb thi\u1ebfu +modpack.incorrect_format.no_jar=\u0110\u1ecbnh d\u1ea1ng c\u1ee7a modpack kh\u00f4ng \u0111\u00fang, file pack.json kh\u00f4ng c\u00f3 \u0111\u1eb7c t\u00ednh jar +modpack.cannot_read_version=L\u1ea5y phi\u00ean b\u1ea3n c\u1ee7a minecraft th\u1ea5t b\u1ea1i +modpack.not_a_valid_location=N\u01a1i ch\u1ee9a modpack kh\u00f4ng \u0111\u00fang +modpack.name=T\u00ean c\u1ee7a modpack +modpack.not_a_valid_name=T\u00ean c\u1ee7a modpack kh\u00f4ng \u0111\u00fang + +modpack.files.servers_dat=Danh s\u00e1ch server +modpack.files.saves=Th\u01b0 m\u1ee5c ch\u1ee9a d\u1eef li\u1ec7u th\u1ebf gi\u1edbi +modpack.files.mods=Mods +modpack.files.config=C\u1ea5u h\u00ecnh c\u1ee7a mod +modpack.files.liteconfig=C\u1ea5u h\u00ecnh c\u1ee7a LiteLoader +modpack.files.resourcepacks=Resource(Texutre) packs +modpack.files.options_txt=T\u00f9y ch\u1ecdn c\u1ee7a game +modpack.files.optionsshaders_txt=T\u00f9y ch\u1ecdn c\u1ee7a shaders +modpack.files.mods.voxelmods=T\u00f9y ch\u1ecdn c\u1ee7a VoxelMod(t\u00ednh c\u1ea3 VoxelMap) +modpack.files.dumps=NEI debug output +modpack.files.scripts=C\u1ea5u h\u00ecnh c\u1ee7a MineTweaker +modpack.files.blueprints=B\u1ea3n thi\u1ebft k\u1ebf cho BuildCraft + +mods=Mods +mods.choose_mod=Ch\u1ecdn mods +mods.failed=T\u1ea3i mods th\u1ea5t b\u1ea1i +mods.add=Th\u00eam +mods.remove=X\u00f3a +mods.default_information=B\u1ea1n h\u00e3y ch\u1eafc ch\u1eafn r\u1eb1ng b\u1ea1n \u0111\u00e3 c\u00e0i Forge ho\u1eb7c LiteLoader tr\u01b0\u1edbc khi c\u00e0i mods!
        B\u1ea1n c\u00f3 th\u1ec3 k\u00e9o file mods v\u00e0o trong c\u1eeda s\u1ed5 n\u00e0y \u0111\u1ec3 th\u00eam, v\u00e0 x\u00f3a mods b\u1eb1ng c\u00e1ch \u1ea5n n\u00fat x\u00f3a.
        T\u1eaft mods b\u1eb1ng c\u00e1ch b\u1ecf d\u1ea5u v \u1edf ch\u1ed7 h\u1ed9p ki\u1ec3m; Ch\u1ecdn m\u1ed9t m\u1ee5c \u0111\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin.
        + +advancedsettings=N\u00e2ng cao +advancedsettings.launcher_visible=S\u1ef1 hi\u1ec3n th\u1ecb c\u1ee7a launcher +advancedsettings.debug_mode=Ch\u1ebf \u0111\u1ed9 g\u1ee1 l\u1ed7i +advancedsettings.java_permanent_generation_space=Dung l\u01b0\u1ee3ng PermGen/MB +advancedsettings.jvm_args=Arguments c\u1ee7a m\u00e1y \u1ea3o java +advancedsettings.Minecraft_arguments=Arguments c\u1ee7a minecraft +advancedsettings.launcher_visibility.close=\u0110\u00f3ng launcher sau khi minecraft \u0111\u01b0\u1ee3c m\u1edf. +advancedsettings.launcher_visibility.hide=\u1ea8n launcher sau khi minecraft \u0111\u01b0\u1ee3c m\u1edf. +advancedsettings.launcher_visibility.keep=\u0110\u1ec3 cho launcher hi\u1ec3n th\u1ecb. +advancedsettings.game_dir.default=M\u1eb7c \u0111\u1ecbnh (.minecraft/) +advancedsettings.game_dir.independent=Independent (.minecraft/versions//, tr\u1eeb th\u01b0 m\u1ee5c assets,libraries) +advancedsettings.no_jvm_args=Kh\u00f4ng c\u00f3 arguments m\u1eb7c \u0111\u1ecbnh cho m\u00e1y \u1ea3o java +advancedsettings.java_args_default=Java arguments m\u1eb7c \u0111\u1ecbnh: -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -XX:MaxPermSize=???m -Xmx???m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true +advancedsettings.wrapper_launcher=Wrapper Launcher(d\u1ea1ng nh\u01b0 optirun...) +advancedsettings.precall_command=C\u00e2u l\u1ec7nh \u0111\u01b0\u1ee3c ch\u1ea1y tr\u01b0\u1edbc khi game m\u1edf +advancedsettings.server_ip=M\u00e1y ch\u1ee7 +advancedsettings.cancel_wrapper_launcher=H\u1ee7y b\u1ecf Wrapper Launcher +advancedsettings.dont_check_game_completeness=Kh\u00f4ng ki\u1ec3m tra game c\u00f3 \u0111\u1ea7y \u0111\u1ee7 kh\u00f4ng. + +mainwindow.show_log=Xem logs +mainwindow.make_launch_script=T\u1ea1o \u0111o\u1ea1n m\u00e3 launching +mainwindow.make_launch_script_failed=T\u1ea1o \u0111o\u1ea1n m\u00e3 th\u1ea5t b\u1ea1i +mainwindow.enter_script_name=Nh\u1eadp t\u00ean c\u1ee7a \u0111o\u1ea1n m\u00e3. +mainwindow.make_launch_succeed=\u0110\u00e3 t\u1ea1o \u0111o\u1ea1n m\u00e3. +mainwindow.no_version=Kh\u00f4ng c\u00f3 phi\u00ean b\u1ea3n minecraft n\u00e0o \u0111\u01b0\u1ee3c t\u00ecm th\u1ea5y. Chuy\u1ec3n sang tab Game Download? + +launcher.about=V\u1ec1 t\u00e1c gi\u1ea3
        Minecraft Forum ID: klkl6523
        Copyright (c) 2013 huangyuhui
        http://github.com/huanghongxun/HMCL/
        Ph\u1ea7n m\u1ec1m n\u00e0y d\u00f9ng project Gson, c\u1ea3m \u01a1n ng\u01b0\u1eddi \u0111\u00f3ng g\u00f3p. +launcher.download_source=Download Source +launcher.background_location=Background Location +launcher.exit_failed=T\u1eaft launcher th\u1ea5t b\u1ea1i. +launcher.versions_json_not_matched=The version %s is malformed! There are a json:%s in this version. Do you want to fix this problem? +launcher.versions_json_not_matched_cannot_auto_completion=The version %s lost version information file, delete it? +launcher.versions_json_not_formatted=The version information of %s is malformed! Redownload it? +launcher.choose_bgpath=Choose background path. +launcher.background_tooltip=This app uses the default background at first.
        If there is background.png in the directory, it will be used.
        If there is "bg" subdirectory, this app will chooses one picture in "bgskin" randomly.
        If you set the background setting, this app will use it. +launcher.update_launcher=Check for update +launcher.enable_shadow=Enable Window Shadow +launcher.enable_animation=Enable Animation +launcher.enable_blur=Enable Blur +launcher.theme=Theme +launcher.proxy=Proxy +launcher.decorated=Enable system window border(in order to fix the problem that the ui become all gray in Linux OS) +launcher.modpack=Documentations for modpacks. +launcher.lang=Language +launcher.restart=Options will be in operations only if restart this app. + +launcher.title.game=Phi\u00ean b\u1ea3n & Mods +launcher.title.main=HMCL Main +launcher.title.launcher=Launcher + +versions.release=Ch\u00ednh th\u1ee9c +versions.snapshot=Snapshot +versions.old_beta=Beta +versions.old_alpha=Old Alpha + +versions.manage.rename=\u0110\u1ed5i t\u00ean phi\u00ean b\u1ea3n n\u00e0y +versions.manage.rename.message=Nh\u1eadp t\u00ean m\u1edbi +versions.manage.remove=X\u00f3a phi\u00ean b\u1ea3n n\u00e0y +versions.manage.remove.confirm=B\u1ea1n c\u00f3 ch\u1eafc \u0111\u1ec3 x\u00f3a phi\u00ean b\u1ea3n n\u00e0y kh\u00f4ng? +versions.manage.redownload_json=Download l\u1ea1i c\u1ea5u h\u00ecnh c\u1ee7a minecraft(minecraft.json) +versions.manage.redownload_assets_index=Download l\u1ea1i Assets Index +versions.mamage.remove_libraries=X\u00f3a libraries file + +advice.os64butjdk32=H\u1ec7 \u0111i\u1ec1u h\u00e0nh c\u1ee7a b\u1ea1n l\u00e0 64-Bit nh\u01b0ng phi\u00ean b\u1ea3n Java c\u1ee7a b\u1ea1n l\u00e0 32-Bit. Khuy\u00ean b\u1ea1n n\u00ean d\u00f9ng Java 64-Bit. + +assets.download_all=Download file assets +assets.not_refreshed=Danh s\u00e1ch assets ch\u01b0a \u0111\u01b0\u1ee3c load l\u1ea1i, b\u1ea1n h\u00e3y \u1ea5n n\u00fat T\u1ea3i l\u1ea1i. +assets.failed=L\u1ea5y danh s\u00e1ch th\u1ea5t b\u1ea1i, h\u00e3y th\u1eed l\u1ea1i. +assets.list.1_7_3_after=1.7.3 v\u00e0 cao h\u01a1n +assets.list.1_6=1.6(BMCLAPI) +assets.unkown_type_select_one=Phi\u00ean b\u1ea3n minecraft ch\u01b0a \u0111\u01b0\u1ee3c bi\u1ebft: %s, h\u00e3y ch\u1ecdn m\u1ed9t lo\u1ea1i asset. +assets.type=Lo\u1ea1i asset +assets.download=Download Assets +assets.no_assets=Assets ch\u01b0a \u0111\u01b0\u1ee3c ho\u00e0n th\u00e0nh, ho\u00e0n th\u00e0nh n\u00f3 kh\u00f4ng? +assets.failed_download=Download asset th\u1ea5t b\u1ea1i, c\u00f3 th\u1ec3 s\u1ebd kh\u00f4ng c\u00f3 \u00e2m thanh v\u00e0 ng\u00f4n ng\u1eef. + +gamedownload.not_refreshed=Danh s\u00e1ch phi\u00ean b\u1ea3n ch\u01b0a \u0111\u01b0\u1ee3c load l\u1ea1i, b\u1ea1n h\u00e3y \u1ea5n n\u00fat T\u1ea3i l\u1ea1i. + +taskwindow.title=Tasks +taskwindow.single_progress=Single progress +taskwindow.total_progress=Total progress +taskwindow.cancel=Cancel +taskwindow.no_more_instance=Maybe you opened more than one task window, dont open it again! +taskwindow.file_name=Task +taskwindow.download_progress=Pgs. + +setupwindow.include_minecraft=Import game +setupwindow.find_in_configurations=Finished importing. You can find it in the configuration selection bar. +setupwindow.give_a_name=Give a name to the new game. +setupwindow.new=New +setupwindow.no_empty_name=Version name cannot be empty. +setupwindow.clean=Clean game files + +update.no_browser=Kh\u00f4ng th\u1ec3 m\u1edf tr\u00ecnh duy\u1ec7t. \u0110\u01b0\u1eddng link \u0111\u00e3 \u0111\u01b0\u1ee3c copy v\u00e0o clipboard. B\u1ea1n c\u00f3 th\u1ec3 paste n\u00f3 v\u00e0o thanh \u0111\u01b0\u1eddng link. +update.should_open_link=B\u1ea1n c\u00f3 mu\u1ed1n c\u1eadp nh\u1eadt launcher kh\u00f4ng? +update.newest_version=Phi\u00ean b\u1ea3n m\u1edbi nh\u1ea5t: +update.failed=Ki\u1ec3m tra c\u1eadp nh\u1eadt th\u1ea5t b\u1ea1i. +update.found=(\u0110\u00e3 t\u00ecm th\u1ea5y b\u1ea3n c\u1eadp nh\u1eadt!) + +logwindow.terminate_game=T\u1eaft Game +logwindow.tieba=Baidu Tieba +logwindow.title=HMCL Error Log (H\u00e3y \u0111\u0103ng c\u00e1i n\u00e0y l\u00ean forum!) + +selector.choose=Ch\u1ecdn + +serverlistview.title=Ch\u1ecdn m\u00e1y ch\u1ee7 +serverlistview.name=T\u00ean +serverlistview.type=L\u1ecdai +serverlistview.version=Phi\u00ean b\u1ea3n +serverlistview.info=Th\u00f4ng tin + +minecraft.invalid=Kh\u00f4ng h\u1ee3p l\u1ec7 +minecraft.invalid_jar=File jar kh\u00f4ng h\u1ee3p l\u1ec7 +minecraft.not_a_file=Not a file +minecraft.not_found=Kh\u00f4ng t\u00ecm th\u1ea5y +minecraft.not_readable=Kh\u00f4ng \u0111\u1ecdc \u0111\u01b0\u1ee3c +minecraft.modified=(\u0110\u00e3 s\u1eeda \u0111\u1ed5i!) + +color.red=\u0110\u1ecf +color.blue=Xanh da tr\u1eddi +color.green=Xanh l\u1ee5c +color.orange=Cam +color.dark_blue=Xanh da tr\u1eddi t\u1ed1i +color.purple=T\u00edm + +wizard.next_>=Next > +wizard.next_mnemonic=N +wizard.<_prev=< Prev +wizard.prev_mnemonic=P +wizard.finish=Finish +wizard.finish_mnemonic=F +wizard.cancel=Cancel +wizard.cancel_mnemonic=C +wizard.help=Help +wizard.help_mnemonic=H +wizard.close=Close +wizard.close_mnemonic=C +wizard.summary=Summary +wizard.failed=Failed +wizard.steps=Steps + +lang=Vietnamese +lang.default=Thu\u1ed9c v\u1ec1 ng\u00f4n ng\u1eef c\u1ee7a h\u1ec7 \u0111i\u1ec1u h\u00e0nh diff --git a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_TW.lang b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh.lang similarity index 96% rename from HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_TW.lang rename to HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh.lang index feaaa638c..811170b33 100755 --- a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_TW.lang +++ b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh.lang @@ -13,6 +13,8 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see {http://www.gnu.org/licenses/}. +# +#author: huangyuhui launch.failed=啟動失敗 launch.failed_creating_process=啟動失敗,在創建新進程時發生錯誤,可能是Java路徑錯誤。 launch.failed_sh_permission=為啟動資料添加權限時發生錯誤 @@ -187,6 +189,7 @@ message.error=錯誤 message.cannot_open_explorer=無法打開資料管理器: message.cancelled=已取消 message.info=提示 +message.loading=加載中... folder.game=遊戲資料夾 folder.mod=MOD資料夾 @@ -230,7 +233,7 @@ modpack.enter_name=給遊戲起個你喜歡的名字 modpack.task.save=導出懶人包 modpack.task.install=導入懶人包 modpack.task.install.error=安裝失敗,可能是懶人包格式不正確或操作資料失敗 -modpack.task.install.will_install=將會安裝懶人包: +modpack.task.install.will=將會安裝懶人包: modpack.wizard=導出懶人包嚮導 modpack.wizard.step.1=基本設定 @@ -298,7 +301,7 @@ mainwindow.enter_script_name=輸入要生成腳本的資料名 mainwindow.make_launch_succeed=啟動腳本已生成完畢: mainwindow.no_version=未找到任何版本,是否進入遊戲下載? -launcher.about=默認背景圖感謝gamerteam提供。
        如果您希望本軟件繼續發展,請贊助
        關於作者:
        百度ID:huanghongxun20
        mcbbs:huanghongxun
        郵箱:huanghongxun2008@126.com
        Minecraft Forum ID: klkl6523
        歡迎提交Bug哦
        Copyright (c) 2013-2016 huangyuhui.
        免責聲明:Minecraft軟體版權歸Mojang AB所有,遊戲由於誤操作本啟動器而丟失數據的概不負責。
        本啟動器在GPLv3協議下開源:http://github.com/huanghongxun/HMCL/ ,感谢issues和pull requests贡献者
        本軟體使用了基於Apache License 2.0的Gson項目,感謝貢獻者。 +launcher.about=默認背景圖感謝gamerteam提供。
        關於作者:
        百度ID:huanghongxun20
        mcbbs:huanghongxun
        Minecraft Forum ID: klkl6523
        歡迎提交Bug哦
        Copyright (c) 2013-2016 huangyuhui.
        免責聲明:Minecraft軟體版權歸Mojang AB所有,遊戲由於誤操作本啟動器而丟失數據的概不負責。
        本啟動器在GPLv3協議下開源:http://github.com/huanghongxun/HMCL/ ,感谢issues和pull requests贡献者
        本軟體使用了基於Apache License 2.0的Gson項目,感謝貢獻者。 launcher.download_source=下載源 launcher.background_location=背景地址 launcher.exit_failed=強制退出失敗,可能是Forge 1.7.10及更高版本導致的,無法解決。 @@ -308,12 +311,13 @@ launcher.versions_json_not_formatted=版本%s信息資料格式错误,是否 launcher.choose_bgpath=選擇背景路徑 launcher.background_tooltip=啟動器默認使用自帶的背景
        如果當前目錄有background.png,則會使用該資料作為背景
        如果當前目錄有bg子目錄,則會隨機使用裡面的一張圖作為背景
        如果該背景地址被修改,則會使用背景地址裡的一張圖作為背景
        背景地址允許有多個地址,使用半角分號";"(不包含雙引號)分隔 launcher.update_launcher=检查更新 -launcher.enable_shadow=启用窗口阴影 +launcher.enable_shadow=啟用窗口陰影 +launcher.enable_animation=啟用動態效果 +launcher.enable_blur=啟用主界面模糊 launcher.theme=主题 launcher.proxy=代理 launcher.decorated=啟用窗口邊框(Linux下可解決程序界面全灰問題) launcher.modpack=整合包作者帮助 -launcher.enable_animation=啟用動態效果 launcher.lang=語言 launcher.restart=本界面選項需要重啟本啟動器生效 @@ -413,4 +417,4 @@ wizard.failed=失败 wizard.steps=步驟 lang=正體中文 -lang.default=跟隨系統語言 \ No newline at end of file +lang.default=跟隨系統語言 diff --git a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_TW.properties b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh.properties similarity index 96% rename from HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_TW.properties rename to HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh.properties index 1d6f19cd8..3430e3e8b 100755 --- a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_TW.properties +++ b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh.properties @@ -13,6 +13,8 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see {http://www.gnu.org/licenses/}. +# +#author: huangyuhui launch.failed=\u555f\u52d5\u5931\u6557 launch.failed_creating_process=\u555f\u52d5\u5931\u6557\uff0c\u5728\u5275\u5efa\u65b0\u9032\u7a0b\u6642\u767c\u751f\u932f\u8aa4\uff0c\u53ef\u80fd\u662fJava\u8def\u5f91\u932f\u8aa4\u3002 launch.failed_sh_permission=\u70ba\u555f\u52d5\u8cc7\u6599\u6dfb\u52a0\u6b0a\u9650\u6642\u767c\u751f\u932f\u8aa4 @@ -187,6 +189,7 @@ message.error=\u932f\u8aa4 message.cannot_open_explorer=\u7121\u6cd5\u6253\u958b\u8cc7\u6599\u7ba1\u7406\u5668: message.cancelled=\u5df2\u53d6\u6d88 message.info=\u63d0\u793a +message.loading=\u52a0\u8f09\u4e2d... folder.game=\u904a\u6232\u8cc7\u6599\u593e folder.mod=MOD\u8cc7\u6599\u593e @@ -230,7 +233,7 @@ modpack.enter_name=\u7d66\u904a\u6232\u8d77\u500b\u4f60\u559c\u6b61\u7684\u540d\ modpack.task.save=\u5c0e\u51fa\u61f6\u4eba\u5305 modpack.task.install=\u5c0e\u5165\u61f6\u4eba\u5305 modpack.task.install.error=\u5b89\u88dd\u5931\u6557\uff0c\u53ef\u80fd\u662f\u61f6\u4eba\u5305\u683c\u5f0f\u4e0d\u6b63\u78ba\u6216\u64cd\u4f5c\u8cc7\u6599\u5931\u6557 -modpack.task.install.will_install=\u5c07\u6703\u5b89\u88dd\u61f6\u4eba\u5305\uff1a +modpack.task.install.will=\u5c07\u6703\u5b89\u88dd\u61f6\u4eba\u5305\uff1a modpack.wizard=\u5c0e\u51fa\u61f6\u4eba\u5305\u56ae\u5c0e modpack.wizard.step.1=\u57fa\u672c\u8a2d\u5b9a @@ -298,7 +301,7 @@ mainwindow.enter_script_name=\u8f38\u5165\u8981\u751f\u6210\u8173\u672c\u7684\u8 mainwindow.make_launch_succeed=\u555f\u52d5\u8173\u672c\u5df2\u751f\u6210\u5b8c\u7562: mainwindow.no_version=\u672a\u627e\u5230\u4efb\u4f55\u7248\u672c\uff0c\u662f\u5426\u9032\u5165\u904a\u6232\u4e0b\u8f09\uff1f -launcher.about=\u9ed8\u8a8d\u80cc\u666f\u5716\u611f\u8b1dgamerteam\u63d0\u4f9b\u3002
        \u5982\u679c\u60a8\u5e0c\u671b\u672c\u8edf\u4ef6\u7e7c\u7e8c\u767c\u5c55\uff0c\u8acb\u8d0a\u52a9
        \u95dc\u65bc\u4f5c\u8005\uff1a
        \u767e\u5ea6ID\uff1ahuanghongxun20
        mcbbs\uff1ahuanghongxun
        \u90f5\u7bb1\uff1ahuanghongxun2008@126.com
        Minecraft Forum ID: klkl6523
        \u6b61\u8fce\u63d0\u4ea4Bug\u54e6
        Copyright (c) 2013-2016 huangyuhui.
        \u514d\u8cac\u8072\u660e\uff1aMinecraft\u8edf\u9ad4\u7248\u6b0a\u6b78Mojang AB\u6240\u6709\uff0c\u904a\u6232\u7531\u65bc\u8aa4\u64cd\u4f5c\u672c\u555f\u52d5\u5668\u800c\u4e1f\u5931\u6578\u64da\u7684\u6982\u4e0d\u8ca0\u8cac\u3002
        \u672c\u555f\u52d5\u5668\u5728GPLv3\u5354\u8b70\u4e0b\u958b\u6e90:http://github.com/huanghongxun/HMCL/ ,\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005
        \u672c\u8edf\u9ad4\u4f7f\u7528\u4e86\u57fa\u65bcApache License 2.0\u7684Gson\u9805\u76ee\uff0c\u611f\u8b1d\u8ca2\u737b\u8005\u3002 +launcher.about=\u9ed8\u8a8d\u80cc\u666f\u5716\u611f\u8b1dgamerteam\u63d0\u4f9b\u3002
        \u95dc\u65bc\u4f5c\u8005\uff1a
        \u767e\u5ea6ID\uff1ahuanghongxun20
        mcbbs\uff1ahuanghongxun
        Minecraft Forum ID: klkl6523
        \u6b61\u8fce\u63d0\u4ea4Bug\u54e6
        Copyright (c) 2013-2016 huangyuhui.
        \u514d\u8cac\u8072\u660e\uff1aMinecraft\u8edf\u9ad4\u7248\u6b0a\u6b78Mojang AB\u6240\u6709\uff0c\u904a\u6232\u7531\u65bc\u8aa4\u64cd\u4f5c\u672c\u555f\u52d5\u5668\u800c\u4e1f\u5931\u6578\u64da\u7684\u6982\u4e0d\u8ca0\u8cac\u3002
        \u672c\u555f\u52d5\u5668\u5728GPLv3\u5354\u8b70\u4e0b\u958b\u6e90:http://github.com/huanghongxun/HMCL/ ,\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005
        \u672c\u8edf\u9ad4\u4f7f\u7528\u4e86\u57fa\u65bcApache License 2.0\u7684Gson\u9805\u76ee\uff0c\u611f\u8b1d\u8ca2\u737b\u8005\u3002 launcher.download_source=\u4e0b\u8f09\u6e90 launcher.background_location=\u80cc\u666f\u5730\u5740 launcher.exit_failed=\u5f37\u5236\u9000\u51fa\u5931\u6557\uff0c\u53ef\u80fd\u662fForge 1.7.10\u53ca\u66f4\u9ad8\u7248\u672c\u5c0e\u81f4\u7684\uff0c\u7121\u6cd5\u89e3\u6c7a\u3002 @@ -308,12 +311,13 @@ launcher.versions_json_not_formatted=\u7248\u672c%s\u4fe1\u606f\u8cc7\u6599\u683 launcher.choose_bgpath=\u9078\u64c7\u80cc\u666f\u8def\u5f91 launcher.background_tooltip=\u555f\u52d5\u5668\u9ed8\u8a8d\u4f7f\u7528\u81ea\u5e36\u7684\u80cc\u666f
        \u5982\u679c\u7576\u524d\u76ee\u9304\u6709background.png\uff0c\u5247\u6703\u4f7f\u7528\u8a72\u8cc7\u6599\u4f5c\u70ba\u80cc\u666f
        \u5982\u679c\u7576\u524d\u76ee\u9304\u6709bg\u5b50\u76ee\u9304\uff0c\u5247\u6703\u96a8\u6a5f\u4f7f\u7528\u88e1\u9762\u7684\u4e00\u5f35\u5716\u4f5c\u70ba\u80cc\u666f
        \u5982\u679c\u8a72\u80cc\u666f\u5730\u5740\u88ab\u4fee\u6539\uff0c\u5247\u6703\u4f7f\u7528\u80cc\u666f\u5730\u5740\u88e1\u7684\u4e00\u5f35\u5716\u4f5c\u70ba\u80cc\u666f
        \u80cc\u666f\u5730\u5740\u5141\u8a31\u6709\u591a\u500b\u5730\u5740\uff0c\u4f7f\u7528\u534a\u89d2\u5206\u865f";"(\u4e0d\u5305\u542b\u96d9\u5f15\u865f)\u5206\u9694 launcher.update_launcher=\u68c0\u67e5\u66f4\u65b0 -launcher.enable_shadow=\u542f\u7528\u7a97\u53e3\u9634\u5f71 +launcher.enable_shadow=\u555f\u7528\u7a97\u53e3\u9670\u5f71 +launcher.enable_animation=\u555f\u7528\u52d5\u614b\u6548\u679c +launcher.enable_blur=\u555f\u7528\u4e3b\u754c\u9762\u6a21\u7cca launcher.theme=\u4e3b\u9898 launcher.proxy=\u4ee3\u7406 launcher.decorated=\u555f\u7528\u7a97\u53e3\u908a\u6846(Linux\u4e0b\u53ef\u89e3\u6c7a\u7a0b\u5e8f\u754c\u9762\u5168\u7070\u554f\u984c) launcher.modpack=\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9 -launcher.enable_animation=\u555f\u7528\u52d5\u614b\u6548\u679c launcher.lang=\u8a9e\u8a00 launcher.restart=\u672c\u754c\u9762\u9078\u9805\u9700\u8981\u91cd\u555f\u672c\u555f\u52d5\u5668\u751f\u6548 @@ -413,4 +417,4 @@ wizard.failed=\u5931\u8d25 wizard.steps=\u6b65\u9a5f lang=\u6b63\u9ad4\u4e2d\u6587 -lang.default=\u8ddf\u96a8\u7cfb\u7d71\u8a9e\u8a00 \ No newline at end of file +lang.default=\u8ddf\u96a8\u7cfb\u7d71\u8a9e\u8a00 diff --git a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_CN.lang b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_CN.lang new file mode 100755 index 000000000..b0ca61fc1 --- /dev/null +++ b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_CN.lang @@ -0,0 +1,420 @@ +# 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/}. +# +#author: huangyuhui +launch.failed=启动失败 +launch.failed_creating_process=启动失败,在创建新进程时发生错误,可能是Java路径错误。 +launch.failed_sh_permission=为启动文件添加权限时发生错误 +launch.failed_packing_jar=在打包jar时发生错误 +launch.unsupported_launcher_version=对不起,本启动器现在可能不能启动这个版本的Minecraft,但启动器还是会尝试启动,请尽快将此问题报告给作者。 +launch.too_big_memory_alloc_64bit=您设置的内存大小过大,由于可能超过了32位Java的内存分配限制,所以可能无法启动游戏,请将内存调至1024MB或更小,启动器仍会尝试启动。 +launch.too_big_memory_alloc_free_space_too_low=您设置的内存大小过大,由于超过了系统内存大小%dMB,所以可能影响游戏体验或无法启动游戏,启动器仍会尝试启动。 +launch.cannot_create_jvm=截获到无法创建Java虚拟机,可能是Java参数有问题,可以在设置中开启无参数模式启动 +launch.circular_dependency_versions=发现游戏版本循环引用,请确认您的客户端未被修改或修改导致出现此问题。 +launch.not_finished_downloading_libraries=未完成游戏依赖库的下载,还要继续启动游戏吗? +launch.not_finished_decompressing_natives=未能解压游戏本地库,还要继续启动游戏吗? +launch.wrong_javadir=错误的Java路径,将自动重置为默认Java路径。 +launch.exited_abnormally=游戏非正常退出,请查看日志文件,或联系他人寻求帮助。 + +launch.state.logging_in=登录中 +launch.state.generating_launching_codes=正在生成启动代码 +launch.state.downloading_libraries=正在下载必要文件 +launch.state.decompressing_natives=正在释放本地文件 + +install.no_version=未找到要安装的对应MC版本 +install.no_version_if_intall=未找到要安装的对应MC版本,是否自动安装需要的MC版本? +install.not_refreshed=未刷新列表 +install.download_list=下载列表 + +install.liteloader.get_list=获取LiteLoader列表 +install.liteloader.install=安装LiteLoader + +install.forge.get_list=获取Forge列表 +install.forge.install=安装Forge +install.forge.get_changelogs=获取Forge更新记录 + +install.optifine.install=安装OptiFine +install.optifine.get_list=获取OptiFine列表 +install.optifine.get_download_link=获取OptiFine下载地址 + +install.failed_forge=安装Forge失败 +install.failed_optifine=安装OptiFine失败 +install.failed_liteloader=安装LiteLoader失败 +install.failed_download_forge=下载Forge失败 +install.failed_download_optifine=下载OptiFine失败 +install.failed=安装失败 +install.success=安装成功 +install.no_forge=没有安装Forge +install.choose_forge=选择你安装的Forge版本 +install.version=版本 +install.mcversion=游戏版本 +install.time=时间 +install.release_time=释放时间 +install.type=类型 +install.please_refresh=如需使用自动安装请点击右侧刷新按钮 + +crash.launcher=启动器崩溃了! +crash.minecraft=Minecraft崩溃了!请认真阅读建议。 + +login.choose_charactor=请选择您要使用的角色 +login.no_charactor=该帐号没有角色 +login.your_password=您的密码 +login.failed=登录失败: +login.no_Player007=你还未设置用户名! +login.wrong_password=可能是您的用户名或密码错误 +login.invalid_username=无效的用户名 +login.invalid_uuid_and_username=无效的UUID和用户名 +login.invalid_password=无效的密码 +login.invalid_access_token=无效的访问令牌 +login.changed_client_token=服务器回应已经修改客户端令牌 +login.not_email=用户名必须是邮箱 +login.type=登录 +login.username=名字 +login.account=邮箱 +login.invalid_token=请尝试登出并重新输入密码登录 +login.no_valid_character=无有效的角色,自行到skinme.cc登陆并创建角色 + +proxy.username=账户 +proxy.password=密码 +proxy.host=主机 +proxy.port=端口 + +login.failed.connect_authentication_server=无法连接认证服务器,可能是网络问题 + +login.profile.not_logged_in=无法修改游戏资料同时未登录 +login.profile.selected=无法修改游戏资料. 你必须登出再返回. + +login.methods.yggdrasil=正版登录 +login.methods.offline=离线模式 +login.methods.no_method=没有登入方式... + +log.playername_null=玩家名为空,这代表着登录方法出现问题 + +minecraft.no_selected_version=没有选择任何一个Minecraft版本 +minecraft.wrong_path=错误的Minecraft路径,启动器未找到设定的Minecraft路径,请检查。 + +operation.stopped=操作被强行终止 +operation.confirm_stop=真的要终止操作吗? + +ui.login.password=密码 +ui.more=更多 + +crash.advice.UnsupportedClassVersionError=这可能是因为您的Java版本过于老旧,可以尝试更换最新Java并在版本设置的Java路径中设置. +crash.advice.ConcurrentModificationException=这可能是因为您的Java版本高于Java 1.8.0_11导致的,可以尝试卸载Java8安装Java7。 +crash.advice.ClassNotFoundException=Minecraft不完整或Mod冲突,如果有未能下载的文件请下载成功后重试或是客户端损坏请重试请重新制作客户端或下载整合包解决问题,另可尝试游戏设置->(版本)管理->删除库文件解决问题 +crash.advice.NoSuchFieldError=Minecraft不完整或Mod冲突,如果有未能下载的文件请下载成功后重试或是客户端损坏请重试请重新制作客户端或下载整合包解决问题。 +crash.advice.LWJGLException=您的电脑不正常,可能需要使用驱动精灵或其他安装器更新显卡驱动。 +crash.advice.SecurityException=可能是您修改了minecraft.jar但未删除META-INF文件夹的原因。请通过压缩软件删除jar中的META-INF文件夹。 +crash.advice.OutOfMemoryError=内存溢出,您设置的Minecraft最大内存过小,请调大! +crash.advice.otherwise=可能是Mod或其他问题。 + +crash.advice.OpenGL=可能是显卡/声卡驱动问题,也可能是Mod导致的问题。 +crash.advice.no_lwjgl=可能是游戏依赖库不完整或解压依赖库时出错。可以通过下载整合包解决问题。 + +crash.advice.no=无建议。 + +crash.user_fault=您的系统或Java环境可能安装不当导致本软件崩溃,请检查您的Java环境或您的电脑!可以尝试重新安装Java。 +crash.headless=如果您的操作系统是Linux,请注意不要使用OpenJDK,务必使用Oracle JDK,或尝试添加-Djava.awt.headless=false参数,或检查您的Xserver是否正常 +crash.NoClassDefFound=请确认HMCL本体是否完整 + +crash.error=您的Minecraft崩溃了。 +crash.main_class_not_found=找不到主类,可能是您的JSON文件填写错误。无法启动游戏。可以通过下载整合包解决问题。 +crash.class_path_wrong=解析Class Path时出现错误,此错误本不应该发生。可能是启动脚本错误,请仔细检查启动脚本。 + +ui.label.newProfileWindow.new_profile_name=新配置名: +ui.label.newProfileWindow.copy_from=复制配置: +ui.newProfileWindow.title=新建配置 + +ui.button.ok=确认 +ui.button.refresh=刷新 +ui.button.run=启动Minecraft +ui.button.settings= +ui.button.about=关于 +ui.button.others=其他 +ui.button.logout=登出 +ui.button.download=下载 +ui.button.retry=重试 +ui.button.delete=删除 +ui.button.install=安装 +ui.button.info=信息 +ui.button.save=保存 +ui.button.copy=复制 +ui.button.clear=清除 +ui.button.close=关闭 +ui.button.explore=浏览 +ui.button.test=测试 +ui.button.preview=预览 +button.cancel=取消 +button.ok=确定 + +ui.label.version=版本 +ui.label.password=密码 +ui.label.profile=配置 + +ui.message.first_load=请在左边输入您的账号 +ui.message.enter_password=请在左边输入您的密码 +ui.message.launching=启动中 +ui.message.making=生成中 +ui.message.sure_remove=真的要删除配置%s吗? +ui.message.update_java=请更新您的Java + +ui.label.settings=选项 +ui.label.crashing=Hello Minecraft!遇到了无法处理的错误,请复制下列内容并通过mcbbs、贴吧、Github或Minecraft Forum反馈bug。 +ui.label.crashing_out_dated=Hello Minecraft! Launcher遇到了无法处理的错误,已检测到您的启动器不是最新版本,请更新后再试! +ui.label.failed_set=设置失败: + +download=下载 +download.mojang=官方 +download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/) +download.rapid_data=RapidData (锐网云计算, https://www.rapiddata.org/) +download.not_200=下载失败,回复码 +download.failed=下载失败 +download.successfully=下载完成 +download.source=下载源 + +message.error=错误 +message.cannot_open_explorer=无法打开文件管理器: +message.cancelled=已取消 +message.info=提示 +message.loading=加载中... + +folder.game=游戏文件夹 +folder.mod=MOD文件夹 +folder.coremod=核心MOD文件夹 +folder.config=配置文件夹 +folder.resourcepacks=资源包文件夹 +folder.screenshots=截图文件夹 +folder.saves=存档文件夹 + +settings.tabs.game_download=游戏下载 +settings.tabs.installers=自动安装 +settings.tabs.assets_downloads=资源下载 + +settings=普通设置 +settings.explore=浏览 +settings.manage=管理 +settings.cannot_remove_default_config=不能删除默认配置 +settings.max_memory=最大内存/MB +settings.java_dir=Java路径 +settings.game_directory=游戏路径 +settings.dimension=游戏窗口分辨率 +settings.fullscreen=全屏 +settings.update_version=更新版本文件 +settings.run_directory=运行路径(版本隔离) +settings.physical_memory=物理内存大小 +settings.choose_javapath=选择Java路径 +settings.default=默认 +settings.custom=自定义 +settings.choose_gamedir=选择游戏路径 +settings.failed_load=设置文件加载失败,可能是升级了启动器或被人工修改造成错误,是否清除? +settings.test_game=测试游戏 + +modpack=整合包 +modpack.choose=选择要导入的游戏整合包文件,如果您希望更新整合包,请输入要更新的版本名 +modpack.export_error=导出失败,可能是您的游戏文件夹格式不正确或操作文件失败 +modpack.export_finished=整合包导出完成,参见 +modpack.included_launcher=整合包已包含启动器,可直接发布 +modpack.not_included_launcher=整合包未包含启动器,可使用本软件的导入整合包功能导入整合包 +modpack.enter_name=给游戏起个你喜欢的名字 + +modpack.task.save=导出整合包 +modpack.task.install=导入整合包 +modpack.task.install.error=安装失败,可能是整合包格式不正确或操作文件失败 +modpack.task.install.will=将会安装整合包: + +modpack.wizard=导出整合包向导 +modpack.wizard.step.1=基本设置 +modpack.wizard.step.1.title=设置整合包的主要信息 +modpack.wizard.step.initialization.include_launcher=包含启动器 +modpack.wizard.step.initialization.exported_version=要导出的游戏版本 +modpack.wizard.step.initialization.save=选择要导出到的游戏整合包位置 +modpack.wizard.step.initialization.warning=在制作整合包前,请您确认您选择的版本可以正常启动,
        并保证您的Minecraft是正式版而非快照版,
        而且不应当将不允许非官方途径传播的Mod、材质包等纳入整合包。
        整合包会保存您目前的下载源设置 +modpack.wizard.step.2=文件选择 +modpack.wizard.step.2.title=选中你不想加到整合包中的文件(夹) +modpack.wizard.step.3=整合包描述 +modpack.wizard.step.3.title=描述你要制作的整合包 + +modpack.desc=描述你要制作的整合包,比如整合包注意事项和更新记录,支持Markdown(图片请用网络图片)。 +modpack.incorrect_format.no_json=整合包格式错误,pack.json丢失 +modpack.incorrect_format.no_jar=整合包格式错误,pack.json丢失jar字段 +modpack.cannot_read_version=读取游戏版本失败 +modpack.not_a_valid_location=不是一个有效整合包位置 +modpack.name=整合包名称 +modpack.not_a_valid_name=不是一个有效的整合包名称 + +modpack.files.servers_dat=多人游戏服务器列表 +modpack.files.saves=游戏存档 +modpack.files.mods=Mod +modpack.files.config=Mod配置文件 +modpack.files.liteconfig=Mod配置文件 +modpack.files.resourcepacks=资源包(材质包) +modpack.files.options_txt=游戏设定 +modpack.files.optionsshaders_txt=光影设定 +modpack.files.mods.voxelmods=VoxelMods配置,如小地图 +modpack.files.dumps=NEI调试输出 +modpack.files.scripts=MineTweaker配置 +modpack.files.blueprints=BuildCraft蓝图 + +mods=Mod管理 +mods.choose_mod=选择模组 +mods.failed=添加失败 +mods.add=添加 +mods.remove=删除 +mods.default_information=安装Mod前你需要确保已安装Forge或LiteLoader!
        您可以从资源管理器拖动mod文件到列表中来添加mod,同时使用删除键可快速删除选中mod
        点掉mod前面的勾可禁用mod,不会加载;选择mod可以获取mod信息
        + +advancedsettings=高级设置 +advancedsettings.launcher_visible=启动器可见性 +advancedsettings.debug_mode=调试模式 +advancedsettings.java_permanent_generation_space=内存永久保存区域(不必填写,MB) +advancedsettings.jvm_args=Java虚拟机参数(不必填写) +advancedsettings.Minecraft_arguments=Minecraft额外参数(不必填写) +advancedsettings.launcher_visibility.close=游戏启动后结束启动器 +advancedsettings.launcher_visibility.hide=游戏启动后隐藏启动器 +advancedsettings.launcher_visibility.keep=保持启动器可见 +advancedsettings.game_dir.default=默认(.minecraft/) +advancedsettings.game_dir.independent=各版本独立(.minecraft/versions/<版本名>/,除assets,libraries) +advancedsettings.no_jvm_args=不添加默认的JVM参数(使用Java9时必勾) +advancedsettings.java_args_default=启动器默认添加的参数(请不要重复添加):-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -XX:MaxPermSize=???m -Xmx???m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true +advancedsettings.wrapper_launcher=前置指令(不必填写,如optirun) +advancedsettings.precall_command=启动前执行命令(不必填写,将在游戏启动前调用) +advancedsettings.server_ip=直入服务器ip地址(不必填写,启动游戏后直接进入对应服务器) +advancedsettings.cancel_wrapper_launcher=取消包裹启动器(出现奇怪问题时可尝试使用,与调试模式冲突) +advancedsettings.dont_check_game_completeness=不检查游戏完整性 + +mainwindow.show_log=查看日志 +mainwindow.make_launch_script=生成启动脚本 +mainwindow.make_launch_script_failed=生成启动脚本失败 +mainwindow.enter_script_name=输入要生成脚本的文件名 +mainwindow.make_launch_succeed=启动脚本已生成完毕: +mainwindow.no_version=未找到任何版本,是否进入游戏下载? + +launcher.about=默认背景图感谢gamerteam提供。
        关于作者:
        百度ID:huanghongxun20
        mcbbs:huanghongxun
        Minecraft Forum ID: klkl6523
        欢迎提交Bug哦
        Copyright (c) 2013-2017 huangyuhui.
        免责声明:Minecraft软件版权归Mojang AB所有,使用本软件产生的版权问题本软件制作方概不负责。
        本启动器在GPLv3协议下开源:https://github.com/huanghongxun/HMCL/ ,感谢issues和pull requests贡献者
        本软件使用了基于Apache License 2.0的Gson项目,感谢贡献者。 +launcher.download_source=下载源 +launcher.background_location=背景地址 +launcher.exit_failed=强制退出失败,可能是Forge 1.7.10及更高版本导致的,无法解决。 +launcher.versions_json_not_matched=版本%s格式不规范!该版本文件夹下有json:%s,是否更名这个文件来规范格式? +launcher.versions_json_not_matched_cannot_auto_completion=版本%s缺失必要的版本信息文件,是否删除该版本? +launcher.versions_json_not_formatted=版本%s信息文件格式错误,是否重新下载? +launcher.choose_bgpath=选择背景路径 +launcher.background_tooltip=启动器默认使用自带的背景
        如果当前目录有background.png,则会使用该文件作为背景
        如果当前目录有bg子目录,则会随机使用里面的一张图作为背景
        如果该背景地址被修改,则会使用背景地址里的一张图作为背景
        背景地址允许有多个地址,使用半角分号";"(不包含双引号)分隔 +launcher.update_launcher=检查更新 +launcher.enable_shadow=启用窗口阴影 +launcher.enable_animation=启用动态效果 +launcher.enable_blur=启用主界面模糊 +launcher.theme=主题 +launcher.proxy=代理 +launcher.decorated=启用窗口边框(Linux下可解决程序界面全灰问题) +launcher.modpack=整合包作者帮助 +launcher.lang=语言 +launcher.restart=本界面选项需要重启本启动器生效 + +launcher.title.game=游戏设置 +launcher.title.main=主页 +launcher.title.launcher=启动器设置 + +versions.release=稳定版 +versions.snapshot=快照版 +versions.old_beta=测试版 +versions.old_alpha=远古版 + +versions.manage.rename=重命名该版本 +versions.manage.rename.message=请输入要改成的名字 +versions.manage.remove=删除该版本 +versions.manage.remove.confirm=真的要删除版本 +versions.manage.redownload_json=重新下载版本配置(minecraft.json) +versions.manage.redownload_assets_index=重新下载资源配置(assets_index.json) +versions.mamage.remove_libraries=删除所有库文件 + +advice.os64butjdk32=您的系统是64位的但是Java是32位的,推荐您安装64位Java. + +assets.download_all=下载资源文件 +assets.not_refreshed=资源列表未刷新,请刷新一次。 +assets.failed=获取列表失败,请刷新重试。 +assets.list.1_7_3_after=1.7.3及以后 +assets.list.1_6=1.6(BMCLAPI) +assets.unkown_type_select_one=无法解析游戏版本:%s,请选择一种资源类型下载。 +assets.type=资源类型 +assets.download=下载资源 +assets.no_assets=资源文件不完整,是否补全? +assets.failed_download=下载资源文件失败,可能导致没有中文和声音。 + +gamedownload.not_refreshed=游戏下载列表未刷新,请再刷新一次。 + +taskwindow.title=任务 +taskwindow.single_progress=单项进度 +taskwindow.total_progress=总进度 +taskwindow.cancel=取消 +taskwindow.no_more_instance=可能同时打开了多个任务窗口,请不要多次打开! +taskwindow.file_name=任务 +taskwindow.download_progress=进度 + +setupwindow.include_minecraft=导入游戏文件夹 +setupwindow.find_in_configurations=导入完成,快到配置下拉框中找新游戏路径吧! +setupwindow.give_a_name=给新游戏路径起个名字吧 +setupwindow.new=新建 +setupwindow.no_empty_name=名字不可为空 +setupwindow.clean=清理游戏文件 + +update.no_browser=无法打开浏览器,网址已经复制到剪贴板了,您可以手动粘贴网址打开页面 +update.should_open_link=是否更新? +update.newest_version=最新版本为: +update.failed=检查更新失败 +update.found=(发现更新!) + +logwindow.terminate_game=结束游戏进程 +logwindow.tieba=贴吧 +logwindow.title=日志 + +selector.choose=选择 + +serverlistview.title=选择服务器 +serverlistview.name=名称 +serverlistview.type=类型 +serverlistview.version=版本 +serverlistview.info=信息 + +minecraft.invalid=无效的 +minecraft.invalid_jar=无效的jar包 +minecraft.not_a_file=不是文件 +minecraft.not_found=找不到minecraft.jar +minecraft.not_readable=minecraft.jar不可读 +minecraft.modified=(修改的!) + +color.red=红色 +color.blue=蓝色 +color.green=绿色 +color.orange=橙色 +color.dark_blue=深蓝色 +color.purple=紫色 + +wizard.next_>=下一步 > +wizard.next_mnemonic=下 +wizard.<_prev=< 上一步 +wizard.prev_mnemonic=上 +wizard.finish=完成 +wizard.finish_mnemonic=完 +wizard.cancel=取消 +wizard.cancel_mnemonic=取 +wizard.help=帮助 +wizard.help_mnemonic=帮 +wizard.close=关闭 +wizard.close_mnemonic=关 +wizard.summary=概要 +wizard.failed=失败 +wizard.steps=步骤 + +lang=简体中文 +lang.default=跟随系统语言 diff --git a/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_CN.properties b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_CN.properties new file mode 100755 index 000000000..db409d584 --- /dev/null +++ b/HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang/I18N_zh_CN.properties @@ -0,0 +1,420 @@ +# 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/}. +# +#author: huangyuhui +launch.failed=\u542f\u52a8\u5931\u8d25 +launch.failed_creating_process=\u542f\u52a8\u5931\u8d25\uff0c\u5728\u521b\u5efa\u65b0\u8fdb\u7a0b\u65f6\u53d1\u751f\u9519\u8bef\uff0c\u53ef\u80fd\u662fJava\u8def\u5f84\u9519\u8bef\u3002 +launch.failed_sh_permission=\u4e3a\u542f\u52a8\u6587\u4ef6\u6dfb\u52a0\u6743\u9650\u65f6\u53d1\u751f\u9519\u8bef +launch.failed_packing_jar=\u5728\u6253\u5305jar\u65f6\u53d1\u751f\u9519\u8bef +launch.unsupported_launcher_version=\u5bf9\u4e0d\u8d77\uff0c\u672c\u542f\u52a8\u5668\u73b0\u5728\u53ef\u80fd\u4e0d\u80fd\u542f\u52a8\u8fd9\u4e2a\u7248\u672c\u7684Minecraft\uff0c\u4f46\u542f\u52a8\u5668\u8fd8\u662f\u4f1a\u5c1d\u8bd5\u542f\u52a8\uff0c\u8bf7\u5c3d\u5feb\u5c06\u6b64\u95ee\u9898\u62a5\u544a\u7ed9\u4f5c\u8005\u3002 +launch.too_big_memory_alloc_64bit=\u60a8\u8bbe\u7f6e\u7684\u5185\u5b58\u5927\u5c0f\u8fc7\u5927\uff0c\u7531\u4e8e\u53ef\u80fd\u8d85\u8fc7\u4e8632\u4f4dJava\u7684\u5185\u5b58\u5206\u914d\u9650\u5236\uff0c\u6240\u4ee5\u53ef\u80fd\u65e0\u6cd5\u542f\u52a8\u6e38\u620f\uff0c\u8bf7\u5c06\u5185\u5b58\u8c03\u81f31024MB\u6216\u66f4\u5c0f\uff0c\u542f\u52a8\u5668\u4ecd\u4f1a\u5c1d\u8bd5\u542f\u52a8\u3002 +launch.too_big_memory_alloc_free_space_too_low=\u60a8\u8bbe\u7f6e\u7684\u5185\u5b58\u5927\u5c0f\u8fc7\u5927\uff0c\u7531\u4e8e\u8d85\u8fc7\u4e86\u7cfb\u7edf\u5185\u5b58\u5927\u5c0f%dMB\uff0c\u6240\u4ee5\u53ef\u80fd\u5f71\u54cd\u6e38\u620f\u4f53\u9a8c\u6216\u65e0\u6cd5\u542f\u52a8\u6e38\u620f\uff0c\u542f\u52a8\u5668\u4ecd\u4f1a\u5c1d\u8bd5\u542f\u52a8\u3002 +launch.cannot_create_jvm=\u622a\u83b7\u5230\u65e0\u6cd5\u521b\u5efaJava\u865a\u62df\u673a\uff0c\u53ef\u80fd\u662fJava\u53c2\u6570\u6709\u95ee\u9898\uff0c\u53ef\u4ee5\u5728\u8bbe\u7f6e\u4e2d\u5f00\u542f\u65e0\u53c2\u6570\u6a21\u5f0f\u542f\u52a8 +launch.circular_dependency_versions=\u53d1\u73b0\u6e38\u620f\u7248\u672c\u5faa\u73af\u5f15\u7528\uff0c\u8bf7\u786e\u8ba4\u60a8\u7684\u5ba2\u6237\u7aef\u672a\u88ab\u4fee\u6539\u6216\u4fee\u6539\u5bfc\u81f4\u51fa\u73b0\u6b64\u95ee\u9898\u3002 +launch.not_finished_downloading_libraries=\u672a\u5b8c\u6210\u6e38\u620f\u4f9d\u8d56\u5e93\u7684\u4e0b\u8f7d\uff0c\u8fd8\u8981\u7ee7\u7eed\u542f\u52a8\u6e38\u620f\u5417\uff1f +launch.not_finished_decompressing_natives=\u672a\u80fd\u89e3\u538b\u6e38\u620f\u672c\u5730\u5e93\uff0c\u8fd8\u8981\u7ee7\u7eed\u542f\u52a8\u6e38\u620f\u5417\uff1f +launch.wrong_javadir=\u9519\u8bef\u7684Java\u8def\u5f84\uff0c\u5c06\u81ea\u52a8\u91cd\u7f6e\u4e3a\u9ed8\u8ba4Java\u8def\u5f84\u3002 +launch.exited_abnormally=\u6e38\u620f\u975e\u6b63\u5e38\u9000\u51fa\uff0c\u8bf7\u67e5\u770b\u65e5\u5fd7\u6587\u4ef6\uff0c\u6216\u8054\u7cfb\u4ed6\u4eba\u5bfb\u6c42\u5e2e\u52a9\u3002 + +launch.state.logging_in=\u767b\u5f55\u4e2d +launch.state.generating_launching_codes=\u6b63\u5728\u751f\u6210\u542f\u52a8\u4ee3\u7801 +launch.state.downloading_libraries=\u6b63\u5728\u4e0b\u8f7d\u5fc5\u8981\u6587\u4ef6 +launch.state.decompressing_natives=\u6b63\u5728\u91ca\u653e\u672c\u5730\u6587\u4ef6 + +install.no_version=\u672a\u627e\u5230\u8981\u5b89\u88c5\u7684\u5bf9\u5e94MC\u7248\u672c +install.no_version_if_intall=\u672a\u627e\u5230\u8981\u5b89\u88c5\u7684\u5bf9\u5e94MC\u7248\u672c\uff0c\u662f\u5426\u81ea\u52a8\u5b89\u88c5\u9700\u8981\u7684MC\u7248\u672c\uff1f +install.not_refreshed=\u672a\u5237\u65b0\u5217\u8868 +install.download_list=\u4e0b\u8f7d\u5217\u8868 + +install.liteloader.get_list=\u83b7\u53d6LiteLoader\u5217\u8868 +install.liteloader.install=\u5b89\u88c5LiteLoader + +install.forge.get_list=\u83b7\u53d6Forge\u5217\u8868 +install.forge.install=\u5b89\u88c5Forge +install.forge.get_changelogs=\u83b7\u53d6Forge\u66f4\u65b0\u8bb0\u5f55 + +install.optifine.install=\u5b89\u88c5OptiFine +install.optifine.get_list=\u83b7\u53d6OptiFine\u5217\u8868 +install.optifine.get_download_link=\u83b7\u53d6OptiFine\u4e0b\u8f7d\u5730\u5740 + +install.failed_forge=\u5b89\u88c5Forge\u5931\u8d25 +install.failed_optifine=\u5b89\u88c5OptiFine\u5931\u8d25 +install.failed_liteloader=\u5b89\u88c5LiteLoader\u5931\u8d25 +install.failed_download_forge=\u4e0b\u8f7dForge\u5931\u8d25 +install.failed_download_optifine=\u4e0b\u8f7dOptiFine\u5931\u8d25 +install.failed=\u5b89\u88c5\u5931\u8d25 +install.success=\u5b89\u88c5\u6210\u529f +install.no_forge=\u6ca1\u6709\u5b89\u88c5Forge +install.choose_forge=\u9009\u62e9\u4f60\u5b89\u88c5\u7684Forge\u7248\u672c +install.version=\u7248\u672c +install.mcversion=\u6e38\u620f\u7248\u672c +install.time=\u65f6\u95f4 +install.release_time=\u91ca\u653e\u65f6\u95f4 +install.type=\u7c7b\u578b +install.please_refresh=\u5982\u9700\u4f7f\u7528\u81ea\u52a8\u5b89\u88c5\u8bf7\u70b9\u51fb\u53f3\u4fa7\u5237\u65b0\u6309\u94ae + +crash.launcher=\u542f\u52a8\u5668\u5d29\u6e83\u4e86\uff01 +crash.minecraft=Minecraft\u5d29\u6e83\u4e86\uff01\u8bf7\u8ba4\u771f\u9605\u8bfb\u5efa\u8bae\u3002 + +login.choose_charactor=\u8bf7\u9009\u62e9\u60a8\u8981\u4f7f\u7528\u7684\u89d2\u8272 +login.no_charactor=\u8be5\u5e10\u53f7\u6ca1\u6709\u89d2\u8272 +login.your_password=\u60a8\u7684\u5bc6\u7801 +login.failed=\u767b\u5f55\u5931\u8d25\uff1a +login.no_Player007=\u4f60\u8fd8\u672a\u8bbe\u7f6e\u7528\u6237\u540d\uff01 +login.wrong_password=\u53ef\u80fd\u662f\u60a8\u7684\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef +login.invalid_username=\u65e0\u6548\u7684\u7528\u6237\u540d +login.invalid_uuid_and_username=\u65e0\u6548\u7684UUID\u548c\u7528\u6237\u540d +login.invalid_password=\u65e0\u6548\u7684\u5bc6\u7801 +login.invalid_access_token=\u65e0\u6548\u7684\u8bbf\u95ee\u4ee4\u724c +login.changed_client_token=\u670d\u52a1\u5668\u56de\u5e94\u5df2\u7ecf\u4fee\u6539\u5ba2\u6237\u7aef\u4ee4\u724c +login.not_email=\u7528\u6237\u540d\u5fc5\u987b\u662f\u90ae\u7bb1 +login.type=\u767b\u5f55 +login.username=\u540d\u5b57 +login.account=\u90ae\u7bb1 +login.invalid_token=\u8bf7\u5c1d\u8bd5\u767b\u51fa\u5e76\u91cd\u65b0\u8f93\u5165\u5bc6\u7801\u767b\u5f55 +login.no_valid_character=\u65e0\u6709\u6548\u7684\u89d2\u8272\uff0c\u81ea\u884c\u5230skinme.cc\u767b\u9646\u5e76\u521b\u5efa\u89d2\u8272 + +proxy.username=\u8d26\u6237 +proxy.password=\u5bc6\u7801 +proxy.host=\u4e3b\u673a +proxy.port=\u7aef\u53e3 + +login.failed.connect_authentication_server=\u65e0\u6cd5\u8fde\u63a5\u8ba4\u8bc1\u670d\u52a1\u5668,\u53ef\u80fd\u662f\u7f51\u7edc\u95ee\u9898 + +login.profile.not_logged_in=\u65e0\u6cd5\u4fee\u6539\u6e38\u620f\u8d44\u6599\u540c\u65f6\u672a\u767b\u5f55 +login.profile.selected=\u65e0\u6cd5\u4fee\u6539\u6e38\u620f\u8d44\u6599. \u4f60\u5fc5\u987b\u767b\u51fa\u518d\u8fd4\u56de. + +login.methods.yggdrasil=\u6b63\u7248\u767b\u5f55 +login.methods.offline=\u79bb\u7ebf\u6a21\u5f0f +login.methods.no_method=\u6ca1\u6709\u767b\u5165\u65b9\u5f0f... + +log.playername_null=\u73a9\u5bb6\u540d\u4e3a\u7a7a\uff0c\u8fd9\u4ee3\u8868\u7740\u767b\u5f55\u65b9\u6cd5\u51fa\u73b0\u95ee\u9898 + +minecraft.no_selected_version=\u6ca1\u6709\u9009\u62e9\u4efb\u4f55\u4e00\u4e2aMinecraft\u7248\u672c +minecraft.wrong_path=\u9519\u8bef\u7684Minecraft\u8def\u5f84\uff0c\u542f\u52a8\u5668\u672a\u627e\u5230\u8bbe\u5b9a\u7684Minecraft\u8def\u5f84\uff0c\u8bf7\u68c0\u67e5\u3002 + +operation.stopped=\u64cd\u4f5c\u88ab\u5f3a\u884c\u7ec8\u6b62 +operation.confirm_stop=\u771f\u7684\u8981\u7ec8\u6b62\u64cd\u4f5c\u5417\uff1f + +ui.login.password=\u5bc6\u7801 +ui.more=\u66f4\u591a + +crash.advice.UnsupportedClassVersionError=\u8fd9\u53ef\u80fd\u662f\u56e0\u4e3a\u60a8\u7684Java\u7248\u672c\u8fc7\u4e8e\u8001\u65e7\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u66f4\u6362\u6700\u65b0Java\u5e76\u5728\u7248\u672c\u8bbe\u7f6e\u7684Java\u8def\u5f84\u4e2d\u8bbe\u7f6e. +crash.advice.ConcurrentModificationException=\u8fd9\u53ef\u80fd\u662f\u56e0\u4e3a\u60a8\u7684Java\u7248\u672c\u9ad8\u4e8eJava 1.8.0_11\u5bfc\u81f4\u7684,\u53ef\u4ee5\u5c1d\u8bd5\u5378\u8f7dJava8\u5b89\u88c5Java7\u3002 +crash.advice.ClassNotFoundException=Minecraft\u4e0d\u5b8c\u6574\u6216Mod\u51b2\u7a81\uff0c\u5982\u679c\u6709\u672a\u80fd\u4e0b\u8f7d\u7684\u6587\u4ef6\u8bf7\u4e0b\u8f7d\u6210\u529f\u540e\u91cd\u8bd5\u6216\u662f\u5ba2\u6237\u7aef\u635f\u574f\u8bf7\u91cd\u8bd5\u8bf7\u91cd\u65b0\u5236\u4f5c\u5ba2\u6237\u7aef\u6216\u4e0b\u8f7d\u6574\u5408\u5305\u89e3\u51b3\u95ee\u9898\uff0c\u53e6\u53ef\u5c1d\u8bd5\u6e38\u620f\u8bbe\u7f6e->\uff08\u7248\u672c\uff09\u7ba1\u7406->\u5220\u9664\u5e93\u6587\u4ef6\u89e3\u51b3\u95ee\u9898 +crash.advice.NoSuchFieldError=Minecraft\u4e0d\u5b8c\u6574\u6216Mod\u51b2\u7a81\uff0c\u5982\u679c\u6709\u672a\u80fd\u4e0b\u8f7d\u7684\u6587\u4ef6\u8bf7\u4e0b\u8f7d\u6210\u529f\u540e\u91cd\u8bd5\u6216\u662f\u5ba2\u6237\u7aef\u635f\u574f\u8bf7\u91cd\u8bd5\u8bf7\u91cd\u65b0\u5236\u4f5c\u5ba2\u6237\u7aef\u6216\u4e0b\u8f7d\u6574\u5408\u5305\u89e3\u51b3\u95ee\u9898\u3002 +crash.advice.LWJGLException=\u60a8\u7684\u7535\u8111\u4e0d\u6b63\u5e38\uff0c\u53ef\u80fd\u9700\u8981\u4f7f\u7528\u9a71\u52a8\u7cbe\u7075\u6216\u5176\u4ed6\u5b89\u88c5\u5668\u66f4\u65b0\u663e\u5361\u9a71\u52a8\u3002 +crash.advice.SecurityException=\u53ef\u80fd\u662f\u60a8\u4fee\u6539\u4e86minecraft.jar\u4f46\u672a\u5220\u9664META-INF\u6587\u4ef6\u5939\u7684\u539f\u56e0\u3002\u8bf7\u901a\u8fc7\u538b\u7f29\u8f6f\u4ef6\u5220\u9664jar\u4e2d\u7684META-INF\u6587\u4ef6\u5939\u3002 +crash.advice.OutOfMemoryError=\u5185\u5b58\u6ea2\u51fa\uff0c\u60a8\u8bbe\u7f6e\u7684Minecraft\u6700\u5927\u5185\u5b58\u8fc7\u5c0f\uff0c\u8bf7\u8c03\u5927\uff01 +crash.advice.otherwise=\u53ef\u80fd\u662fMod\u6216\u5176\u4ed6\u95ee\u9898\u3002 + +crash.advice.OpenGL=\u53ef\u80fd\u662f\u663e\u5361/\u58f0\u5361\u9a71\u52a8\u95ee\u9898\uff0c\u4e5f\u53ef\u80fd\u662fMod\u5bfc\u81f4\u7684\u95ee\u9898\u3002 +crash.advice.no_lwjgl=\u53ef\u80fd\u662f\u6e38\u620f\u4f9d\u8d56\u5e93\u4e0d\u5b8c\u6574\u6216\u89e3\u538b\u4f9d\u8d56\u5e93\u65f6\u51fa\u9519\u3002\u53ef\u4ee5\u901a\u8fc7\u4e0b\u8f7d\u6574\u5408\u5305\u89e3\u51b3\u95ee\u9898\u3002 + +crash.advice.no=\u65e0\u5efa\u8bae\u3002 + +crash.user_fault=\u60a8\u7684\u7cfb\u7edf\u6216Java\u73af\u5883\u53ef\u80fd\u5b89\u88c5\u4e0d\u5f53\u5bfc\u81f4\u672c\u8f6f\u4ef6\u5d29\u6e83\uff0c\u8bf7\u68c0\u67e5\u60a8\u7684Java\u73af\u5883\u6216\u60a8\u7684\u7535\u8111\uff01\u53ef\u4ee5\u5c1d\u8bd5\u91cd\u65b0\u5b89\u88c5Java\u3002 +crash.headless=\u5982\u679c\u60a8\u7684\u64cd\u4f5c\u7cfb\u7edf\u662fLinux\uff0c\u8bf7\u6ce8\u610f\u4e0d\u8981\u4f7f\u7528OpenJDK\uff0c\u52a1\u5fc5\u4f7f\u7528Oracle JDK\uff0c\u6216\u5c1d\u8bd5\u6dfb\u52a0-Djava.awt.headless=false\u53c2\u6570\uff0c\u6216\u68c0\u67e5\u60a8\u7684Xserver\u662f\u5426\u6b63\u5e38 +crash.NoClassDefFound=\u8bf7\u786e\u8ba4HMCL\u672c\u4f53\u662f\u5426\u5b8c\u6574 + +crash.error=\u60a8\u7684Minecraft\u5d29\u6e83\u4e86\u3002 +crash.main_class_not_found=\u627e\u4e0d\u5230\u4e3b\u7c7b\uff0c\u53ef\u80fd\u662f\u60a8\u7684JSON\u6587\u4ef6\u586b\u5199\u9519\u8bef\u3002\u65e0\u6cd5\u542f\u52a8\u6e38\u620f\u3002\u53ef\u4ee5\u901a\u8fc7\u4e0b\u8f7d\u6574\u5408\u5305\u89e3\u51b3\u95ee\u9898\u3002 +crash.class_path_wrong=\u89e3\u6790Class Path\u65f6\u51fa\u73b0\u9519\u8bef\uff0c\u6b64\u9519\u8bef\u672c\u4e0d\u5e94\u8be5\u53d1\u751f\u3002\u53ef\u80fd\u662f\u542f\u52a8\u811a\u672c\u9519\u8bef\uff0c\u8bf7\u4ed4\u7ec6\u68c0\u67e5\u542f\u52a8\u811a\u672c\u3002 + +ui.label.newProfileWindow.new_profile_name=\u65b0\u914d\u7f6e\u540d: +ui.label.newProfileWindow.copy_from=\u590d\u5236\u914d\u7f6e: +ui.newProfileWindow.title=\u65b0\u5efa\u914d\u7f6e + +ui.button.ok=\u786e\u8ba4 +ui.button.refresh=\u5237\u65b0 +ui.button.run=\u542f\u52a8Minecraft +ui.button.settings= +ui.button.about=\u5173\u4e8e +ui.button.others=\u5176\u4ed6 +ui.button.logout=\u767b\u51fa +ui.button.download=\u4e0b\u8f7d +ui.button.retry=\u91cd\u8bd5 +ui.button.delete=\u5220\u9664 +ui.button.install=\u5b89\u88c5 +ui.button.info=\u4fe1\u606f +ui.button.save=\u4fdd\u5b58 +ui.button.copy=\u590d\u5236 +ui.button.clear=\u6e05\u9664 +ui.button.close=\u5173\u95ed +ui.button.explore=\u6d4f\u89c8 +ui.button.test=\u6d4b\u8bd5 +ui.button.preview=\u9884\u89c8 +button.cancel=\u53d6\u6d88 +button.ok=\u786e\u5b9a + +ui.label.version=\u7248\u672c +ui.label.password=\u5bc6\u7801 +ui.label.profile=\u914d\u7f6e + +ui.message.first_load=\u8bf7\u5728\u5de6\u8fb9\u8f93\u5165\u60a8\u7684\u8d26\u53f7 +ui.message.enter_password=\u8bf7\u5728\u5de6\u8fb9\u8f93\u5165\u60a8\u7684\u5bc6\u7801 +ui.message.launching=\u542f\u52a8\u4e2d +ui.message.making=\u751f\u6210\u4e2d +ui.message.sure_remove=\u771f\u7684\u8981\u5220\u9664\u914d\u7f6e%s\u5417\uff1f +ui.message.update_java=\u8bf7\u66f4\u65b0\u60a8\u7684Java + +ui.label.settings=\u9009\u9879 +ui.label.crashing=Hello Minecraft!\u9047\u5230\u4e86\u65e0\u6cd5\u5904\u7406\u7684\u9519\u8bef\uff0c\u8bf7\u590d\u5236\u4e0b\u5217\u5185\u5bb9\u5e76\u901a\u8fc7mcbbs\u3001\u8d34\u5427\u3001Github\u6216Minecraft Forum\u53cd\u9988bug\u3002 +ui.label.crashing_out_dated=Hello Minecraft! Launcher\u9047\u5230\u4e86\u65e0\u6cd5\u5904\u7406\u7684\u9519\u8bef\uff0c\u5df2\u68c0\u6d4b\u5230\u60a8\u7684\u542f\u52a8\u5668\u4e0d\u662f\u6700\u65b0\u7248\u672c\uff0c\u8bf7\u66f4\u65b0\u540e\u518d\u8bd5\uff01 +ui.label.failed_set=\u8bbe\u7f6e\u5931\u8d25\uff1a + +download=\u4e0b\u8f7d +download.mojang=\u5b98\u65b9 +download.BMCL=BMCLAPI (bangbang93, http://bmclapi.bangbang93.com/) +download.rapid_data=RapidData (\u9510\u7f51\u4e91\u8ba1\u7b97, https://www.rapiddata.org/) +download.not_200=\u4e0b\u8f7d\u5931\u8d25\uff0c\u56de\u590d\u7801 +download.failed=\u4e0b\u8f7d\u5931\u8d25 +download.successfully=\u4e0b\u8f7d\u5b8c\u6210 +download.source=\u4e0b\u8f7d\u6e90 + +message.error=\u9519\u8bef +message.cannot_open_explorer=\u65e0\u6cd5\u6253\u5f00\u6587\u4ef6\u7ba1\u7406\u5668: +message.cancelled=\u5df2\u53d6\u6d88 +message.info=\u63d0\u793a +message.loading=\u52a0\u8f7d\u4e2d... + +folder.game=\u6e38\u620f\u6587\u4ef6\u5939 +folder.mod=MOD\u6587\u4ef6\u5939 +folder.coremod=\u6838\u5fc3MOD\u6587\u4ef6\u5939 +folder.config=\u914d\u7f6e\u6587\u4ef6\u5939 +folder.resourcepacks=\u8d44\u6e90\u5305\u6587\u4ef6\u5939 +folder.screenshots=\u622a\u56fe\u6587\u4ef6\u5939 +folder.saves=\u5b58\u6863\u6587\u4ef6\u5939 + +settings.tabs.game_download=\u6e38\u620f\u4e0b\u8f7d +settings.tabs.installers=\u81ea\u52a8\u5b89\u88c5 +settings.tabs.assets_downloads=\u8d44\u6e90\u4e0b\u8f7d + +settings=\u666e\u901a\u8bbe\u7f6e +settings.explore=\u6d4f\u89c8 +settings.manage=\u7ba1\u7406 +settings.cannot_remove_default_config=\u4e0d\u80fd\u5220\u9664\u9ed8\u8ba4\u914d\u7f6e +settings.max_memory=\u6700\u5927\u5185\u5b58/MB +settings.java_dir=Java\u8def\u5f84 +settings.game_directory=\u6e38\u620f\u8def\u5f84 +settings.dimension=\u6e38\u620f\u7a97\u53e3\u5206\u8fa8\u7387 +settings.fullscreen=\u5168\u5c4f +settings.update_version=\u66f4\u65b0\u7248\u672c\u6587\u4ef6 +settings.run_directory=\u8fd0\u884c\u8def\u5f84(\u7248\u672c\u9694\u79bb) +settings.physical_memory=\u7269\u7406\u5185\u5b58\u5927\u5c0f +settings.choose_javapath=\u9009\u62e9Java\u8def\u5f84 +settings.default=\u9ed8\u8ba4 +settings.custom=\u81ea\u5b9a\u4e49 +settings.choose_gamedir=\u9009\u62e9\u6e38\u620f\u8def\u5f84 +settings.failed_load=\u8bbe\u7f6e\u6587\u4ef6\u52a0\u8f7d\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u5347\u7ea7\u4e86\u542f\u52a8\u5668\u6216\u88ab\u4eba\u5de5\u4fee\u6539\u9020\u6210\u9519\u8bef\uff0c\u662f\u5426\u6e05\u9664\uff1f +settings.test_game=\u6d4b\u8bd5\u6e38\u620f + +modpack=\u6574\u5408\u5305 +modpack.choose=\u9009\u62e9\u8981\u5bfc\u5165\u7684\u6e38\u620f\u6574\u5408\u5305\u6587\u4ef6\uff0c\u5982\u679c\u60a8\u5e0c\u671b\u66f4\u65b0\u6574\u5408\u5305\uff0c\u8bf7\u8f93\u5165\u8981\u66f4\u65b0\u7684\u7248\u672c\u540d +modpack.export_error=\u5bfc\u51fa\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u60a8\u7684\u6e38\u620f\u6587\u4ef6\u5939\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u64cd\u4f5c\u6587\u4ef6\u5931\u8d25 +modpack.export_finished=\u6574\u5408\u5305\u5bfc\u51fa\u5b8c\u6210\uff0c\u53c2\u89c1 +modpack.included_launcher=\u6574\u5408\u5305\u5df2\u5305\u542b\u542f\u52a8\u5668\uff0c\u53ef\u76f4\u63a5\u53d1\u5e03 +modpack.not_included_launcher=\u6574\u5408\u5305\u672a\u5305\u542b\u542f\u52a8\u5668\uff0c\u53ef\u4f7f\u7528\u672c\u8f6f\u4ef6\u7684\u5bfc\u5165\u6574\u5408\u5305\u529f\u80fd\u5bfc\u5165\u6574\u5408\u5305 +modpack.enter_name=\u7ed9\u6e38\u620f\u8d77\u4e2a\u4f60\u559c\u6b22\u7684\u540d\u5b57 + +modpack.task.save=\u5bfc\u51fa\u6574\u5408\u5305 +modpack.task.install=\u5bfc\u5165\u6574\u5408\u5305 +modpack.task.install.error=\u5b89\u88c5\u5931\u8d25\uff0c\u53ef\u80fd\u662f\u6574\u5408\u5305\u683c\u5f0f\u4e0d\u6b63\u786e\u6216\u64cd\u4f5c\u6587\u4ef6\u5931\u8d25 +modpack.task.install.will=\u5c06\u4f1a\u5b89\u88c5\u6574\u5408\u5305\uff1a + +modpack.wizard=\u5bfc\u51fa\u6574\u5408\u5305\u5411\u5bfc +modpack.wizard.step.1=\u57fa\u672c\u8bbe\u7f6e +modpack.wizard.step.1.title=\u8bbe\u7f6e\u6574\u5408\u5305\u7684\u4e3b\u8981\u4fe1\u606f +modpack.wizard.step.initialization.include_launcher=\u5305\u542b\u542f\u52a8\u5668 +modpack.wizard.step.initialization.exported_version=\u8981\u5bfc\u51fa\u7684\u6e38\u620f\u7248\u672c +modpack.wizard.step.initialization.save=\u9009\u62e9\u8981\u5bfc\u51fa\u5230\u7684\u6e38\u620f\u6574\u5408\u5305\u4f4d\u7f6e +modpack.wizard.step.initialization.warning=\u5728\u5236\u4f5c\u6574\u5408\u5305\u524d\uff0c\u8bf7\u60a8\u786e\u8ba4\u60a8\u9009\u62e9\u7684\u7248\u672c\u53ef\u4ee5\u6b63\u5e38\u542f\u52a8\uff0c
        \u5e76\u4fdd\u8bc1\u60a8\u7684Minecraft\u662f\u6b63\u5f0f\u7248\u800c\u975e\u5feb\u7167\u7248\uff0c
        \u800c\u4e14\u4e0d\u5e94\u5f53\u5c06\u4e0d\u5141\u8bb8\u975e\u5b98\u65b9\u9014\u5f84\u4f20\u64ad\u7684Mod\u3001\u6750\u8d28\u5305\u7b49\u7eb3\u5165\u6574\u5408\u5305\u3002
        \u6574\u5408\u5305\u4f1a\u4fdd\u5b58\u60a8\u76ee\u524d\u7684\u4e0b\u8f7d\u6e90\u8bbe\u7f6e +modpack.wizard.step.2=\u6587\u4ef6\u9009\u62e9 +modpack.wizard.step.2.title=\u9009\u4e2d\u4f60\u4e0d\u60f3\u52a0\u5230\u6574\u5408\u5305\u4e2d\u7684\u6587\u4ef6(\u5939) +modpack.wizard.step.3=\u6574\u5408\u5305\u63cf\u8ff0 +modpack.wizard.step.3.title=\u63cf\u8ff0\u4f60\u8981\u5236\u4f5c\u7684\u6574\u5408\u5305 + +modpack.desc=\u63cf\u8ff0\u4f60\u8981\u5236\u4f5c\u7684\u6574\u5408\u5305\uff0c\u6bd4\u5982\u6574\u5408\u5305\u6ce8\u610f\u4e8b\u9879\u548c\u66f4\u65b0\u8bb0\u5f55\uff0c\u652f\u6301Markdown(\u56fe\u7247\u8bf7\u7528\u7f51\u7edc\u56fe\u7247)\u3002 +modpack.incorrect_format.no_json=\u6574\u5408\u5305\u683c\u5f0f\u9519\u8bef\uff0cpack.json\u4e22\u5931 +modpack.incorrect_format.no_jar=\u6574\u5408\u5305\u683c\u5f0f\u9519\u8bef\uff0cpack.json\u4e22\u5931jar\u5b57\u6bb5 +modpack.cannot_read_version=\u8bfb\u53d6\u6e38\u620f\u7248\u672c\u5931\u8d25 +modpack.not_a_valid_location=\u4e0d\u662f\u4e00\u4e2a\u6709\u6548\u6574\u5408\u5305\u4f4d\u7f6e +modpack.name=\u6574\u5408\u5305\u540d\u79f0 +modpack.not_a_valid_name=\u4e0d\u662f\u4e00\u4e2a\u6709\u6548\u7684\u6574\u5408\u5305\u540d\u79f0 + +modpack.files.servers_dat=\u591a\u4eba\u6e38\u620f\u670d\u52a1\u5668\u5217\u8868 +modpack.files.saves=\u6e38\u620f\u5b58\u6863 +modpack.files.mods=Mod +modpack.files.config=Mod\u914d\u7f6e\u6587\u4ef6 +modpack.files.liteconfig=Mod\u914d\u7f6e\u6587\u4ef6 +modpack.files.resourcepacks=\u8d44\u6e90\u5305(\u6750\u8d28\u5305) +modpack.files.options_txt=\u6e38\u620f\u8bbe\u5b9a +modpack.files.optionsshaders_txt=\u5149\u5f71\u8bbe\u5b9a +modpack.files.mods.voxelmods=VoxelMods\u914d\u7f6e\uff0c\u5982\u5c0f\u5730\u56fe +modpack.files.dumps=NEI\u8c03\u8bd5\u8f93\u51fa +modpack.files.scripts=MineTweaker\u914d\u7f6e +modpack.files.blueprints=BuildCraft\u84dd\u56fe + +mods=Mod\u7ba1\u7406 +mods.choose_mod=\u9009\u62e9\u6a21\u7ec4 +mods.failed=\u6dfb\u52a0\u5931\u8d25 +mods.add=\u6dfb\u52a0 +mods.remove=\u5220\u9664 +mods.default_information=\u5b89\u88c5Mod\u524d\u4f60\u9700\u8981\u786e\u4fdd\u5df2\u5b89\u88c5Forge\u6216LiteLoader!
        \u60a8\u53ef\u4ee5\u4ece\u8d44\u6e90\u7ba1\u7406\u5668\u62d6\u52a8mod\u6587\u4ef6\u5230\u5217\u8868\u4e2d\u6765\u6dfb\u52a0mod\uff0c\u540c\u65f6\u4f7f\u7528\u5220\u9664\u952e\u53ef\u5feb\u901f\u5220\u9664\u9009\u4e2dmod
        \u70b9\u6389mod\u524d\u9762\u7684\u52fe\u53ef\u7981\u7528mod\uff0c\u4e0d\u4f1a\u52a0\u8f7d\uff1b\u9009\u62e9mod\u53ef\u4ee5\u83b7\u53d6mod\u4fe1\u606f
        + +advancedsettings=\u9ad8\u7ea7\u8bbe\u7f6e +advancedsettings.launcher_visible=\u542f\u52a8\u5668\u53ef\u89c1\u6027 +advancedsettings.debug_mode=\u8c03\u8bd5\u6a21\u5f0f +advancedsettings.java_permanent_generation_space=\u5185\u5b58\u6c38\u4e45\u4fdd\u5b58\u533a\u57df(\u4e0d\u5fc5\u586b\u5199,MB) +advancedsettings.jvm_args=Java\u865a\u62df\u673a\u53c2\u6570(\u4e0d\u5fc5\u586b\u5199) +advancedsettings.Minecraft_arguments=Minecraft\u989d\u5916\u53c2\u6570(\u4e0d\u5fc5\u586b\u5199) +advancedsettings.launcher_visibility.close=\u6e38\u620f\u542f\u52a8\u540e\u7ed3\u675f\u542f\u52a8\u5668 +advancedsettings.launcher_visibility.hide=\u6e38\u620f\u542f\u52a8\u540e\u9690\u85cf\u542f\u52a8\u5668 +advancedsettings.launcher_visibility.keep=\u4fdd\u6301\u542f\u52a8\u5668\u53ef\u89c1 +advancedsettings.game_dir.default=\u9ed8\u8ba4(.minecraft/) +advancedsettings.game_dir.independent=\u5404\u7248\u672c\u72ec\u7acb(.minecraft/versions/<\u7248\u672c\u540d>/,\u9664assets,libraries) +advancedsettings.no_jvm_args=\u4e0d\u6dfb\u52a0\u9ed8\u8ba4\u7684JVM\u53c2\u6570(\u4f7f\u7528Java9\u65f6\u5fc5\u52fe) +advancedsettings.java_args_default=\u542f\u52a8\u5668\u9ed8\u8ba4\u6dfb\u52a0\u7684\u53c2\u6570\uff08\u8bf7\u4e0d\u8981\u91cd\u590d\u6dfb\u52a0\uff09\uff1a-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -XX:MaxPermSize=???m -Xmx???m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true +advancedsettings.wrapper_launcher=\u524d\u7f6e\u6307\u4ee4(\u4e0d\u5fc5\u586b\u5199,\u5982optirun) +advancedsettings.precall_command=\u542f\u52a8\u524d\u6267\u884c\u547d\u4ee4(\u4e0d\u5fc5\u586b\u5199\uff0c\u5c06\u5728\u6e38\u620f\u542f\u52a8\u524d\u8c03\u7528) +advancedsettings.server_ip=\u76f4\u5165\u670d\u52a1\u5668ip\u5730\u5740(\u4e0d\u5fc5\u586b\u5199\uff0c\u542f\u52a8\u6e38\u620f\u540e\u76f4\u63a5\u8fdb\u5165\u5bf9\u5e94\u670d\u52a1\u5668) +advancedsettings.cancel_wrapper_launcher=\u53d6\u6d88\u5305\u88f9\u542f\u52a8\u5668\uff08\u51fa\u73b0\u5947\u602a\u95ee\u9898\u65f6\u53ef\u5c1d\u8bd5\u4f7f\u7528,\u4e0e\u8c03\u8bd5\u6a21\u5f0f\u51b2\u7a81\uff09 +advancedsettings.dont_check_game_completeness=\u4e0d\u68c0\u67e5\u6e38\u620f\u5b8c\u6574\u6027 + +mainwindow.show_log=\u67e5\u770b\u65e5\u5fd7 +mainwindow.make_launch_script=\u751f\u6210\u542f\u52a8\u811a\u672c +mainwindow.make_launch_script_failed=\u751f\u6210\u542f\u52a8\u811a\u672c\u5931\u8d25 +mainwindow.enter_script_name=\u8f93\u5165\u8981\u751f\u6210\u811a\u672c\u7684\u6587\u4ef6\u540d +mainwindow.make_launch_succeed=\u542f\u52a8\u811a\u672c\u5df2\u751f\u6210\u5b8c\u6bd5: +mainwindow.no_version=\u672a\u627e\u5230\u4efb\u4f55\u7248\u672c\uff0c\u662f\u5426\u8fdb\u5165\u6e38\u620f\u4e0b\u8f7d\uff1f + +launcher.about=\u9ed8\u8ba4\u80cc\u666f\u56fe\u611f\u8c22gamerteam\u63d0\u4f9b\u3002
        \u5173\u4e8e\u4f5c\u8005\uff1a
        \u767e\u5ea6ID\uff1ahuanghongxun20
        mcbbs\uff1ahuanghongxun
        Minecraft Forum ID: klkl6523
        \u6b22\u8fce\u63d0\u4ea4Bug\u54e6
        Copyright (c) 2013-2017 huangyuhui.
        \u514d\u8d23\u58f0\u660e\uff1aMinecraft\u8f6f\u4ef6\u7248\u6743\u5f52Mojang AB\u6240\u6709\uff0c\u4f7f\u7528\u672c\u8f6f\u4ef6\u4ea7\u751f\u7684\u7248\u6743\u95ee\u9898\u672c\u8f6f\u4ef6\u5236\u4f5c\u65b9\u6982\u4e0d\u8d1f\u8d23\u3002
        \u672c\u542f\u52a8\u5668\u5728GPLv3\u534f\u8bae\u4e0b\u5f00\u6e90:https://github.com/huanghongxun/HMCL/ ,\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005
        \u672c\u8f6f\u4ef6\u4f7f\u7528\u4e86\u57fa\u4e8eApache License 2.0\u7684Gson\u9879\u76ee\uff0c\u611f\u8c22\u8d21\u732e\u8005\u3002 +launcher.download_source=\u4e0b\u8f7d\u6e90 +launcher.background_location=\u80cc\u666f\u5730\u5740 +launcher.exit_failed=\u5f3a\u5236\u9000\u51fa\u5931\u8d25\uff0c\u53ef\u80fd\u662fForge 1.7.10\u53ca\u66f4\u9ad8\u7248\u672c\u5bfc\u81f4\u7684\uff0c\u65e0\u6cd5\u89e3\u51b3\u3002 +launcher.versions_json_not_matched=\u7248\u672c%s\u683c\u5f0f\u4e0d\u89c4\u8303\uff01\u8be5\u7248\u672c\u6587\u4ef6\u5939\u4e0b\u6709json:%s\uff0c\u662f\u5426\u66f4\u540d\u8fd9\u4e2a\u6587\u4ef6\u6765\u89c4\u8303\u683c\u5f0f\uff1f +launcher.versions_json_not_matched_cannot_auto_completion=\u7248\u672c%s\u7f3a\u5931\u5fc5\u8981\u7684\u7248\u672c\u4fe1\u606f\u6587\u4ef6\uff0c\u662f\u5426\u5220\u9664\u8be5\u7248\u672c\uff1f +launcher.versions_json_not_formatted=\u7248\u672c%s\u4fe1\u606f\u6587\u4ef6\u683c\u5f0f\u9519\u8bef\uff0c\u662f\u5426\u91cd\u65b0\u4e0b\u8f7d\uff1f +launcher.choose_bgpath=\u9009\u62e9\u80cc\u666f\u8def\u5f84 +launcher.background_tooltip=\u542f\u52a8\u5668\u9ed8\u8ba4\u4f7f\u7528\u81ea\u5e26\u7684\u80cc\u666f
        \u5982\u679c\u5f53\u524d\u76ee\u5f55\u6709background.png\uff0c\u5219\u4f1a\u4f7f\u7528\u8be5\u6587\u4ef6\u4f5c\u4e3a\u80cc\u666f
        \u5982\u679c\u5f53\u524d\u76ee\u5f55\u6709bg\u5b50\u76ee\u5f55\uff0c\u5219\u4f1a\u968f\u673a\u4f7f\u7528\u91cc\u9762\u7684\u4e00\u5f20\u56fe\u4f5c\u4e3a\u80cc\u666f
        \u5982\u679c\u8be5\u80cc\u666f\u5730\u5740\u88ab\u4fee\u6539\uff0c\u5219\u4f1a\u4f7f\u7528\u80cc\u666f\u5730\u5740\u91cc\u7684\u4e00\u5f20\u56fe\u4f5c\u4e3a\u80cc\u666f
        \u80cc\u666f\u5730\u5740\u5141\u8bb8\u6709\u591a\u4e2a\u5730\u5740\uff0c\u4f7f\u7528\u534a\u89d2\u5206\u53f7";"(\u4e0d\u5305\u542b\u53cc\u5f15\u53f7)\u5206\u9694 +launcher.update_launcher=\u68c0\u67e5\u66f4\u65b0 +launcher.enable_shadow=\u542f\u7528\u7a97\u53e3\u9634\u5f71 +launcher.enable_animation=\u542f\u7528\u52a8\u6001\u6548\u679c +launcher.enable_blur=\u542f\u7528\u4e3b\u754c\u9762\u6a21\u7cca +launcher.theme=\u4e3b\u9898 +launcher.proxy=\u4ee3\u7406 +launcher.decorated=\u542f\u7528\u7a97\u53e3\u8fb9\u6846(Linux\u4e0b\u53ef\u89e3\u51b3\u7a0b\u5e8f\u754c\u9762\u5168\u7070\u95ee\u9898) +launcher.modpack=\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9 +launcher.lang=\u8bed\u8a00 +launcher.restart=\u672c\u754c\u9762\u9009\u9879\u9700\u8981\u91cd\u542f\u672c\u542f\u52a8\u5668\u751f\u6548 + +launcher.title.game=\u6e38\u620f\u8bbe\u7f6e +launcher.title.main=\u4e3b\u9875 +launcher.title.launcher=\u542f\u52a8\u5668\u8bbe\u7f6e + +versions.release=\u7a33\u5b9a\u7248 +versions.snapshot=\u5feb\u7167\u7248 +versions.old_beta=\u6d4b\u8bd5\u7248 +versions.old_alpha=\u8fdc\u53e4\u7248 + +versions.manage.rename=\u91cd\u547d\u540d\u8be5\u7248\u672c +versions.manage.rename.message=\u8bf7\u8f93\u5165\u8981\u6539\u6210\u7684\u540d\u5b57 +versions.manage.remove=\u5220\u9664\u8be5\u7248\u672c +versions.manage.remove.confirm=\u771f\u7684\u8981\u5220\u9664\u7248\u672c +versions.manage.redownload_json=\u91cd\u65b0\u4e0b\u8f7d\u7248\u672c\u914d\u7f6e(minecraft.json) +versions.manage.redownload_assets_index=\u91cd\u65b0\u4e0b\u8f7d\u8d44\u6e90\u914d\u7f6e(assets_index.json) +versions.mamage.remove_libraries=\u5220\u9664\u6240\u6709\u5e93\u6587\u4ef6 + +advice.os64butjdk32=\u60a8\u7684\u7cfb\u7edf\u662f64\u4f4d\u7684\u4f46\u662fJava\u662f32\u4f4d\u7684\uff0c\u63a8\u8350\u60a8\u5b89\u88c564\u4f4dJava. + +assets.download_all=\u4e0b\u8f7d\u8d44\u6e90\u6587\u4ef6 +assets.not_refreshed=\u8d44\u6e90\u5217\u8868\u672a\u5237\u65b0\uff0c\u8bf7\u5237\u65b0\u4e00\u6b21\u3002 +assets.failed=\u83b7\u53d6\u5217\u8868\u5931\u8d25\uff0c\u8bf7\u5237\u65b0\u91cd\u8bd5\u3002 +assets.list.1_7_3_after=1.7.3\u53ca\u4ee5\u540e +assets.list.1_6=1.6(BMCLAPI) +assets.unkown_type_select_one=\u65e0\u6cd5\u89e3\u6790\u6e38\u620f\u7248\u672c\uff1a%s\uff0c\u8bf7\u9009\u62e9\u4e00\u79cd\u8d44\u6e90\u7c7b\u578b\u4e0b\u8f7d\u3002 +assets.type=\u8d44\u6e90\u7c7b\u578b +assets.download=\u4e0b\u8f7d\u8d44\u6e90 +assets.no_assets=\u8d44\u6e90\u6587\u4ef6\u4e0d\u5b8c\u6574\uff0c\u662f\u5426\u8865\u5168\uff1f +assets.failed_download=\u4e0b\u8f7d\u8d44\u6e90\u6587\u4ef6\u5931\u8d25\uff0c\u53ef\u80fd\u5bfc\u81f4\u6ca1\u6709\u4e2d\u6587\u548c\u58f0\u97f3\u3002 + +gamedownload.not_refreshed=\u6e38\u620f\u4e0b\u8f7d\u5217\u8868\u672a\u5237\u65b0\uff0c\u8bf7\u518d\u5237\u65b0\u4e00\u6b21\u3002 + +taskwindow.title=\u4efb\u52a1 +taskwindow.single_progress=\u5355\u9879\u8fdb\u5ea6 +taskwindow.total_progress=\u603b\u8fdb\u5ea6 +taskwindow.cancel=\u53d6\u6d88 +taskwindow.no_more_instance=\u53ef\u80fd\u540c\u65f6\u6253\u5f00\u4e86\u591a\u4e2a\u4efb\u52a1\u7a97\u53e3\uff0c\u8bf7\u4e0d\u8981\u591a\u6b21\u6253\u5f00\uff01 +taskwindow.file_name=\u4efb\u52a1 +taskwindow.download_progress=\u8fdb\u5ea6 + +setupwindow.include_minecraft=\u5bfc\u5165\u6e38\u620f\u6587\u4ef6\u5939 +setupwindow.find_in_configurations=\u5bfc\u5165\u5b8c\u6210\uff0c\u5feb\u5230\u914d\u7f6e\u4e0b\u62c9\u6846\u4e2d\u627e\u65b0\u6e38\u620f\u8def\u5f84\u5427\uff01 +setupwindow.give_a_name=\u7ed9\u65b0\u6e38\u620f\u8def\u5f84\u8d77\u4e2a\u540d\u5b57\u5427 +setupwindow.new=\u65b0\u5efa +setupwindow.no_empty_name=\u540d\u5b57\u4e0d\u53ef\u4e3a\u7a7a +setupwindow.clean=\u6e05\u7406\u6e38\u620f\u6587\u4ef6 + +update.no_browser=\u65e0\u6cd5\u6253\u5f00\u6d4f\u89c8\u5668\uff0c\u7f51\u5740\u5df2\u7ecf\u590d\u5236\u5230\u526a\u8d34\u677f\u4e86\uff0c\u60a8\u53ef\u4ee5\u624b\u52a8\u7c98\u8d34\u7f51\u5740\u6253\u5f00\u9875\u9762 +update.should_open_link=\u662f\u5426\u66f4\u65b0\uff1f +update.newest_version=\u6700\u65b0\u7248\u672c\u4e3a\uff1a +update.failed=\u68c0\u67e5\u66f4\u65b0\u5931\u8d25 +update.found=(\u53d1\u73b0\u66f4\u65b0!) + +logwindow.terminate_game=\u7ed3\u675f\u6e38\u620f\u8fdb\u7a0b +logwindow.tieba=\u8d34\u5427 +logwindow.title=\u65e5\u5fd7 + +selector.choose=\u9009\u62e9 + +serverlistview.title=\u9009\u62e9\u670d\u52a1\u5668 +serverlistview.name=\u540d\u79f0 +serverlistview.type=\u7c7b\u578b +serverlistview.version=\u7248\u672c +serverlistview.info=\u4fe1\u606f + +minecraft.invalid=\u65e0\u6548\u7684 +minecraft.invalid_jar=\u65e0\u6548\u7684jar\u5305 +minecraft.not_a_file=\u4e0d\u662f\u6587\u4ef6 +minecraft.not_found=\u627e\u4e0d\u5230minecraft.jar +minecraft.not_readable=minecraft.jar\u4e0d\u53ef\u8bfb +minecraft.modified=(\u4fee\u6539\u7684!) + +color.red=\u7ea2\u8272 +color.blue=\u84dd\u8272 +color.green=\u7eff\u8272 +color.orange=\u6a59\u8272 +color.dark_blue=\u6df1\u84dd\u8272 +color.purple=\u7d2b\u8272 + +wizard.next_>=\u4e0b\u4e00\u6b65 > +wizard.next_mnemonic=\u4e0b +wizard.<_prev=< \u4e0a\u4e00\u6b65 +wizard.prev_mnemonic=\u4e0a +wizard.finish=\u5b8c\u6210 +wizard.finish_mnemonic=\u5b8c +wizard.cancel=\u53d6\u6d88 +wizard.cancel_mnemonic=\u53d6 +wizard.help=\u5e2e\u52a9 +wizard.help_mnemonic=\u5e2e +wizard.close=\u5173\u95ed +wizard.close_mnemonic=\u5173 +wizard.summary=\u6982\u8981 +wizard.failed=\u5931\u8d25 +wizard.steps=\u6b65\u9aa4 + +lang=\u7b80\u4f53\u4e2d\u6587 +lang.default=\u8ddf\u968f\u7cfb\u7edf\u8bed\u8a00 diff --git a/README.md b/README.md index d636c0f41..49138745c 100755 --- a/README.md +++ b/README.md @@ -1,31 +1,26 @@ # Hello Minecraft! Launcher [![Build Status](https://travis-ci.org/huanghongxun/HMCL.svg?branch=master)](https://travis-ci.org/huanghongxun/HMCL) 开源协议为GPL v3, 详情参见http://www.gnu.org/licenses/gpl.html -## 介绍 +## Introduction -HMCL是一个Minecraft启动器,支持Mod管理,游戏定制,自动安装,整合包制作,界面主题定制等功能。 -并且一天的使用次数在工作日时有40万左右、节假日有150万左右的使用次数,也就是说日活跃用户在10万以上。 -但是本项目的代码不够完善,希望有更多的人能加入HMCL的开发。 +HMCL is a Minecraft launcher which supports Mod management, game customizing, auto installing(Forge, LiteLoader and OptiFine), modpack creating, UI customizing and so on. -## 贡献 -如果你很想为本项目贡献代码,这里有一些要求: -* 开发环境为Netbeans 8.1 -* 编译器为Java 1.8,通过retrolambda兼容Java 1.7,所以请不要使用Java 8的新API(如Stream) -* 请不要修改`gradle`文件 +## Contribution +If you want to submit a pull request, there're some requirements: +* IDE: Netbeans 8.1 +* Compiler: Java 1.8 and libraries only supports Java 1.7(because of retrolambda). +* Do NOT modify `gradle` files. -## 代码 -* 包 `org.jackhuang.hellominecraft.util` 为HMCL和HMCSM的共用工具代码 -* 包 `org.jackhuang.hellominecraft.launcher` 包含了HMCL的界面以及逻辑代码 -* 包 `org.jackhuang.hellominecraft.launcher.core` 为HMCL的启动核心 -* 包 `org.jackhuang.hellominecraft.launcher.api` 是HMCL为了便于定制提供的API,暂不支持加载插件 -* 包 `org.jackhuang.hellominecraft.svrmgr` 为HMCSM的所有代码 -* 文件夹 `HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang` 包含了HMCL和HMCSM使用的语言文件 +## Code +* package `org.jackhuang.hellominecraft.util`: HMCL development utilities. +* package `org.jackhuang.hellominecraft.launcher`: HMCL UI core. +* package `org.jackhuang.hellominecraft.launcher.core`: HMCL game launcher core. +* package `org.jackhuang.hellominecraft.launcher.api`: Nothing here! +* package `org.jackhuang.hellominecraft.svrmgr`: All HMCSM codes. +* Folder `HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang` contains language files. -由于包树已经相当清晰,因此不再赘述各包各类的用途。 - -## 注意事项 -* 包 `org.jackhuang.hellominecraft.util.logging` 包含了经过精简的Apache License 2.0的Log4j项目的代码 -* 包 `com.google.gson` 为Google Gson项目Apache License 2.0的代码 -* 包 `org.jackhuang.hellominecraft.lookandfeel.ui` 包含了Sun Microsystems的NimbusLookAndFeel项目的部分LGPL代码 -* 所有Pull Request提交的代码均会被重写 -* 本项目的开源协议是GPL v3,因此包含LGPL和Apache License 2.0的代码是没有法律问题的 +## Pay Attention +* When you do decide to modify this app, please and you MUST delete `org.jackhuang.hellominecraft.launcher.util.CrashReporter`, or errors your code cause will be sent to my server. +* package `org.jackhuang.hellominecraft.util.logging`: repackaged Apache Log4j, Apache License 2.0. +* package `com.google.gson`: Apache License 2.0 +* package `org.jackhuang.hellominecraft.lookandfeel.ui`: contains some NimbusLAF's code belonging to Sun Microsystems under LGPL. \ No newline at end of file