Fix syncing TaskWindow.
This commit is contained in:
@@ -31,6 +31,8 @@ import java.net.URLClassLoader;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarFile;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
@@ -139,7 +141,11 @@ public final class Main implements Runnable {
|
||||
JarFile jarFile = new JarFile(jar);
|
||||
String mainClass = jarFile.getManifest().getMainAttributes().getValue("Main-Class");
|
||||
if (mainClass != null) {
|
||||
new URLClassLoader(new URL[]{jar.toURI().toURL()}, URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass).getMethod("main", String[].class).invoke(null, new Object[]{new String[]{"nofound"}});
|
||||
ArrayList<String> al = new ArrayList<>(Arrays.asList(args));
|
||||
al.add("notfound");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,10 +43,9 @@ public class DefaultGameLauncher extends GameLauncher {
|
||||
|
||||
private void register() {
|
||||
downloadLibrariesEvent.register((sender, t) -> {
|
||||
final TaskWindow dw = TaskWindow.getInstance();
|
||||
final TaskWindow.TaskWindowFactory dw = TaskWindow.getInstance();
|
||||
ParallelTask parallelTask = new ParallelTask();
|
||||
for (DownloadLibraryJob s : t)
|
||||
//parallelTask.addDependsTask(new FileDownloadTask(s.url, s.path).setTag(s.name));
|
||||
parallelTask.addDependsTask(new LibraryDownloadTask(s));
|
||||
dw.addTask(parallelTask);
|
||||
boolean flag = true;
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.jackhuang.mojang.authlib;
|
||||
public class Agent {
|
||||
|
||||
public static final Agent MINECRAFT = new Agent("Minecraft", 1);
|
||||
public static final Agent SCROLLS = new Agent("Scrolls", 1);
|
||||
private final String name;
|
||||
private final int version;
|
||||
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
package org.jackhuang.mojang.authlib;
|
||||
|
||||
import org.jackhuang.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
|
||||
public abstract interface AuthenticationService {
|
||||
|
||||
public abstract UserAuthentication createUserAuthentication(Agent paramAgent);
|
||||
|
||||
public abstract MinecraftSessionService createMinecraftSessionService();
|
||||
|
||||
public abstract GameProfileRepository createProfileRepository();
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib;
|
||||
|
||||
public abstract class BaseAuthenticationService
|
||||
implements AuthenticationService {
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib;
|
||||
|
||||
public abstract interface GameProfileRepository {
|
||||
|
||||
public abstract void findProfilesByNames(String[] paramArrayOfString, Agent paramAgent, ProfileLookupCallback paramProfileLookupCallback);
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
|
||||
public abstract class HttpAuthenticationService extends BaseAuthenticationService {
|
||||
public abstract class HttpAuthenticationService implements AuthenticationService {
|
||||
|
||||
private static final Logger LOGGER = new Logger("HttpAuthenticationService");
|
||||
private final Proxy proxy;
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib;
|
||||
|
||||
public abstract interface ProfileLookupCallback {
|
||||
|
||||
public abstract void onProfileLookupSucceeded(GameProfile paramGameProfile);
|
||||
|
||||
public abstract void onProfileLookupFailed(GameProfile paramGameProfile, Exception paramException);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.minecraft;
|
||||
|
||||
import org.jackhuang.mojang.authlib.AuthenticationService;
|
||||
|
||||
public abstract class BaseMinecraftSessionService
|
||||
implements MinecraftSessionService {
|
||||
|
||||
private final AuthenticationService authenticationService;
|
||||
|
||||
protected BaseMinecraftSessionService(AuthenticationService authenticationService) {
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
public AuthenticationService getAuthenticationService() {
|
||||
return this.authenticationService;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.minecraft;
|
||||
|
||||
import org.jackhuang.mojang.authlib.HttpAuthenticationService;
|
||||
|
||||
public abstract class HttpMinecraftSessionService extends BaseMinecraftSessionService {
|
||||
|
||||
protected HttpMinecraftSessionService(HttpAuthenticationService authenticationService) {
|
||||
super(authenticationService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpAuthenticationService getAuthenticationService() {
|
||||
return (HttpAuthenticationService) super.getAuthenticationService();
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.minecraft;
|
||||
|
||||
import org.jackhuang.mojang.authlib.GameProfile;
|
||||
import org.jackhuang.mojang.authlib.exceptions.AuthenticationException;
|
||||
import org.jackhuang.mojang.authlib.exceptions.AuthenticationUnavailableException;
|
||||
|
||||
public abstract interface MinecraftSessionService {
|
||||
|
||||
public abstract void joinServer(GameProfile paramGameProfile, String paramString1, String paramString2)
|
||||
throws AuthenticationException;
|
||||
|
||||
public abstract GameProfile hasJoinedServer(GameProfile paramGameProfile, String paramString)
|
||||
throws AuthenticationUnavailableException;
|
||||
|
||||
public abstract GameProfile fillProfileProperties(GameProfile paramGameProfile, boolean paramBoolean);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.yggdrasil;
|
||||
|
||||
public class ProfileIncompleteException extends RuntimeException {
|
||||
|
||||
public ProfileIncompleteException() {
|
||||
}
|
||||
|
||||
public ProfileIncompleteException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ProfileIncompleteException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ProfileIncompleteException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.yggdrasil;
|
||||
|
||||
public class ProfileNotFoundException extends RuntimeException {
|
||||
|
||||
public ProfileNotFoundException() {
|
||||
}
|
||||
|
||||
public ProfileNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ProfileNotFoundException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ProfileNotFoundException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -11,14 +11,12 @@ import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import org.jackhuang.mojang.authlib.Agent;
|
||||
import org.jackhuang.mojang.authlib.GameProfile;
|
||||
import org.jackhuang.mojang.authlib.GameProfileRepository;
|
||||
import org.jackhuang.mojang.authlib.HttpAuthenticationService;
|
||||
import org.jackhuang.mojang.authlib.UserAuthentication;
|
||||
import org.jackhuang.mojang.authlib.exceptions.AuthenticationException;
|
||||
import org.jackhuang.mojang.authlib.exceptions.AuthenticationUnavailableException;
|
||||
import org.jackhuang.mojang.authlib.exceptions.InvalidCredentialsException;
|
||||
import org.jackhuang.mojang.authlib.exceptions.UserMigratedException;
|
||||
import org.jackhuang.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
import org.jackhuang.mojang.authlib.properties.PropertyMap;
|
||||
import org.jackhuang.mojang.authlib.yggdrasil.response.Response;
|
||||
import org.jackhuang.mojang.util.UUIDTypeAdapter;
|
||||
@@ -50,16 +48,6 @@ public class YggdrasilAuthenticationService extends HttpAuthenticationService {
|
||||
return new YggdrasilUserAuthentication(this, agent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftSessionService createMinecraftSessionService() {
|
||||
return new YggdrasilMinecraftSessionService(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameProfileRepository createProfileRepository() {
|
||||
return new YggdrasilGameProfileRepository(this);
|
||||
}
|
||||
|
||||
protected <T extends Response> T makeRequest(URL url, Object input, Class<T> classOfT) throws AuthenticationException {
|
||||
try {
|
||||
String jsonResult = input == null ? performGetRequest(url) : performPostRequest(url, this.gson.toJson(input), "application/json");
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.yggdrasil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.jackhuang.hellominecraft.logging.logger.Logger;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.mojang.authlib.Agent;
|
||||
import org.jackhuang.mojang.authlib.GameProfile;
|
||||
import org.jackhuang.mojang.authlib.GameProfileRepository;
|
||||
import org.jackhuang.mojang.authlib.ProfileLookupCallback;
|
||||
import org.jackhuang.mojang.authlib.exceptions.AuthenticationException;
|
||||
import org.jackhuang.mojang.authlib.yggdrasil.response.ProfileSearchResultsResponse;
|
||||
|
||||
public class YggdrasilGameProfileRepository
|
||||
implements GameProfileRepository {
|
||||
|
||||
private static final Logger LOGGER = new Logger("YggdrasilGameProfileRepository");
|
||||
private static final String BASE_URL = "https://api.mojang.com/";
|
||||
private static final String SEARCH_PAGE_URL = BASE_URL + "profiles/page/";
|
||||
private static final int MAX_FAIL_COUNT = 3;
|
||||
private static final int DELAY_BETWEEN_PAGES = 100;
|
||||
private static final int DELAY_BETWEEN_FAILURES = 750;
|
||||
private final YggdrasilAuthenticationService authenticationService;
|
||||
|
||||
public YggdrasilGameProfileRepository(YggdrasilAuthenticationService authenticationService) {
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findProfilesByNames(String[] names, Agent agent, ProfileLookupCallback callback) {
|
||||
Set<ProfileCriteria> criteria = new HashSet<ProfileCriteria>();
|
||||
|
||||
for (String name : names) {
|
||||
if (StrUtils.isNotBlank(name)) {
|
||||
criteria.add(new ProfileCriteria(name, agent));
|
||||
}
|
||||
}
|
||||
|
||||
Exception exception = null;
|
||||
Set request = new HashSet<ProfileCriteria>(criteria);
|
||||
int page = 1;
|
||||
int failCount = 0;
|
||||
while (!criteria.isEmpty()) {
|
||||
try {
|
||||
ProfileSearchResultsResponse response = (ProfileSearchResultsResponse) this.authenticationService.makeRequest(NetUtils.constantURL("https://api.mojang.com/profiles/page/" + page), request, ProfileSearchResultsResponse.class);
|
||||
failCount = 0;
|
||||
exception = null;
|
||||
|
||||
if ((response.getSize() == 0) || (response.getProfiles().length == 0)) {
|
||||
LOGGER.debug("Page {} returned empty, aborting search", new Object[]{page});
|
||||
} else {
|
||||
LOGGER.debug("Page {} returned {} results of {}, parsing", new Object[]{page, response.getProfiles().length, response.getSize()});
|
||||
|
||||
for (GameProfile profile : response.getProfiles()) {
|
||||
LOGGER.debug("Successfully looked up profile {}", new Object[]{profile});
|
||||
criteria.remove(new ProfileCriteria(profile.getName(), agent));
|
||||
callback.onProfileLookupSucceeded(profile);
|
||||
}
|
||||
|
||||
LOGGER.debug("Page {} successfully parsed", new Object[]{page});
|
||||
page++;
|
||||
try {
|
||||
Thread.sleep(DELAY_BETWEEN_PAGES);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
} catch (AuthenticationException e) {
|
||||
exception = e;
|
||||
failCount++;
|
||||
|
||||
if (failCount != 3) {
|
||||
try {
|
||||
Thread.sleep(DELAY_BETWEEN_FAILURES);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (criteria.isEmpty()) {
|
||||
LOGGER.debug("Successfully found every profile requested");
|
||||
} else {
|
||||
LOGGER.debug("{} profiles were missing from search results", new Object[]{criteria.size()});
|
||||
if (exception == null) {
|
||||
exception = new ProfileNotFoundException("Server did not find the requested profile");
|
||||
}
|
||||
for (ProfileCriteria profileCriteria : criteria) {
|
||||
callback.onProfileLookupFailed(new GameProfile(null, profileCriteria.getName()), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ProfileCriteria {
|
||||
|
||||
private final String name;
|
||||
private final String agent;
|
||||
|
||||
private ProfileCriteria(String name, Agent agent) {
|
||||
this.name = name;
|
||||
this.agent = agent.getName();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getAgent() {
|
||||
return this.agent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if ((o == null) || (getClass() != o.getClass())) {
|
||||
return false;
|
||||
}
|
||||
ProfileCriteria that = (ProfileCriteria) o;
|
||||
return (this.agent.equals(that.agent)) && (this.name.toLowerCase().equals(that.name.toLowerCase()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * this.name.toLowerCase().hashCode() + this.agent.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProfileCriteria{" + "name=" + name + ", agent=" + agent + '}';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.yggdrasil;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.logging.logger.Logger;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.mojang.authlib.GameProfile;
|
||||
import org.jackhuang.mojang.authlib.HttpAuthenticationService;
|
||||
import org.jackhuang.mojang.authlib.exceptions.AuthenticationException;
|
||||
import org.jackhuang.mojang.authlib.exceptions.AuthenticationUnavailableException;
|
||||
import org.jackhuang.mojang.authlib.minecraft.HttpMinecraftSessionService;
|
||||
import org.jackhuang.mojang.authlib.yggdrasil.request.JoinMinecraftServerRequest;
|
||||
import org.jackhuang.mojang.authlib.yggdrasil.response.HasJoinedMinecraftServerResponse;
|
||||
import org.jackhuang.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse;
|
||||
import org.jackhuang.mojang.authlib.yggdrasil.response.Response;
|
||||
import org.jackhuang.mojang.util.UUIDTypeAdapter;
|
||||
|
||||
public class YggdrasilMinecraftSessionService extends HttpMinecraftSessionService {
|
||||
|
||||
private static final Logger LOGGER = new Logger("YggdrasilMinecraftSessionService");
|
||||
private static final String BASE_URL = "https://sessionserver.mojang.com/session/minecraft/";
|
||||
private static final URL JOIN_URL = NetUtils.constantURL(BASE_URL + "join");
|
||||
private static final URL CHECK_URL = NetUtils.constantURL(BASE_URL + "hasJoined");
|
||||
|
||||
protected YggdrasilMinecraftSessionService(YggdrasilAuthenticationService authenticationService) {
|
||||
super(authenticationService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void joinServer(GameProfile profile, String authenticationToken, String serverId) throws AuthenticationException {
|
||||
JoinMinecraftServerRequest request = new JoinMinecraftServerRequest();
|
||||
request.accessToken = authenticationToken;
|
||||
request.selectedProfile = profile.getId();
|
||||
request.serverId = serverId;
|
||||
|
||||
getAuthenticationService().makeRequest(JOIN_URL, request, Response.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameProfile hasJoinedServer(GameProfile user, String serverId) throws AuthenticationUnavailableException {
|
||||
Map arguments = new HashMap();
|
||||
|
||||
arguments.put("username", user.getName());
|
||||
arguments.put("serverId", serverId);
|
||||
|
||||
URL url = NetUtils.concatenateURL(CHECK_URL, HttpAuthenticationService.buildQuery(arguments));
|
||||
try {
|
||||
HasJoinedMinecraftServerResponse response = (HasJoinedMinecraftServerResponse) getAuthenticationService().makeRequest(url, null, HasJoinedMinecraftServerResponse.class);
|
||||
|
||||
if ((response != null) && (response.getId() != null)) {
|
||||
GameProfile result = new GameProfile(response.getId(), user.getName());
|
||||
|
||||
if (response.getProperties() != null) {
|
||||
result.getProperties().putAll(response.getProperties());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
} catch (AuthenticationUnavailableException e) {
|
||||
throw e;
|
||||
} catch (AuthenticationException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameProfile fillProfileProperties(GameProfile profile, boolean requireSecure) {
|
||||
if (profile.getId() == null) {
|
||||
return profile;
|
||||
}
|
||||
try {
|
||||
URL url = NetUtils.constantURL(new StringBuilder().append("https://sessionserver.mojang.com/session/minecraft/profile/").append(UUIDTypeAdapter.fromUUID(profile.getId())).toString());
|
||||
url = NetUtils.concatenateURL(url, new StringBuilder().append("unsigned=").append(!requireSecure).toString());
|
||||
MinecraftProfilePropertiesResponse response = (MinecraftProfilePropertiesResponse) getAuthenticationService().makeRequest(url, null, MinecraftProfilePropertiesResponse.class);
|
||||
|
||||
if (response == null) {
|
||||
LOGGER.debug(new StringBuilder().append("Couldn't fetch profile properties for ").append(profile).append(" as the profile does not exist").toString());
|
||||
return profile;
|
||||
}
|
||||
GameProfile result = new GameProfile(response.getId(), response.getName());
|
||||
result.getProperties().putAll(response.getProperties());
|
||||
profile.getProperties().putAll(response.getProperties());
|
||||
LOGGER.debug(new StringBuilder().append("Successfully fetched profile properties for ").append(profile).toString());
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn(new StringBuilder().append("Couldn't look up profile properties for ").append(profile).toString(), e);
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public YggdrasilAuthenticationService getAuthenticationService() {
|
||||
return (YggdrasilAuthenticationService) super.getAuthenticationService();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.yggdrasil.request;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class JoinMinecraftServerRequest {
|
||||
|
||||
public String accessToken;
|
||||
public UUID selectedProfile;
|
||||
public String serverId;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.yggdrasil.response;
|
||||
|
||||
import org.jackhuang.mojang.authlib.properties.PropertyMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class HasJoinedMinecraftServerResponse extends Response {
|
||||
|
||||
private UUID id;
|
||||
private PropertyMap properties;
|
||||
|
||||
public UUID getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public PropertyMap getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.yggdrasil.response;
|
||||
|
||||
import org.jackhuang.mojang.authlib.properties.PropertyMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MinecraftProfilePropertiesResponse extends Response {
|
||||
|
||||
private UUID id;
|
||||
private String name;
|
||||
private PropertyMap properties;
|
||||
|
||||
public UUID getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public PropertyMap getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.jackhuang.mojang.authlib.yggdrasil.response;
|
||||
|
||||
import org.jackhuang.mojang.authlib.GameProfile;
|
||||
|
||||
public class ProfileSearchResultsResponse extends Response {
|
||||
|
||||
private GameProfile[] profiles;
|
||||
private int size;
|
||||
|
||||
public GameProfile[] getProfiles() {
|
||||
return this.profiles;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return this.size;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
@@ -30,7 +31,7 @@ import org.jackhuang.hellominecraft.HMCLog;
|
||||
*/
|
||||
public class TaskList extends Thread {
|
||||
|
||||
List<Task> taskQueue = Collections.synchronizedList(new ArrayList());
|
||||
List<Task> taskQueue = Collections.synchronizedList(new LinkedList<>());
|
||||
ArrayList<Runnable> allDone = new ArrayList();
|
||||
ArrayList<DoingDoneListener<Task>> taskListener = new ArrayList();
|
||||
|
||||
@@ -143,8 +144,8 @@ public class TaskList extends Thread {
|
||||
|
||||
threadPool.clear();
|
||||
totTask = taskQueue.size();
|
||||
for (Task taskQueue1 : taskQueue)
|
||||
executeTask(taskQueue1);
|
||||
while(!taskQueue.isEmpty())
|
||||
executeTask(taskQueue.remove(0));
|
||||
if (shouldContinue)
|
||||
for (Runnable d : allDone)
|
||||
d.run();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
</SyntheticProperties>
|
||||
<Events>
|
||||
<EventHandler event="windowClosed" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosed"/>
|
||||
<EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosing"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
@@ -33,10 +34,14 @@ public class TaskWindow extends javax.swing.JDialog
|
||||
|
||||
private static final TaskWindow instance = new TaskWindow();
|
||||
|
||||
public static TaskWindow getInstance() {
|
||||
private static TaskWindow inst() {
|
||||
instance.clean();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static TaskWindowFactory getInstance() {
|
||||
return new TaskWindowFactory();
|
||||
}
|
||||
|
||||
boolean suc = false;
|
||||
|
||||
@@ -75,7 +80,7 @@ public class TaskWindow extends javax.swing.JDialog
|
||||
}
|
||||
|
||||
public boolean start() {
|
||||
if (taskList.isAlive()) return false;
|
||||
if (isVisible() || taskList.isAlive()) return false;
|
||||
pgsTotal.setValue(0);
|
||||
suc = false;
|
||||
SwingUtils.clearDefaultTable(lstDownload);
|
||||
@@ -113,6 +118,9 @@ public class TaskWindow extends javax.swing.JDialog
|
||||
public void windowClosed(java.awt.event.WindowEvent evt) {
|
||||
formWindowClosed(evt);
|
||||
}
|
||||
public void windowClosing(java.awt.event.WindowEvent evt) {
|
||||
formWindowClosing(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnCancel.setText(bundle.getString("taskwindow.cancel")); // NOI18N
|
||||
@@ -174,8 +182,13 @@ public class TaskWindow extends javax.swing.JDialog
|
||||
SwingUtilities.invokeLater(taskList::abort);
|
||||
HMCLog.log("Tasks have been canceled by user.");
|
||||
}
|
||||
taskList = null;
|
||||
}//GEN-LAST:event_formWindowClosed
|
||||
|
||||
private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_formWindowClosing
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnCancel;
|
||||
private javax.swing.JTable lstDownload;
|
||||
@@ -262,4 +275,23 @@ public class TaskWindow extends javax.swing.JDialog
|
||||
SwingUtils.setValueAt(lstDownload, task.getInfo() + ": " + sta, idx, 0);
|
||||
});
|
||||
}
|
||||
|
||||
public static class TaskWindowFactory {
|
||||
public static final Object obj = new Object();
|
||||
|
||||
LinkedList<Task> ll = new LinkedList<>();
|
||||
|
||||
public TaskWindowFactory addTask(Task t) {
|
||||
ll.add(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean start() {
|
||||
synchronized(obj) {
|
||||
TaskWindow tw = inst();
|
||||
for(Task t : ll) tw.addTask(t);
|
||||
return tw.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,23 +78,19 @@ public class ForgeInstaller {
|
||||
//forge.format();
|
||||
File file = new File(gameDir, profile.install.filePath);
|
||||
file.getParentFile().mkdirs();
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
BufferedOutputStream bos = new BufferedOutputStream(fos);
|
||||
int c;
|
||||
while ((c = is.read()) != -1)
|
||||
bos.write((byte) c);
|
||||
bos.close();
|
||||
fos.close();
|
||||
try (FileOutputStream fos = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
|
||||
int c;
|
||||
while ((c = is.read()) != -1)
|
||||
bos.write((byte) c);
|
||||
}
|
||||
|
||||
File minecraftserver = new File(gameDir, "minecraft_server." + profile.install.minecraft + ".jar");
|
||||
TaskWindow tw = TaskWindow.getInstance();
|
||||
if (minecraftserver.exists() && JOptionPane.showConfirmDialog(null, "已发现官方服务端文件,是否要重新下载?") == JOptionPane.YES_OPTION) {
|
||||
tw.clean();
|
||||
if (!tw.addTask(new FileDownloadTask("https://s3.amazonaws.com/Minecraft.Download/versions/{MCVER}/minecraft_server.{MCVER}.jar".replace("{MCVER}", profile.install.minecraft),
|
||||
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())
|
||||
MessageBox.Show("Minecraft官方服务端下载失败!");
|
||||
}
|
||||
tw.clean();
|
||||
TaskWindow.TaskWindowFactory tw = TaskWindow.getInstance();
|
||||
for (MinecraftLibrary library : profile.versionInfo.libraries) {
|
||||
library.init();
|
||||
File lib = new File(gameDir, "libraries" + File.separator + library.formatted + ".pack.xz");
|
||||
@@ -103,10 +99,10 @@ public class ForgeInstaller {
|
||||
libURL = library.url;
|
||||
tw.addTask(new FileDownloadTask(libURL + library.formatted.replace("\\", "/"), lib).setTag(library.name));
|
||||
}
|
||||
tw.start();
|
||||
if (!tw.areTasksFinished())
|
||||
if (!tw.start())
|
||||
MessageBox.Show("压缩库下载失败!");
|
||||
tw.clean();
|
||||
|
||||
tw = TaskWindow.getInstance();
|
||||
for (MinecraftLibrary library : profile.versionInfo.libraries) {
|
||||
File packxz = new File(gameDir, "libraries" + File.separator + library.formatted + ".pack.xz");
|
||||
if (packxz.exists()) return;
|
||||
@@ -117,11 +113,10 @@ public class ForgeInstaller {
|
||||
libURL = library.url;
|
||||
tw.addTask(new FileDownloadTask(libURL + library.formatted.replace("\\", "/"), lib).setTag(library.name));
|
||||
}
|
||||
tw.start();
|
||||
if (!tw.areTasksFinished())
|
||||
if (!tw.start())
|
||||
MessageBox.Show("库下载失败!");
|
||||
tw.clean();
|
||||
ArrayList<String> badLibs = new ArrayList<String>();
|
||||
|
||||
ArrayList<String> badLibs = new ArrayList<>();
|
||||
for (MinecraftLibrary library : profile.versionInfo.libraries) {
|
||||
File lib = new File(gameDir, "libraries" + File.separator + library.formatted);
|
||||
File packFile = new File(gameDir, "libraries" + File.separator + library.formatted + ".pack.xz");
|
||||
@@ -157,17 +152,15 @@ public class ForgeInstaller {
|
||||
|
||||
byte[] checksums = Arrays.copyOfRange(decompressed, decompressed.length - len - 8, decompressed.length - 8);
|
||||
|
||||
FileOutputStream jarBytes = new FileOutputStream(output);
|
||||
JarOutputStream jos = new JarOutputStream(jarBytes);
|
||||
|
||||
Pack200.newUnpacker().unpack(new ByteArrayInputStream(decompressed), jos);
|
||||
|
||||
jos.putNextEntry(new JarEntry("checksums.sha1"));
|
||||
jos.write(checksums);
|
||||
jos.closeEntry();
|
||||
|
||||
jos.close();
|
||||
jarBytes.close();
|
||||
try (FileOutputStream jarBytes = new FileOutputStream(output); JarOutputStream jos = new JarOutputStream(jarBytes)) {
|
||||
|
||||
Pack200.newUnpacker().unpack(new ByteArrayInputStream(decompressed), jos);
|
||||
|
||||
jos.putNextEntry(new JarEntry("checksums.sha1"));
|
||||
jos.write(checksums);
|
||||
jos.closeEntry();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checksumValid(File libPath, List<String> checksums) {
|
||||
@@ -186,21 +179,21 @@ public class ForgeInstaller {
|
||||
private static boolean validateJar(File libPath, byte[] data, List<String> checksums) throws IOException {
|
||||
System.out.println("Checking \"" + libPath.getAbsolutePath() + "\" internal checksums");
|
||||
|
||||
HashMap<String, String> files = new HashMap<String, String>();
|
||||
HashMap<String, String> files = new HashMap<>();
|
||||
String[] hashes = null;
|
||||
JarInputStream jar = new JarInputStream(new ByteArrayInputStream(data));
|
||||
JarEntry entry = jar.getNextJarEntry();
|
||||
while (entry != null) {
|
||||
byte[] eData = IOUtils.readFully(jar);
|
||||
|
||||
if (entry.getName().equals("checksums.sha1"))
|
||||
hashes = new String(eData, Charset.forName("UTF-8")).split("\n");
|
||||
|
||||
if (!entry.isDirectory())
|
||||
files.put(entry.getName(), DigestUtils.sha1Hex(eData));
|
||||
entry = jar.getNextJarEntry();
|
||||
try (JarInputStream jar = new JarInputStream(new ByteArrayInputStream(data))) {
|
||||
JarEntry entry = jar.getNextJarEntry();
|
||||
while (entry != null) {
|
||||
byte[] eData = IOUtils.readFully(jar);
|
||||
|
||||
if (entry.getName().equals("checksums.sha1"))
|
||||
hashes = new String(eData, Charset.forName("UTF-8")).split("\n");
|
||||
|
||||
if (!entry.isDirectory())
|
||||
files.put(entry.getName(), DigestUtils.sha1Hex(eData));
|
||||
entry = jar.getNextJarEntry();
|
||||
}
|
||||
}
|
||||
jar.close();
|
||||
|
||||
if (hashes != null) {
|
||||
boolean failed = !checksums.contains(files.get("checksums.sha1"));
|
||||
|
||||
Reference in New Issue
Block a user