Fixed #42
This commit is contained in:
@@ -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]));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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".
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user