mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-10 20:37:30 -04:00
添加可以在线控制的下载源
This commit is contained in:
parent
9ae010a391
commit
94b6cda86e
@ -98,7 +98,7 @@ public class AssetsMojangLoader extends IAssetsHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task getDownloadTask(IDownloadProvider sourceType) {
|
public Task getDownloadTask(IDownloadProvider sourceType) {
|
||||||
return new AssetsTask(sourceType.getAssetsDownloadURL());
|
return new AssetsTask(sourceType.getAssetsDownloadURL(), sourceType.getRetryAssetsDownloadURL());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,6 +34,8 @@ import org.jackhuang.hellominecraft.util.code.DigestUtils;
|
|||||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||||
import org.jackhuang.hellominecraft.util.OverridableSwingWorker;
|
import org.jackhuang.hellominecraft.util.OverridableSwingWorker;
|
||||||
|
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||||
|
import org.jackhuang.hellominecraft.util.func.Function;
|
||||||
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
|
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,30 +91,37 @@ public abstract class IAssetsHandler {
|
|||||||
|
|
||||||
protected class AssetsTask extends TaskInfo {
|
protected class AssetsTask extends TaskInfo {
|
||||||
|
|
||||||
ArrayList<Task> al;
|
ArrayList<Task> tasks;
|
||||||
String u;
|
String baseUrl;
|
||||||
|
String retryBaseUrl;
|
||||||
|
|
||||||
public AssetsTask(String url) {
|
public AssetsTask(String url, String retryUrl) {
|
||||||
super(C.i18n("assets.download"));
|
super(C.i18n("assets.download"));
|
||||||
this.u = url;
|
this.baseUrl = url;
|
||||||
|
this.retryBaseUrl = retryUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void executeTask() {
|
public void executeTask() {
|
||||||
if (assetsDownloadURLs == null || assetsLocalNames == null || contents == null)
|
if (assetsDownloadURLs == null || assetsLocalNames == null || contents == null)
|
||||||
throw new IllegalStateException(C.i18n("assets.not_refreshed"));
|
throw new IllegalStateException(C.i18n("assets.not_refreshed"));
|
||||||
|
|
||||||
|
tasks = new ArrayList<>();
|
||||||
int max = assetsDownloadURLs.size();
|
int max = assetsDownloadURLs.size();
|
||||||
al = new ArrayList<>();
|
|
||||||
int hasDownloaded = 0;
|
int hasDownloaded = 0;
|
||||||
for (int i = 0; i < max; i++) {
|
for (int i = 0; i < max; i++) {
|
||||||
String mark = assetsDownloadURLs.get(i);
|
String mark = assetsDownloadURLs.get(i);
|
||||||
String url = u + mark;
|
String downloadUrl = baseUrl + mark;
|
||||||
|
String downloadRetryUrl = StrUtils.isNotBlank(retryBaseUrl) ? retryBaseUrl + mark : "";
|
||||||
File location = assetsLocalNames.get(i);
|
File location = assetsLocalNames.get(i);
|
||||||
|
|
||||||
if (!location.getParentFile().exists() && !location.getParentFile().mkdirs())
|
if (!location.getParentFile().exists() && !location.getParentFile().mkdirs())
|
||||||
HMCLog.warn("Failed to make directories: " + location.getParent());
|
HMCLog.warn("Failed to make directories: " + location.getParent());
|
||||||
|
|
||||||
if (location.isDirectory())
|
if (location.isDirectory())
|
||||||
continue;
|
continue;
|
||||||
boolean need = true;
|
|
||||||
|
boolean needDownload = true;
|
||||||
try {
|
try {
|
||||||
if (location.exists()) {
|
if (location.exists()) {
|
||||||
FileInputStream fis = new FileInputStream(location);
|
FileInputStream fis = new FileInputStream(location);
|
||||||
@ -121,23 +130,39 @@ public abstract class IAssetsHandler {
|
|||||||
if (contents.get(i).geteTag().equals(sha)) {
|
if (contents.get(i).geteTag().equals(sha)) {
|
||||||
++hasDownloaded;
|
++hasDownloaded;
|
||||||
HMCLog.log("File " + assetsLocalNames.get(i) + " has been downloaded successfully, skipped downloading.");
|
HMCLog.log("File " + assetsLocalNames.get(i) + " has been downloaded successfully, skipped downloading.");
|
||||||
if (ppl != null)
|
if (ppl != null) {
|
||||||
ppl.setProgress(this, hasDownloaded, max);
|
ppl.setProgress(this, hasDownloaded, max);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
HMCLog.warn("Failed to get hash: " + location, e);
|
HMCLog.warn("Failed to get hash: " + location, e);
|
||||||
need = !location.exists();
|
needDownload = !location.exists();
|
||||||
}
|
}
|
||||||
if (need)
|
|
||||||
al.add(new FileDownloadTask(url, location).setTag(mark));
|
if (needDownload) {
|
||||||
|
FileDownloadTask fileDownloadTask = new FileDownloadTask(downloadUrl, location);
|
||||||
|
fileDownloadTask.setTag(mark);
|
||||||
|
|
||||||
|
// retry
|
||||||
|
if (StrUtils.isNotBlank(downloadRetryUrl)) {
|
||||||
|
fileDownloadTask.setFailedCallbackReturnsNewURL(new Function<Integer, String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(Integer t) {
|
||||||
|
return downloadRetryUrl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.add(fileDownloadTask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Task> getAfterTasks() {
|
public Collection<Task> getAfterTasks() {
|
||||||
return al;
|
return tasks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,8 @@ public class MinecraftAssetService extends IMinecraftAssetService {
|
|||||||
public Task downloadAssets(final MinecraftVersion mv) {
|
public Task downloadAssets(final MinecraftVersion mv) {
|
||||||
if (mv == null)
|
if (mv == null)
|
||||||
return null;
|
return null;
|
||||||
return IAssetsHandler.ASSETS_HANDLER.getList(mv, service.asset()).after(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider()));
|
return IAssetsHandler.ASSETS_HANDLER.getList(mv, service.asset())
|
||||||
|
.after(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,10 +29,12 @@ public class DownloadLibraryJob {
|
|||||||
|
|
||||||
public IMinecraftLibrary lib;
|
public IMinecraftLibrary lib;
|
||||||
public String url;
|
public String url;
|
||||||
|
public String retryUrl;
|
||||||
public File path;
|
public File path;
|
||||||
|
|
||||||
public DownloadLibraryJob(IMinecraftLibrary n, String u, File p) {
|
public DownloadLibraryJob(IMinecraftLibrary n, String u, String retry, File p) {
|
||||||
url = u;
|
url = u;
|
||||||
|
retryUrl = retry;
|
||||||
lib = n;
|
lib = n;
|
||||||
path = IOUtils.tryGetCanonicalFile(p);
|
path = IOUtils.tryGetCanonicalFile(p);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,8 @@ public enum DownloadType {
|
|||||||
Mojang("download.mojang", new MojangDownloadProvider()),
|
Mojang("download.mojang", new MojangDownloadProvider()),
|
||||||
BMCL("download.BMCL", new BMCLAPIDownloadProvider()),
|
BMCL("download.BMCL", new BMCLAPIDownloadProvider()),
|
||||||
//RapidData("download.rapid_data", new RapidDataDownloadProvider()),
|
//RapidData("download.rapid_data", new RapidDataDownloadProvider()),
|
||||||
Curse("Curse CDN", new CurseDownloadProvider());
|
Curse("Curse CDN", new CurseDownloadProvider()),
|
||||||
|
Dynamic(DynamicDownloadProvider.getInstance().getName(), DynamicDownloadProvider.getInstance());
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final IDownloadProvider provider;
|
private final IDownloadProvider provider;
|
||||||
@ -47,7 +48,7 @@ public enum DownloadType {
|
|||||||
return C.i18n(name);
|
return C.i18n(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DownloadType suggestedDownloadType = Mojang;
|
private static DownloadType suggestedDownloadType = Dynamic;
|
||||||
|
|
||||||
public static DownloadType getSuggestedDownloadType() {
|
public static DownloadType getSuggestedDownloadType() {
|
||||||
return suggestedDownloadType;
|
return suggestedDownloadType;
|
||||||
|
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* 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.download;
|
||||||
|
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.jackhuang.hellominecraft.util.C;
|
||||||
|
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||||
|
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author evilwk <evilwk@gmail.com>
|
||||||
|
*/
|
||||||
|
public class DynamicDownloadProvider extends MojangDownloadProvider {
|
||||||
|
|
||||||
|
private static final String PROVIDER_ADDR = "http://localhost/provider.php";
|
||||||
|
|
||||||
|
private volatile static DynamicDownloadProvider instance;
|
||||||
|
|
||||||
|
private String librariesAddr = null;
|
||||||
|
private String assetsAddr = null;
|
||||||
|
private String name = "MCHost";
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLibrariesAddr() {
|
||||||
|
return librariesAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLibrariesAddr(String librariesAddr) {
|
||||||
|
this.librariesAddr = librariesAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAssetsAddr() {
|
||||||
|
return assetsAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAssetsAddr(String assetsAddr) {
|
||||||
|
this.assetsAddr = assetsAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private DynamicDownloadProvider() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DynamicDownloadProvider getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
synchronized (DynamicDownloadProvider.class) {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new DynamicDownloadProvider();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRetryAssetsDownloadURL() {
|
||||||
|
return super.getAssetsDownloadURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRetryLibraryDownloadURL() {
|
||||||
|
return super.getLibraryDownloadURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAssetsDownloadURL() {
|
||||||
|
if (StrUtils.isNotBlank(assetsAddr)) {
|
||||||
|
return assetsAddr;
|
||||||
|
}
|
||||||
|
return super.getAssetsDownloadURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLibraryDownloadURL() {
|
||||||
|
if (StrUtils.isNotBlank(librariesAddr)) {
|
||||||
|
return librariesAddr;
|
||||||
|
}
|
||||||
|
return super.getLibraryDownloadURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getParsedDownloadURL(String str) {
|
||||||
|
if (StrUtils.isNotBlank(librariesAddr)) {
|
||||||
|
str = str.replace("https://libraries.minecraft.net", librariesAddr);
|
||||||
|
}
|
||||||
|
return super.getParsedDownloadURL(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
String providerInfo = NetUtils.get(PROVIDER_ADDR);
|
||||||
|
Map<String, String> addrInfo = null;
|
||||||
|
addrInfo = C.GSON.fromJson(providerInfo, new TypeToken<Map<String, String>>(){}.getType());
|
||||||
|
if (addrInfo != null) {
|
||||||
|
if (addrInfo.containsKey("libraries")) {
|
||||||
|
String librariesAddr = addrInfo.get("libraries");
|
||||||
|
if (StrUtils.isNotBlank(librariesAddr)) {
|
||||||
|
DynamicDownloadProvider.this.setLibrariesAddr(librariesAddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (addrInfo.containsKey("assets")) {
|
||||||
|
String assetsAddr = addrInfo.get("assets");
|
||||||
|
if (StrUtils.isNotBlank(assetsAddr)) {
|
||||||
|
DynamicDownloadProvider.this.setAssetsAddr(assetsAddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (addrInfo.containsKey("name")) {
|
||||||
|
String name = addrInfo.get("name");
|
||||||
|
if (StrUtils.isNotBlank(name)) {
|
||||||
|
DynamicDownloadProvider.this.setName(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,7 @@ public abstract class IDownloadProvider {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract InstallerVersionList getForgeInstaller();
|
public abstract InstallerVersionList getForgeInstaller();
|
||||||
|
|
||||||
public abstract InstallerVersionList getLiteLoaderInstaller();
|
public abstract InstallerVersionList getLiteLoaderInstaller();
|
||||||
@ -46,6 +46,10 @@ public abstract class IDownloadProvider {
|
|||||||
public abstract InstallerVersionList getOptiFineInstaller();
|
public abstract InstallerVersionList getOptiFineInstaller();
|
||||||
|
|
||||||
public abstract String getLibraryDownloadURL();
|
public abstract String getLibraryDownloadURL();
|
||||||
|
|
||||||
|
public String getRetryLibraryDownloadURL() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
public abstract String getVersionsDownloadURL();
|
public abstract String getVersionsDownloadURL();
|
||||||
|
|
||||||
@ -55,6 +59,10 @@ public abstract class IDownloadProvider {
|
|||||||
|
|
||||||
public abstract String getAssetsDownloadURL();
|
public abstract String getAssetsDownloadURL();
|
||||||
|
|
||||||
|
public String getRetryAssetsDownloadURL() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For example, minecraft.json/assetIndex/url or
|
* For example, minecraft.json/assetIndex/url or
|
||||||
* minecraft.json/downloads/client/url
|
* minecraft.json/downloads/client/url
|
||||||
|
@ -31,6 +31,7 @@ import org.jackhuang.hellominecraft.launcher.core.GameException;
|
|||||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.version.GameDownloadInfo;
|
import org.jackhuang.hellominecraft.launcher.core.version.GameDownloadInfo;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
|
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
|
||||||
|
import org.jackhuang.hellominecraft.launcher.core.version.LibraryDownloadInfo;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||||
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
||||||
import org.jackhuang.hellominecraft.util.func.Function;
|
import org.jackhuang.hellominecraft.util.func.Function;
|
||||||
@ -53,14 +54,17 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
|
|||||||
ArrayList<DownloadLibraryJob> downloadLibraries = new ArrayList<>();
|
ArrayList<DownloadLibraryJob> downloadLibraries = new ArrayList<>();
|
||||||
if (mv == null)
|
if (mv == null)
|
||||||
return downloadLibraries;
|
return downloadLibraries;
|
||||||
|
|
||||||
MinecraftVersion v = mv.resolve(service.version());
|
MinecraftVersion v = mv.resolve(service.version());
|
||||||
for (IMinecraftLibrary l : v.getLibraries())
|
for (IMinecraftLibrary libraryInfo : v.getLibraries())
|
||||||
if (l != null && l.allow() && l.getDownloadInfo() != null) {
|
if (libraryInfo != null && libraryInfo.allow() && libraryInfo.getDownloadInfo() != null) {
|
||||||
File ff = l.getFilePath(service.baseDirectory());
|
File ff = libraryInfo.getFilePath(service.baseDirectory());
|
||||||
if (!ff.exists()) {
|
if (!ff.exists()) {
|
||||||
String libURL = l.getDownloadInfo().getUrl(service.getDownloadType());
|
LibraryDownloadInfo downloadInfo = libraryInfo.getDownloadInfo();
|
||||||
if (libURL != null)
|
String downloadUrl = downloadInfo.getUrl(service.getDownloadType());
|
||||||
downloadLibraries.add(new DownloadLibraryJob(l, libURL, ff));
|
String retryDownloadUrl = downloadInfo.getRetryUrl(service.getDownloadType());
|
||||||
|
if (downloadUrl != null)
|
||||||
|
downloadLibraries.add(new DownloadLibraryJob(libraryInfo, downloadUrl, retryDownloadUrl, ff));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return downloadLibraries;
|
return downloadLibraries;
|
||||||
@ -114,10 +118,13 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(Integer t) {
|
public String apply(Integer repeat) {
|
||||||
return DownloadType.values()[t / 2].getProvider().getVersionsDownloadURL() + suffix;
|
int index = repeat / 2;
|
||||||
|
if (index > DownloadType.values().length) {
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
return DownloadType.values()[index].getProvider().getVersionsDownloadURL() + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,27 +41,32 @@ public class MojangDownloadProvider extends IDownloadProvider {
|
|||||||
public InstallerVersionList getOptiFineInstaller() {
|
public InstallerVersionList getOptiFineInstaller() {
|
||||||
return org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla.OptiFineVersionList.getInstance();
|
return org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla.OptiFineVersionList.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jars
|
||||||
@Override
|
@Override
|
||||||
public String getLibraryDownloadURL() {
|
public String getLibraryDownloadURL() {
|
||||||
return "https://libraries.minecraft.net";
|
return "https://libraries.minecraft.net";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jars
|
||||||
@Override
|
@Override
|
||||||
public String getVersionsDownloadURL() {
|
public String getVersionsDownloadURL() {
|
||||||
return "http://s3.amazonaws.com/Minecraft.Download/versions/";
|
return "http://s3.amazonaws.com/Minecraft.Download/versions/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resource
|
||||||
@Override
|
@Override
|
||||||
public String getIndexesDownloadURL() {
|
public String getIndexesDownloadURL() {
|
||||||
return "http://s3.amazonaws.com/Minecraft.Download/indexes/";
|
return "http://s3.amazonaws.com/Minecraft.Download/indexes/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// game versions json
|
||||||
@Override
|
@Override
|
||||||
public String getVersionsListDownloadURL() {
|
public String getVersionsListDownloadURL() {
|
||||||
return "https://launchermeta.mojang.com/mc/game/version_manifest.json";
|
return "https://launchermeta.mojang.com/mc/game/version_manifest.json";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resource
|
||||||
@Override
|
@Override
|
||||||
public String getAssetsDownloadURL() {
|
public String getAssetsDownloadURL() {
|
||||||
return "https://resources.download.minecraft.net/";
|
return "https://resources.download.minecraft.net/";
|
||||||
|
@ -21,6 +21,8 @@ import java.io.File;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import org.jackhuang.hellominecraft.util.C;
|
import org.jackhuang.hellominecraft.util.C;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||||
|
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||||
|
import org.jackhuang.hellominecraft.util.func.Function;
|
||||||
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,12 +51,20 @@ public class LibraryDownloadTask extends FileDownloadTask {
|
|||||||
if (s.length == 3 && s[2].length() > 3)
|
if (s.length == 3 && s[2].length() > 3)
|
||||||
job.url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + s[2].substring(0, s[2].length() - 3) + "/liteloader-" + s[2] + ".jar";
|
job.url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + s[2].substring(0, s[2].length() - 3) + "/liteloader-" + s[2] + ".jar";
|
||||||
}
|
}
|
||||||
download(new URL(job.url), job.path);
|
download(new URL(job.url), job.retryUrl, job.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void download(URL url, File filePath) throws Throwable {
|
void download(URL url, String retryUrl, File filePath) throws Throwable {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.filePath = filePath;
|
this.filePath = filePath;
|
||||||
|
if (StrUtils.isNotBlank(retryUrl)) {
|
||||||
|
this.failedCallbackReturnsNewURL = new Function<Integer, String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(Integer t) {
|
||||||
|
return retryUrl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
super.executeTask();
|
super.executeTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.launcher.core.version;
|
|||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||||
|
import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider;
|
||||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||||
|
|
||||||
@ -35,14 +36,36 @@ public class LibraryDownloadInfo extends GameDownloadInfo {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(DownloadType dt, boolean allowSelf) {
|
public String getUrl(DownloadType dt, boolean allowSelf) {
|
||||||
String myURL = (forgeURL == null ? dt.getProvider().getLibraryDownloadURL() : forgeURL);
|
IDownloadProvider provider = dt.getProvider();
|
||||||
if (StrUtils.isNotBlank(url) && allowSelf)
|
String downloadUrl = (forgeURL == null ? provider.getLibraryDownloadURL() : forgeURL);
|
||||||
myURL = url;
|
if (StrUtils.isNotBlank(url) && allowSelf) {
|
||||||
if (!myURL.endsWith(".jar"))
|
downloadUrl = provider.getParsedDownloadURL(url);
|
||||||
|
}
|
||||||
|
return getUrlWithBaseUrl(downloadUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrlWithBaseUrl(String baseUrl) {
|
||||||
|
if (!baseUrl.endsWith(".jar")) {
|
||||||
if (path == null)
|
if (path == null)
|
||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
myURL = IOUtils.addURLSeparator(myURL) + path.replace('\\', '/');
|
baseUrl = IOUtils.addURLSeparator(baseUrl) + path.replace('\\', '/');
|
||||||
return myURL;
|
}
|
||||||
}
|
return baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRetryUrl(DownloadType dt) {
|
||||||
|
IDownloadProvider provider = dt.getProvider();
|
||||||
|
String retryBaseUrl = provider.getRetryLibraryDownloadURL();
|
||||||
|
if (StrUtils.isBlank(retryBaseUrl)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String downloadUrl = (forgeURL == null ? retryBaseUrl : forgeURL);
|
||||||
|
if (StrUtils.isNotBlank(url) && provider.isAllowedToUseSelfURL()) {
|
||||||
|
downloadUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getUrlWithBaseUrl(downloadUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,29 +48,25 @@ public class MinecraftLibrary extends IMinecraftLibrary {
|
|||||||
|
|
||||||
public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract, LibraryDownloadInfo downloads) {
|
public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract, LibraryDownloadInfo downloads) {
|
||||||
super(name);
|
super(name);
|
||||||
this.rules = rules == null ? null : (ArrayList<Rules>) rules.clone();
|
this.rules = (rules == null) ? null : (ArrayList<Rules>) rules.clone();
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.natives = natives == null ? null : (Natives) natives.clone();
|
this.natives = (natives == null) ? null : (Natives) natives.clone();
|
||||||
this.extract = extract == null ? null : (Extract) extract.clone();
|
this.extract = (extract == null) ? null : (Extract) extract.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* is the library allowed to load.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allow() {
|
public boolean allow() {
|
||||||
if (rules != null) {
|
if (rules != null) {
|
||||||
boolean flag = false;
|
boolean flag = false;
|
||||||
for (Rules r : rules)
|
for (Rules r : rules) {
|
||||||
if ("disallow".equals(r.action()))
|
if ("disallow".equals(r.action()))
|
||||||
return false;
|
return false;
|
||||||
else if ("allow".equals(r.action()))
|
else if ("allow".equals(r.action()))
|
||||||
flag = true;
|
flag = true;
|
||||||
|
}
|
||||||
return flag;
|
return flag;
|
||||||
} else
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatArch(String nati) {
|
private String formatArch(String nati) {
|
||||||
@ -95,19 +91,24 @@ public class MinecraftLibrary extends IMinecraftLibrary {
|
|||||||
|
|
||||||
public String formatName() {
|
public String formatName() {
|
||||||
String[] s = name.split(":");
|
String[] s = name.split(":");
|
||||||
if (s.length < 3)
|
if (s.length < 3) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder(s[0].replace('.', '/')).append('/').append(s[1]).append('/').append(s[2]).append('/').append(s[1]).append('-').append(s[2]);
|
StringBuilder sb = new StringBuilder(s[0].replace('.', '/')).append('/').append(s[1]).append('/').append(s[2]).append('/').append(s[1]).append('-').append(s[2]);
|
||||||
if (natives != null)
|
if (natives != null) {
|
||||||
sb.append('-').append(getNative());
|
sb.append('-').append(getNative());
|
||||||
|
}
|
||||||
|
|
||||||
return sb.append(".jar").toString();
|
return sb.append(".jar").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getFilePath(File gameDir) {
|
public File getFilePath(File gameDir) {
|
||||||
LibraryDownloadInfo info = getDownloadInfo();
|
LibraryDownloadInfo info = getDownloadInfo();
|
||||||
if (info == null)
|
if (info == null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
return new File(gameDir, "libraries/" + info.path);
|
return new File(gameDir, "libraries/" + info.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,25 +118,34 @@ public class MinecraftLibrary extends IMinecraftLibrary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LibraryDownloadInfo getDownloadInfo() {
|
public LibraryDownloadInfo getDownloadInfo() {
|
||||||
if (downloads == null)
|
if (downloads == null) {
|
||||||
downloads = new LibrariesDownloadInfo();
|
downloads = new LibrariesDownloadInfo();
|
||||||
LibraryDownloadInfo info;
|
}
|
||||||
|
|
||||||
|
LibraryDownloadInfo info = null;
|
||||||
if (natives != null) {
|
if (natives != null) {
|
||||||
if (downloads.classifiers == null)
|
if (downloads.classifiers == null) {
|
||||||
downloads.classifiers = new HashMap<>();
|
downloads.classifiers = new HashMap<>();
|
||||||
if (!downloads.classifiers.containsKey(getNative()))
|
} else {
|
||||||
downloads.classifiers.put(getNative(), info = new LibraryDownloadInfo());
|
if (!downloads.classifiers.containsKey(getNative())) {
|
||||||
else
|
downloads.classifiers.put(getNative(), info = new LibraryDownloadInfo());
|
||||||
info = downloads.classifiers.get(getNative());
|
} else {
|
||||||
} else if (downloads.artifact == null)
|
info = downloads.classifiers.get(getNative());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (downloads.artifact == null) {
|
||||||
downloads.artifact = info = new LibraryDownloadInfo();
|
downloads.artifact = info = new LibraryDownloadInfo();
|
||||||
else
|
} else {
|
||||||
info = downloads.artifact;
|
info = downloads.artifact;
|
||||||
|
}
|
||||||
|
|
||||||
if (StrUtils.isBlank(info.path)) {
|
if (StrUtils.isBlank(info.path)) {
|
||||||
info.path = formatName();
|
info.path = formatName();
|
||||||
if (info.path == null)
|
if (info.path == null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info.forgeURL = this.url;
|
info.forgeURL = this.url;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -59,144 +59,147 @@ import org.jackhuang.hellominecraft.util.VersionNumber;
|
|||||||
*/
|
*/
|
||||||
public final class Main implements Runnable {
|
public final class Main implements Runnable {
|
||||||
|
|
||||||
private static final X509TrustManager XTM = new X509TrustManager() {
|
private static final X509TrustManager XTM = new X509TrustManager() {
|
||||||
@Override
|
@Override
|
||||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public X509Certificate[] getAcceptedIssuers() {
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
return new X509Certificate[0];
|
return new X509Certificate[0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private static final HostnameVerifier HNV = (hostname, session) -> true;
|
private static final HostnameVerifier HNV = (hostname, session) -> true;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
SSLContext sslContext = null;
|
SSLContext sslContext = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sslContext = SSLContext.getInstance("TLS");
|
sslContext = SSLContext.getInstance("TLS");
|
||||||
X509TrustManager[] xtmArray = new X509TrustManager[] { XTM };
|
X509TrustManager[] xtmArray = new X509TrustManager[]{XTM};
|
||||||
sslContext.init(null, xtmArray, new java.security.SecureRandom());
|
sslContext.init(null, xtmArray, new java.security.SecureRandom());
|
||||||
} catch (GeneralSecurityException gse) {
|
} catch (GeneralSecurityException gse) {
|
||||||
}
|
}
|
||||||
if (sslContext != null)
|
if (sslContext != null) {
|
||||||
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
||||||
|
}
|
||||||
|
|
||||||
HttpsURLConnection.setDefaultHostnameVerifier(HNV);
|
HttpsURLConnection.setDefaultHostnameVerifier(HNV);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String LAUNCHER_NAME = "Hello Minecraft! Launcher";
|
public static final String LAUNCHER_NAME = "Hello Minecraft! Launcher";
|
||||||
public static final String LAUNCHER_VERSION = "@HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING@";
|
public static final String LAUNCHER_VERSION = "@HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING@";
|
||||||
public static final int MINIMUM_LAUNCHER_VERSION = 16;
|
public static final int MINIMUM_LAUNCHER_VERSION = 16;
|
||||||
|
|
||||||
public static VersionNumber getVersionNumber() {
|
public static VersionNumber getVersionNumber() {
|
||||||
return VersionNumber.check(LAUNCHER_VERSION);
|
return VersionNumber.check(LAUNCHER_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the main window title.
|
* Make the main window title.
|
||||||
*
|
*
|
||||||
* @return the MainWindow title.
|
* @return the MainWindow title.
|
||||||
*/
|
*/
|
||||||
public static String makeTitle() {
|
public static String makeTitle() {
|
||||||
return LAUNCHER_NAME + ' ' + LAUNCHER_VERSION;
|
return LAUNCHER_NAME + ' ' + LAUNCHER_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String shortTitle() {
|
public static String shortTitle() {
|
||||||
return "HMCL" + ' ' + LAUNCHER_VERSION;
|
return "HMCL" + ' ' + LAUNCHER_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Main INSTANCE = new Main();
|
public static final Main INSTANCE = new Main();
|
||||||
private static HelloMinecraftLookAndFeel LOOK_AND_FEEL;
|
private static HelloMinecraftLookAndFeel LOOK_AND_FEEL;
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
|
||||||
|
|
||||||
@SuppressWarnings({ "CallToPrintStackTrace", "UseSpecificCatch" })
|
@SuppressWarnings({"CallToPrintStackTrace", "UseSpecificCatch"})
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
{
|
PluginManager.getPlugin(DefaultPlugin.class);
|
||||||
PluginManager.getPlugin(DefaultPlugin.class);
|
if (IUpgrader.NOW_UPGRADER.parseArguments(getVersionNumber(), args)) {
|
||||||
if (IUpgrader.NOW_UPGRADER.parseArguments(getVersionNumber(), args))
|
return;
|
||||||
return;
|
}
|
||||||
|
|
||||||
System.setProperty("awt.useSystemAAFontSettings", "on");
|
System.setProperty("awt.useSystemAAFontSettings", "on");
|
||||||
System.setProperty("swing.aatext", "true");
|
System.setProperty("swing.aatext", "true");
|
||||||
System.setProperty("sun.java2d.noddraw", "true");
|
System.setProperty("sun.java2d.noddraw", "true");
|
||||||
System.setProperty("sun.java2d.dpiaware", "false");
|
System.setProperty("sun.java2d.dpiaware", "false");
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new CrashReporter(true));
|
Thread.setDefaultUncaughtExceptionHandler(new CrashReporter(true));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File file = new File("hmcl.log");
|
File file = new File("hmcl.log");
|
||||||
if (!file.exists() && !file.createNewFile())
|
if (!file.exists() && !file.createNewFile()) {
|
||||||
HMCLog.warn("Failed to create log file " + file);
|
HMCLog.warn("Failed to create log file " + file);
|
||||||
Configuration.DEFAULT.appenders.add(new ConsoleAppender("File", new DefaultLayout(), true, new FileOutputStream(file), true));
|
}
|
||||||
} catch (IOException ex) {
|
Configuration.DEFAULT.appenders.add(new ConsoleAppender("File", new DefaultLayout(), true, new FileOutputStream(file), true));
|
||||||
LOGGER.log(Level.SEVERE, "Failed to add log appender File because an error occurred while creating or opening hmcl.log", ex);
|
} catch (IOException ex) {
|
||||||
}
|
LOGGER.log(Level.SEVERE, "Failed to add log appender File because an error occurred while creating or opening hmcl.log", ex);
|
||||||
|
}
|
||||||
|
|
||||||
HMCLog.log("*** " + Main.makeTitle() + " ***");
|
HMCLog.log("*** " + Main.makeTitle() + " ***");
|
||||||
|
|
||||||
String s = Settings.getInstance().getLocalization();
|
String s = Settings.getInstance().getLocalization();
|
||||||
for (SupportedLocales sl : SupportedLocales.values())
|
for (SupportedLocales sl : SupportedLocales.values()) {
|
||||||
if (sl.name().equals(s)) {
|
if (sl.name().equals(s)) {
|
||||||
SupportedLocales.NOW_LOCALE = sl;
|
SupportedLocales.NOW_LOCALE = sl;
|
||||||
Locale.setDefault(sl.self);
|
Locale.setDefault(sl.self);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LogWindow.INSTANCE.clean();
|
LogWindow.INSTANCE.clean();
|
||||||
LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses);
|
LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings);
|
LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings);
|
||||||
UIManager.setLookAndFeel(LOOK_AND_FEEL);
|
UIManager.setLookAndFeel(LOOK_AND_FEEL);
|
||||||
} catch (ParseException | UnsupportedLookAndFeelException ex) {
|
} catch (ParseException | UnsupportedLookAndFeelException ex) {
|
||||||
HMCLog.warn("Failed to set look and feel...", ex);
|
HMCLog.warn("Failed to set look and feel...", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.UPDATE_CHECKER.outdated.register(IUpgrader.NOW_UPGRADER);
|
Settings.UPDATE_CHECKER.outdated.register(IUpgrader.NOW_UPGRADER);
|
||||||
Settings.UPDATE_CHECKER.process(false).reg(t -> Main.invokeUpdate()).execute();
|
Settings.UPDATE_CHECKER.process(false).reg(t -> Main.invokeUpdate()).execute();
|
||||||
|
|
||||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) {
|
if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) {
|
||||||
HMCLog.log("Initializing customized proxy");
|
HMCLog.log("Initializing customized proxy");
|
||||||
System.setProperty("http.proxyHost", Settings.getInstance().getProxyHost());
|
System.setProperty("http.proxyHost", Settings.getInstance().getProxyHost());
|
||||||
System.setProperty("http.proxyPort", Settings.getInstance().getProxyPort());
|
System.setProperty("http.proxyPort", Settings.getInstance().getProxyPort());
|
||||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyUserName()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPassword()))
|
if (StrUtils.isNotBlank(Settings.getInstance().getProxyUserName()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPassword())) {
|
||||||
Authenticator.setDefault(new Authenticator() {
|
Authenticator.setDefault(new Authenticator() {
|
||||||
@Override
|
@Override
|
||||||
protected PasswordAuthentication getPasswordAuthentication() {
|
protected PasswordAuthentication getPasswordAuthentication() {
|
||||||
return new PasswordAuthentication(Settings.getInstance().getProxyUserName(), Settings.getInstance().getProxyPassword().toCharArray());
|
return new PasswordAuthentication(Settings.getInstance().getProxyUserName(), Settings.getInstance().getProxyPassword().toCharArray());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PluginManager.plugin().showUI();
|
PluginManager.plugin().showUI();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
new CrashReporter(false).uncaughtException(Thread.currentThread(), t);
|
new CrashReporter(false).uncaughtException(Thread.currentThread(), t);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
GameLauncher.PROCESS_MANAGER.stopAllProcesses();
|
GameLauncher.PROCESS_MANAGER.stopAllProcesses();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void invokeUpdate() {
|
public static void invokeUpdate() {
|
||||||
MainFrame.INSTANCE.invokeUpdate();
|
MainFrame.INSTANCE.invokeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageIcon getIcon(String path) {
|
public static ImageIcon getIcon(String path) {
|
||||||
try {
|
try {
|
||||||
return new ImageIcon(Main.class.getResource("/org/jackhuang/hellominecraft/launcher/" + path));
|
return new ImageIcon(Main.class.getResource("/org/jackhuang/hellominecraft/launcher/" + path));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
HMCLog.err("Failed to load icon", e);
|
HMCLog.err("Failed to load icon", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,8 @@ public final class Config implements Cloneable {
|
|||||||
|
|
||||||
public Config() {
|
public Config() {
|
||||||
clientToken = UUID.randomUUID().toString();
|
clientToken = UUID.randomUUID().toString();
|
||||||
logintype = downloadtype = 0;
|
logintype = 0;
|
||||||
|
downloadtype = DownloadType.Dynamic.ordinal();
|
||||||
enableShadow = false;
|
enableShadow = false;
|
||||||
enableAnimation = true;
|
enableAnimation = true;
|
||||||
theme = 4;
|
theme = 4;
|
||||||
@ -203,7 +204,7 @@ public final class Config implements Cloneable {
|
|||||||
|
|
||||||
public DownloadType getDownloadSource() {
|
public DownloadType getDownloadSource() {
|
||||||
if (downloadtype >= DownloadType.values().length || downloadtype < 0) {
|
if (downloadtype >= DownloadType.values().length || downloadtype < 0) {
|
||||||
downloadtype = 0;
|
downloadtype = DownloadType.Dynamic.ordinal();
|
||||||
Settings.save();
|
Settings.save();
|
||||||
}
|
}
|
||||||
return DownloadType.values()[downloadtype];
|
return DownloadType.values()[downloadtype];
|
||||||
|
@ -22,6 +22,8 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import org.jackhuang.hellominecraft.util.C;
|
import org.jackhuang.hellominecraft.util.C;
|
||||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||||
import org.jackhuang.hellominecraft.launcher.Main;
|
import org.jackhuang.hellominecraft.launcher.Main;
|
||||||
|
@ -48,6 +48,7 @@ import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
|||||||
import org.jackhuang.hellominecraft.launcher.Main;
|
import org.jackhuang.hellominecraft.launcher.Main;
|
||||||
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
||||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||||
|
import org.jackhuang.hellominecraft.launcher.core.download.DynamicDownloadProvider;
|
||||||
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
|
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
|
||||||
import org.jackhuang.hellominecraft.lookandfeel.Theme;
|
import org.jackhuang.hellominecraft.lookandfeel.Theme;
|
||||||
import org.jackhuang.hellominecraft.util.MessageBox;
|
import org.jackhuang.hellominecraft.util.MessageBox;
|
||||||
@ -85,23 +86,27 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
setUndecorated(!Settings.getInstance().isDecorated());
|
setUndecorated(!Settings.getInstance().isDecorated());
|
||||||
defaultTitle = isUndecorated() ? Main.makeTitle() : "";
|
defaultTitle = isUndecorated() ? Main.makeTitle() : "";
|
||||||
enableShadow = Settings.getInstance().isEnableShadow() && isUndecorated();
|
enableShadow = Settings.getInstance().isEnableShadow() && isUndecorated();
|
||||||
if (enableShadow)
|
if (enableShadow) {
|
||||||
setContentSize(834, 542);
|
setContentSize(834, 542);
|
||||||
else
|
} else {
|
||||||
setContentSize(802, 511);
|
setContentSize(802, 511);
|
||||||
|
}
|
||||||
|
|
||||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||||
setTitle(Main.makeTitle());
|
setTitle(Main.makeTitle());
|
||||||
initComponents();
|
initComponents();
|
||||||
loadBackground();
|
loadBackground();
|
||||||
|
|
||||||
|
DynamicDownloadProvider.getInstance().init();
|
||||||
|
|
||||||
setLocationRelativeTo(null);
|
setLocationRelativeTo(null);
|
||||||
if (MainFrame.this.isUndecorated())
|
if (MainFrame.this.isUndecorated()) {
|
||||||
setResizable(false);
|
setResizable(false);
|
||||||
|
}
|
||||||
|
|
||||||
this.addWindowListener(new WindowListener() {
|
this.addWindowListener(new WindowListener() {
|
||||||
@Override
|
@Override
|
||||||
public void windowOpened(WindowEvent e) {
|
public void windowOpened(WindowEvent e) { }
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowClosing(WindowEvent e) {
|
public void windowClosing(WindowEvent e) {
|
||||||
@ -109,16 +114,13 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowClosed(WindowEvent e) {
|
public void windowClosed(WindowEvent e) { }
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowIconified(WindowEvent e) {
|
public void windowIconified(WindowEvent e) { }
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowDeiconified(WindowEvent e) {
|
public void windowDeiconified(WindowEvent e) { }
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowActivated(WindowEvent e) {
|
public void windowActivated(WindowEvent e) {
|
||||||
@ -131,11 +133,10 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowDeactivated(WindowEvent e) {
|
public void windowDeactivated(WindowEvent e) { }
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (enableShadow)
|
if (enableShadow) {
|
||||||
try {
|
try {
|
||||||
setBackground(new Color(0, 0, 0, 0));
|
setBackground(new Color(0, 0, 0, 0));
|
||||||
getRootPane().setBorder(border = new DropShadowBorder(borderColor, 4));
|
getRootPane().setBorder(border = new DropShadowBorder(borderColor, 4));
|
||||||
@ -144,6 +145,8 @@ public final class MainFrame extends DraggableFrame {
|
|||||||
Settings.getInstance().setEnableShadow(false);
|
Settings.getInstance().setEnableShadow(false);
|
||||||
setSize(802, 511);
|
setSize(802, 511);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
((JPanel) getContentPane()).setOpaque(true);
|
((JPanel) getContentPane()).setOpaque(true);
|
||||||
|
|
||||||
Settings.getInstance().themeChangedEvent.register(this::reloadColor);
|
Settings.getInstance().themeChangedEvent.register(this::reloadColor);
|
||||||
|
@ -118,7 +118,7 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
|
|||||||
this.url = IOUtils.parseURL(p.getResult());
|
this.url = IOUtils.parseURL(p.getResult());
|
||||||
|
|
||||||
for (int repeat = 0; repeat < 6; repeat++) {
|
for (int repeat = 0; repeat < 6; repeat++) {
|
||||||
if (repeat > 0)
|
if (repeat > 0) {
|
||||||
if (failedCallbackReturnsNewURL != null) {
|
if (failedCallbackReturnsNewURL != null) {
|
||||||
URL tmp = IOUtils.parseURL(failedCallbackReturnsNewURL.apply(repeat));
|
URL tmp = IOUtils.parseURL(failedCallbackReturnsNewURL.apply(repeat));
|
||||||
if (tmp != null) {
|
if (tmp != null) {
|
||||||
@ -126,6 +126,8 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
|
|||||||
HMCLog.warn("Switch to: " + url);
|
HMCLog.warn("Switch to: " + url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HMCLog.log("Downloading: " + url + ", to: " + filePath);
|
HMCLog.log("Downloading: " + url + ", to: " + filePath);
|
||||||
if (!shouldContinue)
|
if (!shouldContinue)
|
||||||
break;
|
break;
|
||||||
@ -260,4 +262,8 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
|
|||||||
al.add(pr);
|
al.add(pr);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFailedCallbackReturnsNewURL() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user