This commit is contained in:
huangyuhui
2016-03-03 20:20:52 +08:00
parent 5dc812072f
commit afde41135a
8 changed files with 89 additions and 45 deletions

View File

@@ -19,6 +19,8 @@ package org.jackhuang.hellominecraft.launcher.core.asset;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
@@ -30,8 +32,8 @@ import org.jackhuang.hellominecraft.util.system.IOUtils;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider; import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider;
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
import org.jackhuang.hellominecraft.util.OverridableSwingWorker;
import org.jackhuang.hellominecraft.util.VersionNumber; import org.jackhuang.hellominecraft.util.VersionNumber;
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
/** /**
* *
@@ -44,19 +46,26 @@ public class AssetsMojangLoader extends IAssetsHandler {
} }
@Override @Override
public OverridableSwingWorker<String[]> getList(final MinecraftVersion mv, final IMinecraftAssetService mp) { public Task getList(final MinecraftVersion mv, final IMinecraftAssetService mp) {
return new OverridableSwingWorker<String[]>() { if (mv == null)
throw new IllegalArgumentException("AssetsMojangLoader: null argument: MinecraftVersion");
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"));
return new TaskInfo("Gather asset index") {
@Override @Override
protected void work() throws Exception { public Collection<Task> getDependTasks() {
if (mv == null) if (!f.exists())
throw new IllegalArgumentException("AssetsMojangLoader: null argument: MinecraftVersion"); return Arrays.asList(mp.downloadMinecraftAssetsIndex(mv.getAssetsIndex()));
String assetsId = mv.getAssetsIndex().getId(); else
File assets = mp.getAssets(); return null;
HMCLog.log("Gathering asset index: " + assetsId); }
File f = IOUtils.tryGetCanonicalFile(new File(assets, "indexes/" + assetsId + ".json"));
if (!f.exists() && !mp.downloadMinecraftAssetsIndex(mv.getAssetsIndex()))
throw new IllegalStateException("Failed to get index json");
@Override
public void executeTask() throws Throwable {
if (!areDependTasksSucceeded)
throw new IllegalStateException("Failed to get asset index");
String result = FileUtils.readFileToString(f); String result = FileUtils.readFileToString(f);
if (StrUtils.isBlank(result)) if (StrUtils.isBlank(result))
throw new IllegalStateException("Index json is empty, please redownload it!"); throw new IllegalStateException("Index json is empty, please redownload it!");
@@ -66,6 +75,7 @@ public class AssetsMojangLoader extends IAssetsHandler {
ArrayList<String> al = new ArrayList<>(); ArrayList<String> al = new ArrayList<>();
contents = new ArrayList<>(); contents = new ArrayList<>();
HashSet<String> loadedHashes = new HashSet<>(); HashSet<String> loadedHashes = new HashSet<>();
int pgs = 0;
if (o != null && o.getFileMap() != null) if (o != null && o.getFileMap() != null)
for (Map.Entry<String, AssetsObject> e : o.getFileMap().entrySet()) { for (Map.Entry<String, AssetsObject> e : o.getFileMap().entrySet()) {
if (loadedHashes.contains(e.getValue().getHash())) if (loadedHashes.contains(e.getValue().getHash()))
@@ -79,9 +89,9 @@ public class AssetsMojangLoader extends IAssetsHandler {
assetsDownloadURLs.add(c.key); assetsDownloadURLs.add(c.key);
assetsLocalNames.add(new File(assets, "objects" + File.separator + c.key.replace("/", File.separator))); assetsLocalNames.add(new File(assets, "objects" + File.separator + c.key.replace("/", File.separator)));
al.add(e.getKey()); al.add(e.getKey());
if (ppl != null)
ppl.setProgress(this, ++pgs, o.getFileMap().size());
} }
publish(al.toArray(new String[1]));
} }
}; };
} }

View File

@@ -74,7 +74,7 @@ public abstract class IAssetsHandler {
* @param mp Asset Service * @param mp Asset Service
* @param x finished event * @param x finished event
*/ */
public abstract OverridableSwingWorker<String[]> getList(MinecraftVersion mv, IMinecraftAssetService mp); public abstract Task getList(MinecraftVersion mv, IMinecraftAssetService mp);
/** /**
* Will be invoked when the user invoked "Download all assets". * Will be invoked when the user invoked "Download all assets".

View File

@@ -20,6 +20,7 @@ package org.jackhuang.hellominecraft.launcher.core.asset;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@@ -58,15 +59,17 @@ public class MinecraftAssetService extends IMinecraftAssetService {
Collection<Task> afters = new HashSet<>(); Collection<Task> afters = new HashSet<>();
@Override @Override
public void executeTask() throws Throwable { public Collection<Task> getDependTasks() {
IAssetsHandler type = IAssetsHandler.ASSETS_HANDLER; return Arrays.asList(IAssetsHandler.ASSETS_HANDLER.getList(mv, service.asset()));
type.getList(mv, service.asset()).justDo(); }
afters.add(type.getDownloadTask(service.getDownloadType().getProvider()));
@Override
public void executeTask() {
} }
@Override @Override
public Collection<Task> getAfterTasks() { public Collection<Task> getAfterTasks() {
return afters; return Arrays.asList(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider()));
} }
}; };
} }
@@ -80,7 +83,7 @@ public class MinecraftAssetService extends IMinecraftAssetService {
} }
@Override @Override
public boolean downloadMinecraftAssetsIndex(AssetIndexDownloadInfo assets) { public Task downloadMinecraftAssetsIndex(AssetIndexDownloadInfo assets) {
File assetsLocation = getAssets(); File assetsLocation = getAssets();
if (!assetsLocation.exists() && !assetsLocation.mkdirs()) if (!assetsLocation.exists() && !assetsLocation.mkdirs())
HMCLog.warn("Failed to make directories: " + assetsLocation); HMCLog.warn("Failed to make directories: " + assetsLocation);
@@ -91,14 +94,22 @@ public class MinecraftAssetService extends IMinecraftAssetService {
if (assetsIndex.renameTo(renamed)) if (assetsIndex.renameTo(renamed))
HMCLog.warn("Failed to rename " + assetsIndex + " to " + renamed); HMCLog.warn("Failed to rename " + assetsIndex + " to " + renamed);
} }
if (new FileDownloadTask(assets.getUrl(service.getDownloadType()), IOUtils.tryGetCanonicalFile(assetsIndex), assets.sha1).setTag(assets.getId() + ".json").run()) { File renamedFinal = renamed;
if (renamed != null && !renamed.delete()) return new TaskInfo("Download Asset Index") {
HMCLog.warn("Failed to delete " + renamed + ", maybe you should do it."); @Override
return true; public Collection<Task> getDependTasks() {
} return Arrays.asList(new FileDownloadTask(assets.getUrl(service.getDownloadType()), IOUtils.tryGetCanonicalFile(assetsIndex), assets.sha1).setTag(assets.getId() + ".json"));
if (renamed != null && !renamed.renameTo(assetsIndex)) }
HMCLog.warn("Failed to rename " + renamed + " to " + assetsIndex);
return false; @Override
public void executeTask() throws Throwable {
if (areDependTasksSucceeded) {
if (renamedFinal != null && !renamedFinal.delete())
HMCLog.warn("Failed to delete " + renamedFinal + ", maybe you should do it.");
} else if (renamedFinal != null && !renamedFinal.renameTo(assetsIndex))
HMCLog.warn("Failed to rename " + renamedFinal + " to " + assetsIndex);
}
};
} }
@Override @Override

View File

@@ -47,7 +47,7 @@ public abstract class IMinecraftAssetService extends IMinecraftBasicService {
public abstract boolean downloadMinecraftAssetsIndexAsync(AssetIndexDownloadInfo assetsId); public abstract boolean downloadMinecraftAssetsIndexAsync(AssetIndexDownloadInfo assetsId);
public abstract boolean downloadMinecraftAssetsIndex(AssetIndexDownloadInfo assetsId); public abstract Task downloadMinecraftAssetsIndex(AssetIndexDownloadInfo assetsId);
public abstract File getAssetObject(String assetVersion, String name) throws IOException; public abstract File getAssetObject(String assetVersion, String name) throws IOException;
} }

View File

@@ -54,7 +54,7 @@ public final class Profile {
this(); this();
if (v == null) if (v == null)
return; return;
name = v.name; this.name = name;
gameDir = v.gameDir; gameDir = v.gameDir;
} }

View File

@@ -64,6 +64,7 @@ import org.jackhuang.hellominecraft.util.system.FileUtils;
import org.jackhuang.hellominecraft.util.system.IOUtils; import org.jackhuang.hellominecraft.util.system.IOUtils;
import org.jackhuang.hellominecraft.util.ui.SwingUtils; import org.jackhuang.hellominecraft.util.ui.SwingUtils;
import org.jackhuang.hellominecraft.util.system.Java; import org.jackhuang.hellominecraft.util.system.Java;
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
import org.jackhuang.hellominecraft.util.ui.LogWindow; import org.jackhuang.hellominecraft.util.ui.LogWindow;
/** /**
@@ -975,7 +976,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
private void btnDownloadAllAssetsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDownloadAllAssetsActionPerformed private void btnDownloadAllAssetsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDownloadAllAssetsActionPerformed
if (mcVersion != null) if (mcVersion != null)
Settings.getLastProfile().service().asset().downloadAssets(mcVersion).run(); TaskWindow.execute(Settings.getLastProfile().service().asset().downloadAssets(mcVersion));
}//GEN-LAST:event_btnDownloadAllAssetsActionPerformed }//GEN-LAST:event_btnDownloadAllAssetsActionPerformed
private void txtGameDirFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtGameDirFocusLost private void txtGameDirFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtGameDirFocusLost

View File

@@ -95,6 +95,8 @@ public abstract class Task {
return null; return null;
} }
public boolean areDependTasksSucceeded;
protected ProgressProviderListener ppl; protected ProgressProviderListener ppl;
public Task setProgressProviderListener(ProgressProviderListener p) { public Task setProgressProviderListener(ProgressProviderListener p) {
@@ -110,9 +112,21 @@ public abstract class Task {
return new DoubleTask(t, this); return new DoubleTask(t, this);
} }
public void runWithException() throws Throwable {
Collection<Task> c = getDependTasks();
if (c != null)
for (Task t : c)
t.runWithException();
executeTask();
c = getAfterTasks();
if (c != null)
for (Task t : c)
t.runWithException();
}
public boolean run() { public boolean run() {
try { try {
executeTask(); runWithException();
return true; return true;
} catch (Throwable t) { } catch (Throwable t) {
HMCLog.err("Failed to execute task", t); HMCLog.err("Failed to execute task", t);

View File

@@ -28,6 +28,7 @@ import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import org.jackhuang.hellominecraft.util.logging.HMCLog; import org.jackhuang.hellominecraft.util.logging.HMCLog;
/** /**
@@ -72,15 +73,18 @@ public class TaskList extends Thread {
Task task; Task task;
Set<Invoker> s; Set<Invoker> s;
AtomicBoolean bool;
public Invoker(Task task, Set<Invoker> ss) { public Invoker(Task task, Set<Invoker> ss, AtomicBoolean bool) {
this.task = task; this.task = task;
s = ss; s = ss;
this.bool = bool;
} }
@Override @Override
public void run() { public void run() {
executeTask(task); if (!executeTask(task))
bool.set(false);
s.remove(this); s.remove(this);
} }
@@ -90,32 +94,35 @@ public class TaskList extends Thread {
HashMap<Invoker, Future<?>> futures = new HashMap<>(); HashMap<Invoker, Future<?>> futures = new HashMap<>();
HashSet<Invoker> invokers = new HashSet<>(); HashSet<Invoker> invokers = new HashSet<>();
private void processTasks(Collection<? extends Task> c) { private boolean processTasks(Collection<? extends Task> c) {
if (c == null || c.isEmpty()) if (c == null || c.isEmpty())
return; return true;
this.totTask += c.size(); this.totTask += c.size();
AtomicBoolean bool = new AtomicBoolean(true);
Set<Invoker> runningThread = Collections.synchronizedSet(new HashSet<Invoker>()); Set<Invoker> runningThread = Collections.synchronizedSet(new HashSet<Invoker>());
for (Task t2 : c) { for (Task t2 : c) {
t2.setParallelExecuting(true); t2.setParallelExecuting(true);
Invoker thread = new Invoker(t2, runningThread); Invoker thread = new Invoker(t2, runningThread, bool);
runningThread.add(thread); runningThread.add(thread);
invokers.add(thread); invokers.add(thread);
if (!EXECUTOR_SERVICE.isTerminated()) if (!EXECUTOR_SERVICE.isShutdown() && !EXECUTOR_SERVICE.isTerminated())
futures.put(thread, EXECUTOR_SERVICE.submit(thread)); futures.put(thread, EXECUTOR_SERVICE.submit(thread));
} }
while (!runningThread.isEmpty()) while (!runningThread.isEmpty())
try { try {
if (this.isInterrupted()) if (this.isInterrupted())
return; return false;
Thread.sleep(1); Thread.sleep(1);
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) {
} }
return bool.get();
} }
private void executeTask(Task t) { private boolean executeTask(Task t) {
if (!shouldContinue || t == null) if (!shouldContinue)
return; return false;
if (t == null)
return true;
Collection<Task> c = t.getDependTasks(); Collection<Task> c = t.getDependTasks();
if (c == null) if (c == null)
@@ -125,7 +132,7 @@ public class TaskList extends Thread {
d.onDoing(t, c); d.onDoing(t, c);
for (DoingDoneListener<Task> d : taskListener) for (DoingDoneListener<Task> d : taskListener)
d.onDoing(t, c); d.onDoing(t, c);
processTasks(c); t.areDependTasksSucceeded = processTasks(c);
boolean flag = true; boolean flag = true;
try { try {
@@ -151,6 +158,7 @@ public class TaskList extends Thread {
for (DoingDoneListener<Task> d : t.getTaskListeners()) for (DoingDoneListener<Task> d : t.getTaskListeners())
d.onFailed(t); d.onFailed(t);
} }
return flag;
} }
@Override @Override