Supported 16w05a version json

This commit is contained in:
huangyuhui 2016-02-06 12:56:16 +08:00
parent b0845c700f
commit 0e4c38d99e
26 changed files with 270 additions and 103 deletions

View File

@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.launcher.core.asset;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
@ -49,11 +50,11 @@ public class AssetsMojangLoader extends IAssetsHandler {
protected void work() throws Exception {
if (mv == null)
throw new IllegalArgumentException("AssetsMojangLoader: null argument: MinecraftVersion");
String assetsId = mv.assets == null ? "legacy" : mv.assets;
String assetsId = mv.getAssetsIndex().getId();
File assets = mp.getAssets();
HMCLog.log("Gathering asset index: " + assetsId);
File f = IOUtils.tryGetCanonicalFile(new File(assets, "indexes/" + assetsId + ".json"));
if (!f.exists() && !mp.downloadMinecraftAssetsIndex(assetsId))
if (!f.exists() && !mp.downloadMinecraftAssetsIndex(mv.getAssetsIndex()))
throw new IllegalStateException("Failed to get index json");
String result = FileUtils.readFileToString(f);
@ -64,8 +65,12 @@ public class AssetsMojangLoader extends IAssetsHandler {
assetsLocalNames = new ArrayList<>();
ArrayList<String> al = new ArrayList<>();
contents = new ArrayList<>();
HashSet<String> loadedHashes = new HashSet<>();
if (o != null && o.getFileMap() != null)
for (Map.Entry<String, AssetsObject> e : o.getFileMap().entrySet()) {
if (loadedHashes.contains(e.getValue().getHash()))
continue;
loadedHashes.add(e.getValue().getHash());
Contents c = new Contents();
c.eTag = e.getValue().getHash();
c.key = c.eTag.substring(0, 2) + "/" + e.getValue().getHash();

View File

@ -23,6 +23,7 @@ import java.io.IOException;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.core.version.AssetIndexDownloadInfo;
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.tasks.Task;
@ -49,7 +50,7 @@ public class MinecraftAssetService extends IMinecraftAssetService {
public void executeTask() throws Throwable {
IAssetsHandler type = IAssetsHandler.ASSETS_HANDLER;
type.getList(service.version().getVersionById(mcVersion), service.asset())
.reg((t) -> TaskWindow.getInstance().addTask(type.getDownloadTask(service.getDownloadType().getProvider())).start()).execute();
.reg((t) -> TaskWindow.factory().append(type.getDownloadTask(service.getDownloadType().getProvider())).create()).execute();
}
@Override
@ -64,26 +65,28 @@ public class MinecraftAssetService extends IMinecraftAssetService {
MinecraftVersion mv = service.version().getVersionById(id);
if (mv == null)
return false;
return downloadMinecraftAssetsIndex(mv.assets);
return downloadMinecraftAssetsIndex(mv.getAssetsIndex());
}
@Override
public boolean downloadMinecraftAssetsIndex(String assetsId) {
String aurl = service.getDownloadType().getProvider().getIndexesDownloadURL();
public boolean downloadMinecraftAssetsIndex(AssetIndexDownloadInfo assets) {
String aurl = service.getDownloadType().getProvider().getIndexesDownloadURL() + assets.getId() + ".json";
if (assets.url != null && service.getDownloadType().getProvider().isAllowedToUseSelfURL())
aurl = assets.url;
File assetsLocation = getAssets();
if (!assetsLocation.exists() && !assetsLocation.mkdirs())
HMCLog.warn("Failed to make directories: " + assetsLocation);
File assetsIndex = new File(assetsLocation, "indexes/" + assetsId + ".json");
File assetsIndex = new File(assetsLocation, "indexes/" + assets.getId() + ".json");
File renamed = null;
if (assetsIndex.exists()) {
renamed = new File(assetsLocation, "indexes/" + assetsId + "-renamed.json");
renamed = new File(assetsLocation, "indexes/" + assets.getId() + "-renamed.json");
if (assetsIndex.renameTo(renamed))
HMCLog.warn("Failed to rename " + assetsIndex + " to " + renamed);
}
if (TaskWindow.getInstance()
.addTask(new FileDownloadTask(aurl + assetsId + ".json", IOUtils.tryGetCanonicalFile(assetsIndex)).setTag(assetsId + ".json"))
.start()) {
if (TaskWindow.factory()
.append(new FileDownloadTask(aurl, IOUtils.tryGetCanonicalFile(assetsIndex), assets.sha1).setTag(assets.getId() + ".json"))
.create()) {
if (renamed != null && !renamed.delete())
HMCLog.warn("Failed to delete " + renamed + ", maybe you should do it.");
return true;

View File

@ -21,11 +21,14 @@ import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftDownloadServ
import com.google.gson.JsonSyntaxException;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.core.version.GameDownloadInfo;
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
@ -33,7 +36,7 @@ import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
import org.jackhuang.hellominecraft.util.NetUtils;
import org.jackhuang.hellominecraft.util.OverridableSwingWorker;
import org.jackhuang.hellominecraft.util.system.FileUtils;
import org.jackhuang.hellominecraft.util.system.IOUtils;
import org.jackhuang.hellominecraft.util.tasks.DoingDoneListener;
import org.jackhuang.hellominecraft.util.tasks.Task;
import org.jackhuang.hellominecraft.util.version.MinecraftRemoteVersion;
import org.jackhuang.hellominecraft.util.version.MinecraftRemoteVersions;
@ -83,19 +86,51 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
if (mvj.exists() && !mvj.delete())
HMCLog.warn("Failed to delete " + mvj);
if (TaskWindow.getInstance()
.addTask(new FileDownloadTask(vurl + id + ".json", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".json"))
.addTask(new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvj)).setTag(id + ".jar"))
.start())
Task t = new FileDownloadTask(vurl + id + ".json", 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);
} catch (JsonSyntaxException ex) {
HMCLog.err("Failed to parse minecraft version json.", ex);
onFailed(k);
return;
}
String jarURL = vurl + id + ".jar", hash = null;
if (service.getDownloadType().getProvider().isAllowedToUseSelfURL() && mv.downloads != null) {
GameDownloadInfo gdi = mv.downloads.get("client");
if (gdi != null) {
if (gdi.url != null)
jarURL = gdi.url;
if (gdi.sha1 != null)
hash = gdi.sha1;
}
}
taskCollection.add(new FileDownloadTask(jarURL, mvj, hash).setTag(id + ".jar"));
}
@Override
public void onDoing(Task k, Collection<Task> taskCollection) {
}
@Override
public void onFailed(Task k) {
FileUtils.deleteDirectoryQuietly(vpath);
}
});
if (!TaskWindow.factory().append(t).create())
return null;
try {
return C.GSON.fromJson(FileUtils.readFileToStringQuietly(mvt), MinecraftVersion.class);
} catch (JsonSyntaxException ex) {
HMCLog.err("Failed to parse minecraft version json.", ex);
}
else
FileUtils.deleteDirectoryQuietly(vpath);
return null;
}
}
@Override
public boolean downloadMinecraftJar(String id) {
@ -110,9 +145,9 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
File mvt = new File(vpath, id + ".jar");
if (!vpath.exists() && !vpath.mkdirs())
HMCLog.warn("Failed to make version folder " + vpath);
if (TaskWindow.getInstance()
.addTask(new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".jar"))
.start()) {
if (TaskWindow.factory()
.append(new FileDownloadTask(vurl + id + ".jar", mvt).setTag(id + ".jar"))
.create()) {
if (moved != null && moved.exists() && !moved.delete())
HMCLog.warn("Failed to delete " + moved);
return true;
@ -128,7 +163,7 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
@Override
public Task downloadMinecraftJarTo(String id, File mvt) {
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
return new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".jar");
return new FileDownloadTask(vurl + id + ".jar", mvt).setTag(id + ".jar");
}
@Override
@ -144,9 +179,9 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
File mvt = new File(vpath, id + ".json");
if (!vpath.exists() && !vpath.mkdirs())
HMCLog.warn("Failed to make version folder " + vpath);
if (TaskWindow.getInstance()
.addTask(new FileDownloadTask(vurl + id + ".json", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".json"))
.start()) {
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;

View File

@ -63,10 +63,10 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
public void executeTask() {
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "forge-installer.jar");
if (v.installer != null)
TaskWindow.getInstance()
.addTask(new FileDownloadTask(service.getDownloadType().getProvider().getParsedLibraryDownloadURL(v.installer), filepath).setTag("forge"))
.addTask(new ForgeInstaller(service, filepath))
.start();
TaskWindow.factory()
.append(new FileDownloadTask(service.getDownloadType().getProvider().getParsedLibraryDownloadURL(v.installer), filepath).setTag("forge"))
.append(new ForgeInstaller(service, filepath))
.create();
}
};
}
@ -79,10 +79,10 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "optifine-installer.jar");
if (v.installer != null) {
OptiFineDownloadFormatter task = new OptiFineDownloadFormatter(v.installer);
TaskWindow.getInstance().addTask(task)
.addTask(new FileDownloadTask(filepath).registerPreviousResult(task).setTag("optifine"))
.addTask(new OptiFineInstaller(service, installId, v, filepath))
.start();
TaskWindow.factory().append(task)
.append(new FileDownloadTask(filepath).registerPreviousResult(task).setTag("optifine"))
.append(new OptiFineInstaller(service, installId, v, filepath))
.create();
}
}
};
@ -95,9 +95,9 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
public void executeTask() {
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "liteloader-universal.jar");
FileDownloadTask task = (FileDownloadTask) new FileDownloadTask(v.universal, filepath).setTag("LiteLoader");
TaskWindow.getInstance()
.addTask(task).addTask(new LiteLoaderInstaller(service, installId, (LiteLoaderVersionList.LiteLoaderInstallerVersion) v).registerPreviousResult(task))
.start();
TaskWindow.factory()
.append(task).append(new LiteLoaderInstaller(service, installId, (LiteLoaderVersionList.LiteLoaderInstallerVersion) v).registerPreviousResult(task))
.create();
}
};
}

