From d20d06ace7dd232f62049ff8bf128f264a2d2c71 Mon Sep 17 00:00:00 2001 From: huangyuhui Date: Fri, 12 Feb 2016 11:30:02 +0800 Subject: [PATCH] Fixed a lot of bugs --- HMCL/build.gradle | 2 +- .../yggdrasil/YggdrasilAuthentication.java | 5 +- .../core/launch/AbstractMinecraftLoader.java | 2 + .../core/launch/DefaultGameLauncher.java | 8 ++- .../launcher/setting/Settings.java | 12 ++++- .../launcher/ui/AnimatedPanel.java | 4 ++ .../launcher/ui/GameSettingsPanel.java | 6 ++- .../hellominecraft/launcher/ui/MainFrame.java | 1 + .../launcher/ui/MainPagePanel.java | 4 +- .../launcher/ui/Selectable.java | 2 + .../modpack/ModpackInitializationPanel.java | 18 ++++--- .../util/DefaultMinecraftService.java | 11 ++++- .../launcher/util/HMCLGameProvider.java | 11 +++-- .../util/upgrade/AppDataUpgrader.java | 49 +++++++++++-------- .../hellominecraft/util/UpdateChecker.java | 1 - .../util/tasks/download/FileDownloadTask.java | 2 + common.gradle | 15 +++++- 17 files changed, 109 insertions(+), 44 deletions(-) diff --git a/HMCL/build.gradle b/HMCL/build.gradle index 13c3c16c3..8bca5a987 100755 --- a/HMCL/build.gradle +++ b/HMCL/build.gradle @@ -29,7 +29,7 @@ if (!hasProperty('mainClass')) { def buildnumber = System.getenv("BUILD_NUMBER") == null ? ".10" : "."+System.getenv("BUILD_NUMBER") String mavenGroupId = 'HMCL' -String mavenVersion = '2.4.0' + buildnumber +String mavenVersion = '2.3.5' + buildnumber String bundleName = "Hello Minecraft! Launcher" group = mavenGroupId diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/YggdrasilAuthentication.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/YggdrasilAuthentication.java index a2647a16c..93a79777e 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/YggdrasilAuthentication.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/auth/yggdrasil/YggdrasilAuthentication.java @@ -96,7 +96,10 @@ public class YggdrasilAuthentication { } public GameProfile[] getAvailableProfiles() { - return profiles.clone(); + if (profiles == null) + return null; + else + return profiles.clone(); } public String getAuthenticatedToken() { diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/AbstractMinecraftLoader.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/AbstractMinecraftLoader.java index 0083dbbef..dce7f2068 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/AbstractMinecraftLoader.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/AbstractMinecraftLoader.java @@ -50,6 +50,8 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader { protected final MinecraftVersion version; public AbstractMinecraftLoader(LaunchOptions options, IMinecraftService service, String versionId, UserProfileProvider lr) throws GameException { + if (service.version().getVersionById(versionId) == null) + throw new GameException("No version: " + versionId); this.lr = lr; this.options = options; diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java index f301a3af4..5120293df 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/core/launch/DefaultGameLauncher.java @@ -18,6 +18,7 @@ package org.jackhuang.hellominecraft.launcher.core.launch; import java.io.IOException; +import java.util.HashSet; import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.logging.HMCLog; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; @@ -40,8 +41,13 @@ public class DefaultGameLauncher extends GameLauncher { downloadLibrariesEvent.register((sender, t) -> { final TaskWindow.TaskWindowFactory dw = TaskWindow.factory(); ParallelTask parallelTask = new ParallelTask(); - for (DownloadLibraryJob s : t) + HashSet names = new HashSet<>(); + for (DownloadLibraryJob s : t) { + if (names.contains(s.name)) + continue; + names.add(s.name); parallelTask.addDependsTask(new LibraryDownloadTask(s)); + } dw.append(parallelTask); boolean flag = true; if (t.size() > 0) diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Settings.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Settings.java index f85366aa5..a0a14e090 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Settings.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/setting/Settings.java @@ -99,9 +99,15 @@ public final class Settings { } public static Profile getProfile(String name) { + Profile p; if (name == null) - return getProfiles().get("Default"); - return getProfiles().get(name); + p = getProfiles().get("Default"); + else + p = getProfiles().get(name); + if (p == null) + if (!getProfiles().containsKey(DEFAULT_PROFILE)) + getProfiles().put(DEFAULT_PROFILE, p = new Profile()); + return p; } public static Map getProfiles() { @@ -144,6 +150,8 @@ public final class Settings { static void onProfileChanged() { Profile p = getLastProfile(); + if (p == null) + throw new Error("No profiles here, it should not happen"); profileChangedEvent.execute(p); p.onSelected(); } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/AnimatedPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/AnimatedPanel.java index 98d43f16b..4a989c8e1 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/AnimatedPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/AnimatedPanel.java @@ -107,4 +107,8 @@ public class AnimatedPanel extends JPanel implements Selectable { public void onLeaving() { selected = false; } + + @Override + public void onCreated() { + } } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.java index ff2893b0f..aa6372eda 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/GameSettingsPanel.java @@ -1300,8 +1300,8 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget } @Override - public void onSelected() { - super.onSelected(); + public void onCreated() { + super.onCreated(); Settings.onProfileLoading(); } @@ -1387,6 +1387,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget private final javax.swing.JPanel pnlGameDownloads; // + // final Runnable onLoadingProfiles = this::loadProfiles; private void loadProfiles() { @@ -1436,4 +1437,5 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget ((DefaultComboBoxModel) cboProfiles.getModel()).setSelectedItem(t.getName()); txtGameDir.setText(t.getGameDir()); }; + // } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainFrame.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainFrame.java index 53ce9e62e..49e99ab23 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainFrame.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainFrame.java @@ -275,6 +275,7 @@ public final class MainFrame extends DraggableFrame { if (tabContent[i] == null) { try { tabContent[i] = tabClasses.get(i).newInstance(); + tabContent[i].onCreated(); } catch (Exception mustnothappen) { throw new Error(mustnothappen); } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.java index 21cadc1fc..6912146fb 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/MainPagePanel.java @@ -418,8 +418,8 @@ public class MainPagePanel extends AnimatedPanel { } @Override - public void onSelected() { - super.onSelected(); + public void onCreated() { + super.onCreated(); Settings.onProfileLoading(); } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/Selectable.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/Selectable.java index d3a587706..d6768bc6e 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/Selectable.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/Selectable.java @@ -23,6 +23,8 @@ package org.jackhuang.hellominecraft.launcher.ui; */ public interface Selectable { + void onCreated(); + void onSelected(); boolean isSelected(); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackInitializationPanel.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackInitializationPanel.java index b2e016629..cbb369326 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackInitializationPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/ui/modpack/ModpackInitializationPanel.java @@ -48,7 +48,7 @@ public class ModpackInitializationPanel extends javax.swing.JPanel { wizardData.put(KEY_GAME_VERSION, versions); configureComboContents(); - controller.setProblem(C.i18n("modpack.not_a_valid_location")); + checkProblem(); } private void configureComboContents() { @@ -170,10 +170,7 @@ public class ModpackInitializationPanel extends javax.swing.JPanel { private void txtModpackLocationCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_txtModpackLocationCaretUpdate wizardData.put(KEY_MODPACK_LOCATION, txtModpackLocation.getText()); - if (txtModpackLocation.getText().trim().isEmpty()) - controller.setProblem(C.i18n("modpack.not_a_valid_location")); - else - controller.setProblem(null); + checkProblem(); }//GEN-LAST:event_txtModpackLocationCaretUpdate private void cboGameVersionItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboGameVersionItemStateChanged @@ -183,11 +180,16 @@ public class ModpackInitializationPanel extends javax.swing.JPanel { private void txtModpackNameCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_txtModpackNameCaretUpdate wizardData.put(KEY_MODPACK_NAME, txtModpackName.getText()); + checkProblem(); + }//GEN-LAST:event_txtModpackNameCaretUpdate + + void checkProblem() { + controller.setProblem(null); + if (txtModpackLocation.getText().trim().isEmpty()) + controller.setProblem(C.i18n("modpack.not_a_valid_location")); if (txtModpackName.getText().trim().isEmpty()) controller.setProblem(C.i18n("modpack.not_a_valid_name")); - else - controller.setProblem(null); - }//GEN-LAST:event_txtModpackNameCaretUpdate + } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JComboBox cboGameVersion; diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/DefaultMinecraftService.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/DefaultMinecraftService.java index 4833d0a73..bdac9ca0a 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/DefaultMinecraftService.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/DefaultMinecraftService.java @@ -83,13 +83,15 @@ public class DefaultMinecraftService extends IMinecraftService { private void loadVersionSetting(String id) { if (provider.getVersionById(id) == null) return; - VersionSetting vs = new VersionSetting(); + VersionSetting vs = null; File f = new File(provider.versionRoot(id), "hmclversion.cfg"); if (f.exists()) { String s = FileUtils.readFileToStringQuietly(f); if (s != null) vs = C.GSON.fromJson(s, VersionSetting.class); } + if (vs == null) + vs = new VersionSetting(); vs.id = id; vs.propertyChanged.register((sender, t) -> { saveVersionSetting(((VersionSetting) sender).id); @@ -98,6 +100,13 @@ public class DefaultMinecraftService extends IMinecraftService { versionSettings.put(id, vs); } + /** + * Get the version setting for version id. + * + * @param id version id + * + * @return may return null if the id not exists + */ public VersionSetting getVersionSetting(String id) { if (!versionSettings.containsKey(id)) loadVersionSetting(id); diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLGameProvider.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLGameProvider.java index 27303ee1f..f243d6053 100644 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLGameProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/HMCLGameProvider.java @@ -20,6 +20,7 @@ package org.jackhuang.hellominecraft.launcher.util; import java.io.File; import org.jackhuang.hellominecraft.launcher.core.version.GameDirType; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersionManager; +import org.jackhuang.hellominecraft.launcher.setting.VersionSetting; /** * @@ -33,8 +34,12 @@ public class HMCLGameProvider extends MinecraftVersionManager { @Override public File getRunDirectory(String id) { - return ((DefaultMinecraftService) service).getVersionSetting(id).getGameDirType() == GameDirType.VERSION_FOLDER - ? service.version().versionRoot(id) - : super.getRunDirectory(id); + VersionSetting vs = ((DefaultMinecraftService) service).getVersionSetting(id); + if (vs == null) + return super.getRunDirectory(id); + else + return ((DefaultMinecraftService) service).getVersionSetting(id).getGameDirType() == GameDirType.VERSION_FOLDER + ? service.version().versionRoot(id) + : super.getRunDirectory(id); } } diff --git a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/AppDataUpgrader.java b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/AppDataUpgrader.java index 66e9eab3d..15349e450 100755 --- a/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/AppDataUpgrader.java +++ b/HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/util/upgrade/AppDataUpgrader.java @@ -57,6 +57,24 @@ import org.jackhuang.hellominecraft.util.system.OS; */ public class AppDataUpgrader extends IUpgrader { + private boolean launchNewerVersion(String[] args, File jar) throws Exception { + try (JarFile jarFile = new JarFile(jar)) { + String mainClass = jarFile.getManifest().getMainAttributes().getValue("Main-Class"); + if (mainClass != null) { + ArrayList al = new ArrayList<>(Arrays.asList(args)); + al.add("nofound"); + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + new URLClassLoader(new URL[] { jar.toURI().toURL() }, + URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass) + .getMethod("main", String[].class).invoke(null, new Object[] { al.toArray(new String[0]) }); + return null; + }); + return true; + } + } + return false; + } + @Override public boolean parseArguments(VersionNumber nowVersion, String[] args) { if (!ArrayUtils.contains(args, "nofound")) @@ -70,20 +88,7 @@ public class AppDataUpgrader extends IUpgrader { if (j != null) { File jar = new File(j); if (jar.exists()) - try (JarFile jarFile = new JarFile(jar)) { - String mainClass = jarFile.getManifest().getMainAttributes().getValue("Main-Class"); - if (mainClass != null) { - ArrayList al = new ArrayList<>(Arrays.asList(args)); - al.add("notfound"); - AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - new URLClassLoader(new URL[] { jar.toURI().toURL() }, - URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass) - .getMethod("main", String[].class).invoke(null, new Object[] { al.toArray(new String[0]) }); - return null; - }); - return true; - } - } + return launchNewerVersion(args, jar); } } } @@ -98,7 +103,10 @@ public class AppDataUpgrader extends IUpgrader { ((UpdateChecker) sender).requestDownloadLink().reg(map -> { if (map != null && map.containsKey("pack")) try { - if (TaskWindow.factory().append(new AppDataUpgraderTask(map.get("pack"), number.version)).create()) { + String hash = null; + if (map.containsKey("packsha1")) + hash = map.get("packsha1"); + if (TaskWindow.factory().append(new AppDataUpgraderTask(map.get("pack"), number.version, hash)).create()) { new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(number.version).getAbsolutePath() }).directory(new File(".")).start(); System.exit(0); } @@ -137,18 +145,19 @@ public class AppDataUpgrader extends IUpgrader { return new File(BASE_FOLDER, "HMCL-" + ver + ".jar"); } - private final String downloadLink, newestVersion; + private final String downloadLink, newestVersion, expectedHash; File tempFile; - public AppDataUpgraderTask(String downloadLink, String newestVersion) throws IOException { + public AppDataUpgraderTask(String downloadLink, String newestVersion, String hash) throws IOException { this.downloadLink = downloadLink; this.newestVersion = newestVersion; - tempFile = File.createTempFile("hmcl", ".pack.xz"); + this.expectedHash = hash; + tempFile = File.createTempFile("hmcl", ".pack.gz"); } @Override public Collection getDependTasks() { - return Arrays.asList(new FileDownloadTask(downloadLink, tempFile)); + return Arrays.asList(new FileDownloadTask(downloadLink, tempFile, expectedHash)); } @Override @@ -169,7 +178,7 @@ public class AppDataUpgrader extends IUpgrader { json.put("ver", newestVersion); json.put("loc", f.getAbsolutePath()); String result = C.GSON.toJson(json); - FileUtils.write(HMCL_VER_FILE, result); + FileUtils.writeStringToFile(HMCL_VER_FILE, result); } @Override diff --git a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/UpdateChecker.java b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/UpdateChecker.java index bbf14a425..e440e0995 100755 --- a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/UpdateChecker.java +++ b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/UpdateChecker.java @@ -44,7 +44,6 @@ public final class UpdateChecker implements IUpdateChecker { return new OverridableSwingWorker() { @Override protected void work() throws Exception { - if (value == null) { versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type); value = VersionNumber.check(versionString); diff --git a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/FileDownloadTask.java b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/FileDownloadTask.java index 6b42f96fd..0cbb367e7 100755 --- a/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/FileDownloadTask.java +++ b/HMCLAPI/src/main/java/org/jackhuang/hellominecraft/util/tasks/download/FileDownloadTask.java @@ -177,6 +177,8 @@ public class FileDownloadTask extends Task implements PreviousResult, Prev lastTime = now; } } + if (downloaded != contentLength) + throw new IllegalStateException("Unexptected file size: " + downloaded + ", expected: " + contentLength); closeFiles(); if (aborted) tempFile.delete(); diff --git a/common.gradle b/common.gradle index aa80ac75b..1f42145e5 100755 --- a/common.gradle +++ b/common.gradle @@ -18,6 +18,8 @@ import java.util.jar.JarFile import java.util.jar.Pack200 import java.util.zip.GZIPOutputStream +import java.security.MessageDigest + apply plugin: 'java' @@ -94,6 +96,15 @@ task makePackGZ(dependsOn: jar) << { } def loc = new File(project.buildDir, "libs/" + makeExecutableoutjar.getName().substring(0, makeExecutableoutjar.getName().length()-4)+".pack.gz") def os = new GZIPOutputStream(new FileOutputStream(loc)) - Pack200.newPacker().pack(new JarFile(makeExecutableinjar), os) + Pack200.newPacker().pack new JarFile(makeExecutableinjar), os os.close() -} \ No newline at end of file + + def messageDigest = MessageDigest.getInstance("SHA1") + loc.eachByte 1024 * 1024, { byte[] buf, int bytesRead -> + messageDigest.update(buf, 0, bytesRead); + } + def sha1Hex = new BigInteger(1, messageDigest.digest()).toString(16).padLeft(40, '0') + def fileEx = new File(project.buildDir, "libs/" + makeExecutableoutjar.getName().substring(0, makeExecutableoutjar.getName().length()-4)+".sha1") + if (!fileEx.exists()) fileEx.createNewFile() + fileEx.append sha1Hex +}