Compare commits

...
12 Commits
27 ... 38
36 changed files with 307 additions and 222 deletions

No files matched your search

@@ -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);
@@ -30,6 +30,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.Utils;
import org.jackhuang.hellominecraft.util.func.Function;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.tasks.Task;
@@ -55,6 +56,8 @@ public class MinecraftAssetService extends IMinecraftAssetService {
}
public Task downloadAssets(final MinecraftVersion mv) {
if (mv == null)
return null;
return new TaskInfo("Download Assets") {
Collection<Task> afters = new HashSet<>();
@@ -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,7 +24,7 @@ package org.jackhuang.hellominecraft.launcher.core.download;
public class CurseDownloadProvider 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://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.readFileToStringQuietly(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;
}
};
}
}
@@ -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");
}
@@ -64,7 +64,7 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
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 FileDownloadTask(service.getDownloadType().getProvider().getParsedDownloadURL(v.installer), filepath).setTag("forge"))
.append(new ForgeInstaller(service, filepath))
.create();
}
@@ -51,7 +51,7 @@ public class MinecraftForgeVersionList extends InstallerVersionList {
public void refreshList(String[] needed) throws Exception {
if (root != null)
return;
String s = NetUtils.get(DownloadType.getSuggestedDownloadType().getProvider().getParsedLibraryDownloadURL(C.URL_FORGE_LIST));
String s = NetUtils.get(DownloadType.getSuggestedDownloadType().getProvider().getParsedDownloadURL(C.URL_FORGE_LIST));
root = C.GSON.fromJson(s, MinecraftForgeVersionRoot.class);
@@ -70,7 +70,7 @@ public class MinecraftForgeVersionList extends InstallerVersionList {
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);
String url = DownloadType.getSuggestedDownloadType().getProvider().getParsedDownloadURL(root.webpath + ver + "/" + filename);
switch (f[1]) {
case "installer":
iv.installer = url;
@@ -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");
@@ -166,7 +168,7 @@ public final class ModpackManager {
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));
if (!json.renameTo(new File(nowFile, id + ".json")))
@@ -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.
@@ -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
@@ -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);
}
}
@@ -46,8 +46,12 @@ public final class Profile {
}
public Profile(String name) {
this(name, new File(IOUtils.currentDir(), ".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,6 +25,7 @@ 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;
@@ -40,6 +41,7 @@ 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");
@@ -55,7 +57,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();
@@ -81,8 +83,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 +155,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);
@@ -388,43 +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 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>
<EmptySpace 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"/>
<EmptySpace 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" 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>
<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="664" 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">
<EmptySpace max="-2" attributes="0"/>
<Component id="chkNoJVMArgs" min="-2" max="-2" 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 type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="chkNoJVMArgs" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
@@ -103,8 +103,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);
@@ -949,8 +951,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
@@ -1376,10 +1377,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 +1428,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>
}
@@ -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;
@@ -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;
@@ -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;
};
}
@@ -48,7 +48,7 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler {
put("MessageBox", "");
put("AWTError", "");
put("JFileChooser", "Has your operating system been installed completely or is a ghost system? ");
put("JceSecurity", "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");
@@ -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;
});
}
}
}
@@ -93,6 +93,7 @@ public class ZipEngine {
if (file.isDirectory()) {
pathName = file.getPath().substring(basePath.length() + 1)
+ "/";
pathName = pathName.replace('\\', '/');
if (pathNameCallback != null)
pathName = pathNameCallback.apply(pathName, true);
if (pathName == null)
@@ -100,9 +101,10 @@ public class ZipEngine {
zos.putNextEntry(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)
@@ -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);
}
}
@@ -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
@@ -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;
}
@@ -297,7 +297,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 +311,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 +364,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=(发现更新!)
@@ -297,7 +297,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 +311,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 +364,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!)
@@ -364,7 +364,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!)
@@ -364,7 +364,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!)
@@ -297,7 +297,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 +311,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 +364,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=(發現更新!)
@@ -297,7 +297,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 +311,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 +364,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!)
@@ -22,6 +22,7 @@ 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;
@@ -56,7 +57,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,6 +73,8 @@ 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();
// 构造返回对象
@@ -137,7 +140,39 @@ public class MonitorServiceImpl implements IMonitorService {
}
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
return 1;
} finally {
freeResource(is, isr, brStat);
}
}
private double getCpuRatioForMac() {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader brStat = null;
StringTokenizer tokenStat;
try {
Process process = Runtime.getRuntime().exec("top -l 1");
is = process.getInputStream();
isr = new InputStreamReader(is);
brStat = new BufferedReader(isr);
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());
return 1;
} finally {
freeResource(is, isr, brStat);