View File

@ -39,14 +39,14 @@ public class DefaultGameLauncher extends GameLauncher {
private void register() {
downloadLibrariesEvent.register((sender, t) -> {
final TaskWindow.TaskWindowFactory dw = TaskWindow.getInstance();
final TaskWindow.TaskWindowFactory dw = TaskWindow.factory();
ParallelTask parallelTask = new ParallelTask();
for (DownloadLibraryJob s : t)
parallelTask.addDependsTask(new LibraryDownloadTask(s));
dw.addTask(parallelTask);
dw.append(parallelTask);
boolean flag = true;
if (t.size() > 0)
flag = dw.start();
flag = dw.create();
if (!flag && MessageBox.Show(C.i18n("launch.not_finished_downloading_libraries"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
flag = true;
return flag;

View File

@ -29,7 +29,7 @@ import org.jackhuang.hellominecraft.util.system.JdkVersion;
public class LaunchOptions {
private String name, versionName, javaArgs, minecraftArgs, maxMemory, permSize, width, height, serverIp;
private String proxyHost, proxyPort, proxyUser, proxyPass, javaDir, launchVersion;
private String proxyHost, proxyPort, proxyUser, proxyPass, javaDir, launchVersion, type, precalledCommand;
private boolean fullscreen, debug, noJVMArgs, canceledWrapper;
private JdkVersion java;
private File gameDir;
@ -207,8 +207,6 @@ public class LaunchOptions {
this.proxyPass = proxyPass;
}
private String precalledCommand;
public String getPrecalledCommand() {
return precalledCommand;
}
@ -224,4 +222,12 @@ public class LaunchOptions {
public void setLaunchVersion(String launchVersion) {
this.launchVersion = launchVersion;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@ -25,7 +25,6 @@ import java.util.List;
import java.util.Map;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.launcher.Main;
import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
import org.jackhuang.hellominecraft.util.system.IOUtils;
@ -72,7 +71,7 @@ public class MinecraftLoader extends AbstractMinecraftLoader {
if (!checkAssetsExist())
if (MessageBox.Show(C.i18n("assets.no_assets"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
IAssetsHandler.ASSETS_HANDLER.getList(version, service.asset()).run();
TaskWindow.getInstance().addTask(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider())).start();
TaskWindow.factory().append(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider())).create();
}
String game_assets = reconstructAssets().getAbsolutePath();
@ -81,14 +80,15 @@ public class MinecraftLoader extends AbstractMinecraftLoader {
t = t.replace("${auth_player_name}", lr.getUserName());
t = t.replace("${auth_session}", lr.getSession());
t = t.replace("${auth_uuid}", lr.getUserId());
t = t.replace("${version_name}", Main.makeTitle());
t = t.replace("${version_name}", options.getVersionName());
t = t.replace("${profile_name}", options.getName());
t = t.replace("${version_type}", options.getType());
t = t.replace("${game_directory}", service.version().getRunDirectory(version.id).getAbsolutePath());
t = t.replace("${game_assets}", game_assets);
t = t.replace("${assets_root}", service.asset().getAssets().getAbsolutePath());
t = t.replace("${auth_access_token}", lr.getAccessToken());
t = t.replace("${user_type}", lr.getUserType());
t = t.replace("${assets_index_name}", version.getAssets());
t = t.replace("${assets_index_name}", version.getAssetsIndex().getId());
t = t.replace("${user_properties}", lr.getUserProperties());
res.add(t);
}
@ -105,7 +105,7 @@ public class MinecraftLoader extends AbstractMinecraftLoader {
try {
if (OS.os() == OS.OSX) {
list.add("-Xdock:icon=" + service.asset().getAssetObject(version.assets, "icons/minecraft.icns").getAbsolutePath());
list.add("-Xdock:icon=" + service.asset().getAssetObject(version.getAssetsIndex().getId(), "icons/minecraft.icns").getAbsolutePath());
list.add("-Xdock:name=Minecraft");
}
} catch (IOException e) {
@ -117,7 +117,7 @@ public class MinecraftLoader extends AbstractMinecraftLoader {
File assetsDir = new File(service.baseDirectory(), "assets");
File indexDir = new File(assetsDir, "indexes");
File objectDir = new File(assetsDir, "objects");
File indexFile = new File(indexDir, version.getAssets() + ".json");
File indexFile = new File(indexDir, version.getAssetsIndex().getId() + ".json");
if (!assetsDir.exists() && !indexFile.isFile())
return false;
@ -140,7 +140,7 @@ public class MinecraftLoader extends AbstractMinecraftLoader {
File assetsDir = new File(service.baseDirectory(), "assets");
File indexDir = new File(assetsDir, "indexes");
File objectDir = new File(assetsDir, "objects");
String assetVersion = version.getAssets();
String assetVersion = version.getAssetsIndex().getId();
File indexFile = new File(indexDir, assetVersion + ".json");
File virtualRoot = new File(new File(assetsDir, "virtual"), assetVersion);

View File

@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.launcher.core.service;
import java.io.File;
import java.io.IOException;
import org.jackhuang.hellominecraft.launcher.core.version.AssetIndexDownloadInfo;
import org.jackhuang.hellominecraft.util.tasks.Task;
/**
@ -44,7 +45,7 @@ public abstract class IMinecraftAssetService extends IMinecraftBasicService {
*/
public abstract boolean refreshAssetsIndex(String a);
public abstract boolean downloadMinecraftAssetsIndex(String assetsId);
public abstract boolean downloadMinecraftAssetsIndex(AssetIndexDownloadInfo assetsId);
public abstract File getAssetObject(String assetVersion, String name) throws IOException;
}

View File

@ -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.launcher.core.version;
/**
*
* @author huangyuhui
*/
public class AssetIndexDownloadInfo extends GameDownloadInfo {
String id;
int totalSize;
public AssetIndexDownloadInfo() {
}
public AssetIndexDownloadInfo(String id) {
this.id = id;
url = null;
}
public String getId() {
return id;
}
public int getTotalSize() {
return totalSize;
}
}

View File

@ -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.launcher.core.version;
/**
*
* @author huangyuhui
*/
public class GameDownloadInfo {
public String sha1, url;
public int size;
}

View File

@ -21,12 +21,14 @@ import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
import org.jackhuang.hellominecraft.launcher.core.asset.AssetsIndex;
import org.jackhuang.hellominecraft.util.ArrayUtils;
import org.jackhuang.hellominecraft.util.Utils;
/**
*
@ -35,9 +37,12 @@ import org.jackhuang.hellominecraft.util.ArrayUtils;
public class MinecraftVersion implements Cloneable, Comparable<MinecraftVersion> {
public String minecraftArguments, mainClass, time, id, type, processArguments,
releaseTime, assets, jar, inheritsFrom, runDir;
releaseTime, jar, inheritsFrom, runDir;
protected String assets;
public int minimumLauncherVersion;
public boolean hidden;
public AssetIndexDownloadInfo assetIndex;
public Map<String, GameDownloadInfo> downloads;
public ArrayList<MinecraftLibrary> libraries;
@ -127,12 +132,14 @@ public class MinecraftVersion implements Cloneable, Comparable<MinecraftVersion>
return true;
}
public String getAssets() {
return assets == null ? AssetsIndex.DEFAULT_ASSET_NAME : assets;
}
@Override
public int compareTo(MinecraftVersion o) {
return id.compareTo(o.id);
}
public AssetIndexDownloadInfo getAssetsIndex() {
if (assetIndex == null)
assetIndex = new AssetIndexDownloadInfo((String) Utils.firstNonNull(assets, AssetsIndex.DEFAULT_ASSET_NAME));
return assetIndex;
}
}

View File

@ -291,6 +291,6 @@ public class MinecraftVersionManager extends IMinecraftProvider {
public void downloadModpack(String url) throws IOException {
File tmp = File.createTempFile("hmcl", ".zip");
TaskWindow.getInstance().addTask(new FileDownloadTask(url, tmp)).addTask(new DecompressTask(tmp, service.baseDirectory())).start();
TaskWindow.factory().append(new FileDownloadTask(IOUtils.parseURL(url), tmp)).append(new DecompressTask(tmp, service.baseDirectory())).create();
}
}

View File

@ -287,6 +287,7 @@ public class VersionSetting {
x.setMaxMemory(getMaxMemory());
x.setMinecraftArgs(getMinecraftArgs());
x.setName(Main.makeTitle());
x.setType(Main.makeTitle());
x.setNoJVMArgs(isNoJVMArgs());
x.setPermSize(getPermSize());
x.setPrecalledCommand(getPrecalledCommand());

View File

@ -123,9 +123,9 @@ public class InstallerPanel extends AnimatedPanel {
InstallerType id;
void refreshVersions() {
if (TaskWindow.getInstance().addTask(new TaskRunnableArg1<>(C.i18n("install." + id.id + ".get_list"), list)
if (TaskWindow.factory().append(new TaskRunnableArg1<>(C.i18n("install." + id.id + ".get_list"), list)
.registerPreviousResult(new DefaultPreviousResult<>(new String[] { gsp.getMinecraftVersionFormatted() })))
.start())
.create())
loadVersions();
}

View File

@ -373,7 +373,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.getInstance().addTask(ModpackManager.install(fc.getSelectedFile(), getProfile().service(), suggestedModpackId)).start();
TaskWindow.factory().append(ModpackManager.install(fc.getSelectedFile(), getProfile().service(), suggestedModpackId)).create();
loadMinecraftVersions();
}//GEN-LAST:event_btnImportModpackActionPerformed

View File

@ -98,7 +98,7 @@ public class AppDataUpgrader extends IUpgrader {
((UpdateChecker) sender).requestDownloadLink().reg(map -> {
if (map != null && map.containsKey("pack"))
try {
if (TaskWindow.getInstance().addTask(new AppDataUpgraderTask(map.get("pack"), number.version)).start()) {
if (TaskWindow.factory().append(new AppDataUpgraderTask(map.get("pack"), number.version)).create()) {
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(number.version).getAbsolutePath() }).directory(new File(".")).start();
System.exit(0);
}
@ -147,7 +147,7 @@ public class AppDataUpgrader extends IUpgrader {
}
@Override
public Collection<? extends Task> getDependTasks() {
public Collection<Task> getDependTasks() {
return Arrays.asList(new FileDownloadTask(downloadLink, tempFile));
}

View File

@ -48,7 +48,7 @@ public class NewFileUpgrader extends IUpgrader {
public boolean call(Object sender, VersionNumber number) {
String str = requestDownloadLink();
File newf = new File(FileUtils.getName(str));
if (TaskWindow.getInstance().addTask(new FileDownloadTask(str, newf)).start()) {
if (TaskWindow.factory().append(new FileDownloadTask(str, newf)).create()) {
try {
new ProcessBuilder(new String[] { IOUtils.tryGetCanonicalFilePath(newf), "--removeOldLauncher", IOUtils.getRealPath() }).directory(new File(".")).start();
} catch (IOException ex) {

View File

@ -151,4 +151,11 @@ public final class Utils {
if (o == null)
throw new NullPointerException("Oh dear, there is a problem...");
}
public static Object firstNonNull(Object... o) {
for (Object s : o)
if (s != null)
return s;
return null;
}
}

View File

@ -17,6 +17,8 @@
*/
package org.jackhuang.hellominecraft.util.tasks;
import java.util.Collection;
/**
*
* @author huangyuhui
@ -28,14 +30,14 @@ public interface DoingDoneListener<K> {
*
* @param k
*/
void onDone(K k);
void onDone(K k, Collection<Task> tasks);
/**
* Before task executing.
*
* @param k
*/
void onDoing(K k);
void onDoing(K k, Collection<Task> tasks);
/**
* Task failed.

View File

@ -87,11 +87,11 @@ public abstract class Task {
public abstract String getInfo();
public Collection<? extends Task> getDependTasks() {
public Collection<Task> getDependTasks() {
return null;
}
public Collection<? extends Task> getAfterTasks() {
public Collection<Task> getAfterTasks() {
return null;
}

View File

@ -88,7 +88,7 @@ public class TaskList extends Thread {
static final Set<Task> TASK_POOL = Collections.synchronizedSet(new HashSet<Task>());
private void processTasks(Collection<? extends Task> c) {
if (c == null)
if (c == null || c.isEmpty())
return;
this.totTask += c.size();
Set<InvokeThread> runningThread = Collections.synchronizedSet(new HashSet<InvokeThread>());
@ -112,13 +112,16 @@ public class TaskList extends Thread {
private void executeTask(Task t) {
if (!shouldContinue || t == null)
return;
processTasks(t.getDependTasks());
Collection<Task> c = t.getDependTasks();
if (c == null)
c = new HashSet<>();
HMCLog.log("Executing task: " + t.getInfo());
for (DoingDoneListener<Task> d : taskListener)
d.onDoing(t);
d.onDoing(t, c);
for (DoingDoneListener<Task> d : t.getTaskListeners())
d.onDoing(t);
d.onDoing(t, c);
processTasks(c);
boolean flag = true;
try {
@ -129,11 +132,14 @@ public class TaskList extends Thread {
}
if (flag) {
HMCLog.log((t.isAborted() ? "Task aborted: " : "Task finished: ") + t.getInfo());
Collection<Task> at = t.getAfterTasks();
if (at == null)
at = new HashSet<>();
for (DoingDoneListener<Task> d : taskListener)
d.onDone(t);
d.onDone(t, at);
for (DoingDoneListener<Task> d : t.getTaskListeners())
d.onDone(t);
processTasks(t.getAfterTasks());
d.onDone(t, at);
processTasks(at);
} else {
HMCLog.err("Task failed: " + t.getInfo(), t.getFailReason());
for (DoingDoneListener<Task> d : taskListener)

View File

@ -18,6 +18,7 @@
package org.jackhuang.hellominecraft.util.tasks;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.util.C;
@ -35,12 +36,12 @@ public class TaskWindow extends javax.swing.JDialog
private static final TaskWindow INSTANCE = new TaskWindow();
private static TaskWindow inst() {
private static TaskWindow instance() {
INSTANCE.clean();
return INSTANCE;
}
public static TaskWindowFactory getInstance() {
public static TaskWindowFactory factory() {
return new TaskWindowFactory();
}
@ -225,7 +226,7 @@ public class TaskWindow extends javax.swing.JDialog
}
@Override
public void onDoing(Task task) {
public void onDoing(Task task, Collection<Task> taskCollection) {
if (task == null)
return;
task.setProgressProviderListener(this);
@ -245,7 +246,7 @@ public class TaskWindow extends javax.swing.JDialog
}
@Override
public void onDone(Task task) {
public void onDone(Task task, Collection<Task> taskCollection) {
SwingUtilities.invokeLater(() -> {
if (taskList == null || task == null)
return;
@ -299,18 +300,18 @@ public class TaskWindow extends javax.swing.JDialog
LinkedList<Task> ll = new LinkedList<>();
boolean flag;
public TaskWindowFactory addTask(Task t) {
public TaskWindowFactory append(Task t) {
ll.add(t);
return this;
}
public boolean start() {
public boolean create() {
String stacktrace = StrUtils.getStackTrace(new Throwable());
return SwingUtils.invokeAndWait(() -> {
synchronized (INSTANCE) {
if (INSTANCE.isVisible())
return false;
TaskWindow tw = inst();
TaskWindow tw = instance();
for (Task t : ll)
tw.addTask(t);
tw.lastStackTrace = tw.stackTrace;

View File

@ -21,10 +21,13 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.ArrayList;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.code.DigestUtils;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.tasks.Task;
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult;
@ -44,6 +47,7 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
protected URL url; // download URL
protected int downloaded = 0; // number of bytes downloaded
protected File filePath;
protected String expectedHash;
public FileDownloadTask() {
}
@ -56,10 +60,18 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
this(IOUtils.parseURL(url), filePath);
}
// Constructor for Download.
public FileDownloadTask(URL url, File filePath) {
this(url, filePath, null);
}
public FileDownloadTask(String url, File filePath, String hash) {
this(IOUtils.parseURL(url), filePath, hash);
}
public FileDownloadTask(URL url, File file, String hash) {
this.url = url;
this.filePath = filePath;
this.filePath = file;
this.expectedHash = hash;
}
// Get this download's URL.
@ -130,6 +142,8 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
// Open file and seek to the end of it.
file = new RandomAccessFile(tempFile, "rw");
MessageDigest digest = DigestUtils.getSha1Digest();
stream = connection.getInputStream();
int lastDownloaded = 0;
downloaded = 0;
@ -149,6 +163,8 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
if (read == -1)
break;
digest.update(buffer, 0, read);
// Write buffer to file.
file.write(buffer, 0, read);
downloaded += read;
@ -169,6 +185,10 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
filePath.delete();
tempFile.renameTo(filePath);
}
String hashCode = String.format("%1$040x", new Object[] { new BigInteger(1, digest.digest()) });
if (expectedHash != null && !expectedHash.equals(hashCode))
throw new IllegalStateException("Unexpected hash code: " + hashCode + ", expected: " + expectedHash);
if (ppl != null)
ppl.onProgressProviderDone(this);
return;

View File

@ -87,22 +87,22 @@ public class ForgeInstaller {
File minecraftserver = new File(gameDir, "minecraft_server." + profile.install.minecraft + ".jar");
if (minecraftserver.exists() && JOptionPane.showConfirmDialog(null, "已发现官方服务端文件,是否要重新下载?") == JOptionPane.YES_OPTION)
if (!TaskWindow.getInstance().addTask(new FileDownloadTask("https://s3.amazonaws.com/Minecraft.Download/versions/{MCVER}/minecraft_server.{MCVER}.jar".replace("{MCVER}", profile.install.minecraft),
minecraftserver).setTag("minecraft_server")).start())
if (!TaskWindow.factory().append(new FileDownloadTask("https://s3.amazonaws.com/Minecraft.Download/versions/{MCVER}/minecraft_server.{MCVER}.jar".replace("{MCVER}", profile.install.minecraft),
minecraftserver).setTag("minecraft_server")).create())
MessageBox.Show("Minecraft官方服务端下载失败");
TaskWindow.TaskWindowFactory tw = TaskWindow.getInstance();
TaskWindow.TaskWindowFactory tw = TaskWindow.factory();
for (MinecraftLibrary library : profile.versionInfo.libraries) {
library.init();
File lib = new File(gameDir, "libraries" + File.separator + library.formatted + ".pack.xz");
String libURL = "https://libraries.minecraft.net/";
if (StrUtils.isNotBlank(library.url))
libURL = library.url;
tw.addTask(new FileDownloadTask(libURL + library.formatted.replace("\\", "/"), lib).setTag(library.name));
tw.append(new FileDownloadTask(libURL + library.formatted.replace("\\", "/"), lib).setTag(library.name));
}
if (!tw.start())
if (!tw.create())
MessageBox.Show("压缩库下载失败!");
tw = TaskWindow.getInstance();
tw = TaskWindow.factory();
for (MinecraftLibrary library : profile.versionInfo.libraries) {
File packxz = new File(gameDir, "libraries" + File.separator + library.formatted + ".pack.xz");
if (packxz.exists())
@ -112,9 +112,9 @@ public class ForgeInstaller {
String libURL = "https://libraries.minecraft.net/";
if (StrUtils.isNotBlank(library.url))
libURL = library.url;
tw.addTask(new FileDownloadTask(libURL + library.formatted.replace("\\", "/"), lib).setTag(library.name));
tw.append(new FileDownloadTask(libURL + library.formatted.replace("\\", "/"), lib).setTag(library.name));
}
if (!tw.start())
if (!tw.create())
MessageBox.Show("库下载失败!");
ArrayList<String> badLibs = new ArrayList<>();

View File

@ -2994,7 +2994,7 @@ public final class MainWindow extends javax.swing.JFrame
void refreshDownloads() {
clearListDownloads();
TaskWindow.getInstance().addTask(new RefreshDownloadsDone()).start();
TaskWindow.factory().append(new RefreshDownloadsDone()).create();
}
void refreshInfos() {
@ -3716,7 +3716,7 @@ public final class MainWindow extends javax.swing.JFrame
serverjar.delete();
String downloadURL = url + "minecraft_server." + id + ".jar";
TaskWindow.getInstance().addTask(new FileDownloadTask(downloadURL, serverjar).setTag(id)).start();
TaskWindow.factory().append(new FileDownloadTask(downloadURL, serverjar).setTag(id)).create();
}//GEN-LAST:event_btnMinecraftServerDownloadActionPerformed
private void btnRefreshInfosActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshInfosActionPerformed
@ -3850,8 +3850,8 @@ public final class MainWindow extends javax.swing.JFrame
}
BukkitVersion v = cb.get(idx);
File file = new File(IOUtils.currentDir(), "craftbukkit-" + ext + "-" + v.version + ".jar");
TaskWindow.getInstance().addTask(new FileDownloadTask(v.downloadLink, IOUtils.tryGetCanonicalFile(file)).setTag("bukkit-" + ext + "-" + v.version))
.start();
TaskWindow.factory().append(new FileDownloadTask(v.downloadLink, IOUtils.tryGetCanonicalFile(file)).setTag("bukkit-" + ext + "-" + v.version))
.create();
}//GEN-LAST:event_btnDownloadCraftbukkitActionPerformed
private void btnDownloadMCPCActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDownloadMCPCActionPerformed
@ -3862,7 +3862,7 @@ public final class MainWindow extends javax.swing.JFrame
String url;
File filepath = new File(IOUtils.currentDir(), "forge-installer.jar");
url = v.installer[1];
if (!TaskWindow.getInstance().addTask(new FileDownloadTask(url, filepath).setTag("cauldron-" + v.ver)).start())
if (!TaskWindow.factory().append(new FileDownloadTask(url, filepath).setTag("cauldron-" + v.ver)).create())
MessageBox.Show(C.i18n("install.failed_download_forge"));
else
installMCPC(filepath);

View File

@ -231,10 +231,10 @@ public class PluginInfoDialog extends javax.swing.JDialog {
if (index == -1)
return;
String url = pi.versions.get(index).download;
TaskWindow.getInstance()
.addTask(new FileDownloadTask(url, new File(Utilities.getGameDir() + "plugins"
TaskWindow.factory()
.append(new FileDownloadTask(url, new File(Utilities.getGameDir() + "plugins"
+ File.separator + pi.versions.get(index).filename)))
.start();
.create();
}//GEN-LAST:event_jButton1ActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables