Compare commits

...
27 Commits
26 ... 50
Author SHA1 Message Date
huangyuhui 62fecc08ac Fixed #65 2016-05-08 10:04:23 +08:00
huangyuhui 491ca63342 Merge branch 'master' of https://github.com/huanghongxun/HMCL 2016-05-08 09:42:00 +08:00
huangyuhui b232a255e7 Fixed #66 2016-05-08 09:41:27 +08:00
huanghongxun 0870f42557 Merge pull request #64 from Cat7373/master
在 Windows 的启动脚本里增加一行 cd %appdata%
2016-05-03 19:12:59 +08:00
Cat73 85237eac7e 在 Windows 的启动脚本里增加一行 cd %appdata%
这样可以避免一些文件如 logs 生成在脚本所在目录,而不是 .minecraft 目录
2016-05-03 09:41:55 +08:00
huangyuhui 8d5088d2e4 Removed findbugs 2016-04-25 23:28:29 +08:00
huangyuhui 47f5bf1ea5 Added an options to disable online game complete check 2016-04-25 23:09:56 +08:00
huangyuhui deebadef3a Fixed #61 2016-04-11 13:40:06 +08:00
huangyuhui ce24ae4fae Fixed #60 2016-04-06 19:41:33 +08:00
huangyuhui 16152de39d Fixed ClassCastException 2016-04-05 22:16:29 +08:00
huangyuhui 4a2ac63d25 Added removal of installers for Issue #55 2016-03-28 20:57:01 +08:00
huangyuhui 5437968c83 Fixed #56 2016-03-28 20:45:06 +08:00
huangyuhui 8022252452 Fixed task system 2016-03-27 14:13:59 +08:00
huangyuhui ea6571fdb6 Fix #53 2016-03-26 13:02:47 +08:00
huanghongxun 2f7f692b84 Merge pull request #51 from tsl0922/master
Fix cpu ratio for mac
2016-03-25 19:19:46 +08:00
Shuanglei Tao 721df1d17c Fix cpu ratio for mac 2016-03-24 21:29:48 +08:00
huangyuhui 7a2e43f949 Fixed #50 2016-03-19 19:55:42 +08:00
huangyuhui 4e5cc3dadb sponsor 2016-03-17 18:38:17 +08:00
huangyuhui f6d5dd5a82 Fixed NullPointerException when a version not exists. 2016-03-15 18:49:31 +08:00
huangyuhui cafcf458b8 Fixed auto-loading when deleting a profile 2016-03-12 11:57:30 +08:00
huangyuhui e7d0624b96 Added default profile: Home whose default game directory is $USER/.minecraft 2016-03-11 23:05:31 +08:00
huangyuhui 156de2457d Fixed wrong path in modpack zip on Linux/Mac 2016-03-11 20:13:10 +08:00
huangyuhui c839d045cc Might fix some problems 2016-03-09 13:14:53 +08:00
huangyuhui 2eaf32b23d Fixed BMCLAPI 2016-03-06 14:45:42 +08:00
huangyuhui 5899c73ab8 Should fixed #46 2016-03-05 21:43:54 +08:00
huangyuhui 6c0a446692 Fixed: Cannot cancel modpack installing 2016-03-05 14:31:32 +08:00
huangyuhui 7c2cfc171e Switch to CountDownLatch 2016-03-05 13:23:16 +08:00
76 changed files with 1028 additions and 994 deletions

No files matched your search

@@ -20,7 +20,6 @@ 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.IOUtils;
import org.jackhuang.hellominecraft.util.system.OS;
/**
@@ -63,14 +62,11 @@ public final class MCUtils {
}
public static File getInitGameDir() {
File gameDir = IOUtils.currentDir();
if (gameDir.exists()) {
gameDir = new File(gameDir, MCUtils.minecraft());
if (!gameDir.exists()) {
File newFile = MCUtils.getLocation();
if (newFile.exists())
gameDir = newFile;
}
File gameDir = new File(MCUtils.minecraft());
if (!gameDir.exists()) {
File newFile = MCUtils.getLocation();
if (newFile.exists())
gameDir = newFile;
}
return gameDir;
}
@@ -80,6 +76,6 @@ public final class MCUtils {
public static void tryWriteProfile(File gameDir) throws IOException {
File file = new File(gameDir, "launcher_profiles.json");
if (!file.exists())
FileUtils.writeStringToFile(file, PROFILE);
FileUtils.write(file, PROFILE);
}
}
@@ -32,6 +32,7 @@ import org.jackhuang.hellominecraft.util.system.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;
@@ -47,8 +48,7 @@ public class AssetsMojangLoader extends IAssetsHandler {
@Override
public Task getList(final MinecraftVersion mv, final IMinecraftAssetService mp) {
if (mv == null)
throw new IllegalArgumentException("AssetsMojangLoader: null argument: MinecraftVersion");
Utils.requireNonNull(mv);
String assetsId = mv.getAssetsIndex().getId();
File assets = mp.getAssets();
HMCLog.log("Gathering asset index: " + assetsId);
@@ -66,7 +66,7 @@ public class AssetsMojangLoader extends IAssetsHandler {
public void executeTask() throws Throwable {
if (!areDependTasksSucceeded)
throw new IllegalStateException("Failed to get asset index");
String result = FileUtils.readFileToString(f);
String result = FileUtils.read(f);
if (StrUtils.isBlank(result))
throw new IllegalStateException("Index json is empty, please redownload it!");
AssetsIndex o = C.GSON.fromJson(result, AssetsIndex.class);
@@ -22,7 +22,6 @@ import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
@@ -30,7 +29,7 @@ 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.Function;
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;
@@ -55,23 +54,9 @@ public class MinecraftAssetService extends IMinecraftAssetService {
}
public Task downloadAssets(final MinecraftVersion mv) {
return new TaskInfo("Download Assets") {
Collection<Task> afters = new HashSet<>();
@Override
public Collection<Task> getDependTasks() {
return Arrays.asList(IAssetsHandler.ASSETS_HANDLER.getList(mv, service.asset()));
}
@Override
public void executeTask() {
}
@Override
public Collection<Task> getAfterTasks() {
return Arrays.asList(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider()));
}
};
if (mv == null)
return null;
return IAssetsHandler.ASSETS_HANDLER.getList(mv, service.asset()).after(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider()));
}
@Override
@@ -148,7 +133,7 @@ public class MinecraftAssetService extends IMinecraftAssetService {
File objectsDir = new File(assetsDir, "objects");
File indexFile = new File(indexDir, assetVersion + ".json");
try {
AssetsIndex index = (AssetsIndex) C.GSON.fromJson(FileUtils.readFileToString(indexFile, "UTF-8"), AssetsIndex.class);
AssetsIndex index = (AssetsIndex) C.GSON.fromJson(FileUtils.read(indexFile, "UTF-8"), AssetsIndex.class);
String hash = ((AssetsObject) index.getFileMap().get(name)).getHash();
return new File(objectsDir, hash.substring(0, 2) + "/" + hash);
@@ -167,7 +152,7 @@ public class MinecraftAssetService extends IMinecraftAssetService {
return false;
try {
String assetIndexContent = FileUtils.readFileToString(indexFile, "UTF-8");
String assetIndexContent = FileUtils.read(indexFile, "UTF-8");
AssetsIndex index = (AssetsIndex) C.GSON.fromJson(assetIndexContent, AssetsIndex.class);
if (index == null)
@@ -195,7 +180,7 @@ public class MinecraftAssetService extends IMinecraftAssetService {
}
try {
String assetIndexContent = FileUtils.readFileToString(indexFile, "UTF-8");
String assetIndexContent = FileUtils.read(indexFile, "UTF-8");
AssetsIndex index = (AssetsIndex) C.GSON.fromJson(assetIndexContent, AssetsIndex.class);
if (index == null)
@@ -210,7 +195,7 @@ public class MinecraftAssetService extends IMinecraftAssetService {
if (original.exists()) {
cnt++;
if (!target.isFile())
FileUtils.copyFile(original, target, false);
FileUtils.copyFile(original, target);
}
}
// If the scale new format existent file is lower then 0.1, use the old format.
@@ -224,8 +209,8 @@ public class MinecraftAssetService extends IMinecraftAssetService {
return virtualRoot;
}
public final Function<MinecraftVersion, String> ASSET_PROVIDER_IMPL = t -> {
if (!checkAssetsExistance(t.getAssetsIndex()))
public final BiFunction<MinecraftVersion, Boolean, String> 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));
return reconstructAssets(t.getAssetsIndex()).getAbsolutePath();
@@ -96,7 +96,8 @@ public abstract class IAuthenticator {
public void onLoadSettings(Map m) {
if (m == null)
return;
username = (String) m.get("IAuthenticator_UserName");
Object o = m.get("IAuthenticator_UserName");
username = o instanceof String ? (String) o : "";
}
public String getUserName() {
@@ -57,7 +57,7 @@ public class BMCLAPIDownloadProvider extends IDownloadProvider {
@Override
public String getVersionsListDownloadURL() {
return "http://bmclapi2.bangbang93.com/versions/versions.json";
return "http://bmclapi2.bangbang93.com/mc/game/version_manifest.json";
}
@Override
@@ -66,13 +66,17 @@ public class BMCLAPIDownloadProvider extends IDownloadProvider {
}
@Override
public String getParsedLibraryDownloadURL(String str) {
return str == null ? null : str.replace("http://files.minecraftforge.net/maven", "http://bmclapi2.bangbang93.com/maven");
public String getParsedDownloadURL(String str) {
return str == null ? null
: 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");
}
@Override
public boolean isAllowedToUseSelfURL() {
return false;
return true;
}
}
@@ -24,8 +24,8 @@ package org.jackhuang.hellominecraft.launcher.core.download;
public class CurseDownloadProvider extends MojangDownloadProvider {
@Override
public String getParsedLibraryDownloadURL(String str) {
return str == null ? null : str.replace("http://files.minecraftforge.net/maven", "http://ftb.cursecdn.com/FTB2/maven/");
public String getParsedDownloadURL(String str) {
return str == null ? null : str.replace("http://files.minecraftforge.net/maven", "http://ftb.cursecdn.com/FTB2/maven");
}
}
@@ -55,7 +55,15 @@ public abstract class IDownloadProvider {
public abstract String getAssetsDownloadURL();
public abstract String getParsedLibraryDownloadURL(String str);
/**
* For example, minecraft.json/assetIndex/url or
* minecraft.json/downloads/client/url
*
* @param str baseURL
*
* @return parsedURL
*/
public abstract String getParsedDownloadURL(String str);
public abstract boolean isAllowedToUseSelfURL();
}
@@ -21,6 +21,7 @@ import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftDownloadServ
import com.google.gson.JsonSyntaxException;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@@ -31,11 +32,9 @@ 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.TaskWindow;
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
import org.jackhuang.hellominecraft.util.func.Function;
import org.jackhuang.hellominecraft.util.system.FileUtils;
import org.jackhuang.hellominecraft.util.tasks.DoingDoneListener;
import org.jackhuang.hellominecraft.util.tasks.Task;
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
@@ -55,74 +54,46 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
if (mv == null)
return downloadLibraries;
MinecraftVersion v = mv.resolve(service.version());
if (v.libraries != null)
for (IMinecraftLibrary l : v.libraries)
if (l.allow()) {
File ff = l.getFilePath(service.baseDirectory());
if (!ff.exists()) {
String libURL = service.getDownloadType().getProvider().getParsedLibraryDownloadURL(l.getDownloadInfo().getUrl(service.getDownloadType()));
if (libURL != null)
downloadLibraries.add(new DownloadLibraryJob(l, libURL, ff));
}
for (IMinecraftLibrary l : v.getLibraries())
if (l != null && l.allow() && l.getDownloadInfo() != null) {
File ff = l.getFilePath(service.baseDirectory());
if (!ff.exists()) {
String libURL = l.getDownloadInfo().getUrl(service.getDownloadType());
if (libURL != null)
downloadLibraries.add(new DownloadLibraryJob(l, libURL, ff));
}
}
return downloadLibraries;
}
@Override
public Task downloadMinecraft(String id) {
return new TaskInfo("Download Minecraft") {
@Override
public Collection<Task> getDependTasks() {
return Arrays.asList(downloadMinecraftVersionJson(id));
}
@Override
public void executeTask() throws Throwable {
List<MinecraftRemoteVersion> versions = MinecraftRemoteVersions.getRemoteVersions(service.getDownloadType()).justDo();
MinecraftRemoteVersion currentVersion = null;
for (MinecraftRemoteVersion v : versions)
if (id.equals(v.id)) {
currentVersion = v;
break;
}
if (currentVersion == null)
throw new RuntimeException("Cannot find version: " + id + " in remote repository.");
String jsonURL = currentVersion.getUrl(service.getDownloadType());
File vpath = new File(service.baseDirectory(), "versions/" + id);
File mvt = new File(vpath, id + ".json");
if (!areDependTasksSucceeded) {
FileUtils.deleteDirectory(vpath);
throw new RuntimeException("Cannot continue because of download failing.");
}
File mvj = new File(vpath, id + ".jar");
if (!vpath.exists() && !vpath.mkdirs())
HMCLog.warn("Failed to make directories: " + vpath);
if (mvt.exists() && !mvt.delete())
HMCLog.warn("Failed to delete " + mvt);
if (mvj.exists() && !mvj.delete())
HMCLog.warn("Failed to delete " + mvj);
try {
MinecraftVersion mv = C.GSON.fromJson(FileUtils.readQuietly(new File(vpath, id + ".json")), MinecraftVersion.class);
if (mv == null)
throw new JsonSyntaxException("incorrect version");
Task t = new FileDownloadTask(jsonURL, mvt).setTag(id + ".json");
t.addTaskListener(new DoingDoneListener<Task>() {
@Override
public void onDone(Task k, Collection<Task> taskCollection) {
MinecraftVersion mv;
try {
mv = C.GSON.fromJson(FileUtils.readFileToStringQuietly(mvt), MinecraftVersion.class);
if (mv == null)
throw new JsonSyntaxException("incorrect version");
} catch (JsonSyntaxException ex) {
HMCLog.err("Failed to parse minecraft version json.", ex);
onFailed(k);
return;
}
GameDownloadInfo i = mv.getClientDownloadInfo();
taskCollection.add(new FileDownloadTask(i.getUrl(service.getDownloadType()), mvj, i.sha1)
.setFailedCallbackReturnsNewURL(new DownloadTypeSwitcher(id + "/" + id + ".jar")).setTag(id + ".jar"));
}
@Override
public void onDoing(Task k, Collection<Task> taskCollection) {
}
@Override
public void onFailed(Task k) {
FileUtils.deleteDirectoryQuietly(vpath);
}
});
afters.add(t);
afters.add(downloadMinecraftJar(mv, mvj));
} catch (JsonSyntaxException ex) {
HMCLog.err("Failed to parse minecraft version json.", ex);
FileUtils.deleteDirectory(vpath);
}
}
Collection<Task> afters = new HashSet<>();
@@ -134,34 +105,6 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
};
}
@Override
public boolean downloadMinecraftJar(String id) {
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
File vpath = new File(service.baseDirectory(), "versions/" + id);
File mvv = new File(vpath, id + ".jar"), moved = null;
if (mvv.exists()) {
moved = new File(vpath, id + "-renamed.jar");
if (!mvv.renameTo(moved))
HMCLog.warn("Failed to rename " + mvv + " to " + moved);
}
File mvt = new File(vpath, id + ".jar");
if (!vpath.exists() && !vpath.mkdirs())
HMCLog.warn("Failed to make version folder " + vpath);
if (TaskWindow.factory()
.append(new FileDownloadTask(vurl + id + ".jar", mvt).setFailedCallbackReturnsNewURL(new DownloadTypeSwitcher(id + "/" + id + ".jar")).setTag(id + ".jar"))
.create()) {
if (moved != null && moved.exists() && !moved.delete())
HMCLog.warn("Failed to delete " + moved);
return true;
} else {
if (mvt.exists() && !mvt.delete())
HMCLog.warn("Failed to delete game jar " + mvt);
if (moved != null && moved.exists() && !moved.renameTo(mvt))
HMCLog.warn("Failed to rename " + moved + " to " + mvt);
return false;
}
}
private static class DownloadTypeSwitcher implements Function<Integer, String> {
String suffix;
@@ -178,37 +121,43 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
}
@Override
public Task downloadMinecraftJarTo(MinecraftVersion mv, File mvt) {
String jar = mv.jar == null ? mv.id : mv.jar;
public Task downloadMinecraftJar(MinecraftVersion mv, File mvj) {
GameDownloadInfo i = mv.getClientDownloadInfo();
return new FileDownloadTask(i.getUrl(service.getDownloadType(), true), mvt, i.sha1).setTag(jar + ".jar");
return new FileDownloadTask(i.getUrl(service.getDownloadType()), mvj, i.sha1)
.setFailedCallbackReturnsNewURL(new DownloadTypeSwitcher(mv.id + "/" + mv.id + ".jar")).setTag(mv.id + ".jar");
}
@Override
public boolean downloadMinecraftVersionJson(String id) {
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
File vpath = new File(service.baseDirectory(), "versions/" + id);
File mvv = new File(vpath, id + ".json"), moved = null;
if (mvv.exists()) {
moved = new File(vpath, id + "-renamed.json");
if (!mvv.renameTo(moved))
HMCLog.warn("Failed to rename " + mvv + " to " + moved);
}
File mvt = new File(vpath, id + ".json");
if (!vpath.exists() && !vpath.mkdirs())
HMCLog.warn("Failed to make version folder " + vpath);
if (TaskWindow.factory()
.append(new FileDownloadTask(vurl + id + ".json", mvt).setTag(id + ".json"))
.create()) {
if (moved != null && moved.exists() && !moved.delete())
HMCLog.warn("Failed to delete " + moved);
return true;
} else {
if (mvt.exists() && !mvt.delete())
HMCLog.warn("Failed to delete minecraft version json" + mvt);
if (moved != null && moved.exists() && !moved.renameTo(mvt))
HMCLog.warn("Failed to rename " + moved + " to " + mvt);
return false;
}
public Task downloadMinecraftVersionJson(String id) {
return new TaskInfo("Download Minecraft Json") {
@Override
public void executeTask() throws Throwable {
List<MinecraftRemoteVersion> versions = MinecraftRemoteVersions.getRemoteVersions(service.getDownloadType()).justDo();
MinecraftRemoteVersion currentVersion = null;
for (MinecraftRemoteVersion v : versions)
if (id.equals(v.id)) {
currentVersion = v;
break;
}
if (currentVersion == null)
throw new RuntimeException("Cannot find version: " + id + " in remote repository.");
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())
HMCLog.warn("Failed to make directories: " + vpath);
if (mvt.exists() && !mvt.delete())
HMCLog.warn("Failed to delete " + mvt);
afters.add(new FileDownloadTask(jsonURL, mvt).setTag(id + ".json"));
}
Collection<Task> afters = new HashSet<>();
@Override
public Collection<Task> getAfterTasks() {
return afters;
}
};
}
}
@@ -29,6 +29,6 @@ public class MinecraftRemoteVersion {
public String getUrl(DownloadType type) {
if (url == null)
return type.getProvider().getVersionsDownloadURL() + id + "/" + id + ".json";
return url;
return type.getProvider().getParsedDownloadURL(url);
}
}
@@ -64,7 +64,7 @@ public class MojangDownloadProvider extends IDownloadProvider {
@Override
public String getAssetsDownloadURL() {
return "http://resources.download.minecraft.net/";
return "https://resources.download.minecraft.net/";
}
@Override
@@ -73,7 +73,7 @@ public class MojangDownloadProvider extends IDownloadProvider {
}
@Override
public String getParsedLibraryDownloadURL(String str) {
public String getParsedDownloadURL(String str) {
if (str == null)
return null;
else if (str.contains("scala-swing") || str.contains("scala-xml") || str.contains("scala-parser-combinators"))
@@ -86,5 +86,4 @@ public class MojangDownloadProvider extends IDownloadProvider {
else
return str;
}
}
@@ -49,7 +49,7 @@ public class RapidDataDownloadProvider extends MojangDownloadProvider {
}
@Override
public String getParsedLibraryDownloadURL(String str) {
public String getParsedDownloadURL(String str) {
return str == null ? null : str.replace("http://files.minecraftforge.net/maven", "http://mirrors.rapiddata.org/forge/maven");
}
@@ -22,13 +22,13 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.tasks.Task;
/**
*
* @author huangyuhui
*/
public abstract class InstallerVersionList implements Consumer<String[]> {
public abstract class InstallerVersionList {
/**
* Refresh installer versions list from the downloaded content.
@@ -37,7 +37,7 @@ public abstract class InstallerVersionList implements Consumer<String[]> {
*
* @throws java.lang.Exception including network exceptions, IO exceptions.
*/
public abstract void refreshList(String[] versions) throws Exception;
public abstract Task refresh(String[] versions);
/**
* Installer name.
@@ -117,13 +117,4 @@ public abstract class InstallerVersionList implements Consumer<String[]> {
return o2.compareTo(o1);
}
}
@Override
public void accept(String[] v) {
try {
refreshList(v);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
@@ -27,10 +27,9 @@ import org.jackhuang.hellominecraft.launcher.core.install.liteloader.LiteLoaderV
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.TaskInfo;
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
import org.jackhuang.hellominecraft.util.system.IOUtils;
import org.jackhuang.hellominecraft.util.tasks.DeleteFileTask;
/**
*
@@ -58,47 +57,31 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
@Override
public Task downloadForge(String installId, InstallerVersion v) {
return new TaskInfo("Forge Downloader") {
@Override
public void executeTask() {
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "forge-installer.jar");
if (v.installer != null)
TaskWindow.factory()
.append(new FileDownloadTask(service.getDownloadType().getProvider().getParsedLibraryDownloadURL(v.installer), filepath).setTag("forge"))
.append(new ForgeInstaller(service, filepath))
.create();
}
};
File filepath = IOUtils.tryGetCanonicalFile("forge-installer.jar");
if (v.installer == null)
return null;
else
return new FileDownloadTask(service.getDownloadType().getProvider().getParsedDownloadURL(v.installer), filepath).setTag("forge")
.after(new ForgeInstaller(service, filepath))
.after(new DeleteFileTask(filepath));
}
@Override
public Task downloadOptiFine(String installId, InstallerVersion v) {
return new TaskInfo("OptiFine Downloader") {
@Override
public void executeTask() {
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "optifine-installer.jar");
if (v.installer != null) {
OptiFineDownloadFormatter task = new OptiFineDownloadFormatter(v.installer);
TaskWindow.factory().append(task)
.append(new FileDownloadTask(filepath).registerPreviousResult(task).setTag("optifine"))
.append(new OptiFineInstaller(service, installId, v, filepath))
.create();
}
}
};
File filepath = IOUtils.tryGetCanonicalFile("optifine-installer.jar");
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));
}
@Override
public Task downloadLiteLoader(String installId, InstallerVersion v) {
return new TaskInfo("LiteLoader Downloader") {
@Override
public void executeTask() {
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "liteloader-universal.jar");
FileDownloadTask task = (FileDownloadTask) new FileDownloadTask(v.universal, filepath).setTag("LiteLoader");
TaskWindow.factory()
.append(task).append(new LiteLoaderInstaller(service, installId, (LiteLoaderVersionList.LiteLoaderInstallerVersion) v).registerPreviousResult(task))
.create();
}
};
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));
}
}
@@ -23,7 +23,6 @@ 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;
import org.jackhuang.hellominecraft.util.system.IOUtils;
/**
*
@@ -40,7 +39,7 @@ public class PackMinecraftInstaller {
}
public void install() throws IOException {
File file = new File(IOUtils.currentDir(), "HMCL-MERGE-TEMP");
File file = new File("HMCL-MERGE-TEMP");
if (!file.exists() && !file.mkdirs())
HMCLog.warn("Failed to make directories: " + file);
for (String src1 : src)
@@ -18,6 +18,8 @@
package org.jackhuang.hellominecraft.launcher.core.install.forge;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -27,7 +29,9 @@ 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.NetUtils;
import org.jackhuang.hellominecraft.util.tasks.Task;
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
import org.jackhuang.hellominecraft.util.tasks.download.HTTPGetTask;
/**
*
@@ -48,54 +52,68 @@ public class MinecraftForgeVersionList extends InstallerVersionList {
public List<InstallerVersion> versions;
@Override
public void refreshList(String[] needed) throws Exception {
public Task refresh(String[] needed) {
if (root != null)
return;
String s = NetUtils.get(DownloadType.getSuggestedDownloadType().getProvider().getParsedLibraryDownloadURL(C.URL_FORGE_LIST));
return null;
return new TaskInfo(C.i18n("install.forge.get_list")) {
HTTPGetTask task = new HTTPGetTask(DownloadType.getSuggestedDownloadType().getProvider().getParsedDownloadURL(C.URL_FORGE_LIST));
root = C.GSON.fromJson(s, MinecraftForgeVersionRoot.class);
versionMap = new HashMap<>();
versions = new ArrayList<>();
for (Map.Entry<String, int[]> arr : root.mcversion.entrySet()) {
String mcver = StrUtils.formatVersion(arr.getKey());
ArrayList<InstallerVersion> al = new ArrayList<>();
for (int num : arr.getValue()) {
MinecraftForgeVersion v = root.number.get(num);
InstallerVersion iv = new InstallerVersion(v.version, StrUtils.formatVersion(v.mcversion));
for (String[] f : v.files) {
String ver = v.mcversion + "-" + v.version;
if (!StrUtils.isBlank(v.branch))
ver = ver + "-" + v.branch;
String filename = root.artifact + "-" + ver + "-" + f[1] + "." + f[0];
String url = DownloadType.getSuggestedDownloadType().getProvider().getParsedLibraryDownloadURL(root.webpath + ver + "/" + filename);
switch (f[1]) {
case "installer":
iv.installer = url;
break;
case "universal":
iv.universal = url;
break;
case "changelog":
iv.changelog = url;
break;
default:
break;
}
}
if (StrUtils.isBlank(iv.installer) || StrUtils.isBlank(iv.universal))
continue;
Collections.sort(al, new InstallerVersionNewerComparator());
al.add(iv);
versions.add(iv);
@Override
public Collection<Task> getDependTasks() {
return Arrays.asList(task);
}
versionMap.put(StrUtils.formatVersion(mcver), al);
}
@Override
public void executeTask() throws Throwable {
if (!areDependTasksSucceeded)
return;
String s = task.getResult();
Collections.sort(versions, new InstallerVersionComparator());
root = C.GSON.fromJson(s, MinecraftForgeVersionRoot.class);
versionMap = new HashMap<>();
versions = new ArrayList<>();
for (Map.Entry<String, int[]> arr : root.mcversion.entrySet()) {
String mcver = StrUtils.formatVersion(arr.getKey());
ArrayList<InstallerVersion> al = new ArrayList<>();
for (int num : arr.getValue()) {
MinecraftForgeVersion v = root.number.get(num);
InstallerVersion iv = new InstallerVersion(v.version, StrUtils.formatVersion(v.mcversion));
for (String[] f : v.files) {
String ver = v.mcversion + "-" + v.version;
if (!StrUtils.isBlank(v.branch))
ver = ver + "-" + v.branch;
String filename = root.artifact + "-" + ver + "-" + f[1] + "." + f[0];
String url = DownloadType.getSuggestedDownloadType().getProvider().getParsedDownloadURL(root.webpath + ver + "/" + filename);
switch (f[1]) {
case "installer":
iv.installer = url;
break;
case "universal":
iv.universal = url;
break;
case "changelog":
iv.changelog = url;
break;
default:
break;
}
}
if (StrUtils.isBlank(iv.installer) || StrUtils.isBlank(iv.universal))
continue;
Collections.sort(al, new InstallerVersionNewerComparator());
al.add(iv);
versions.add(iv);
}
versionMap.put(StrUtils.formatVersion(mcver), al);
}
Collections.sort(versions, new InstallerVersionComparator());
}
};
}
@Override
@@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.launcher.core.install.liteloader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -28,8 +29,10 @@ 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.NetUtils;
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;
/**
*
@@ -50,38 +53,52 @@ public class LiteLoaderVersionList extends InstallerVersionList {
public List<InstallerVersion> versions;
@Override
public void refreshList(String[] needed) throws Exception {
String s = NetUtils.get(C.URL_LITELOADER_LIST);
public Task refresh(String[] needed) {
if (root != null)
return;
return null;
return new TaskInfo(C.i18n("install.liteloader.get_list")) {
HTTPGetTask task = new HTTPGetTask(C.URL_LITELOADER_LIST);
root = C.GSON.fromJson(s, LiteLoaderVersionsRoot.class);
versionMap = new HashMap<>();
versions = new ArrayList<>();
for (Map.Entry<String, LiteLoaderMCVersions> arr : root.versions.entrySet()) {
ArrayList<InstallerVersion> al = new ArrayList<>();
LiteLoaderMCVersions mcv = arr.getValue();
if (mcv == null || mcv.artefacts == null || mcv.artefacts.get("com.mumfrey:liteloader") == null)
continue;
for (Map.Entry<String, LiteLoaderVersion> entry : mcv.artefacts.get("com.mumfrey:liteloader").entrySet()) {
if ("latest".equals(entry.getKey()))
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.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";
al.add(iv);
versions.add(iv);
@Override
public Collection<Task> getDependTasks() {
return Arrays.asList(task);
}
Collections.sort(al, new InstallerVersionNewerComparator());
versionMap.put(StrUtils.formatVersion(arr.getKey()), al);
}
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
@Override
public void executeTask() throws Throwable {
if (!areDependTasksSucceeded)
return;
String s = task.getResult();
root = C.GSON.fromJson(s, LiteLoaderVersionsRoot.class);
versionMap = new HashMap<>();
versions = new ArrayList<>();
for (Map.Entry<String, LiteLoaderMCVersions> arr : root.versions.entrySet()) {
ArrayList<InstallerVersion> al = new ArrayList<>();
LiteLoaderMCVersions mcv = arr.getValue();
if (mcv == null || mcv.artefacts == null || mcv.artefacts.get("com.mumfrey:liteloader") == null)
continue;
for (Map.Entry<String, LiteLoaderVersion> entry : mcv.artefacts.get("com.mumfrey:liteloader").entrySet()) {
if ("latest".equals(entry.getKey()))
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.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";
al.add(iv);
versions.add(iv);
}
Collections.sort(al, new InstallerVersionNewerComparator());
versionMap.put(StrUtils.formatVersion(arr.getKey()), al);
}
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
}
};
}
@Override
@@ -79,7 +79,7 @@ public class OptiFineInstaller extends Task implements PreviousResultRegistrar<F
if (!loc.exists() && loc.mkdirs())
HMCLog.warn("Failed to make directories: " + loc);
File json = new File(loc, mv.id + ".json");
FileUtils.writeStringToFile(json, C.GSON.toJson(mv, MinecraftVersion.class));
FileUtils.write(json, C.GSON.toJson(mv, MinecraftVersion.class));
service.version().refreshVersions();
}
@@ -20,6 +20,8 @@ package org.jackhuang.hellominecraft.launcher.core.install.optifine.bmcl;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -30,8 +32,10 @@ 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.NetUtils;
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;
/**
*
@@ -55,34 +59,46 @@ public class OptiFineBMCLVersionList extends InstallerVersionList {
}.getType();
@Override
public void refreshList(String[] needed) throws Exception {
String s = NetUtils.get("http://bmclapi.bangbang93.com/optifine/versionlist");
public Task refresh(String[] needed) {
return new TaskInfo(C.i18n("install.optifine.get_list")) {
HTTPGetTask task = new HTTPGetTask("http://bmclapi.bangbang93.com/optifine/versionlist");
versionMap = new HashMap<>();
versions = new ArrayList<>();
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));
@Override
public Collection<Task> getDependTasks() {
return Arrays.asList(task);
}
InstallerVersion iv = new InstallerVersion(v.getVersion(), StrUtils.formatVersion(v.getMCVersion()));
List<InstallerVersion> 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);
}
@Override
public void executeTask() throws Throwable {
String s = task.getResult();
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
versionMap = new HashMap<>();
versions = new ArrayList<>();
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));
}
InstallerVersion iv = new InstallerVersion(v.getVersion(), StrUtils.formatVersion(v.getMCVersion()));
List<InstallerVersion> 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);
}
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
}
};
}
@Override
@@ -20,6 +20,8 @@ package org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -32,8 +34,11 @@ import javax.xml.parsers.ParserConfigurationException;
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
import org.jackhuang.hellominecraft.launcher.core.install.optifine.OptiFineVersion;
import org.jackhuang.hellominecraft.util.ArrayUtils;
import org.jackhuang.hellominecraft.util.NetUtils;
import org.jackhuang.hellominecraft.util.C;
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.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -59,60 +64,74 @@ public class OptiFineVersionList extends InstallerVersionList {
public List<InstallerVersion> versions;
@Override
public void refreshList(String[] sss) throws Exception {
String content = NetUtils.get("http://optifine.net/downloads");
public Task refresh(String[] sss) {
if (versions != null)
return;
versionMap = new HashMap<>();
versions = new ArrayList<>();
return null;
return new TaskInfo(C.i18n("install.optifine.get_list")) {
HTTPGetTask task = new HTTPGetTask("http://optifine.net/downloads");
content = content.replace("&nbsp;", " ").replace("&gt;", ">").replace("&lt;", "<").replace("<br>", "<br />");
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = factory.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(content.getBytes("UTF-8")));
Element r = doc.getDocumentElement();
NodeList tables = r.getElementsByTagName("table");
for (int i = 0; i < tables.getLength(); i++) {
Element e = (Element) tables.item(i);
if ("downloadTable".equals(e.getAttribute("class"))) {
NodeList tr = e.getElementsByTagName("tr");
for (int k = 0; k < tr.getLength(); k++) {
NodeList downloadLine = ((Element) tr.item(k)).getElementsByTagName("td");
OptiFineVersion v = new OptiFineVersion();
for (int j = 0; j < downloadLine.getLength(); j++) {
Element td = (Element) downloadLine.item(j);
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineMirror"))
v.setMirror(((Element) td.getElementsByTagName("a").item(0)).getAttribute("href"));
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineDownload"))
v.setDownloadLink(((Element) td.getElementsByTagName("a").item(0)).getAttribute("href"));
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineDate"))
v.setDate(td.getTextContent());
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineFile"))
v.setVersion(td.getTextContent());
}
if (StrUtils.isBlank(v.getMCVersion())) {
Pattern p = Pattern.compile("OptiFine (.*?) ");
Matcher m = p.matcher(v.getVersion());
while (m.find())
v.setMCVersion(StrUtils.formatVersion(m.group(1)));
}
InstallerVersion iv = new InstallerVersion(v.getVersion(), StrUtils.formatVersion(v.getMCVersion()));
iv.installer = iv.universal = v.getMirror();
root.add(v);
versions.add(iv);
List<InstallerVersion> ivl = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.getMCVersion()));
ivl.add(iv);
}
}
@Override
public Collection<Task> getDependTasks() {
return Arrays.asList(task);
}
} catch (ParserConfigurationException | SAXException | IOException | DOMException ex) {
throw new RuntimeException(ex);
}
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
@Override
public void executeTask() throws Throwable {
if (!areDependTasksSucceeded)
return;
String content = task.getResult();
versionMap = new HashMap<>();
versions = new ArrayList<>();
content = content.replace("&nbsp;", " ").replace("&gt;", ">").replace("&lt;", "<").replace("<br>", "<br />");
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = factory.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(content.getBytes("UTF-8")));
Element r = doc.getDocumentElement();
NodeList tables = r.getElementsByTagName("table");
for (int i = 0; i < tables.getLength(); i++) {
Element e = (Element) tables.item(i);
if ("downloadTable".equals(e.getAttribute("class"))) {
NodeList tr = e.getElementsByTagName("tr");
for (int k = 0; k < tr.getLength(); k++) {
NodeList downloadLine = ((Element) tr.item(k)).getElementsByTagName("td");
OptiFineVersion v = new OptiFineVersion();
for (int j = 0; j < downloadLine.getLength(); j++) {
Element td = (Element) downloadLine.item(j);
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineMirror"))
v.setMirror(((Element) td.getElementsByTagName("a").item(0)).getAttribute("href"));
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineDownload"))
v.setDownloadLink(((Element) td.getElementsByTagName("a").item(0)).getAttribute("href"));
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineDate"))
v.setDate(td.getTextContent());
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineFile"))
v.setVersion(td.getTextContent());
}
if (StrUtils.isBlank(v.getMCVersion())) {
Pattern p = Pattern.compile("OptiFine (.*?) ");
Matcher m = p.matcher(v.getVersion());
while (m.find())
v.setMCVersion(StrUtils.formatVersion(m.group(1)));
}
InstallerVersion iv = new InstallerVersion(v.getVersion(), StrUtils.formatVersion(v.getMCVersion()));
iv.installer = iv.universal = v.getMirror();
root.add(v);
versions.add(iv);
List<InstallerVersion> ivl = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.getMCVersion()));
ivl.add(iv);
}
}
}
} catch (ParserConfigurationException | SAXException | IOException | DOMException ex) {
throw new RuntimeException(ex);
}
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
}
};
}
@Override
@@ -29,7 +29,6 @@ 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.StrUtils;
import org.jackhuang.hellominecraft.util.Utils;
import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
@@ -96,10 +96,12 @@ public class GameLauncher {
if (file != null)
FileUtils.cleanDirectoryQuietly(file);
HMCLog.log("Detecting libraries...");
launchingStateChangedEvent.execute(LaunchingState.DownloadingLibraries);
if (!downloadLibrariesEvent.execute(service.download().getDownloadLibraries(loader.getMinecraftVersion())))
throw new GameException("Failed to download libraries");
if (!options.isNotCheckGame()) {
HMCLog.log("Detecting libraries...");
launchingStateChangedEvent.execute(LaunchingState.DownloadingLibraries);
if (!downloadLibrariesEvent.execute(service.download().getDownloadLibraries(loader.getMinecraftVersion())))
throw new GameException("Failed to download libraries");
}
HMCLog.log("Unpacking natives...");
launchingStateChangedEvent.execute(LaunchingState.DecompressingNatives);
@@ -119,7 +121,7 @@ public class GameLauncher {
* @throws IOException failed creating process
*/
public void launch(List str) throws IOException {
if (!service.version().onLaunch())
if (!service.version().onLaunch(options.getLaunchVersion()))
return;
if (StrUtils.isNotBlank(options.getPrecalledCommand())) {
Process p = Runtime.getRuntime().exec(options.getPrecalledCommand());
@@ -153,7 +155,7 @@ public class GameLauncher {
*/
public File makeLauncher(String launcherName, List str) throws IOException {
HMCLog.log("Making shell launcher...");
service.version().onLaunch();
service.version().onLaunch(options.getLaunchVersion());
boolean isWin = OS.os() == OS.WINDOWS;
File f = new File(launcherName + (isWin ? ".bat" : ".sh"));
if (!f.exists() && !f.createNewFile())
@@ -172,6 +174,8 @@ public class GameLauncher {
if (appdata != null) {
writer.write("set appdata=" + appdata);
writer.newLine();
writer.write("cd %appdata%");
writer.newLine();
}
}
if (StrUtils.isNotBlank(options.getPrecalledCommand())) {
@@ -30,7 +30,7 @@ public class LaunchOptions {
private String name, versionName, javaArgs, minecraftArgs, maxMemory, permSize, width, height, serverIp, wrapper;
private String proxyHost, proxyPort, proxyUser, proxyPass, javaDir, launchVersion, type, precalledCommand;
private boolean fullscreen, noJVMArgs;
private boolean fullscreen, noJVMArgs, notCheckGame;
private JdkVersion java;
private File gameDir;
private GameDirType gameDirType;
@@ -222,4 +222,12 @@ public class LaunchOptions {
public void setType(String type) {
this.type = type;
}
public boolean isNotCheckGame() {
return notCheckGame;
}
public void setNotCheckGame(boolean notCheckGame) {
this.notCheckGame = notCheckGame;
}
}
@@ -21,7 +21,6 @@ import java.io.File;
import java.io.IOException;
import java.util.List;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.func.Function;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.system.IOUtils;
import org.jackhuang.hellominecraft.util.system.OS;
@@ -30,6 +29,7 @@ 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;
/**
*
@@ -57,7 +57,7 @@ public class MinecraftLoader extends AbstractMinecraftLoader {
String[] splitted = StrUtils.tokenize(version.minecraftArguments);
String game_assets = assetProvider.apply(version);
String game_assets = assetProvider.apply(version, !options.isNotCheckGame());
for (String t : splitted) {
t = t.replace("${auth_player_name}", lr.getUserName());
@@ -96,13 +96,13 @@ public class MinecraftLoader extends AbstractMinecraftLoader {
}
}
private final Function<MinecraftVersion, String> DEFAULT_ASSET_PROVIDER = t -> {
private final BiFunction<MinecraftVersion, Boolean, String> DEFAULT_ASSET_PROVIDER = (t, allow) -> {
return new File(service.baseDirectory(), "assets").getAbsolutePath();
};
private Function<MinecraftVersion, String> assetProvider = DEFAULT_ASSET_PROVIDER;
private BiFunction<MinecraftVersion, Boolean, String> assetProvider = DEFAULT_ASSET_PROVIDER;
public void setAssetProvider(Function<MinecraftVersion, String> assetProvider) {
public void setAssetProvider(BiFunction<MinecraftVersion, Boolean, String> assetProvider) {
if (assetProvider == null)
this.assetProvider = DEFAULT_ASSET_PROVIDER;
else
@@ -31,6 +31,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
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;
@@ -46,6 +47,7 @@ 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.MinecraftVersionRequest;
import org.jackhuang.hellominecraft.util.tasks.NoShownTaskException;
/**
* A mod pack(*.zip) includes these things:
@@ -79,7 +81,7 @@ public final class ModpackManager {
* @return The installing Task, may take long time, please consider
* TaskWindow.
*/
public static Task install(final File input, final IMinecraftService service, final String idFUCK) {
public static Task install(JFrame parFrame, final File input, final IMinecraftService service, final String idFUCK) {
return new Task() {
Collection<Task> c = new ArrayList<>();
@@ -109,9 +111,9 @@ public final class ModpackManager {
msgs[0] = C.i18n("modpack.task.install");
msgs[1] = new WebPage(description);
((WebPage) msgs[1]).setPreferredSize(new Dimension(800, 350));
int result = JOptionPane.showOptionDialog(null, msgs, (String) msgs[0], JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
int result = JOptionPane.showOptionDialog(parFrame, msgs, (String) msgs[0], JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
if (result == JOptionPane.NO_OPTION)
return;
throw new NoShownTaskException("Operation was canceled by user.");
File versions = new File(service.baseDirectory(), "versions");
@@ -162,13 +164,13 @@ public final class ModpackManager {
HMCLog.warn("Failed to rename incorrect json " + oldFile + " to " + nowFile);
File json = new File(nowFile, "pack.json");
MinecraftVersion mv = C.GSON.fromJson(FileUtils.readFileToString(json), MinecraftVersion.class);
MinecraftVersion mv = C.GSON.fromJson(FileUtils.read(json), MinecraftVersion.class);
if (mv.jar == null)
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_jar"));
c.add(service.download().downloadMinecraftJarTo(mv, new File(nowFile, id + ".jar")));
c.add(service.download().downloadMinecraftJar(mv, new File(nowFile, id + ".jar")));
mv.jar = null;
FileUtils.writeStringToFile(json, C.GSON.toJson(mv));
FileUtils.write(json, C.GSON.toJson(mv));
if (!json.renameTo(new File(nowFile, id + ".json")))
HMCLog.warn("Failed to rename pack.json to new id");
@@ -22,9 +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.OverridableSwingWorker;
import org.jackhuang.hellominecraft.util.tasks.Task;
import org.jackhuang.hellominecraft.launcher.core.download.MinecraftRemoteVersion;
/**
*
@@ -38,11 +36,9 @@ public abstract class IMinecraftDownloadService extends IMinecraftBasicService {
public abstract Task downloadMinecraft(String id);
public abstract boolean downloadMinecraftJar(String id);
public abstract Task downloadMinecraftJar(MinecraftVersion mv, File f);
public abstract Task downloadMinecraftJarTo(MinecraftVersion mv, File f);
public abstract boolean downloadMinecraftVersionJson(String id);
public abstract Task downloadMinecraftVersionJson(String id);
/**
* Get the libraries that need to download.
@@ -72,13 +72,6 @@ public abstract class IMinecraftProvider {
*/
public abstract boolean install(String version, Consumer<MinecraftVersion> callback);
/**
* Returns the thing like ".minecraft/resourcepacks".
*
* @return the thing
*/
public abstract File getResourcePacks();
/**
*
* @param v should be resolved
@@ -164,7 +157,7 @@ public abstract class IMinecraftProvider {
*
* @return if false, will break the launch process.
*/
public abstract boolean onLaunch();
public abstract boolean onLaunch(String id);
public File baseDirectory() {
return service.baseDirectory();
@@ -36,11 +36,8 @@ public class AssetIndexDownloadInfo extends GameDownloadInfo {
}
@Override
public String getUrl(DownloadType dt, boolean allowSelf) {
if (url != null && dt.getProvider().isAllowedToUseSelfURL())
return url;
else
return dt.getProvider().getIndexesDownloadURL() + id + ".json";
public String getCustomizedURL(DownloadType dt) {
return dt.getProvider().getIndexesDownloadURL() + id + ".json";
}
public String getId() {
@@ -55,9 +55,13 @@ public class GameDownloadInfo implements Cloneable {
*/
public String getUrl(DownloadType dt, boolean allowSelf) {
if (url != null && allowSelf)
return url;
return dt.getProvider().getParsedDownloadURL(url);
else
return dt.getProvider().getVersionsDownloadURL() + id + "/" + id + ".jar";
return getCustomizedURL(dt);
}
protected String getCustomizedURL(DownloadType dt) {
return dt.getProvider().getVersionsDownloadURL() + id + "/" + id + ".jar";
}
@Override
@@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.launcher.core.version;
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.system.IOUtils;
/**
*
@@ -31,14 +32,14 @@ public class LibraryDownloadInfo extends GameDownloadInfo {
@Override
public String getUrl(DownloadType dt, boolean allowSelf) {
String myURL = (forgeURL == null ? dt.getProvider().getLibraryDownloadURL() : forgeURL) + "/";
String myURL = (forgeURL == null ? dt.getProvider().getLibraryDownloadURL() : forgeURL);
if (StrUtils.isNotBlank(url) && allowSelf)
myURL = url;
if (!myURL.endsWith(".jar"))
if (path == null)
return null;
else
myURL += path.replace('\\', '/');
myURL = IOUtils.addURLSeparator(myURL) + path.replace('\\', '/');
return myURL;
}
}
@@ -89,6 +89,8 @@ public class MinecraftLibrary extends IMinecraftLibrary {
public String formatName() {
String[] s = name.split(":");
if (s.length < 3)
return null;
StringBuilder sb = new StringBuilder(s[0].replace('.', '/')).append('/').append(s[1]).append('/').append(s[2]).append('/').append(s[1]).append('-').append(s[2]);
if (natives != null)
sb.append('-').append(getNative());
@@ -120,8 +122,11 @@ public class MinecraftLibrary extends IMinecraftLibrary {
downloads.artifact = info = new LibraryDownloadInfo();
else
info = downloads.artifact;
if (StrUtils.isBlank(info.path))
if (StrUtils.isBlank(info.path)) {
info.path = formatName();
if (info.path == null)
return null;
}
info.forgeURL = this.url;
return info;
}
@@ -168,4 +168,8 @@ public class MinecraftVersion implements Cloneable, Comparable<MinecraftVersion>
i.id = id;
return i;
}
public Set<IMinecraftLibrary> getLibraries() {
return libraries == null ? new HashSet() : new HashSet(libraries);
}
}
@@ -111,7 +111,7 @@ public class MinecraftVersionManager extends IMinecraftProvider {
}
MinecraftVersion mcVersion;
try {
mcVersion = C.GSON.fromJson(FileUtils.readFileToString(jsonFile), MinecraftVersion.class);
mcVersion = C.GSON.fromJson(FileUtils.read(jsonFile), MinecraftVersion.class);
if (mcVersion == null)
throw new GameException("Wrong json format, got null.");
} catch (Exception e) {
@@ -119,7 +119,7 @@ public class MinecraftVersionManager extends IMinecraftProvider {
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.readFileToString(jsonFile), MinecraftVersion.class);
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) {
@@ -164,7 +164,7 @@ public class MinecraftVersionManager extends IMinecraftProvider {
public boolean renameVersion(String from, String to) {
try {
File fromJson = new File(versionRoot(from), from + ".json");
MinecraftVersion mcVersion = C.GSON.fromJson(FileUtils.readFileToString(fromJson), MinecraftVersion.class);
MinecraftVersion mcVersion = C.GSON.fromJson(FileUtils.read(fromJson), MinecraftVersion.class);
mcVersion.id = to;
FileUtils.writeQuietly(fromJson, C.GSON.toJson(mcVersion));
File toDir = versionRoot(to);
@@ -198,7 +198,7 @@ public class MinecraftVersionManager extends IMinecraftProvider {
return false;
if (callback != null) {
File mvt = new File(versionRoot(id), id + ".json");
MinecraftVersion v = C.GSON.fromJson(FileUtils.readFileToStringQuietly(mvt), MinecraftVersion.class);
MinecraftVersion v = C.GSON.fromJson(FileUtils.readQuietly(mvt), MinecraftVersion.class);
if (v == null)
return false;
callback.accept(v);
@@ -254,13 +254,8 @@ public class MinecraftVersionManager extends IMinecraftProvider {
}
@Override
public File getResourcePacks() {
return new File(service.baseDirectory(), "resourcepacks");
}
@Override
public boolean onLaunch() {
File resourcePacks = getResourcePacks();
public boolean onLaunch(String id) {
File resourcePacks = new File(getRunDirectory(id), "resourcepacks");
if (!resourcePacks.exists() && !resourcePacks.mkdirs())
HMCLog.warn("Failed to make resourcePacks: " + resourcePacks);
return true;
@@ -75,6 +75,8 @@ public final class Config implements Cloneable {
public transient final EventHandler<IAuthenticator> authChangedEvent = new EventHandler<>(this);
public Theme getTheme() {
if (theme >= Theme.values().length)
theme = 0;
return Theme.values()[theme];
}
@@ -46,8 +46,12 @@ public final class Profile {
}
public Profile(String name) {
this(name, new File(".minecraft").getPath());
}
public Profile(String name, String gameDir) {
this.name = name;
gameDir = MCUtils.getInitGameDir().getPath();
this.gameDir = gameDir;
}
public Profile(String name, Profile v) {
@@ -25,11 +25,11 @@ import java.util.Map;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.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.system.IOUtils;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.UpdateChecker;
@@ -40,8 +40,9 @@ import org.jackhuang.hellominecraft.util.UpdateChecker;
public final class Settings {
public static final String DEFAULT_PROFILE = "Default";
public static final String HOME_PROFILE = "Home";
public static final File SETTINGS_FILE = new File(IOUtils.currentDir(), "hmcl.json");
public static final File SETTINGS_FILE = new File("hmcl.json");
private static final Config SETTINGS;
public static final UpdateChecker UPDATE_CHECKER = new UpdateChecker(Main.getVersionNumber(), "hmcl");
@@ -55,7 +56,7 @@ public final class Settings {
SETTINGS.downloadTypeChangedEvent.register(DownloadType::setSuggestedDownloadType);
DownloadType.setSuggestedDownloadType(SETTINGS.getDownloadSource());
if (!getProfiles().containsKey(DEFAULT_PROFILE))
getProfiles().put(DEFAULT_PROFILE, new Profile());
getProfiles().put(DEFAULT_PROFILE, new Profile(DEFAULT_PROFILE));
for (Map.Entry<String, Profile> entry : getProfiles().entrySet()) {
Profile e = entry.getValue();
@@ -69,7 +70,7 @@ public final class Settings {
Config c = new Config();
if (SETTINGS_FILE.exists())
try {
String str = FileUtils.readFileToString(SETTINGS_FILE);
String str = FileUtils.read(SETTINGS_FILE);
if (str == null || str.trim().equals(""))
HMCLog.log("Settings file is empty, use the default settings.");
else {
@@ -81,8 +82,11 @@ public final class Settings {
} catch (IOException | JsonSyntaxException e) {
HMCLog.warn("Something happened wrongly when load settings.", e);
}
else
else {
HMCLog.log("No settings file here, may be first loading.");
if (!c.getConfigurations().containsKey(HOME_PROFILE))
c.getConfigurations().put(HOME_PROFILE, new Profile(HOME_PROFILE, MCUtils.getLocation().getPath()));
}
return c;
}
@@ -150,7 +154,13 @@ public final class Settings {
MessageBox.Show(C.i18n("settings.cannot_remove_default_config"));
return false;
}
return getProfiles().remove(ver) != null;
boolean notify = false;
if (getLastProfile().getName().equals(ver))
notify = true;
boolean flag = getProfiles().remove(ver) != null;
if (notify && flag)
onProfileChanged();
return flag;
}
public static final EventHandler<Profile> profileChangedEvent = new EventHandler(null);
@@ -41,7 +41,7 @@ public class VersionSetting {
private String javaArgs, minecraftArgs, maxMemory, permSize, width, height;
private String javaDir, precalledCommand, serverIp, java, wrapper;
private boolean fullscreen, noJVMArgs;
private boolean fullscreen, noJVMArgs, notCheckGame;
/**
* 0 - Close the launcher when the game starts.<br/>
@@ -265,6 +265,15 @@ public class VersionSetting {
propertyChanged.execute("serverIp");
}
public boolean isNotCheckGame() {
return notCheckGame;
}
public void setNotCheckGame(boolean notCheckGame) {
this.notCheckGame = notCheckGame;
propertyChanged.execute("notCheckGame");
}
public LaunchOptions createLaunchOptions(File gameDir) {
LaunchOptions x = new LaunchOptions();
x.setFullscreen(isFullscreen());
@@ -280,6 +289,7 @@ public class VersionSetting {
x.setType(Main.shortTitle());
x.setVersionName(Main.shortTitle());
x.setNoJVMArgs(isNoJVMArgs());
x.setNotCheckGame(isNotCheckGame());
x.setPermSize(getPermSize());
x.setPrecalledCommand(getPrecalledCommand());
x.setProxyHost(Settings.getInstance().getProxyHost());
@@ -42,7 +42,7 @@
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="btnIncludeMinecraft" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="916" max="32767" attributes="0"/>
<EmptySpace pref="577" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
@@ -63,7 +63,7 @@
</Group>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace pref="576" max="32767" attributes="0"/>
<EmptySpace pref="447" max="32767" attributes="0"/>
<Component id="btnIncludeMinecraft" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
@@ -122,7 +122,7 @@
<Component id="lblDimensionX" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="txtHeight" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace pref="402" max="32767" attributes="0"/>
<EmptySpace pref="63" max="32767" attributes="0"/>
<Component id="chkFullscreen" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
@@ -195,7 +195,7 @@
<Component id="lblDimension" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="txtWidth" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="228" max="32767" attributes="0"/>
<EmptySpace pref="99" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="btnDownloadAllAssets" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnCleanGame" alignment="3" min="-2" max="-2" attributes="0"/>
@@ -388,44 +388,40 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" alignment="0" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtWrapperLauncher" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="lblPrecalledCommand1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="txtPrecalledCommand" alignment="0" max="32767" attributes="0"/>
<Component id="txtServerIP" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lblMinecraftArgs" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lblPermSize" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lblJavaArgs" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="txtPrecalledCommand" alignment="0" max="32767" attributes="0"/>
<Component id="txtServerIP" alignment="0" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lblPrecalledCommand" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lblServerIP" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="716" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lblMinecraftArgs" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lblPermSize" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lblJavaArgs" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtJavaArgs" max="32767" attributes="0"/>
<Component id="txtMinecraftArgs" max="32767" attributes="0"/>
<Component id="txtPermSize" alignment="1" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtJavaArgs" pref="325" max="32767" attributes="0"/>
<Component id="txtMinecraftArgs" max="32767" attributes="0"/>
<Component id="txtPermSize" alignment="1" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="txtWrapperLauncher" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="chkNoJVMArgs" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="chkDontCheckGame" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lblPrecalledCommand1" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lblPrecalledCommand" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lblServerIP" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="chkNoJVMArgs" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -459,8 +455,11 @@
<Component id="lblServerIP" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="txtServerIP" min="-2" pref="26" max="-2" attributes="0"/>
<EmptySpace pref="168" max="32767" attributes="0"/>
<Component id="chkNoJVMArgs" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="39" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="chkNoJVMArgs" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="chkDontCheckGame" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
@@ -554,6 +553,16 @@
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtWrapperLauncherFocusLost"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="chkDontCheckGame">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="advancedsettings.dont_check_game_completeness" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="chkDontCheckGameItemStateChanged"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="pnlModManagement">
@@ -589,7 +598,7 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="jScrollPane1" pref="889" max="32767" attributes="0"/>
<Component id="jScrollPane1" pref="550" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="btnRemoveMod" max="32767" attributes="0"/>
@@ -597,7 +606,7 @@
</Group>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="lblModInfo" pref="985" max="32767" attributes="0"/>
<Component id="lblModInfo" pref="646" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
@@ -612,7 +621,7 @@
<Component id="btnRemoveMod" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Component id="jScrollPane1" pref="428" max="32767" attributes="0"/>
<Component id="jScrollPane1" pref="299" max="32767" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="lblModInfo" min="-2" max="-2" attributes="0"/>
@@ -61,7 +61,6 @@ import org.jackhuang.hellominecraft.util.system.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.system.IOUtils;
import org.jackhuang.hellominecraft.util.ui.SwingUtils;
import org.jackhuang.hellominecraft.util.system.Java;
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
@@ -103,8 +102,10 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
initExternalModsTable();
initTabs();
isLoading = true;
for (Java j : Java.JAVA)
cboJava.addItem(j.getLocalizedName());
isLoading = false;
Settings.profileLoadingEvent.register(onLoadingProfiles);
Settings.profileChangedEvent.register(onSelectedProfilesChanged);
@@ -290,6 +291,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
txtServerIP = new javax.swing.JTextField();
lblPrecalledCommand1 = new javax.swing.JLabel();
txtWrapperLauncher = new javax.swing.JTextField();
chkDontCheckGame = new javax.swing.JCheckBox();
pnlModManagement = new AnimatedPanel();
pnlModManagementContent = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
@@ -449,7 +451,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
.addComponent(lblDimensionX)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtHeight, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 402, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 63, Short.MAX_VALUE)
.addComponent(chkFullscreen))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlSettingsLayout.createSequentialGroup()
.addComponent(txtMaxMemory)
@@ -506,7 +508,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
.addComponent(lblDimensionX, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblDimension)
.addComponent(txtWidth, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 228, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 99, Short.MAX_VALUE)
.addGroup(pnlSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnDownloadAllAssets)
.addComponent(btnCleanGame))
@@ -571,39 +573,46 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
}
});
chkDontCheckGame.setText(C.i18n("advancedsettings.dont_check_game_completeness")); // NOI18N
chkDontCheckGame.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
chkDontCheckGameItemStateChanged(evt);
}
});
javax.swing.GroupLayout pnlAdvancedSettingsLayout = new javax.swing.GroupLayout(pnlAdvancedSettings);
pnlAdvancedSettings.setLayout(pnlAdvancedSettingsLayout);
pnlAdvancedSettingsLayout.setHorizontalGroup(
pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnlAdvancedSettingsLayout.createSequentialGroup()
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtWrapperLauncher)
.addGroup(pnlAdvancedSettingsLayout.createSequentialGroup()
.addComponent(lblPrecalledCommand1)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
.addComponent(txtPrecalledCommand)
.addComponent(txtServerIP)
.addGroup(pnlAdvancedSettingsLayout.createSequentialGroup()
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblPrecalledCommand)
.addComponent(lblServerIP))
.addGap(0, 716, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlAdvancedSettingsLayout.createSequentialGroup()
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblMinecraftArgs)
.addComponent(lblPermSize)
.addComponent(lblJavaArgs))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtJavaArgs)
.addComponent(txtMinecraftArgs)
.addComponent(txtPermSize, javax.swing.GroupLayout.Alignment.TRAILING))))
.addComponent(txtPrecalledCommand)
.addComponent(txtServerIP)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlAdvancedSettingsLayout.createSequentialGroup()
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblMinecraftArgs)
.addComponent(lblPermSize)
.addComponent(lblJavaArgs))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtJavaArgs, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE)
.addComponent(txtMinecraftArgs)
.addComponent(txtPermSize, javax.swing.GroupLayout.Alignment.TRAILING)))
.addGroup(pnlAdvancedSettingsLayout.createSequentialGroup()
.addContainerGap()
.addComponent(chkNoJVMArgs)
.addGap(0, 0, Short.MAX_VALUE))
.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)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(chkDontCheckGame))
.addGroup(pnlAdvancedSettingsLayout.createSequentialGroup()
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblPrecalledCommand)
.addComponent(lblServerIP))
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
pnlAdvancedSettingsLayout.setVerticalGroup(
pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -632,8 +641,10 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
.addComponent(lblServerIP)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtServerIP, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 168, Short.MAX_VALUE)
.addComponent(chkNoJVMArgs)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 39, Short.MAX_VALUE)
.addGroup(pnlAdvancedSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(chkNoJVMArgs)
.addComponent(chkDontCheckGame))
.addContainerGap())
);
@@ -677,13 +688,13 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
pnlModManagementContentLayout.setHorizontalGroup(
pnlModManagementContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnlModManagementContentLayout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 889, Short.MAX_VALUE)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 550, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnlModManagementContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(btnRemoveMod, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnAddMod, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlModManagementContentLayout.createSequentialGroup()
.addComponent(lblModInfo, javax.swing.GroupLayout.DEFAULT_SIZE, 985, Short.MAX_VALUE)
.addComponent(lblModInfo, javax.swing.GroupLayout.DEFAULT_SIZE, 646, Short.MAX_VALUE)
.addContainerGap())
);
pnlModManagementContentLayout.setVerticalGroup(
@@ -695,7 +706,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnRemoveMod)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 428, Short.MAX_VALUE))
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 299, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblModInfo))
);
@@ -912,7 +923,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(btnIncludeMinecraft)
.addContainerGap(916, Short.MAX_VALUE)))
.addContainerGap(577, Short.MAX_VALUE)))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -928,7 +939,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
.addContainerGap())
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(576, Short.MAX_VALUE)
.addContainerGap(447, Short.MAX_VALUE)
.addComponent(btnIncludeMinecraft)
.addContainerGap()))
);
@@ -949,8 +960,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
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;
if (Settings.delProfile(Settings.getLastProfile()))
loadProfiles();
Settings.delProfile(Settings.getLastProfile());
}//GEN-LAST:event_btnRemoveProfileActionPerformed
private void cboVersionsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboVersionsItemStateChanged
@@ -1084,7 +1094,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
}//GEN-LAST:event_btnMakeLaunchScriptActionPerformed
private void btnIncludeMinecraftActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnIncludeMinecraftActionPerformed
JFileChooser fc = new JFileChooser(IOUtils.currentDir());
JFileChooser fc = new JFileChooser(new File("."));
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
File newGameDir = fc.getSelectedFile();
@@ -1159,6 +1169,11 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
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
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Load">
void prepareVersionSetting(VersionSetting profile) {
@@ -1174,6 +1189,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
txtPrecalledCommand.setText(profile.getPrecalledCommand());
txtServerIP.setText(profile.getServerIp());
chkNoJVMArgs.setSelected(profile.isNoJVMArgs());
chkDontCheckGame.setSelected(profile.isNotCheckGame());
chkFullscreen.setSelected(profile.isFullscreen());
cboLauncherVisibility.setSelectedIndex(profile.getLauncherVisibility().ordinal());
cboRunDirectory.setSelectedIndex(profile.getGameDirType().ordinal());
@@ -1324,6 +1340,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
private javax.swing.JComboBox cboProfiles;
private javax.swing.JComboBox cboRunDirectory;
private javax.swing.JComboBox cboVersions;
private javax.swing.JCheckBox chkDontCheckGame;
private javax.swing.JCheckBox chkFullscreen;
private javax.swing.JCheckBox chkNoJVMArgs;
private javax.swing.JScrollPane jScrollPane1;
@@ -1376,10 +1393,12 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
final Runnable onLoadingProfiles = this::loadProfiles;
private void loadProfiles() {
isLoading = true;
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (Profile s : Settings.getProfilesFiltered())
model.addElement(s.getName());
cboProfiles.setModel(model);
isLoading = false;
}
final Consumer<IMinecraftService> onRefreshedVersions = t -> {
@@ -1425,12 +1444,15 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
t.selectedVersionChangedEvent.register(selectedVersionChangedEvent);
txtGameDir.setText(t.getGameDir());
isLoading = true;
DefaultComboBoxModel model = (DefaultComboBoxModel) cboProfiles.getModel();
for (int i = 0; i < model.getSize(); ++i)
if (model.getElementAt(i).equals(t.getName())) {
model.setSelectedItem(t.getName());
break;
}
isLoading = false;
};
//</editor-fold>
}
@@ -25,9 +25,7 @@ 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.TaskRunnableArg1;
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
import org.jackhuang.hellominecraft.util.tasks.communication.DefaultPreviousResult;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.ui.SwingUtils;
@@ -123,9 +121,7 @@ public class InstallerPanel extends AnimatedPanel {
InstallerType id;
void refreshVersions() {
if (TaskWindow.factory().append(new TaskRunnableArg1<>(C.i18n("install." + id.id + ".get_list"), list)
.registerPreviousResult(new DefaultPreviousResult<>(new String[] { gsp.getMinecraftVersionFormatted() })))
.create())
if (TaskWindow.execute(list.refresh(new String[] { gsp.getMinecraftVersionFormatted() })))
loadVersions();
}
@@ -139,7 +135,8 @@ public class InstallerPanel extends AnimatedPanel {
MessageBox.Show(C.i18n("install.not_refreshed"));
return;
}
Settings.getLastProfile().service().install().download(Settings.getLastProfile().getSelectedVersion(), getVersion(idx), id).after(new TaskRunnable(this::refreshVersions)).run();
TaskWindow.execute(Settings.getLastProfile().service().install().download(Settings.getLastProfile().getSelectedVersion(), getVersion(idx), id),
new TaskRunnable(this::refreshVersions));
}
public void loadVersions() {
@@ -153,7 +153,13 @@
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/lang/I18N.properties" key="launcher.about" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
<Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
<Color id="&#x624b;&#x578b;&#x5149;&#x6807;"/>
</Property>
</Properties>
<Events>
<EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="lblAboutMouseClicked"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnSelBackgroundPath">
<Properties>
@@ -124,6 +124,12 @@ 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);
}
});
btnSelBackgroundPath.setText(C.i18n("ui.button.explore")); // NOI18N
btnSelBackgroundPath.addActionListener(new java.awt.event.ActionListener() {
@@ -380,7 +386,7 @@ public class LauncherSettingsPanel extends AnimatedPanel {
}//GEN-LAST:event_cboThemeItemStateChanged
private void lblModpackMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lblModpackMouseClicked
SwingUtils.openLink("http://blog.163.com/huanghongxun2008@126/blog/static/7738046920160323812771/");
SwingUtils.openLink("http://huangyuhui.duapp.com/link.php?type=modpack");
}//GEN-LAST:event_lblModpackMouseClicked
private void cboLangItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboLangItemStateChanged
@@ -415,6 +421,10 @@ 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
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnCheckUpdate;
private javax.swing.JButton btnSelBackgroundPath;
@@ -109,7 +109,7 @@ public class LaunchingUIDaemon {
}
String msg = C.i18n("launch.exited_abnormally") + " exit code: " + t;
if (errorText != null)
msg += ", advice: " + MinecraftCrashAdvicer.getAdvice(FileUtils.readFileToStringQuietly(new File(errorText)));
msg += ", advice: " + MinecraftCrashAdvicer.getAdvice(FileUtils.readQuietly(new File(errorText)));
MessageBox.Show(msg);
WebFrame f = new WebFrame(logs);
f.setModal(true);
@@ -52,10 +52,10 @@ import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
import org.jackhuang.hellominecraft.lookandfeel.Theme;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.Utils;
import org.jackhuang.hellominecraft.util.ui.DropShadowBorder;
import org.jackhuang.hellominecraft.util.ui.TintablePanel;
import org.jackhuang.hellominecraft.util.ui.BasicColors;
import org.jackhuang.hellominecraft.util.ui.SwingUtils;
/**
*
@@ -168,7 +168,7 @@ public final class MainFrame extends DraggableFrame {
ImageIcon headerIcon = Main.getIcon("icon.png");
this.setIconImage(headerIcon.getImage());
headerIcon = Utils.scaleImage(headerIcon, 16, 16);
headerIcon = SwingUtils.scaleImage(headerIcon, 16, 16);
JLabel headerLabel = new JLabel(headerIcon);
headerLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0));
header.add(headerLabel);
@@ -318,7 +318,7 @@ public final class MainFrame extends DraggableFrame {
ImageIcon background;
public void loadBackground() {
background = Utils.searchBackgroundImage(Main.getIcon(Settings.getInstance().getTheme().settings.get("Customized.MainFrame.background_image")), Settings.getInstance().getBgpath(), 800, 480);
background = SwingUtils.searchBackgroundImage(Main.getIcon(Settings.getInstance().getTheme().settings.get("Customized.MainFrame.background_image")), Settings.getInstance().getBgpath(), 800, 480);
if (background != null)
if (backgroundLabel == null) {
backgroundLabel = new JLabel(background);
@@ -37,6 +37,7 @@ import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.launcher.core.mod.ModpackManager;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.ui.modpack.ModpackWizard;
import org.jackhuang.hellominecraft.launcher.util.HMCLMinecraftService;
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton;
@@ -353,7 +354,7 @@ public class MainPagePanel extends AnimatedPanel {
if (l.isLoggedIn())
l.logOut();
cl.first(pnlPassword);
pnlPassword.repaint();
SwingUtilities.invokeLater(this::repaint);
}//GEN-LAST:event_btnLogoutActionPerformed
private void txtPlayerNameKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtPlayerNameKeyPressed
@@ -382,7 +383,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(fc.getSelectedFile(), Settings.getLastProfile().service(), suggestedModpackId)).create();
TaskWindow.factory().append(ModpackManager.install(MainFrame.INSTANCE, fc.getSelectedFile(), Settings.getLastProfile().service(), suggestedModpackId)).create();
Settings.getLastProfile().service().version().refreshVersions();
}//GEN-LAST:event_btnImportModpackActionPerformed
@@ -471,10 +472,12 @@ public class MainPagePanel extends AnimatedPanel {
final Runnable onLoadingProfiles = this::loadProfiles;
private void loadProfiles() {
isLoading = true;
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (Profile s : Settings.getProfilesFiltered())
model.addElement(s.getName());
cboProfiles.setModel(model);
isLoading = false;
}
final Consumer<IMinecraftService> onRefreshedVersions = t -> {
@@ -489,7 +492,7 @@ public class MainPagePanel extends AnimatedPanel {
cboVersions.removeAllItems();
String selVersion = Settings.getLastProfile().getSelectedVersion();
if (Settings.getLastProfile().service().version().getVersions().isEmpty()) {
if (!showedNoVersion) {
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)
@@ -528,11 +531,13 @@ public class MainPagePanel extends AnimatedPanel {
t.selectedVersionChangedEvent.register(versionChanged);
t.launcher().launchingStateChanged.register(launchingStateChanged);
isLoading = true;
DefaultComboBoxModel model = (DefaultComboBoxModel) cboProfiles.getModel();
for (int i = 0; i < model.getSize(); ++i)
if (model.getElementAt(i).equals(t.getName())) {
model.setSelectedItem(t.getName());
break;
}
isLoading = false;
};
}
@@ -47,8 +47,8 @@ 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("JceSecurity", "Has your operating system been installed completely or is a ghost system? ");
put("JFileChooser", "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");
put("UnsatisfiedLinkError", "crash.user_fault");
@@ -60,6 +60,7 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler {
put("java.lang.ClassFormatError", "crash.NoClassDefFound");
put("java.lang.OutOfMemoryError", "FUCKING MEMORY LIMIT!");
put("Trampoline", "ui.message.update_java");
put("NoSuchAlgorithmException", "Has your operating system been installed completely or is a ghost system?");
}
};
@@ -53,20 +53,16 @@ public class DefaultPlugin implements IPlugin {
OFFLINE_LOGIN.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(OFFLINE_LOGIN.id()));
YGGDRASIL_LOGIN = new YggdrasilAuthenticator(clientToken);
YGGDRASIL_LOGIN.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(YGGDRASIL_LOGIN.id()));
SKINME_LOGIN = new SkinmeAuthenticator(clientToken);
SKINME_LOGIN.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(SKINME_LOGIN.id()));
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());
Settings.getInstance().setAuthenticatorConfig(SKINME_LOGIN.id(), SKINME_LOGIN.onSaveSettings());
}
});
apply.accept(OFFLINE_LOGIN);
apply.accept(YGGDRASIL_LOGIN);
apply.accept(SKINME_LOGIN);
}
@Override
@@ -21,6 +21,7 @@ import com.google.gson.JsonSyntaxException;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.install.MinecraftInstallerService;
import org.jackhuang.hellominecraft.launcher.core.asset.MinecraftAssetService;
@@ -39,6 +40,7 @@ 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;
@@ -66,18 +68,19 @@ public class HMCLMinecraftService extends IMinecraftService {
this.mis = new MinecraftInstallerService(this);
}
public boolean checkedModpack = false, checkingModpack = false;
private void checkModpack() {
int show = 0;
for (StackTraceElement e : Thread.currentThread().getStackTrace())
if ("checkModpack".equals(e.getMethodName()))
++show;
if (show > 2)
return;
if (version().getVersionCount() == 0) {
File modpack = new File("modpack.zip");
if (modpack.exists()) {
TaskWindow.factory().append(ModpackManager.install(modpack, this, null)).create();
version().refreshVersions();
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;
});
}
}
}
@@ -88,7 +91,7 @@ public class HMCLMinecraftService extends IMinecraftService {
VersionSetting vs = null;
File f = new File(provider.versionRoot(id), "hmclversion.cfg");
if (f.exists()) {
String s = FileUtils.readFileToStringQuietly(f);
String s = FileUtils.readQuietly(f);
if (s != null)
try {
vs = C.GSON.fromJson(s, VersionSetting.class);
@@ -81,7 +81,7 @@ public class AppDataUpgrader extends IUpgrader {
try {
File f = AppDataUpgraderTask.HMCL_VER_FILE;
if (f.exists()) {
Map<String, String> m = C.GSON.fromJson(FileUtils.readFileToString(f), Map.class);
Map<String, String> m = C.GSON.fromJson(FileUtils.read(f), Map.class);
String s = m.get("ver");
if (s != null && VersionNumber.check(s).compareTo(nowVersion) > 0) {
String j = m.get("loc");
@@ -179,7 +179,7 @@ public class AppDataUpgrader extends IUpgrader {
json.put("ver", newestVersion);
json.put("loc", f.getAbsolutePath());
String result = C.GSON.toJson(json);
FileUtils.writeStringToFile(HMCL_VER_FILE, result);
FileUtils.write(HMCL_VER_FILE, result);
}
@Override
@@ -19,19 +19,13 @@ package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import com.sun.management.OperatingSystemMXBean;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.Random;
import javax.swing.ImageIcon;
/**
* @author huangyuhui
@@ -52,18 +46,6 @@ public final class Utils {
return ((URLClassLoader) Utils.class.getClassLoader()).getURLs();
}
public static String[] getURLString() {
URL[] urls = ((URLClassLoader) Utils.class.getClassLoader()).getURLs();
String[] urlStrings = new String[urls.length];
for (int i = 0; i < urlStrings.length; i++)
try {
urlStrings[i] = URLDecoder.decode(urls[i].getPath(), "UTF-8");
} catch (UnsupportedEncodingException ex) {
HMCLog.warn("Unsupported UTF-8 encoding", ex);
}
return urlStrings;
}
public static int getSuggestedMemorySize() {
try {
OperatingSystemMXBean osmb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
@@ -80,65 +62,6 @@ public final class Utils {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text), null);
}
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;
ImageIcon background = init;
// bgpath
if (StrUtils.isNotBlank(bgpath) && !loaded) {
String[] backgroundPath = bgpath.split(";");
if (backgroundPath.length > 0) {
int index = r.nextInt(backgroundPath.length);
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage(backgroundPath[index]).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in bgpath.");
loaded = true;
}
}
// bgskin
if (!loaded) {
File backgroundImageFile = new File("bg");
if (backgroundImageFile.exists() && backgroundImageFile.isDirectory()) {
String[] backgroundPath = backgroundImageFile.list();
if (backgroundPath.length > 0) {
int index = r.nextInt(backgroundPath.length);
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage("bg" + File.separator + backgroundPath[index]).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in bgskin folder.");
loaded = true;
}
}
}
// background.png
if (!loaded) {
File backgroundImageFile = new File("background.png");
if (backgroundImageFile.exists()) {
loaded = true;
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage(backgroundImageFile.getAbsolutePath()).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in background.png.");
}
}
// background.jpg
if (!loaded) {
File backgroundImageFile = new File("background.jpg");
if (backgroundImageFile.exists()) {
//loaded = true;
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage(backgroundImageFile.getAbsolutePath()).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in background.jpg.");
}
}
if (background == null)
return init;
return background;
}
/**
* In order to fight against the permission manager by Minecraft Forge.
*
@@ -24,7 +24,8 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
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;
@@ -134,20 +135,10 @@ public class FileUtils {
public static void copyDirectory(File srcDir, File destDir)
throws IOException {
copyDirectory(srcDir, destDir, true);
}
public static void copyDirectory(File srcDir, File destDir, boolean preserveFileDate)
throws IOException {
copyDirectory(srcDir, destDir, null, preserveFileDate);
copyDirectory(srcDir, destDir, null);
}
public static void copyDirectory(File srcDir, File destDir, FileFilter filter)
throws IOException {
copyDirectory(srcDir, destDir, filter, true);
}
public static void copyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate)
throws IOException {
if (srcDir == null)
throw new NullPointerException("Source must not be null");
@@ -171,10 +162,10 @@ public class FileUtils {
}
}
}
doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList);
doCopyDirectory(srcDir, destDir, filter, exclusionList);
}
private static void doCopyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate, List<String> exclusionList)
private static void doCopyDirectory(File srcDir, File destDir, FileFilter filter, List<String> exclusionList)
throws IOException {
File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
if (srcFiles == null)
@@ -191,22 +182,19 @@ public class FileUtils {
File dstFile = new File(destDir, srcFile.getName());
if ((exclusionList == null) || (!exclusionList.contains(srcFile.getCanonicalPath())))
if (srcFile.isDirectory())
doCopyDirectory(srcFile, dstFile, filter, preserveFileDate, exclusionList);
doCopyDirectory(srcFile, dstFile, filter, exclusionList);
else
doCopyFile(srcFile, dstFile, preserveFileDate);
doCopyFile(srcFile, dstFile);
}
if (preserveFileDate)
destDir.setLastModified(srcDir.lastModified());
destDir.setLastModified(srcDir.lastModified());
}
public static String readFileToString(File file)
public static String read(File file)
throws IOException {
return NetUtils.getStreamContent(IOUtils.openInputStream(file));
}
public static String readFileToStringQuietly(File file) {
public static String readQuietly(File file) {
try {
return NetUtils.getStreamContent(IOUtils.openInputStream(file));
} catch (IOException ex) {
@@ -215,12 +203,12 @@ public class FileUtils {
}
}
public static String readFileToString(File file, String charset)
public static String read(File file, String charset)
throws IOException {
return NetUtils.getStreamContent(IOUtils.openInputStream(file), charset);
}
public static String readFileToStringIgnoreFileNotFound(File file) throws IOException {
public static String readIgnoreFileNotFound(File file) throws IOException {
try {
return NetUtils.getStreamContent(IOUtils.openInputStream(file));
} catch (FileNotFoundException ex) {
@@ -237,11 +225,6 @@ public class FileUtils {
}
public static void copyFile(File srcFile, File destFile)
throws IOException {
copyFile(srcFile, destFile, true);
}
public static void copyFile(File srcFile, File destFile, boolean preserveFileDate)
throws IOException {
if (srcFile == null)
throw new NullPointerException("Source must not be null");
@@ -260,42 +243,12 @@ public class FileUtils {
if ((destFile.exists()) && (!destFile.canWrite()))
throw new IOException("Destination '" + destFile + "' exists but is read-only");
doCopyFile(srcFile, destFile, preserveFileDate);
doCopyFile(srcFile, destFile);
}
private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate)
public static void doCopyFile(File srcFile, File destFile)
throws IOException {
if ((destFile.exists()) && (destFile.isDirectory()))
throw new IOException("Destination '" + destFile + "' exists but is a directory");
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel input = null;
FileChannel output = null;
try {
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
input = fis.getChannel();
output = fos.getChannel();
long size = input.size();
long pos = 0L;
long count;
while (pos < size) {
count = size - pos > 31457280L ? 31457280L : size - pos;
pos += output.transferFrom(input, pos, count);
}
} finally {
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(fos);
IOUtils.closeQuietly(input);
IOUtils.closeQuietly(fis);
}
if (srcFile.length() != destFile.length())
throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'");
if (preserveFileDate)
destFile.setLastModified(srcFile.lastModified());
Files.copy(srcFile.toPath(), destFile.toPath(), StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING);
}
public static int indexOfLastSeparator(String filename) {
@@ -350,9 +303,9 @@ public class FileUtils {
return filename.substring(0, index);
}
public static boolean writeQuietly(File file, CharSequence data) {
public static boolean writeQuietly(File file, String data) {
try {
write(file, data);
FileUtils.write(file, data);
return true;
} catch (IOException e) {
HMCLog.warn("Failed to write data to file: " + file, e);
@@ -360,38 +313,17 @@ public class FileUtils {
}
}
public static void write(File file, CharSequence data)
public static void write(File file, String data)
throws IOException {
write(file, data, "UTF-8", false);
}
public static void write(File file, CharSequence data, boolean append)
throws IOException {
write(file, data, "UTF-8", append);
}
public static void write(File file, CharSequence data, String encoding)
public static void write(File file, String data, String encoding)
throws IOException {
write(file, data, encoding, false);
}
public static void write(File file, CharSequence data, String encoding, boolean append)
throws IOException {
String str = data == null ? null : data.toString();
writeStringToFile(file, str, encoding, append);
}
public static void writeStringToFile(File file, String data)
throws IOException {
writeStringToFile(file, data, "UTF-8", false);
}
public static void writeStringToFile(File file, String data, String encoding)
throws IOException {
writeStringToFile(file, data, encoding, false);
}
public static void writeStringToFile(File file, String data, String encoding, boolean append)
public static void write(File file, String data, String encoding, boolean append)
throws IOException {
OutputStream out = null;
try {
@@ -27,8 +27,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
@@ -37,6 +35,7 @@ import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
/**
@@ -54,6 +53,15 @@ public class IOUtils {
return path + File.separatorChar;
}
public static String addURLSeparator(String path) {
if (path == null || path.trim().length() == 0)
return "";
if (path.charAt(path.length() - 1) == '/')
return path;
else
return path + '/';
}
public static boolean isSeparator(char ch) {
return ch == File.separatorChar || ch == '/' || ch == '\\';
}
@@ -76,40 +84,24 @@ public class IOUtils {
return t.substring(i + 1, (t.length() - i) + (i + 1) - 1);
}
public static ArrayList<String> findAllFile(File f) {
ArrayList<String> arr = new ArrayList<>();
public static void findAllFile(File f, Consumer<String> callback) {
if (f.isDirectory()) {
File[] f1 = f.listFiles();
int len = f1.length;
for (int i = 0; i < len; i++)
if (f1[i].isFile())
arr.add(f1[i].getName());
callback.accept(f1[i].getName());
}
return arr;
}
public static ArrayList<String> findAllFileWithFullName(File f) {
ArrayList<String> arr = new ArrayList<>();
if (f.isDirectory()) {
File[] f1 = f.listFiles();
int len = f1.length;
for (int i = 0; i < len; i++)
if (f1[i].isFile())
arr.add(addSeparator(f.getAbsolutePath()) + f1[i].getName());
}
return arr;
}
public static ArrayList<String> findAllDir(File f) {
ArrayList<String> arr = new ArrayList<>();
public static void findAllDir(File f, Consumer<String> callback) {
if (f.isDirectory()) {
File[] f1 = f.listFiles();
int len = f1.length;
for (int i = 0; i < len; i++)
if (f1[i].isDirectory())
arr.add(f1[i].getName());
callback.accept(f1[i].getName());
}
return arr;
}
public static String getRealPath() {
@@ -130,14 +122,6 @@ public class IOUtils {
return path.startsWith("/") || path.indexOf(":") > 0;
}
public static File currentDir() {
return new File(".");
}
public static String currentDirWithSeparator() {
return addSeparator(currentDir().getAbsolutePath());
}
public static String getLocalMAC() {
InetAddress addr;
try {
@@ -212,22 +196,6 @@ public class IOUtils {
return entryBuffer;
}
public static void closeQuietly(Reader input) {
closeQuietly((Closeable) input);
}
public static void closeQuietly(Writer output) {
closeQuietly((Closeable) output);
}
public static void closeQuietly(InputStream input) {
closeQuietly((Closeable) input);
}
public static void closeQuietly(OutputStream output) {
closeQuietly((Closeable) output);
}
public static void closeQuietly(Closeable closeable) {
try {
if (closeable != null)
@@ -109,7 +109,7 @@ public enum OS {
}
public static String getLinuxReleaseVersion() throws IOException {
return FileUtils.readFileToString(new File("/etc/issue"));
return FileUtils.read(new File("/etc/issue"));
}
public static String getSystemVersion() {
@@ -25,6 +25,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.jackhuang.hellominecraft.util.func.BiFunction;
@@ -88,21 +89,25 @@ public class ZipEngine {
files = new File[1];
files[0] = source;
}
if (files == null)
return;
String pathName;//存相对路径(相对于待压缩的根目录)
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);
if (pathName == null)
continue;
zos.putNextEntry(new ZipEntry(pathName));
put(new ZipEntry(pathName));
putDirectoryImpl(file, basePath, pathNameCallback);
} else {
if (".DS_Store".equals(file.getName())) // For mac computers.
if (".DS_Store".equals(file.getName())) // For Mac computers.
continue;
pathName = file.getPath().substring(basePath.length() + 1);
pathName = pathName.replace('\\', '/');
if (pathNameCallback != null)
pathName = pathNameCallback.apply(pathName, false);
if (pathName == null)
@@ -118,7 +123,7 @@ public class ZipEngine {
public void putStream(InputStream is, String pathName) throws IOException {
int length;
try (BufferedInputStream bis = new BufferedInputStream(is)) {
zos.putNextEntry(new ZipEntry(pathName));
put(new ZipEntry(pathName));
while ((length = bis.read(buf)) > 0)
zos.write(buf, 0, length);
}
@@ -132,4 +137,11 @@ public class ZipEngine {
putStream(new ByteArrayInputStream(text.getBytes(encoding)), pathName);
}
protected HashSet<String> names = new HashSet<>();
public void put(ZipEntry entry) throws IOException {
if (names.add(entry.getName()))
zos.putNextEntry(entry);
}
}
@@ -0,0 +1,44 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* 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;
import java.io.File;
/**
*
* @author huangyuhui
*/
public class DeleteFileTask extends Task {
File f;
public DeleteFileTask(File f) {
this.f = f;
}
@Override
public void executeTask() throws Throwable {
f.delete();
}
@Override
public String getInfo() {
return "Delete: " + f.getAbsolutePath();
}
}
@@ -17,28 +17,39 @@
*/
package org.jackhuang.hellominecraft.util.tasks;
import java.util.Arrays;
import java.util.Collection;
/**
*
* @author huangyuhui
*/
public class DoubleTask extends Task {
public class DoubleTask extends TaskInfo {
Task a, b;
public DoubleTask(Task a, Task b) {
this(a, b, "Double Task");
}
public DoubleTask(Task a, Task b, String info) {
super(info);
this.a = a;
this.b = b;
}
@Override
public void executeTask() throws Throwable {
a.executeTask();
b.executeTask();
public Collection<Task> getDependTasks() {
return Arrays.asList(a);
}
@Override
public String getInfo() {
return "Double Task";
public Collection<Task> getAfterTasks() {
return Arrays.asList(b);
}
@Override
public void executeTask() throws Throwable {
}
}
@@ -0,0 +1,29 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* 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;
/**
*
* @author huangyuhui
*/
public class NoShownTaskException extends RuntimeException {
public NoShownTaskException(String msg) {
super(msg);
}
}
@@ -24,7 +24,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@@ -72,12 +72,12 @@ public class TaskList extends Thread {
private class Invoker implements Runnable {
Task task;
Set<Invoker> s;
CountDownLatch latch;
AtomicBoolean bool;
public Invoker(Task task, Set<Invoker> ss, AtomicBoolean bool) {
public Invoker(Task task, CountDownLatch latch, AtomicBoolean bool) {
this.task = task;
s = ss;
this.latch = latch;
this.bool = bool;
}
@@ -85,7 +85,7 @@ public class TaskList extends Thread {
public void run() {
if (!executeTask(task))
bool.set(false);
s.remove(this);
latch.countDown();
}
}
@@ -99,22 +99,20 @@ public class TaskList extends Thread {
return true;
this.totTask += c.size();
AtomicBoolean bool = new AtomicBoolean(true);
Set<Invoker> runningThread = Collections.synchronizedSet(new HashSet<Invoker>());
CountDownLatch counter = new CountDownLatch(c.size());
for (Task t2 : c) {
if (t2 == null)
continue;
t2.setParallelExecuting(true);
Invoker thread = new Invoker(t2, runningThread, bool);
runningThread.add(thread);
Invoker thread = new Invoker(t2, counter, bool);
invokers.add(thread);
if (!EXECUTOR_SERVICE.isShutdown() && !EXECUTOR_SERVICE.isTerminated())
futures.put(thread, EXECUTOR_SERVICE.submit(thread));
}
while (!runningThread.isEmpty())
try {
if (this.isInterrupted())
return false;
Thread.sleep(1);
} catch (InterruptedException ignore) {
}
try {
counter.await();
} catch (InterruptedException ignore) {
}
return bool.get();
}
@@ -1,54 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* 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;
import java.util.ArrayList;
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult;
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResultRegistrar;
import org.jackhuang.hellominecraft.util.func.Consumer;
/**
*
* @author huangyuhui
* @param <T> Runnable&lt;T&gt;
*/
public class TaskRunnableArg1<T> extends TaskInfo implements PreviousResultRegistrar<T> {
private final Consumer<T> r;
public TaskRunnableArg1(String info, Consumer<T> r) {
super(info);
this.r = r;
}
@Override
public void executeTask() throws Exception {
if (al.size() != 1)
throw new IllegalStateException("the count of args is not one.");
r.accept(al.get(0).getResult());
}
ArrayList<PreviousResult<T>> al = new ArrayList();
@Override
public Task registerPreviousResult(PreviousResult<T> pr) {
al.add(pr);
return this;
}
}
@@ -216,8 +216,8 @@ public class TaskWindow extends javax.swing.JDialog
if (idx == -1)
return;
int pgs = progress * 100 / max;
if (progresses.contains(idx) && progresses.get(idx) != pgs && lstDownload.getRowCount() > idx) {
SwingUtils.setValueAt(lstDownload, pgs + "%", idx, 1);
if (progresses.size() > idx && progresses.get(idx) != pgs && lstDownload.getRowCount() > idx) {
SwingUtils.setValueAt(lstDownload, pgs < 0 ? "???" : pgs + "%", idx, 1);
progresses.set(idx, pgs);
}
});
@@ -225,9 +225,11 @@ public class TaskWindow extends javax.swing.JDialog
@Override
public void run() {
SwingUtilities.invokeLater(this::dispose);
suc = true;
HMCLog.log("Tasks are finished.");
SwingUtilities.invokeLater(() -> {
dispose();
suc = true;
HMCLog.log("Tasks are finished.");
});
}
@Override
@@ -240,7 +242,7 @@ public class TaskWindow extends javax.swing.JDialog
if (taskList == null)
return;
tasks.add(task);
progresses.add(0);
progresses.add(-1);
SwingUtils.appendLast(lstDownload, task.getInfo(), "0%");
SwingUtils.moveEnd(srlDownload);
});
@@ -271,7 +273,14 @@ public class TaskWindow extends javax.swing.JDialog
SwingUtilities.invokeLater(() -> {
if (taskList == null || task == null)
return;
failReasons.add(task.getInfo() + ": " + (null == task.getFailReason() ? "No exception" : (StrUtils.isBlank(task.getFailReason().getLocalizedMessage()) ? task.getFailReason().getClass().getSimpleName() : task.getFailReason().getLocalizedMessage())));
String msg = null;
if (task.getFailReason() != null && !(task.getFailReason() instanceof NoShownTaskException))
if (StrUtils.isBlank(task.getFailReason().getLocalizedMessage()))
msg = task.getFailReason().getClass().getSimpleName();
else
msg = task.getFailReason().getLocalizedMessage();
if (msg != null)
failReasons.add(task.getInfo() + ": " + msg);
pgsTotal.setMaximum(taskList.taskCount());
pgsTotal.setValue(pgsTotal.getValue() + 1);
int idx = tasks.indexOf(task);
@@ -313,7 +322,8 @@ public class TaskWindow extends javax.swing.JDialog
boolean flag;
public TaskWindowFactory append(Task t) {
ll.add(t);
if (t != null)
ll.add(t);
return this;
}
@@ -130,6 +130,8 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
if (!shouldContinue)
break;
try {
if (ppl != null)
ppl.setProgress(this, -1, 1);
// Open connection to URL.
HttpURLConnection connection
@@ -57,15 +57,22 @@ public class HTTPGetTask extends TaskInfo implements PreviousResult<String> {
if (repeat > 0)
HMCLog.warn("Failed to download, repeat: " + repeat);
try {
if (ppl != null)
ppl.setProgress(this, -1, 1);
URLConnection conn = new URL(url).openConnection();
InputStream is = conn.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i;
int size = conn.getContentLength(), read = 0;
long lastTime = System.currentTimeMillis();
while ((i = is.read()) != -1) {
baos.write(i);
if (ppl != null)
ppl.setProgress(this, ++read, size);
++read;
long now = System.currentTimeMillis();
if (ppl != null && (now - lastTime) >= 1000) {
ppl.setProgress(this, read, size);
lastTime = now;
}
if (!shouldContinue)
return;
}
@@ -17,8 +17,6 @@
*/
package org.jackhuang.hellominecraft.util.ui;
import java.awt.Frame;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
@@ -28,7 +26,6 @@ import org.jackhuang.hellominecraft.util.logging.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.MessageBox;
import org.jackhuang.hellominecraft.util.Utils;
/**
@@ -254,7 +251,7 @@ public class LogWindow extends javax.swing.JFrame {
StyleConstants.setForeground(sas, c.COLOR);
try {
d.insertString(d.getLength(), status, sas);
} catch (BadLocationException ex) {
} catch (Exception ex) {
HMCLog.err("Failed to insert \"" + status + "\" to " + d.getLength(), ex);
}
@@ -20,7 +20,8 @@ package org.jackhuang.hellominecraft.util.ui;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Window;
import java.io.File;
import java.io.IOException;
@@ -28,7 +29,9 @@ import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
@@ -302,4 +305,63 @@ public class SwingUtils {
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;
ImageIcon background = init;
// bgpath
if (StrUtils.isNotBlank(bgpath) && !loaded) {
String[] backgroundPath = bgpath.split(";");
if (backgroundPath.length > 0) {
int index = r.nextInt(backgroundPath.length);
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage(backgroundPath[index]).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in bgpath.");
loaded = true;
}
}
// bgskin
if (!loaded) {
File backgroundImageFile = new File("bg");
if (backgroundImageFile.exists() && backgroundImageFile.isDirectory()) {
String[] backgroundPath = backgroundImageFile.list();
if (backgroundPath.length > 0) {
int index = r.nextInt(backgroundPath.length);
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage("bg" + File.separator + backgroundPath[index]).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in bgskin folder.");
loaded = true;
}
}
}
// background.png
if (!loaded) {
File backgroundImageFile = new File("background.png");
if (backgroundImageFile.exists()) {
loaded = true;
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage(backgroundImageFile.getAbsolutePath()).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in background.png.");
}
}
// background.jpg
if (!loaded) {
File backgroundImageFile = new File("background.jpg");
if (backgroundImageFile.exists()) {
//loaded = true;
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage(backgroundImageFile.getAbsolutePath()).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in background.jpg.");
}
}
if (background == null)
return init;
return background;
}
}
@@ -289,6 +289,7 @@ 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=生成启动脚本
@@ -297,7 +298,7 @@ mainwindow.enter_script_name=输入要生成脚本的文件名
mainwindow.make_launch_succeed=启动脚本已生成完毕:
mainwindow.no_version=未找到任何版本,是否进入游戏下载?
launcher.about=<html>默认背景图感谢gamerteam提供。<br/>关于作者:<br/>百度ID:huanghongxun20<br/>mcbbs:huanghongxun<br/>邮箱:huanghongxun2008@126.com<br/>Minecraft Forum ID: klkl6523<br/>欢迎提交Bug哦<br/>Copyright (c) 2013-2016 huangyuhui.<br/>免责声明:Minecraft软件版权归Mojang AB所有,使用本软件产生的版权问题本软件制作方概不负责。<br/>本启动器在GPLv3协议下开源:https://github.com/huanghongxun/HMCL/ ,感谢issues和pull requests贡献者<br/>本软件使用了基于Apache License 2.0的Gson项目,感谢贡献者。</html>
launcher.about=<html>默认背景图感谢gamerteam提供。<br><a href="http://huangyuhui.duapp.com/link.php?type=sponsor">如果您希望本软件继续发展,请赞助</a><br/>关于作者:<br/>百度ID:huanghongxun20<br/>mcbbs:huanghongxun<br/>邮箱:huanghongxun2008@126.com<br/>Minecraft Forum ID: klkl6523<br/>欢迎提交Bug哦<br/>Copyright (c) 2013-2016 huangyuhui.<br/>免责声明:Minecraft软件版权归Mojang AB所有,使用本软件产生的版权问题本软件制作方概不负责。<br/>本启动器在GPLv3协议下开源:https://github.com/huanghongxun/HMCL/ ,感谢issues和pull requests贡献者<br/>本软件使用了基于Apache License 2.0的Gson项目,感谢贡献者。</html>
launcher.download_source=下载源
launcher.background_location=背景地址
launcher.exit_failed=强制退出失败,可能是Forge 1.7.10及更高版本导致的,无法解决。
@@ -311,7 +312,7 @@ launcher.enable_shadow=启用窗口阴影
launcher.theme=主题
launcher.proxy=代理
launcher.decorated=启用窗口边框(Linux下可解决程序界面全灰问题)
launcher.modpack=<html><a href="http://blog.163.com/huanghongxun2008@126/blog/static/7738046920160323812771/">整合包作者帮助</a></html>
launcher.modpack=<html><a href="http://huangyuhui.duapp.com/link.php?type=modpack">整合包作者帮助</a></html>
launcher.enable_animation=启用动态效果
launcher.lang=语言
launcher.restart=本界面选项需要重启本启动器生效
@@ -364,7 +365,7 @@ setupwindow.no_empty_name=名字不可为空
setupwindow.clean=清理游戏文件
update.no_browser=无法打开浏览器,网址已经复制到剪贴板了,您可以手动粘贴网址打开页面
update.should_open_link=是否前往发布页面更新?
update.should_open_link=是否更新?
update.newest_version=最新版本为:
update.failed=检查更新失败
update.found=(发现更新!)
@@ -289,6 +289,7 @@ advancedsettings.wrapper_launcher=\u524d\u7f6e\u6307\u4ee4(\u4e0d\u5fc5\u586b\u5
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
@@ -297,7 +298,7 @@ mainwindow.enter_script_name=\u8f93\u5165\u8981\u751f\u6210\u811a\u672c\u7684\u6
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=<html>\u9ed8\u8ba4\u80cc\u666f\u56fe\u611f\u8c22gamerteam\u63d0\u4f9b\u3002<br/>\u5173\u4e8e\u4f5c\u8005\uff1a<br/>\u767e\u5ea6ID\uff1ahuanghongxun20<br/>mcbbs\uff1ahuanghongxun<br/>\u90ae\u7bb1\uff1ahuanghongxun2008@126.com<br/>Minecraft Forum ID: klkl6523<br/>\u6b22\u8fce\u63d0\u4ea4Bug\u54e6<br/>Copyright (c) 2013-2016 huangyuhui.<br/>\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<br/>\u672c\u542f\u52a8\u5668\u5728GPLv3\u534f\u8bae\u4e0b\u5f00\u6e90:https://github.com/huanghongxun/HMCL/ ,\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005<br/>\u672c\u8f6f\u4ef6\u4f7f\u7528\u4e86\u57fa\u4e8eApache License 2.0\u7684Gson\u9879\u76ee\uff0c\u611f\u8c22\u8d21\u732e\u8005\u3002</html>
launcher.about=<html>\u9ed8\u8ba4\u80cc\u666f\u56fe\u611f\u8c22gamerteam\u63d0\u4f9b\u3002<br><a href="http://huangyuhui.duapp.com/link.php?type=sponsor">\u5982\u679c\u60a8\u5e0c\u671b\u672c\u8f6f\u4ef6\u7ee7\u7eed\u53d1\u5c55\uff0c\u8bf7\u8d5e\u52a9</a><br/>\u5173\u4e8e\u4f5c\u8005\uff1a<br/>\u767e\u5ea6ID\uff1ahuanghongxun20<br/>mcbbs\uff1ahuanghongxun<br/>\u90ae\u7bb1\uff1ahuanghongxun2008@126.com<br/>Minecraft Forum ID: klkl6523<br/>\u6b22\u8fce\u63d0\u4ea4Bug\u54e6<br/>Copyright (c) 2013-2016 huangyuhui.<br/>\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<br/>\u672c\u542f\u52a8\u5668\u5728GPLv3\u534f\u8bae\u4e0b\u5f00\u6e90:https://github.com/huanghongxun/HMCL/ ,\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005<br/>\u672c\u8f6f\u4ef6\u4f7f\u7528\u4e86\u57fa\u4e8eApache License 2.0\u7684Gson\u9879\u76ee\uff0c\u611f\u8c22\u8d21\u732e\u8005\u3002</html>
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
@@ -311,7 +312,7 @@ 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=<html><a href="http://blog.163.com/huanghongxun2008@126/blog/static/7738046920160323812771/">\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9</a></html>
launcher.modpack=<html><a href="http://huangyuhui.duapp.com/link.php?type=modpack">\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9</a></html>
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
@@ -364,7 +365,7 @@ 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\u524d\u5f80\u53d1\u5e03\u9875\u9762\u66f4\u65b0\uff1f
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!)
@@ -289,6 +289,7 @@ 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.
@@ -364,7 +365,7 @@ 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 open the update link?
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!)
@@ -289,6 +289,7 @@ 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.
@@ -364,7 +365,7 @@ 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 open the update link?
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!)
@@ -289,6 +289,7 @@ 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=生成啟動腳本
@@ -297,7 +298,7 @@ mainwindow.enter_script_name=輸入要生成腳本的資料名
mainwindow.make_launch_succeed=啟動腳本已生成完畢:
mainwindow.no_version=未找到任何版本,是否進入遊戲下載?
launcher.about=<html>默認背景圖感謝gamerteam提供。 <br/>關於作者:<br/>百度ID:huanghongxun20<br/>mcbbs:huanghongxun<br/>郵箱:huanghongxun2008@126.com<br/>Minecraft Forum ID: klkl6523<br />歡迎提交Bug哦<br/>Copyright (c) 2013-2016 huangyuhui.<br/>免責聲明:Minecraft軟體版權歸Mojang AB所有,遊戲由於誤操作本啟動器而丟失數據的概不負責。 <br/>本啟動器在GPLv3協議下開源:http://github.com/huanghongxun/HMCL/ ,感谢issues和pull requests贡献者<br/>本軟體使用了基於Apache License 2.0的Gson項目,感謝貢獻者。</html>
launcher.about=<html>默認背景圖感謝gamerteam提供。<br><a href="http://huangyuhui.duapp.com/link.php?type=sponsor">如果您希望本軟件繼續發展,請贊助</a><br>關於作者:<br>百度ID:huanghongxun20<br>mcbbs:huanghongxun<br>郵箱:huanghongxun2008@126.com<br>Minecraft Forum ID: klkl6523<br>歡迎提交Bug哦<br/>Copyright (c) 2013-2016 huangyuhui.<br>免責聲明:Minecraft軟體版權歸Mojang AB所有,遊戲由於誤操作本啟動器而丟失數據的概不負責。<br>本啟動器在GPLv3協議下開源:http://github.com/huanghongxun/HMCL/ ,感谢issues和pull requests贡献者<br>本軟體使用了基於Apache License 2.0的Gson項目,感謝貢獻者。</html>
launcher.download_source=下載源
launcher.background_location=背景地址
launcher.exit_failed=強制退出失敗,可能是Forge 1.7.10及更高版本導致的,無法解決。
@@ -311,7 +312,7 @@ launcher.enable_shadow=启用窗口阴影
launcher.theme=主题
launcher.proxy=代理
launcher.decorated=啟用窗口邊框(Linux下可解決程序界面全灰問題)
launcher.modpack=<html><a href="http://blog.163.com/huanghongxun2008@126/blog/static/7738046920160323812771/">整合包作者帮助</a></html>
launcher.modpack=<html><a href="http://huangyuhui.duapp.com/link.php?type=modpack">整合包作者帮助</a></html>
launcher.enable_animation=啟用動態效果
launcher.lang=語言
launcher.restart=本界面選項需要重啟本啟動器生效
@@ -364,7 +365,7 @@ setupwindow.no_empty_name=名字不可為空
setupwindow.clean=清理遊戲資料
update.no_browser=無法打開瀏覽器,網址已經復製到剪貼板了,您可以手動粘貼網址打開頁面
update.should_open_link=是否前往發布頁面更新?
update.should_open_link=是否更新?
update.newest_version=最新版本為:
update.failed=檢查更新失敗
update.found=(發現更新!)
@@ -289,6 +289,7 @@ advancedsettings.wrapper_launcher=\u524d\u7f6e\u6307\u4ee4(\u4e0d\u5fc5\u586b\u5
advancedsettings.precall_command=\u555f\u52d5\u524d\u57f7\u884c\u547d\u4ee4(\u4e0d\u5fc5\u586b\u5beb,\u5c07\u5728\u904a\u6232\u555f\u52d5\u524d\u8abf\u7528)
advancedsettings.server_ip=\u76f4\u5165\u4f3a\u670d\u5668ip\u5730\u5740(\u4e0d\u5fc5\u586b\u5beb\uff0c\u555f\u52d5\u904a\u6232\u5f8c\u76f4\u63a5\u9032\u5165\u5c0d\u61c9\u4f3a\u670d\u5668)
advancedsettings.cancel_wrapper_launcher=\u53d6\u6d88\u5305\u88f9\u555f\u52d5\u5668(\u51fa\u73fe\u5947\u602a\u554f\u984c\u6642\u53ef\u5617\u8a66\u4f7f\u7528,\u8207\u8abf\u8a66\u6a21\u5f0f\u885d\u7a81)
advancedsettings.dont_check_game_completeness=\u4e0d\u6aa2\u67e5\u904a\u6232\u5b8c\u6574\u6027
mainwindow.show_log=\u67e5\u770b\u65e5\u8a8c
mainwindow.make_launch_script=\u751f\u6210\u555f\u52d5\u8173\u672c
@@ -297,7 +298,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=<html>\u9ed8\u8a8d\u80cc\u666f\u5716\u611f\u8b1dgamerteam\u63d0\u4f9b\u3002 <br/>\u95dc\u65bc\u4f5c\u8005\uff1a<br/>\u767e\u5ea6ID\uff1ahuanghongxun20<br/>mcbbs\uff1ahuanghongxun<br/>\u90f5\u7bb1\uff1ahuanghongxun2008@126.com<br/>Minecraft Forum ID: klkl6523<br />\u6b61\u8fce\u63d0\u4ea4Bug\u54e6<br/>Copyright (c) 2013-2016 huangyuhui.<br/>\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 <br/>\u672c\u555f\u52d5\u5668\u5728GPLv3\u5354\u8b70\u4e0b\u958b\u6e90:http://github.com/huanghongxun/HMCL/ ,\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005<br/>\u672c\u8edf\u9ad4\u4f7f\u7528\u4e86\u57fa\u65bcApache License 2.0\u7684Gson\u9805\u76ee\uff0c\u611f\u8b1d\u8ca2\u737b\u8005\u3002</html>
launcher.about=<html>\u9ed8\u8a8d\u80cc\u666f\u5716\u611f\u8b1dgamerteam\u63d0\u4f9b\u3002<br><a href="http://huangyuhui.duapp.com/link.php?type=sponsor">\u5982\u679c\u60a8\u5e0c\u671b\u672c\u8edf\u4ef6\u7e7c\u7e8c\u767c\u5c55\uff0c\u8acb\u8d0a\u52a9</a><br>\u95dc\u65bc\u4f5c\u8005\uff1a<br>\u767e\u5ea6ID\uff1ahuanghongxun20<br>mcbbs\uff1ahuanghongxun<br>\u90f5\u7bb1\uff1ahuanghongxun2008@126.com<br>Minecraft Forum ID: klkl6523<br>\u6b61\u8fce\u63d0\u4ea4Bug\u54e6<br/>Copyright (c) 2013-2016 huangyuhui.<br>\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<br>\u672c\u555f\u52d5\u5668\u5728GPLv3\u5354\u8b70\u4e0b\u958b\u6e90:http://github.com/huanghongxun/HMCL/ ,\u611f\u8c22issues\u548cpull requests\u8d21\u732e\u8005<br>\u672c\u8edf\u9ad4\u4f7f\u7528\u4e86\u57fa\u65bcApache License 2.0\u7684Gson\u9805\u76ee\uff0c\u611f\u8b1d\u8ca2\u737b\u8005\u3002</html>
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
@@ -311,7 +312,7 @@ launcher.enable_shadow=\u542f\u7528\u7a97\u53e3\u9634\u5f71
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=<html><a href="http://blog.163.com/huanghongxun2008@126/blog/static/7738046920160323812771/">\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9</a></html>
launcher.modpack=<html><a href="http://huangyuhui.duapp.com/link.php?type=modpack">\u6574\u5408\u5305\u4f5c\u8005\u5e2e\u52a9</a></html>
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
@@ -364,7 +365,7 @@ setupwindow.no_empty_name=\u540d\u5b57\u4e0d\u53ef\u70ba\u7a7a
setupwindow.clean=\u6e05\u7406\u904a\u6232\u8cc7\u6599
update.no_browser=\u7121\u6cd5\u6253\u958b\u700f\u89bd\u5668\uff0c\u7db2\u5740\u5df2\u7d93\u5fa9\u88fd\u5230\u526a\u8cbc\u677f\u4e86\uff0c\u60a8\u53ef\u4ee5\u624b\u52d5\u7c98\u8cbc\u7db2\u5740\u6253\u958b\u9801\u9762
update.should_open_link=\u662f\u5426\u524d\u5f80\u767c\u5e03\u9801\u9762\u66f4\u65b0\uff1f
update.should_open_link=\u662f\u5426\u66f4\u65b0\uff1f
update.newest_version=\u6700\u65b0\u7248\u672c\u70ba\uff1a
update.failed=\u6aa2\u67e5\u66f4\u65b0\u5931\u6557
update.found=(\u767c\u73fe\u66f4\u65b0!)
+1 -1
View File
@@ -30,7 +30,7 @@ if (buildnumber == null)
def versionroot = System.getenv("VERSION_ROOT")
if (versionroot == null)
versionroot = "0.8.6"
versionroot = "0.8.7"
String mavenGroupId = 'HMCSM'
String mavenVersion = versionroot + '.' + buildnumber
@@ -20,12 +20,12 @@ package org.jackhuang.hellominecraft.svrmgr.server;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.system.Compressor;
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;
@@ -39,9 +39,8 @@ public class BackupManager {
return Utilities.getGameDir() + "backups-HMCSM" + File.separator;
}
public static ArrayList<String> getBackupList() {
String gameDir = backupDir();
return IOUtils.findAllFile(new File(gameDir));
public static void getBackupList(Consumer<String> c) {
IOUtils.findAllFile(new File(backupDir()), c);
}
public static void addWorldBackup(final String folder) {
@@ -61,17 +60,15 @@ public class BackupManager {
t.start();
}
public static ArrayList<String> findAllWorlds() {
public static void findAllWorlds(Consumer<String> callback) {
String gameDir = Utilities.getGameDir();
ArrayList<String> folders = IOUtils.findAllDir(new File(gameDir));
ArrayList<String> result = new ArrayList<>();
for (String folder : folders) {
String worldPath = gameDir + folder + File.separator;
ArrayList<String> files = IOUtils.findAllFile(new File(worldPath));
if (files.contains("level.dat"))
result.add(folder);
}
return result;
IOUtils.findAllDir(new File(gameDir), folder -> {
String worldPath = gameDir + folder + File.separator;
IOUtils.findAllFile(new File(worldPath), f -> {
if ("level.dat".equals(f))
callback.accept(folder);
});
});
}
public static void restoreBackup(File backupFile) {
@@ -89,10 +86,10 @@ public class BackupManager {
}
public static void backupAllWorlds() {
ArrayList<String> al = findAllWorlds();
for (String world : al)
findAllWorlds(world -> {
if (!SettingsManager.settings.inactiveWorlds.contains(world))
addWorldBackup(world);
});
}
public static void backupAllPlugins() {
@@ -90,7 +90,7 @@ public abstract class PlayerList<T extends BasePlayer> {
op = null;
if (txt.exists())
try {
initByText(FileUtils.readFileToStringIgnoreFileNotFound(txt));
initByText(FileUtils.readIgnoreFileNotFound(txt));
if (op != null)
player.addAll(op);
} catch (IOException e) {
@@ -26,7 +26,6 @@ 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.system.IOUtils;
/**
*
@@ -37,13 +36,13 @@ public class SettingsManager {
public static Settings settings;
public static boolean isFirstLoad = false;
static Gson gson;
private static final File file = new File("hmcsm.json");
public static void load() {
gson = new Gson();
File file = new File(IOUtils.currentDir(), "hmcsm.json");
if (file.exists())
try {
String str = FileUtils.readFileToString(file);
String str = FileUtils.read(file);
if (str == null || str.trim().equals(""))
init();
else
@@ -64,9 +63,8 @@ public class SettingsManager {
}
public static void save() {
File f = new File(IOUtils.currentDir(), "hmcsm.json");
try {
FileUtils.write(f, gson.toJson(settings));
FileUtils.write(file, gson.toJson(settings));
} catch (IOException ex) {
HMCLog.err("Failed to save settings.", ex);
}
@@ -242,9 +242,9 @@ public final class MainWindow extends javax.swing.JFrame
itm.addActionListener(new ActionListenerImpl("time set 0"));
ppmBasically.add(itm);
itm = new JMenuItem("广播");
itm.addActionListener(new ActionListenerImpl("say {}", JOptionPane.showInputDialog("广播讯息")));
itm.addActionListener(new ActionListenerImpl("say {}", "广播讯息"));
itm = new JMenuItem("红字广播");
itm.addActionListener(new ActionListenerImpl("me {}", JOptionPane.showInputDialog("广播讯息")));
itm.addActionListener(new ActionListenerImpl("me {}", "广播讯息"));
itm = new JMenuItem("私聊");
itm.addActionListener(e -> {
InputDialog id = new InputDialog(MainWindow.this, true, new String[] { "玩家", "讯息" });
@@ -253,16 +253,16 @@ public final class MainWindow extends javax.swing.JFrame
});
ppmBasically.add(itm);
itm = new JMenuItem("给予OP");
itm.addActionListener(new ActionListenerImpl("op {}", JOptionPane.showInputDialog("新OP的游戏名")));
itm.addActionListener(new ActionListenerImpl("op {}", "新OP的游戏名"));
ppmBasically.add(itm);
itm = new JMenuItem("卸除OP");
itm.addActionListener(new ActionListenerImpl("deop {}", JOptionPane.showInputDialog("要卸除OP的游戏名")));
itm.addActionListener(new ActionListenerImpl("deop {}", "要卸除OP的游戏名"));
ppmBasically.add(itm);
itm = new JMenuItem("给予玩家白名单");
itm.addActionListener(new ActionListenerImpl("whitelist add {}", JOptionPane.showInputDialog("要添入白名单的游戏名")));
itm.addActionListener(new ActionListenerImpl("whitelist add {}", "要添入白名单的游戏名"));
ppmBasically.add(itm);
itm = new JMenuItem("解除玩家白名单");
itm.addActionListener(new ActionListenerImpl("whitelist remove {}", JOptionPane.showInputDialog("要解除白名单的游戏名")));
itm.addActionListener(new ActionListenerImpl("whitelist remove {}", "要解除白名单的游戏名"));
ppmBasically.add(itm);
itm = new JMenuItem("启用白名单");
itm.addActionListener(new ActionListenerImpl("whitelist on"));
@@ -274,31 +274,31 @@ public final class MainWindow extends javax.swing.JFrame
itm.addActionListener(new ActionListenerImpl("whitelist list"));
ppmBasically.add(itm);
itm = new JMenuItem("封禁玩家");
itm.addActionListener(new ActionListenerImpl("ban {}", JOptionPane.showInputDialog("要封禁玩家的游戏名")));
itm.addActionListener(new ActionListenerImpl("ban {}", "要封禁玩家的游戏名"));
ppmBasically.add(itm);
itm = new JMenuItem("封禁玩家IP");
itm.addActionListener(new ActionListenerImpl("ban-ip {}", JOptionPane.showInputDialog("要封禁玩家IP的游戏名")));
itm.addActionListener(new ActionListenerImpl("ban-ip {}", "要封禁玩家IP的游戏名"));
itm = new JMenuItem("解封玩家");
itm.addActionListener(new ActionListenerImpl("pardon {}", JOptionPane.showInputDialog("要解封玩家的游戏名")));
itm.addActionListener(new ActionListenerImpl("pardon {}", "要解封玩家的游戏名"));
ppmBasically.add(itm);
itm = new JMenuItem("解封玩家IP");
itm.addActionListener(new ActionListenerImpl("pardon-ip {}", JOptionPane.showInputDialog("要解封玩家IP的游戏名")));
itm.addActionListener(new ActionListenerImpl("pardon-ip {}", "要解封玩家IP的游戏名"));
itm = new JMenuItem("封禁玩家");
itm.addActionListener(new ActionListenerImpl("ban {}", JOptionPane.showInputDialog("要封禁玩家的游戏名")));
itm.addActionListener(new ActionListenerImpl("ban {}", "要封禁玩家的游戏名"));
ppmBasically.add(itm);
itm = new JMenuItem("封禁玩家IP");
itm.addActionListener(new ActionListenerImpl("ban-ip {}", JOptionPane.showInputDialog("要封禁玩家IP的游戏名")));
itm.addActionListener(new ActionListenerImpl("ban-ip {}", "要封禁玩家IP的游戏名"));
itm = new JMenuItem("封禁玩家列表");
itm.addActionListener(new ActionListenerImpl("banlist"));
ppmBasically.add(itm);
itm = new JMenuItem("修改时间");
itm.addActionListener(new ActionListenerImpl("time set {}", JOptionPane.showInputDialog("要调整的时间值")));
itm.addActionListener(new ActionListenerImpl("time set {}", "要调整的时间值"));
ppmBasically.add(itm);
itm = new JMenuItem("往后调整时间");
itm.addActionListener(new ActionListenerImpl("time add {}", JOptionPane.showInputDialog("要往后调整的时间值")));
itm.addActionListener(new ActionListenerImpl("time add {}", "要往后调整的时间值"));
ppmBasically.add(itm);
itm = new JMenuItem("调整天气");
itm.addActionListener(new ActionListenerImpl("weather {}", JOptionPane.showInputDialog("要调整的天气(只能填:clear[意思是取消所有天气]或rain[意思是下雨]或thunder[意思是打雷]")));
itm.addActionListener(new ActionListenerImpl("weather {}", "要调整的天气(只能填:clear[意思是取消所有天气]或rain[意思是下雨]或thunder[意思是打雷]"));
ppmBasically.add(itm);
itm = new JMenuItem("调整一定时间的天气");
itm.addActionListener(e -> {
@@ -314,10 +314,10 @@ public final class MainWindow extends javax.swing.JFrame
});
ppmBasically.add(itm);
itm = new JMenuItem("清除背包");
itm.addActionListener(new ActionListenerImpl("clear {}", JOptionPane.showInputDialog("要被清除背包的玩家")));
itm.addActionListener(new ActionListenerImpl("clear {}", "要被清除背包的玩家"));
ppmBasically.add(itm);
itm = new JMenuItem("踢出玩家");
itm.addActionListener(new ActionListenerImpl("kick {}", JOptionPane.showInputDialog("要被踢出的玩家")));
itm.addActionListener(new ActionListenerImpl("kick {}", "要被踢出的玩家"));
ppmBasically.add(itm);
itm = new JMenuItem("在线玩家");
itm.addActionListener(new ActionListenerImpl("list"));
@@ -343,10 +343,10 @@ public final class MainWindow extends javax.swing.JFrame
itm.addActionListener(new ActionListenerImpl("save-off"));
ppmBasically.add(itm);
itm = new JMenuItem("难度");
itm.addActionListener(new ActionListenerImpl("difficulty {}", JOptionPane.showInputDialog("难度")));
itm.addActionListener(new ActionListenerImpl("difficulty {}", "难度"));
ppmBasically.add(itm);
itm = new JMenuItem("默认游戏模式");
itm.addActionListener(new ActionListenerImpl("defaultgamemode {}", JOptionPane.showInputDialog("默认游戏模式")));
itm.addActionListener(new ActionListenerImpl("defaultgamemode {}", "默认游戏模式"));
ppmBasically.add(itm);
itm = new JMenuItem("地图种子");
itm.addActionListener(new ActionListenerImpl("seed"));
@@ -2781,13 +2781,12 @@ public final class MainWindow extends javax.swing.JFrame
String path = Utilities.getPath("mods");
if (path == null)
return;
ArrayList<String> sl = IOUtils.findAllFile(new File(path));
DefaultTableModel model = (DefaultTableModel) lstExternalMods.getModel();
while (model.getRowCount() > 0)
model.removeRow(0);
for (String s : sl)
model.addRow(new Object[] { !SettingsManager.settings.inactiveExtMods.contains(s), s, ModType.getModTypeShowName(ModType.getModType(IOUtils.addSeparator(path) + s)) });
IOUtils.findAllFile(new File(path), s
-> model.addRow(new Object[] { !SettingsManager.settings.inactiveExtMods.contains(s), s, ModType.getModTypeShowName(ModType.getModType(IOUtils.addSeparator(path) + s)) })
);
lstExternalMods.updateUI();
}
@@ -2795,19 +2794,18 @@ public final class MainWindow extends javax.swing.JFrame
String path = Utilities.getPath("plugins");
if (path == null)
return;
ArrayList<String> sl = IOUtils.findAllFile(new File(path));
DefaultTableModel model = (DefaultTableModel) lstPlugins.getModel();
while (model.getRowCount() > 0)
model.removeRow(0);
for (String s : sl) {
PluginInformation p = PluginManager.getPluginYML(new File(Utilities.getGameDir() + "plugins" + File.separator + s));
if (p == null)
model.addRow(new Object[] { !SettingsManager.settings.inactivePlugins.contains(s), s,
"", "", "", "" });
else
model.addRow(new Object[] { !SettingsManager.settings.inactivePlugins.contains(s), s,
p.name, p.version, p.author, p.description });
}
IOUtils.findAllFile(new File(path), s -> {
PluginInformation p = PluginManager.getPluginYML(new File(Utilities.getGameDir() + "plugins" + File.separator + s));
if (p == null)
model.addRow(new Object[] { !SettingsManager.settings.inactivePlugins.contains(s), s,
"", "", "", "" });
else
model.addRow(new Object[] { !SettingsManager.settings.inactivePlugins.contains(s), s,
p.name, p.version, p.author, p.description });
});
lstPlugins.updateUI();
}
@@ -2816,37 +2814,35 @@ public final class MainWindow extends javax.swing.JFrame
String path = Utilities.getPath("coremods");
if (path == null)
return;
ArrayList<String> sl = IOUtils.findAllFile(new File(path));
DefaultTableModel model = (DefaultTableModel) lstCoreMods.getModel();
while (model.getRowCount() > 0)
model.removeRow(0);
for (String s : sl)
model.addRow(new Object[] { !SettingsManager.settings.inactiveCoreMods.contains(s), s, ModType.getModTypeShowName(ModType.getModType(IOUtils.addSeparator(path) + s)) });
IOUtils.findAllFile(new File(path), s
-> model.addRow(new Object[] { !SettingsManager.settings.inactiveCoreMods.contains(s), s, ModType.getModTypeShowName(ModType.getModType(IOUtils.addSeparator(path) + s)) }));
lstCoreMods.updateUI();
}
void loadWorlds() {
ArrayList<String> s = BackupManager.findAllWorlds();
DefaultTableModel model = (DefaultTableModel) lstWorlds.getModel();
if (SettingsManager.settings.inactiveWorlds == null)
SettingsManager.settings.inactiveWorlds = new ArrayList<>();
for (String world : s)
BackupManager.findAllWorlds(world -> {
model.addRow(new Object[] {
world, Utilities.getGameDir() + world, !SettingsManager.settings.inactiveWorlds.contains(world)
});
});
lstWorlds.updateUI();
}
void loadBackups() {
ArrayList<String> al = BackupManager.getBackupList();
DefaultTableModel model = (DefaultTableModel) lstBackups.getModel();
for (String backup : al) {
BackupManager.getBackupList(backup -> {
String[] names = FileUtils.getExtension(backup).split("\\+");
model.addRow(new Object[] {
names[0], names[1], names[2]
});
}
});
lstBackups.updateUI();
}
@@ -3007,17 +3003,16 @@ public final class MainWindow extends javax.swing.JFrame
}
void refreshInfos() {
ArrayList<String> al = IOUtils.findAllFile(new File(Utilities.getGameDir() + "infos-HMCSM"));
DefaultTableModel model = (DefaultTableModel) lstInfos.getModel();
for (String s : al)
model.addRow(new Object[] { s, FileUtils.getExtension(s) });
while (model.getRowCount() > 0)
model.removeRow(0);
IOUtils.findAllFile(new File(Utilities.getGameDir() + "infos-HMCSM"), s -> model.addRow(new Object[] { s, FileUtils.getExtension(s) }));
lstInfos.updateUI();
}
void refreshReports() {
ArrayList<String> al = IOUtils.findAllFile(new File(Utilities.getGameDir() + "crash-reports"));
for (String s : al)
lstCrashReportsModel.addElement(s);
lstCrashReportsModel.clear();
IOUtils.findAllFile(new File(Utilities.getGameDir() + "crash-reports"), s -> lstCrashReportsModel.addElement(s));
lstReports.setModel(lstCrashReportsModel);
}
@@ -3721,7 +3716,7 @@ public final class MainWindow extends javax.swing.JFrame
String id = (String) lstDownloads.getModel().getValueAt(lstDownloads.getSelectedRow(), 0);
final String MC_DOWNLOAD_URL = "https://s3.amazonaws.com/Minecraft.Download/versions/";
String url = MC_DOWNLOAD_URL + id + "/";
File serverjar = new File(IOUtils.currentDir(), "minecraft_server." + id + ".jar");
File serverjar = new File("minecraft_server." + id + ".jar");
serverjar.delete();
String downloadURL = url + "minecraft_server." + id + ".jar";
@@ -3739,7 +3734,7 @@ public final class MainWindow extends javax.swing.JFrame
if (index == -1)
return;
String path = Utilities.getGameDir() + "infos-HMCSM" + File.separator + model.getValueAt(index, 0);
String content = FileUtils.readFileToString(new File(path));
String content = FileUtils.read(new File(path));
txtInfo.setText(content);
} catch (IOException ex) {
HMCLog.warn("Failed to read info.", ex);
@@ -3747,14 +3742,14 @@ public final class MainWindow extends javax.swing.JFrame
}//GEN-LAST:event_btnShowInfoActionPerformed
private void btnAutoSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAutoSearchActionPerformed
ArrayList<String> al = IOUtils.findAllFile(IOUtils.currentDir());
for (String s : al)
if (ServerChecker.isServerJar(new File(s))) {
String path = IOUtils.tryGetCanonicalFilePath(new File(IOUtils.currentDir(), s));
txtMainJar.setText(path);
SettingsManager.settings.mainjar = path;
SettingsManager.save();
}
IOUtils.findAllFile(new File("."), s -> {
if (ServerChecker.isServerJar(new File(s))) {
String path = IOUtils.tryGetCanonicalFilePath(new File(s));
txtMainJar.setText(path);
SettingsManager.settings.mainjar = path;
SettingsManager.save();
}
});
}//GEN-LAST:event_btnAutoSearchActionPerformed
private void cboCategoryItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboCategoryItemStateChanged
@@ -3784,7 +3779,7 @@ public final class MainWindow extends javax.swing.JFrame
if (index == -1)
return;
String path = Utilities.getGameDir() + "crash-reports" + File.separator + lstCrashReportsModel.get(index);
String content = FileUtils.readFileToString(new File(path));
String content = FileUtils.read(new File(path));
txtCrashReport.setText(content);
} catch (IOException ex) {
HMCLog.warn("Failed to get crash-report.", ex);
@@ -3858,7 +3853,7 @@ public final class MainWindow extends javax.swing.JFrame
return;
}
BukkitVersion v = cb.get(idx);
File file = new File(IOUtils.currentDir(), "craftbukkit-" + ext + "-" + v.version + ".jar");
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();
}//GEN-LAST:event_btnDownloadCraftbukkitActionPerformed
@@ -3869,7 +3864,7 @@ public final class MainWindow extends javax.swing.JFrame
return;
ForgeVersion v = mcpcPackages.get(cboCauldronMinecraft.getSelectedItem().toString()).get(idx);
String url;
File filepath = new File(IOUtils.currentDir(), "forge-installer.jar");
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"));
@@ -3879,7 +3874,7 @@ public final class MainWindow extends javax.swing.JFrame
private void installMCPC(final File filepath) {
try {
ForgeInstaller installer = new ForgeInstaller(IOUtils.currentDir(), filepath);
ForgeInstaller installer = new ForgeInstaller(new File("."), filepath);
installer.install();
MessageBox.Show(C.i18n("install.success"));
} catch (Exception e) {
@@ -3910,7 +3905,7 @@ public final class MainWindow extends javax.swing.JFrame
}//GEN-LAST:event_cboCauldronMinecraftItemStateChanged
private void btnInstallMCPCActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnInstallMCPCActionPerformed
File filepath = new File(IOUtils.currentDir(), "forge-installer.jar");
File filepath = new File("forge-installer.jar");
if (!filepath.exists()) {
MessageBox.Show("您还未下载Cauldron!请点击下载按钮下载并自动安装!");
return;
@@ -22,9 +22,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
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;
/**
*
@@ -56,7 +58,7 @@ public class MonitorServiceImpl implements IMonitorService {
long freeMemory = Runtime.getRuntime().freeMemory() / kb;
// 最大可使用内存
long maxMemory = Runtime.getRuntime().maxMemory() / kb;
OperatingSystemMXBean osmxb = (OperatingSystemMXBean) java.lang.management.ManagementFactory.getOperatingSystemMXBean();
OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
// 操作系统
String osName = System.getProperty("os.name");
// 总的物理内存
@@ -72,8 +74,10 @@ public class MonitorServiceImpl implements IMonitorService {
double cpuRatio = 0;
if (osName.toLowerCase().startsWith("windows"))
cpuRatio = this.getCpuRatioForWindows();
else if (osName.toLowerCase().startsWith("mac"))
cpuRatio = this.getCpuRatioForMac();
else
cpuRatio = getCpuRateForLinux();
cpuRatio = this.getCpuRatioForLinux();
// 构造返回对象
MonitorInfoBean infoBean = new MonitorInfoBean();
infoBean.setFreeMemory(freeMemory);
@@ -88,56 +92,86 @@ public class MonitorServiceImpl implements IMonitorService {
return infoBean;
}
private static double getCpuRateForLinux() {
private static double getCpuRatioForLinux() {
float cpuUsage = 0;
Process pro1, pro2;
Runtime r = Runtime.getRuntime();
try {
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();
pro1.destroy();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
HMCLog.err("Failed to catch sysout", e);
}
//第二次采集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();
pro2.destroy();
} catch (IOException e) {
HMCLog.err("Failed to catch sysout", e);
}
return cpuUsage * 100;
}
private double getCpuRatioForMac() {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader brStat = null;
StringTokenizer tokenStat;
try {
Process process = Runtime.getRuntime().exec("top -b -n 1");
Process process = Runtime.getRuntime().exec("top -l 1");
is = process.getInputStream();
isr = new InputStreamReader(is);
brStat = new BufferedReader(isr);
if (linuxVersion == null || linuxVersion.equals("2.4")) {
brStat.readLine();
brStat.readLine();
brStat.readLine();
brStat.readLine();
tokenStat = new StringTokenizer(brStat.readLine());
tokenStat.nextToken();
tokenStat.nextToken();
String user = tokenStat.nextToken();
tokenStat.nextToken();
String system = tokenStat.nextToken();
tokenStat.nextToken();
String nice = tokenStat.nextToken();
System.out.println(user + " , " + system + " , " + nice);
user = user.substring(0, user.indexOf("%"));
system = system.substring(0, system.indexOf("%"));
nice = nice.substring(0, nice.indexOf("%"));
float userUsage = new Float(user);
float systemUsage = new Float(system);
float niceUsage = new Float(nice);
return (userUsage + systemUsage + niceUsage) / 100;
} else {
brStat.readLine();
brStat.readLine();
tokenStat = new StringTokenizer(brStat.readLine());
tokenStat.nextToken();
tokenStat.nextToken();
tokenStat.nextToken();
tokenStat.nextToken();
tokenStat.nextToken();
tokenStat.nextToken();
tokenStat.nextToken();
String cpuUsage = tokenStat.nextToken();
System.out.println("CPU idle : " + cpuUsage);
Float usage = new Float(cpuUsage.substring(0, cpuUsage.indexOf("%")));
return (1 - usage / 100);
}
brStat.readLine();
brStat.readLine();
brStat.readLine();
tokenStat = new StringTokenizer(brStat.readLine());
tokenStat.nextToken();
tokenStat.nextToken();
String user = tokenStat.nextToken();
tokenStat.nextToken();
String system = tokenStat.nextToken();
tokenStat.nextToken();
user = user.substring(0, user.indexOf("%"));
system = system.substring(0, system.indexOf("%"));
float userUsage = new Float(user);
float systemUsage = new Float(system);
return (userUsage + systemUsage) / 100;
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
freeResource(is, isr, brStat);
return 1;
} finally {
freeResource(is, isr, brStat);
-5
View File
@@ -20,12 +20,9 @@ import java.util.jar.Pack200
import java.util.zip.GZIPOutputStream
import java.security.MessageDigest
apply plugin: 'java'
apply plugin: 'maven'
//sourceCompatibility = '1.7'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
repositories {
@@ -39,8 +36,6 @@ buildscript {
}
dependencies {
// Adding dependencies here will add the dependencies to each subproject.
compile 'com.google.code.gson:gson:2.2.4' // Apache License 2.0
}