Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c839d045cc | ||
|
|
2eaf32b23d | ||
|
|
5899c73ab8 | ||
|
|
6c0a446692 | ||
|
|
7c2cfc171e | ||
|
|
5d4a3c1df6 | ||
|
|
587df1f5bb | ||
|
|
019fcf314b | ||
|
|
1818b3575c | ||
|
|
afde41135a | ||
|
|
5dc812072f | ||
|
|
3ba75d2de3 | ||
|
|
dfc6e91321 | ||
|
|
a5504a4b74 | ||
|
|
d10a7fad20 | ||
|
|
f811d4c89f | ||
|
|
dcaa6241ec | ||
|
|
9527783cdb | ||
|
|
db2b0cb159 | ||
|
|
09dbade477 | ||
|
|
0817b9aebb | ||
|
|
e3c923e268 | ||
|
|
761e671ecf | ||
|
|
fe019b8f0f | ||
|
|
55af958792 | ||
|
|
da1bdb1322 | ||
|
|
892d8fe09c | ||
|
|
89fcf4526c | ||
|
|
5d037b5f0e | ||
|
|
1bb7f8ac60 | ||
|
|
52f761095a | ||
|
|
770ec3ab97 | ||
|
|
7c3159fc23 | ||
|
|
d5924fa6ab | ||
|
|
295f44b947 | ||
|
|
115bc85c58 | ||
|
|
6aaad71126 | ||
|
|
24b4004fd9 | ||
|
|
dd0cdb5c83 | ||
|
|
48f14e193a | ||
|
|
7076272768 | ||
|
|
bef6a2d61b | ||
|
|
84c6723adc | ||
|
|
61a179ba67 | ||
|
|
afecb87c6d | ||
|
|
cb125b83cb | ||
|
|
cb337fc22f | ||
|
|
781c7369fb | ||
|
|
5281fc6a69 | ||
|
|
814d137084 | ||
|
|
a567ab1984 | ||
|
|
69eaa04ff6 | ||
|
|
d0c8a95f57 | ||
|
|
d09607766b | ||
|
|
8f90d56e0f | ||
|
|
d20d06ace7 | ||
|
|
98282fd319 | ||
|
|
8e8584656e | ||
|
|
2f97cd8104 | ||
|
|
8b1ff94c5f | ||
|
|
c67e7c0d3a | ||
|
|
21dcb477dc | ||
|
|
cb5391ed28 | ||
|
|
fdc2570945 | ||
|
|
c60b04caf6 | ||
|
|
fc0c99b436 | ||
|
|
0e4c38d99e | ||
|
|
b0845c700f | ||
|
|
27a013450e | ||
|
|
d4dccd1391 | ||
|
|
cd972f5945 | ||
|
|
ed876fa607 | ||
|
|
06d15b045e | ||
|
|
0821b67019 | ||
|
|
0f18e7c1a1 | ||
|
|
ac7f025952 | ||
|
|
05382a0354 | ||
|
|
55b200dec4 | ||
|
|
587abda389 | ||
|
|
da0cc62f16 | ||
|
|
80e60d2753 | ||
|
|
ff0750f1f7 | ||
|
|
f8eec1b7d5 | ||
|
|
d2162f31e4 | ||
|
|
fee3e5251d | ||
|
|
409fc83819 | ||
|
|
54e14a25da |
No files matched your search
+32
@@ -0,0 +1,32 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
before_deploy:
|
||||
- git config --global user.email ${GITHUB_EMAIL}
|
||||
- git config --global user.name ${GITHUB_NAME}
|
||||
- git tag ${TRAVIS_BUILD_NUMBER}
|
||||
- git push -q ${REPO} --tags
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: lfFEwKtij/s9Ao/SKL7oVdsWcfASshZuwT27gllMrTx1ZQqLCG2I5mGJOp5ukx7lb3y4Tu316nFasLjy9NI3eLXSx9f0w4q+wMf0K5Yj9iOwu/TIn7JkLyHDMQ20qRwGxZplS2WUb669gIRg+l6jUHeTBW+dlTxr0mMa6WHIl8UDpHwfFrGC3i6dL4y6WlDwGl2rYktvOoA/iqvtglBcHuXaL2sDfhp5MXRcYULTIw+b9zmiQXP665DQN+Su5I3gwB4y5X8RH72GAacZn13fEIo5i8UUoHM7UQxM8y8DKSO3avyFCfpUle9+9sErQVW7b6JV1c+AoLWuAhNJLMlUTKarZE7UMqfjvoQHxX5hp2B2WHLEON/UJiGf25HJWx6VhJitE0/odujqnG/umesqki2jMTs6gPcxbc9iBjzUg+ZmFztdtC+Emnni7lpqVVl+Y5hsJRn3Z6rIiNgwmaE0r2OQgAm1vRYFc7jvOdRfyFG+uCRZF6nS56BzJ7dLc0WW8dTgSft6YFll4ZYL6hiI9qiIaBAK948y5HV+6VBWuO3xf/G2CUFbE1Y9qUCjToh3ahxNDzZvXB+rXqvlvNQOi5l8n594oQ61n45qIHSKlMBn9Bxhw29oWT5mo1aYIaNXbpzKam2w4mK0T3VrgTszu/3282wRbNr+VAwdGMfwW1s=
|
||||
file:
|
||||
- HMCL/build/libs/HMCL-${HMCL_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.jar
|
||||
- HMCL/build/libs/HMCL-${HMCL_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.exe
|
||||
- HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.jar
|
||||
- HMCSM/build/libs/HMCSM-${HMCSM_VERSION_ROOT}.${TRAVIS_BUILD_NUMBER}.exe
|
||||
on:
|
||||
repo: huanghongxun/HMCL
|
||||
tags: false
|
||||
skip_cleanup: true
|
||||
install: echo "skip 'gradle assemble' step"
|
||||
script: gradle build --continue
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
cache:
|
||||
directories:
|
||||
- "$HOME/.gradle/caches/"
|
||||
- "$HOME/.gradle/wrapper/"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 383 KiB |
+22
-2
@@ -26,10 +26,18 @@ if (!hasProperty('mainClass')) {
|
||||
ext.mainClass = 'org.jackhuang.hellominecraft.launcher.Main'
|
||||
}
|
||||
|
||||
def buildnumber = System.getenv("BUILD_NUMBER") == null ? ".7" : "."+System.getenv("BUILD_NUMBER")
|
||||
def buildnumber = System.getenv("TRAVIS_BUILD_NUMBER")
|
||||
if (buildnumber == null)
|
||||
buildnumber = System.getenv("BUILD_NUMBER")
|
||||
if (buildnumber == null)
|
||||
buildnumber = "233"
|
||||
|
||||
def versionroot = System.getenv("VERSION_ROOT")
|
||||
if (versionroot == null)
|
||||
versionroot = "2.4.1"
|
||||
|
||||
String mavenGroupId = 'HMCL'
|
||||
String mavenVersion = '2.3.5' + buildnumber
|
||||
String mavenVersion = versionroot + '.' + buildnumber
|
||||
String bundleName = "Hello Minecraft! Launcher"
|
||||
|
||||
group = mavenGroupId
|
||||
@@ -37,6 +45,16 @@ version = mavenVersion
|
||||
|
||||
String mavenArtifactId = name
|
||||
|
||||
task generateSources(type: Copy) {
|
||||
from 'src/main/java'
|
||||
into "$buildDir/generated-src"
|
||||
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [
|
||||
'HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING': mavenVersion
|
||||
])
|
||||
}
|
||||
compileJava.setSource "$buildDir/generated-src"
|
||||
compileJava.dependsOn generateSources
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral();
|
||||
@@ -64,6 +82,7 @@ configure(install.repositories.mavenInstaller) {
|
||||
dependencies {
|
||||
compile project(":MetroLookAndFeel")
|
||||
compile project(":HMCLAPI")
|
||||
compile group: "org.commonjava.googlecode.markdown4j", name: "markdown4j", version: "2.2-cj-1.0"
|
||||
}
|
||||
|
||||
retrolambda {
|
||||
@@ -103,3 +122,4 @@ processResources {
|
||||
}
|
||||
|
||||
build.dependsOn makeExecutable
|
||||
build.dependsOn makePackGZ
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.Authenticator;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.views.LogWindow;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.MinecraftCrashAdvicer;
|
||||
import org.jackhuang.hellominecraft.utils.DoubleOutputStream;
|
||||
import org.jackhuang.hellominecraft.utils.LauncherPrintStream;
|
||||
import org.jackhuang.hellominecraft.utils.MathUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Launcher {
|
||||
|
||||
public static void println(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
static String classPath = "", proxyHost = "", proxyPort = "", proxyUsername = "", proxyPassword = "";
|
||||
|
||||
public static void main(String[] args) {
|
||||
println("*** " + Main.makeTitle() + " ***");
|
||||
|
||||
boolean showInfo = false;
|
||||
String mainClass = "net.minecraft.client.Minecraft";
|
||||
|
||||
ArrayList<String> cmdList = new ArrayList<>();
|
||||
|
||||
for (String s : args)
|
||||
if (s.startsWith("-cp="))
|
||||
classPath = classPath.concat(s.substring("-cp=".length()));
|
||||
else if (s.startsWith("-mainClass="))
|
||||
mainClass = s.substring("-mainClass=".length());
|
||||
else if (s.startsWith("-proxyHost="))
|
||||
proxyHost = s.substring("-proxyHost=".length());
|
||||
else if (s.startsWith("-proxyPort="))
|
||||
proxyPort = s.substring("-proxyPort=".length());
|
||||
else if (s.startsWith("-proxyUsername="))
|
||||
proxyUsername = s.substring("-proxyUsername=".length());
|
||||
else if (s.startsWith("-proxyPassword="))
|
||||
proxyPassword = s.substring("-proxyPassword=".length());
|
||||
else if (s.equals("-debug"))
|
||||
showInfo = true;
|
||||
else
|
||||
cmdList.add(s);
|
||||
|
||||
String[] tokenized = StrUtils.tokenize(classPath, File.pathSeparator);
|
||||
int len = tokenized.length;
|
||||
|
||||
if (showInfo) {
|
||||
LogWindow.INSTANCE.setTerminateGame(() -> {
|
||||
try {
|
||||
Utils.shutdownForcely(1);
|
||||
} catch (Exception e) {
|
||||
MessageBox.Show(C.i18n("launcher.exit_failed"));
|
||||
HMCLog.err("Failed to shutdown forcely", e);
|
||||
}
|
||||
});
|
||||
try {
|
||||
File logFile = new File("hmclmc.log");
|
||||
if (!logFile.exists())
|
||||
logFile.createNewFile();
|
||||
FileOutputStream tc = new FileOutputStream(logFile);
|
||||
DoubleOutputStream out = new DoubleOutputStream(tc, System.out);
|
||||
System.setOut(new LauncherPrintStream(out));
|
||||
DoubleOutputStream err = new DoubleOutputStream(tc, System.err);
|
||||
System.setErr(new LauncherPrintStream(err));
|
||||
} catch (Exception e) {
|
||||
println("Failed to add log file appender.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
println("Arguments: {\n" + StrUtils.parseParams(" ", args, "\n") + "\n}");
|
||||
println("Main Class: " + mainClass);
|
||||
println("Class Path: {\n" + StrUtils.parseParams(" ", tokenized, "\n") + "\n}");
|
||||
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.setVisible(true));
|
||||
}
|
||||
|
||||
if (StrUtils.isNotBlank(proxyHost) && StrUtils.isNotBlank(proxyPort) && MathUtils.canParseInt(proxyPort)) {
|
||||
HMCLog.log("Initializing customized proxy");
|
||||
System.setProperty("http.proxyHost", proxyHost);
|
||||
System.setProperty("http.proxyPort", proxyPort);
|
||||
if (StrUtils.isNotBlank(proxyUsername) && StrUtils.isNotBlank(proxyPassword))
|
||||
Authenticator.setDefault(new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(proxyUsername, proxyPassword.toCharArray());
|
||||
}
|
||||
});
|
||||
//PROXY = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(Settings.getInstance().getProxyHost(), Integer.parseInt(Settings.getInstance().getProxyPort())));
|
||||
} else {
|
||||
//PROXY = Proxy.NO_PROXY;
|
||||
}
|
||||
|
||||
URL[] urls = new URL[len];
|
||||
|
||||
try {
|
||||
for (int j = 0; j < len; j++)
|
||||
urls[j] = new File(tokenized[j]).toURI().toURL();
|
||||
} catch (Throwable e) {
|
||||
MessageBox.Show(C.i18n("crash.main_class_not_found"));
|
||||
println("Failed to get classpath.");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
Method minecraftMain;
|
||||
URLClassLoader ucl = new URLClassLoader(urls, URLClassLoader.getSystemClassLoader().getParent());
|
||||
Thread.currentThread().setContextClassLoader(ucl);
|
||||
try {
|
||||
minecraftMain = ucl.loadClass(mainClass).getMethod("main", String[].class);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException t) {
|
||||
MessageBox.Show(C.i18n("crash.main_class_not_found"));
|
||||
println("Minecraft main class not found.");
|
||||
t.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
println("*** Launching Game ***");
|
||||
|
||||
int flag = 0;
|
||||
try {
|
||||
minecraftMain.invoke(null, new Object[] { (String[]) cmdList.toArray(new String[cmdList.size()]) });
|
||||
} catch (Throwable throwable) {
|
||||
String trace = StrUtils.getStackTrace(throwable);
|
||||
final String advice = MinecraftCrashAdvicer.getAdvice(trace);
|
||||
MessageBox.Show(C.i18n("crash.minecraft") + ": " + advice);
|
||||
|
||||
System.err.println(C.i18n("crash.minecraft"));
|
||||
System.err.println(advice);
|
||||
System.err.println(trace);
|
||||
LogWindow.INSTANCE.setExit(() -> true);
|
||||
LogWindow.INSTANCE.setVisible(true);
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
println("*** Game Exited ***");
|
||||
try {
|
||||
Utils.shutdownForcely(flag);
|
||||
} catch (Exception e) {
|
||||
MessageBox.Show(C.i18n("launcher.exit_failed"));
|
||||
HMCLog.err("Failed to shutdown forcely", e);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* static Object getShutdownHaltLock() {
|
||||
* try {
|
||||
* Class z = Class.forName("java.lang.Shutdown");
|
||||
* Field haltLock = z.getDeclaredField("haltLock");
|
||||
* haltLock.setAccessible(true);
|
||||
* return haltLock.get(null);
|
||||
* } catch (Throwable ex) {
|
||||
* ex.printStackTrace();
|
||||
* return new Object();
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
}
|
||||
Executable → Regular
+44
-35
@@ -25,6 +25,9 @@ import java.net.PasswordAuthentication;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
@@ -32,23 +35,22 @@ import javax.net.ssl.X509TrustManager;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
|
||||
import org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.CrashReporter;
|
||||
import org.jackhuang.hellominecraft.utils.logging.Configuration;
|
||||
import org.jackhuang.hellominecraft.utils.logging.appender.ConsoleAppender;
|
||||
import org.jackhuang.hellominecraft.utils.logging.layout.DefaultLayout;
|
||||
import org.jackhuang.hellominecraft.utils.views.LogWindow;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.upgrade.IUpgrader;
|
||||
import org.jackhuang.hellominecraft.launcher.views.MainFrame;
|
||||
import org.jackhuang.hellominecraft.launcher.util.CrashReporter;
|
||||
import org.jackhuang.hellominecraft.util.logging.Configuration;
|
||||
import org.jackhuang.hellominecraft.util.logging.appender.ConsoleAppender;
|
||||
import org.jackhuang.hellominecraft.util.logging.layout.DefaultLayout;
|
||||
import org.jackhuang.hellominecraft.util.ui.LogWindow;
|
||||
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
||||
import org.jackhuang.hellominecraft.launcher.util.upgrade.IUpgrader;
|
||||
import org.jackhuang.hellominecraft.launcher.ui.MainFrame;
|
||||
import org.jackhuang.hellominecraft.lookandfeel.HelloMinecraftLookAndFeel;
|
||||
import org.jackhuang.hellominecraft.utils.MathUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
import org.jackhuang.hellominecraft.utils.system.Compressor;
|
||||
import rx.concurrency.Schedulers;
|
||||
import org.jackhuang.hellominecraft.util.MathUtils;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.lang.SupportedLocales;
|
||||
import org.jackhuang.hellominecraft.util.VersionNumber;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -67,7 +69,7 @@ public final class Main implements Runnable {
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
};
|
||||
private static final HostnameVerifier HNV = (hostname, session) -> true;
|
||||
@@ -88,17 +90,11 @@ public final class Main implements Runnable {
|
||||
}
|
||||
|
||||
public static final String LAUNCHER_NAME = "Hello Minecraft! Launcher";
|
||||
public static final byte VERSION_FIRST = 2, VERSION_SECOND = 3, VERSION_THIRD = 5, VERSION_FORTH = 8;
|
||||
public static final String LAUNCHER_VERSION = "@HELLO_MINECRAFT_LAUNCHER_VERSION_FOR_GRADLE_REPLACING@";
|
||||
public static final int MINIMUM_LAUNCHER_VERSION = 16;
|
||||
//public static Proxy PROXY;
|
||||
|
||||
/**
|
||||
* Make the version of HMCL.
|
||||
*
|
||||
* @return the version: firstVer.secondVer.thirdVer
|
||||
*/
|
||||
public static String makeVersion() {
|
||||
return "" + VERSION_FIRST + '.' + VERSION_SECOND + '.' + VERSION_THIRD + '.' + VERSION_FORTH;
|
||||
public static VersionNumber getVersionNumber() {
|
||||
return VersionNumber.check(LAUNCHER_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,35 +103,49 @@ public final class Main implements Runnable {
|
||||
* @return the MainWindow title.
|
||||
*/
|
||||
public static String makeTitle() {
|
||||
return LAUNCHER_NAME + ' ' + makeVersion();
|
||||
return LAUNCHER_NAME + ' ' + LAUNCHER_VERSION;
|
||||
}
|
||||
|
||||
public static String shortTitle() {
|
||||
return "HMCL" + ' ' + LAUNCHER_VERSION;
|
||||
}
|
||||
|
||||
public static final Main INSTANCE = new Main();
|
||||
public static HelloMinecraftLookAndFeel LOOK_AND_FEEL;
|
||||
private static HelloMinecraftLookAndFeel LOOK_AND_FEEL;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
|
||||
|
||||
@SuppressWarnings({ "CallToPrintStackTrace", "UseSpecificCatch" })
|
||||
public static void main(String[] args) throws IOException {
|
||||
{
|
||||
//PluginManager.getServerPlugin();
|
||||
|
||||
if (IUpgrader.NOW_UPGRADER.parseArguments(new VersionNumber(VERSION_FIRST, VERSION_SECOND, VERSION_THIRD), args))
|
||||
if (IUpgrader.NOW_UPGRADER.parseArguments(getVersionNumber(), args))
|
||||
return;
|
||||
|
||||
System.setProperty("awt.useSystemAAFontSettings", "on");
|
||||
System.setProperty("swing.aatext", "true");
|
||||
System.setProperty("sun.java2d.noddraw", "true");
|
||||
System.setProperty("sun.java2d.dpiaware", "false");
|
||||
Thread.setDefaultUncaughtExceptionHandler(new CrashReporter(true));
|
||||
|
||||
try {
|
||||
File file = new File("hmcl.log");
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
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) {
|
||||
System.err.println("Failed to add log appender File because an error occurred while creating or opening hmcl.log");
|
||||
ex.printStackTrace();
|
||||
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() + " ***");
|
||||
|
||||
String s = Settings.getInstance().getLocalization();
|
||||
for (SupportedLocales sl : SupportedLocales.values())
|
||||
if (sl.name().equals(s)) {
|
||||
SupportedLocales.NOW_LOCALE = sl;
|
||||
Locale.setDefault(sl.self);
|
||||
}
|
||||
|
||||
LogWindow.INSTANCE.clean();
|
||||
LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses);
|
||||
|
||||
@@ -147,8 +157,7 @@ public final class Main implements Runnable {
|
||||
}
|
||||
|
||||
Settings.UPDATE_CHECKER.outdated.register(IUpgrader.NOW_UPGRADER);
|
||||
Settings.UPDATE_CHECKER.process(false).subscribeOn(Schedulers.newThread()).subscribe(t
|
||||
-> Main.invokeUpdate());
|
||||
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())) {
|
||||
HMCLog.log("Initializing customized proxy");
|
||||
@@ -164,7 +173,7 @@ public final class Main implements Runnable {
|
||||
}
|
||||
|
||||
try {
|
||||
PluginManager.NOW_PLUGIN.showUI();
|
||||
PluginManager.plugin().showUI();
|
||||
} catch (Throwable t) {
|
||||
new CrashReporter(false).uncaughtException(Thread.currentThread(), t);
|
||||
System.exit(1);
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.api;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.launcher.setting.Profile;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions;
|
||||
import org.jackhuang.hellominecraft.util.func.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -59,5 +61,5 @@ public interface IPlugin {
|
||||
*/
|
||||
void onProcessingLoginResult(UserProfileProvider result) throws AuthenticationException;
|
||||
|
||||
void onInitializingProfile(Profile p);
|
||||
void onProcessingLaunchOptions(LaunchOptions p) throws GameException;
|
||||
}
|
||||
@@ -17,8 +17,8 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.api;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.DefaultPlugin;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.util.DefaultPlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -26,12 +26,12 @@ import org.jackhuang.hellominecraft.launcher.settings.DefaultPlugin;
|
||||
*/
|
||||
public class PluginManager {
|
||||
|
||||
public static IPlugin NOW_PLUGIN = new DefaultPlugin();
|
||||
private static IPlugin NOW_PLUGIN = new DefaultPlugin();
|
||||
|
||||
public static void getServerPlugin() {
|
||||
try {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
Class c = cl.loadClass("org.jackhuang.hellominecraft.launcher.servers.ServerPlugin");
|
||||
Class c = cl.loadClass("org.jackhuang.hellominecraft.launcher.server.ServerPlugin");
|
||||
IPlugin p = (IPlugin) c.newInstance();
|
||||
NOW_PLUGIN = p;
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
@@ -40,4 +40,8 @@ public class PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static IPlugin plugin() {
|
||||
return NOW_PLUGIN;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,9 +19,9 @@ package org.jackhuang.hellominecraft.launcher.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -56,11 +56,6 @@ public final class MCUtils {
|
||||
return getWorkingDirectory("minecraft");
|
||||
}
|
||||
|
||||
public static boolean is16Folder(String path) {
|
||||
path = IOUtils.addSeparator(path);
|
||||
return new File(path, "versions").exists();
|
||||
}
|
||||
|
||||
public static String minecraft() {
|
||||
if (OS.os() == OS.OSX)
|
||||
return "minecraft";
|
||||
@@ -80,11 +75,11 @@ public final class MCUtils {
|
||||
return gameDir;
|
||||
}
|
||||
|
||||
public static String profile = "{\"selectedProfile\": \"(Default)\",\"profiles\": {\"(Default)\": {\"name\": \"(Default)\"}},\"clientToken\": \"88888888-8888-8888-8888-888888888888\"}";
|
||||
public static final String PROFILE = "{\"selectedProfile\": \"(Default)\",\"profiles\": {\"(Default)\": {\"name\": \"(Default)\"}},\"clientToken\": \"88888888-8888-8888-8888-888888888888\"}";
|
||||
|
||||
public static void tryWriteProfile(File gameDir) throws IOException {
|
||||
File file = new File(gameDir, "launcher_profiles.json");
|
||||
if (!file.exists())
|
||||
FileUtils.writeStringToFile(file, profile);
|
||||
FileUtils.writeStringToFile(file, PROFILE);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -15,7 +15,7 @@
|
||||
* 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.assets;
|
||||
package org.jackhuang.hellominecraft.launcher.core.asset;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -29,8 +29,8 @@ import java.util.Set;
|
||||
public class AssetsIndex {
|
||||
|
||||
public static final String DEFAULT_ASSET_NAME = "legacy";
|
||||
private Map<String, AssetsObject> objects;
|
||||
private boolean virtual;
|
||||
public Map<String, AssetsObject> objects;
|
||||
public boolean virtual;
|
||||
|
||||
public AssetsIndex() {
|
||||
this.objects = new LinkedHashMap();
|
||||
Executable
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.asset;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.util.Utils;
|
||||
import org.jackhuang.hellominecraft.util.VersionNumber;
|
||||
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AssetsMojangLoader extends IAssetsHandler {
|
||||
|
||||
public AssetsMojangLoader(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task getList(final MinecraftVersion mv, final IMinecraftAssetService mp) {
|
||||
Utils.requireNonNull(mv);
|
||||
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
|
||||
public Collection<Task> getDependTasks() {
|
||||
if (!f.exists())
|
||||
return Arrays.asList(mp.downloadMinecraftAssetsIndex(mv.getAssetsIndex()));
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
if (!areDependTasksSucceeded)
|
||||
throw new IllegalStateException("Failed to get asset index");
|
||||
String result = FileUtils.readFileToString(f);
|
||||
if (StrUtils.isBlank(result))
|
||||
throw new IllegalStateException("Index json is empty, please redownload it!");
|
||||
AssetsIndex o = C.GSON.fromJson(result, AssetsIndex.class);
|
||||
assetsDownloadURLs = new ArrayList<>();
|
||||
assetsLocalNames = new ArrayList<>();
|
||||
ArrayList<String> al = new ArrayList<>();
|
||||
contents = new ArrayList<>();
|
||||
HashSet<String> loadedHashes = new HashSet<>();
|
||||
int pgs = 0;
|
||||
if (o != null && o.getFileMap() != null)
|
||||
for (Map.Entry<String, AssetsObject> e : o.getFileMap().entrySet()) {
|
||||
if (loadedHashes.contains(e.getValue().getHash()))
|
||||
continue;
|
||||
loadedHashes.add(e.getValue().getHash());
|
||||
Contents c = new Contents();
|
||||
c.eTag = e.getValue().getHash();
|
||||
c.key = c.eTag.substring(0, 2) + "/" + e.getValue().getHash();
|
||||
c.size = e.getValue().getSize();
|
||||
contents.add(c);
|
||||
assetsDownloadURLs.add(c.key);
|
||||
assetsLocalNames.add(new File(assets, "objects" + File.separator + c.key.replace("/", File.separator)));
|
||||
al.add(e.getKey());
|
||||
if (ppl != null)
|
||||
ppl.setProgress(this, ++pgs, o.getFileMap().size());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task getDownloadTask(IDownloadProvider sourceType) {
|
||||
return new AssetsTask(sourceType.getAssetsDownloadURL());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVersionAllowed(String formattedVersion) {
|
||||
VersionNumber ur = VersionNumber.check(formattedVersion);
|
||||
if (ur == null)
|
||||
return false;
|
||||
return VersionNumber.check("1.6.0").compareTo(ur) <= 0;
|
||||
}
|
||||
}
|
||||
+14
-1
@@ -15,7 +15,7 @@
|
||||
* 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.assets;
|
||||
package org.jackhuang.hellominecraft.launcher.core.asset;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -26,6 +26,19 @@ public class AssetsObject {
|
||||
private String hash;
|
||||
private long size;
|
||||
|
||||
public AssetsObject(String hash, long size) {
|
||||
this.hash = hash;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public void setHash(String hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public AssetsObject() {
|
||||
}
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.asset;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Contents {
|
||||
|
||||
public String key, eTag, lastModified, storageClass;
|
||||
|
||||
public Contents() {
|
||||
}
|
||||
|
||||
public Contents(String key, String eTag, String lastModified, String storageClass, long size) {
|
||||
this();
|
||||
this.key = key;
|
||||
this.eTag = eTag;
|
||||
this.lastModified = lastModified;
|
||||
this.storageClass = storageClass;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String geteTag() {
|
||||
return eTag;
|
||||
}
|
||||
|
||||
public void seteTag(String eTag) {
|
||||
this.eTag = eTag;
|
||||
}
|
||||
|
||||
public String getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
public void setLastModified(String lastModified) {
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
public String getStorageClass() {
|
||||
return storageClass;
|
||||
}
|
||||
|
||||
public void setStorageClass(String storageClass) {
|
||||
this.storageClass = storageClass;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
public long size;
|
||||
|
||||
}
|
||||
+19
-22
@@ -15,7 +15,7 @@
|
||||
* 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.assets;
|
||||
package org.jackhuang.hellominecraft.launcher.core.asset;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -23,17 +23,18 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.code.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import rx.Observable;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.util.code.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||
import org.jackhuang.hellominecraft.util.OverridableSwingWorker;
|
||||
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
|
||||
|
||||
/**
|
||||
* Assets
|
||||
@@ -73,7 +74,7 @@ public abstract class IAssetsHandler {
|
||||
* @param mp Asset Service
|
||||
* @param x finished event
|
||||
*/
|
||||
public abstract Observable<String[]> getList(MinecraftVersion mv, IMinecraftAssetService mp);
|
||||
public abstract Task getList(MinecraftVersion mv, IMinecraftAssetService mp);
|
||||
|
||||
/**
|
||||
* Will be invoked when the user invoked "Download all assets".
|
||||
@@ -86,18 +87,19 @@ public abstract class IAssetsHandler {
|
||||
|
||||
public abstract boolean isVersionAllowed(String formattedVersion);
|
||||
|
||||
protected class AssetsTask extends Task {
|
||||
protected class AssetsTask extends TaskInfo {
|
||||
|
||||
ArrayList<Task> al;
|
||||
String u;
|
||||
|
||||
public AssetsTask(String url) {
|
||||
super(C.i18n("assets.download"));
|
||||
this.u = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() {
|
||||
if (assetsDownloadURLs == null)
|
||||
if (assetsDownloadURLs == null || assetsLocalNames == null || contents == null)
|
||||
throw new IllegalStateException(C.i18n("assets.not_refreshed"));
|
||||
int max = assetsDownloadURLs.size();
|
||||
al = new ArrayList<>();
|
||||
@@ -106,8 +108,8 @@ public abstract class IAssetsHandler {
|
||||
String mark = assetsDownloadURLs.get(i);
|
||||
String url = u + mark;
|
||||
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());
|
||||
if (location.isDirectory())
|
||||
continue;
|
||||
boolean need = true;
|
||||
@@ -116,9 +118,9 @@ public abstract class IAssetsHandler {
|
||||
FileInputStream fis = new FileInputStream(location);
|
||||
String sha = DigestUtils.sha1Hex(NetUtils.getBytesFromStream(fis));
|
||||
IOUtils.closeQuietly(fis);
|
||||
if (contents.get(i).eTag.equals(sha)) {
|
||||
hasDownloaded++;
|
||||
HMCLog.log("File " + assetsLocalNames.get(i) + " has downloaded successfully, skipped downloading.");
|
||||
if (contents.get(i).geteTag().equals(sha)) {
|
||||
++hasDownloaded;
|
||||
HMCLog.log("File " + assetsLocalNames.get(i) + " has been downloaded successfully, skipped downloading.");
|
||||
if (ppl != null)
|
||||
ppl.setProgress(this, hasDownloaded, max);
|
||||
continue;
|
||||
@@ -137,10 +139,5 @@ public abstract class IAssetsHandler {
|
||||
public Collection<Task> getAfterTasks() {
|
||||
return al;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("assets.download");
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+235
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* 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.asset;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.AssetIndexDownloadInfo;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.util.MessageBox;
|
||||
import org.jackhuang.hellominecraft.util.Utils;
|
||||
import org.jackhuang.hellominecraft.util.func.Function;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftAssetService extends IMinecraftAssetService {
|
||||
|
||||
public MinecraftAssetService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task downloadAssets(final String mcVersion) {
|
||||
return downloadAssets(service.version().getVersionById(mcVersion));
|
||||
}
|
||||
|
||||
public Task downloadAssets(final MinecraftVersion mv) {
|
||||
Utils.requireNonNull(mv);
|
||||
return new TaskInfo("Download Assets") {
|
||||
Collection<Task> afters = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public Collection<Task> getDependTasks() {
|
||||
return Arrays.asList(IAssetsHandler.ASSETS_HANDLER.getList(mv, service.asset()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task> getAfterTasks() {
|
||||
return Arrays.asList(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean refreshAssetsIndex(String id) {
|
||||
MinecraftVersion mv = service.version().getVersionById(id);
|
||||
if (mv == null)
|
||||
return false;
|
||||
return downloadMinecraftAssetsIndexAsync(mv.getAssetsIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task downloadMinecraftAssetsIndex(AssetIndexDownloadInfo assets) {
|
||||
File assetsLocation = getAssets();
|
||||
if (!assetsLocation.exists() && !assetsLocation.mkdirs())
|
||||
HMCLog.warn("Failed to make directories: " + assetsLocation);
|
||||
File assetsIndex = new File(assetsLocation, "indexes/" + assets.getId() + ".json");
|
||||
File renamed = null;
|
||||
if (assetsIndex.exists()) {
|
||||
renamed = new File(assetsLocation, "indexes/" + assets.getId() + "-renamed.json");
|
||||
if (assetsIndex.renameTo(renamed))
|
||||
HMCLog.warn("Failed to rename " + assetsIndex + " to " + renamed);
|
||||
}
|
||||
File renamedFinal = renamed;
|
||||
return new TaskInfo("Download Asset Index") {
|
||||
@Override
|
||||
public Collection<Task> getDependTasks() {
|
||||
return Arrays.asList(new FileDownloadTask(assets.getUrl(service.getDownloadType()), IOUtils.tryGetCanonicalFile(assetsIndex), assets.sha1).setTag(assets.getId() + ".json"));
|
||||
}
|
||||
|
||||
@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
|
||||
public boolean downloadMinecraftAssetsIndexAsync(AssetIndexDownloadInfo assets) {
|
||||
File assetsLocation = getAssets();
|
||||
if (!assetsLocation.exists() && !assetsLocation.mkdirs())
|
||||
HMCLog.warn("Failed to make directories: " + assetsLocation);
|
||||
File assetsIndex = new File(assetsLocation, "indexes/" + assets.getId() + ".json");
|
||||
File renamed = null;
|
||||
if (assetsIndex.exists()) {
|
||||
renamed = new File(assetsLocation, "indexes/" + assets.getId() + "-renamed.json");
|
||||
if (assetsIndex.renameTo(renamed))
|
||||
HMCLog.warn("Failed to rename " + assetsIndex + " to " + renamed);
|
||||
}
|
||||
if (TaskWindow.factory()
|
||||
.append(new FileDownloadTask(assets.getUrl(service.getDownloadType()), IOUtils.tryGetCanonicalFile(assetsIndex), assets.sha1).setTag(assets.getId() + ".json"))
|
||||
.create()) {
|
||||
if (renamed != null && !renamed.delete())
|
||||
HMCLog.warn("Failed to delete " + renamed + ", maybe you should do it.");
|
||||
return true;
|
||||
}
|
||||
if (renamed != null && !renamed.renameTo(assetsIndex))
|
||||
HMCLog.warn("Failed to rename " + renamed + " to " + assetsIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getAssets() {
|
||||
return new File(service.baseDirectory(), "assets");
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getAssetObject(String assetVersion, String name) throws IOException {
|
||||
File assetsDir = getAssets();
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectsDir = new File(assetsDir, "objects");
|
||||
File indexFile = new File(indexDir, assetVersion + ".json");
|
||||
try {
|
||||
AssetsIndex index = (AssetsIndex) C.GSON.fromJson(FileUtils.readFileToString(indexFile, "UTF-8"), AssetsIndex.class);
|
||||
|
||||
String hash = ((AssetsObject) index.getFileMap().get(name)).getHash();
|
||||
return new File(objectsDir, hash.substring(0, 2) + "/" + hash);
|
||||
} catch (JsonSyntaxException e) {
|
||||
throw new IOException("Assets file format malformed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkAssetsExistance(AssetIndexDownloadInfo assetIndex) {
|
||||
File assetsDir = getAssets();
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectDir = new File(assetsDir, "objects");
|
||||
File indexFile = new File(indexDir, assetIndex.getId() + ".json");
|
||||
|
||||
if (!assetsDir.exists() || !indexFile.isFile())
|
||||
return false;
|
||||
|
||||
try {
|
||||
String assetIndexContent = FileUtils.readFileToString(indexFile, "UTF-8");
|
||||
AssetsIndex index = (AssetsIndex) C.GSON.fromJson(assetIndexContent, AssetsIndex.class);
|
||||
|
||||
if (index == null)
|
||||
return false;
|
||||
for (Map.Entry entry : index.getFileMap().entrySet())
|
||||
if (!new File(new File(objectDir, ((AssetsObject) entry.getValue()).getHash().substring(0, 2)), ((AssetsObject) entry.getValue()).getHash()).exists())
|
||||
return false;
|
||||
return true;
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private File reconstructAssets(AssetIndexDownloadInfo assetIndex) {
|
||||
File assetsDir = getAssets();
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectDir = new File(assetsDir, "objects");
|
||||
String assetVersion = assetIndex.getId();
|
||||
File indexFile = new File(indexDir, assetVersion + ".json");
|
||||
File virtualRoot = new File(new File(assetsDir, "virtual"), assetVersion);
|
||||
|
||||
if (!indexFile.isFile()) {
|
||||
HMCLog.warn("No assets index file " + virtualRoot + "; can't reconstruct assets");
|
||||
return assetsDir;
|
||||
}
|
||||
|
||||
try {
|
||||
String assetIndexContent = FileUtils.readFileToString(indexFile, "UTF-8");
|
||||
AssetsIndex index = (AssetsIndex) C.GSON.fromJson(assetIndexContent, AssetsIndex.class);
|
||||
|
||||
if (index == null)
|
||||
return assetsDir;
|
||||
if (index.isVirtual()) {
|
||||
int cnt = 0;
|
||||
HMCLog.log("Reconstructing virtual assets folder at " + virtualRoot);
|
||||
int tot = index.getFileMap().entrySet().size();
|
||||
for (Map.Entry entry : index.getFileMap().entrySet()) {
|
||||
File target = new File(virtualRoot, (String) entry.getKey());
|
||||
File original = new File(new File(objectDir, ((AssetsObject) entry.getValue()).getHash().substring(0, 2)), ((AssetsObject) entry.getValue()).getHash());
|
||||
if (original.exists()) {
|
||||
cnt++;
|
||||
if (!target.isFile())
|
||||
FileUtils.copyFile(original, target, false);
|
||||
}
|
||||
}
|
||||
// If the scale new format existent file is lower then 0.1, use the old format.
|
||||
if (cnt * 10 < tot)
|
||||
return assetsDir;
|
||||
}
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
HMCLog.warn("Failed to create virutal assets.", e);
|
||||
}
|
||||
|
||||
return virtualRoot;
|
||||
}
|
||||
|
||||
public final Function<MinecraftVersion, String> ASSET_PROVIDER_IMPL = t -> {
|
||||
if (!checkAssetsExistance(t.getAssetsIndex()))
|
||||
if (MessageBox.Show(C.i18n("assets.no_assets"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
TaskWindow.execute(downloadAssets(t));
|
||||
return reconstructAssets(t.getAssetsIndex()).getAbsolutePath();
|
||||
};
|
||||
}
|
||||
-117
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* 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.assets;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
import rx.Observable;
|
||||
import rx.Observer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AssetsMojangLoader extends IAssetsHandler {
|
||||
|
||||
public AssetsMojangLoader(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<String[]> getList(MinecraftVersion mv, IMinecraftAssetService mp) {
|
||||
return Observable.<String[]>createWithEmptySubscription((Observer<String[]> t1) -> {
|
||||
if (mv == null) {
|
||||
t1.onError(null);
|
||||
return;
|
||||
}
|
||||
String assetsId = mv.assets == null ? "legacy" : mv.assets;
|
||||
File assets = mp.getAssets();
|
||||
HMCLog.log("Get index: " + assetsId);
|
||||
File f = IOUtils.tryGetCanonicalFile(new File(assets, "indexes/" + assetsId + ".json"));
|
||||
if (!f.exists() && !mp.downloadMinecraftAssetsIndex(assetsId)) {
|
||||
t1.onError(null);
|
||||
return;
|
||||
}
|
||||
|
||||
String result;
|
||||
try {
|
||||
result = FileUtils.readFileToString(f);
|
||||
} catch (IOException ex) {
|
||||
HMCLog.warn("Failed to read index json: " + f, ex);
|
||||
t1.onError(null);
|
||||
return;
|
||||
}
|
||||
if (StrUtils.isBlank(result)) {
|
||||
HMCLog.err("Index json is empty, please redownload it!");
|
||||
t1.onError(null);
|
||||
return;
|
||||
}
|
||||
AssetsIndex o;
|
||||
try {
|
||||
o = C.gson.fromJson(result, AssetsIndex.class);
|
||||
} catch (Exception e) {
|
||||
HMCLog.err("Failed to parse index json, please redownload it!", e);
|
||||
t1.onError(null);
|
||||
return;
|
||||
}
|
||||
assetsDownloadURLs = new ArrayList<>();
|
||||
assetsLocalNames = new ArrayList<>();
|
||||
ArrayList<String> al = new ArrayList<>();
|
||||
contents = new ArrayList<>();
|
||||
if (o != null && o.getFileMap() != null)
|
||||
for (Map.Entry<String, AssetsObject> e : o.getFileMap().entrySet()) {
|
||||
Contents c = new Contents();
|
||||
c.eTag = e.getValue().getHash();
|
||||
c.key = c.eTag.substring(0, 2) + "/" + e.getValue().getHash();
|
||||
c.size = e.getValue().getSize();
|
||||
contents.add(c);
|
||||
assetsDownloadURLs.add(c.key);
|
||||
assetsLocalNames.add(new File(assets, "objects" + File.separator + c.key.replace("/", File.separator)));
|
||||
al.add(e.getKey());
|
||||
}
|
||||
|
||||
t1.onNext(al.toArray(new String[1]));
|
||||
t1.onCompleted();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task getDownloadTask(IDownloadProvider sourceType) {
|
||||
return new AssetsTask(sourceType.getAssetsDownloadURL());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVersionAllowed(String formattedVersion) {
|
||||
VersionNumber ur = VersionNumber.check(formattedVersion);
|
||||
if (ur == null)
|
||||
return false;
|
||||
return VersionNumber.check("1.6.0").compareTo(ur) <= 0;
|
||||
}
|
||||
}
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* 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.assets;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import rx.concurrency.Schedulers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftAssetService extends IMinecraftAssetService {
|
||||
|
||||
public MinecraftAssetService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task downloadAssets(String mcVersion) {
|
||||
return new Task() {
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
IAssetsHandler type = IAssetsHandler.ASSETS_HANDLER;
|
||||
type.getList(service.version().getVersionById(mcVersion), service.asset())
|
||||
.subscribeOn(Schedulers.newThread())
|
||||
.observeOn(Schedulers.eventQueue())
|
||||
.subscribe((t) -> TaskWindow.getInstance().addTask(type.getDownloadTask(service.getDownloadType().getProvider())).start());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "Download Assets";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean refreshAssetsIndex(String id) {
|
||||
MinecraftVersion mv = service.version().getVersionById(id);
|
||||
if (mv == null)
|
||||
return false;
|
||||
return downloadMinecraftAssetsIndex(mv.assets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean downloadMinecraftAssetsIndex(String assetsId) {
|
||||
String aurl = service.getDownloadType().getProvider().getIndexesDownloadURL();
|
||||
|
||||
File assetsLocation = getAssets();
|
||||
assetsLocation.mkdirs();
|
||||
File assetsIndex = new File(assetsLocation, "indexes/" + assetsId + ".json");
|
||||
File renamed = null;
|
||||
if (assetsIndex.exists()) {
|
||||
renamed = new File(assetsLocation, "indexes/" + assetsId + "-renamed.json");
|
||||
assetsIndex.renameTo(renamed);
|
||||
}
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(aurl + assetsId + ".json", IOUtils.tryGetCanonicalFile(assetsIndex)).setTag(assetsId + ".json"))
|
||||
.start()) {
|
||||
if (renamed != null)
|
||||
renamed.delete();
|
||||
return true;
|
||||
}
|
||||
if (renamed != null)
|
||||
renamed.renameTo(assetsIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getAssets() {
|
||||
return new File(service.baseDirectory(), "assets");
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getAssetObject(String assetVersion, String name) throws IOException {
|
||||
File assetsDir = getAssets();
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectsDir = new File(assetsDir, "objects");
|
||||
File indexFile = new File(indexDir, assetVersion + ".json");
|
||||
try {
|
||||
AssetsIndex index = (AssetsIndex) C.gson.fromJson(FileUtils.readFileToString(indexFile, "UTF-8"), AssetsIndex.class);
|
||||
|
||||
String hash = ((AssetsObject) index.getFileMap().get(name)).getHash();
|
||||
return new File(objectsDir, hash.substring(0, 2) + "/" + hash);
|
||||
} catch (JsonSyntaxException e) {
|
||||
throw new IOException("Assets file format malformed.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,8 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import org.jackhuang.hellominecraft.utils.code.DigestUtils;
|
||||
import java.nio.charset.Charset;
|
||||
import org.jackhuang.hellominecraft.util.code.DigestUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -41,7 +42,7 @@ public final class BestLogin extends IAuthenticator {
|
||||
Socket socket = new Socket("auth.zhh0000zhh.com", 8);
|
||||
OutputStream os = socket.getOutputStream();
|
||||
os.write(request.length());
|
||||
os.write(request.getBytes());
|
||||
os.write(request.getBytes(Charset.forName("UTF-8")));
|
||||
|
||||
UserProfileProvider lr = new UserProfileProvider();
|
||||
|
||||
@@ -64,13 +65,17 @@ public final class BestLogin extends IAuthenticator {
|
||||
throw new AuthenticationException("server reloading.");
|
||||
case 0:
|
||||
byte[] b = new byte[64];
|
||||
is.read(b, 0, b.length);
|
||||
String[] ss = new String(b).split(":");
|
||||
int x = is.read(b, 0, b.length);
|
||||
if (x != -1)
|
||||
throw new AuthenticationException("server response does not follow the protocol.");
|
||||
String[] ss = new String(b, Charset.forName("UTF-8")).split(":");
|
||||
lr.setUserName(info.username);
|
||||
lr.setUserId(ss[1]);
|
||||
lr.setSession(ss[0]);
|
||||
lr.setAccessToken(ss[0]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
lr.setUserType("Legacy");
|
||||
return lr;
|
||||
@@ -95,7 +100,7 @@ public final class BestLogin extends IAuthenticator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
public void logOut() {
|
||||
}
|
||||
|
||||
}
|
||||
+18
-6
@@ -33,15 +33,19 @@ public abstract class IAuthenticator {
|
||||
public static final List<IAuthenticator> LOGINS = new ArrayList<>();
|
||||
|
||||
static {
|
||||
PluginManager.NOW_PLUGIN.onRegisterAuthenticators(LOGINS::add);
|
||||
PluginManager.plugin().onRegisterAuthenticators(LOGINS::add);
|
||||
}
|
||||
|
||||
protected String clientToken, username;
|
||||
protected String clientToken, username, password;
|
||||
|
||||
public IAuthenticator(String clientToken) {
|
||||
this.clientToken = clientToken;
|
||||
}
|
||||
|
||||
public String getClientToken() {
|
||||
return clientToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login Method
|
||||
*
|
||||
@@ -81,10 +85,10 @@ public abstract class IAuthenticator {
|
||||
|
||||
public abstract UserProfileProvider loginBySettings() throws AuthenticationException;
|
||||
|
||||
public abstract void logout();
|
||||
public abstract void logOut();
|
||||
|
||||
public Map onSaveSettings() {
|
||||
HashMap m = new HashMap();
|
||||
HashMap<String, String> m = new HashMap<>();
|
||||
m.put("IAuthenticator_UserName", username);
|
||||
return m;
|
||||
}
|
||||
@@ -95,11 +99,19 @@ public abstract class IAuthenticator {
|
||||
username = (String) m.get("IAuthenticator_UserName");
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
public String getUserName() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String s) {
|
||||
public void setUserName(String s) {
|
||||
username = s;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -19,9 +19,9 @@ package org.jackhuang.hellominecraft.launcher.core.auth;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.code.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.code.DigestUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -48,7 +48,7 @@ public final class OfflineAuthenticator extends IAuthenticator {
|
||||
@Override
|
||||
public Map onSaveSettings() {
|
||||
Map m = super.onSaveSettings();
|
||||
m.put("uuidMap", m);
|
||||
m.put("uuidMap", uuidMap);
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public final class OfflineAuthenticator extends IAuthenticator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
public void logOut() {
|
||||
}
|
||||
|
||||
}
|
||||
+11
-14
@@ -17,10 +17,11 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.code.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.views.Selector;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.code.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||
import org.jackhuang.hellominecraft.util.lang.SupportedLocales;
|
||||
import org.jackhuang.hellominecraft.util.ui.SwingUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -47,7 +48,7 @@ public final class SkinmeAuthenticator extends IAuthenticator {
|
||||
if (info.username == null || !info.username.contains("@"))
|
||||
throw new AuthenticationException(C.i18n("login.not_email"));
|
||||
try {
|
||||
String usr = info.username.toLowerCase();
|
||||
String usr = info.username.toLowerCase(SupportedLocales.NOW_LOCALE.self);
|
||||
String pwd = info.password;
|
||||
|
||||
String str = DigestUtils.sha1Hex(usr);
|
||||
@@ -60,15 +61,14 @@ public final class SkinmeAuthenticator extends IAuthenticator {
|
||||
if (sl[1].contains("No Valid Character"))
|
||||
sl[1] = C.i18n("login.no_valid_character");
|
||||
throw new AuthenticationException(sl[1]);
|
||||
case "1": {
|
||||
case "1":
|
||||
String[] s = parseType1(sl[1]);
|
||||
req.setUserName(s[0]);
|
||||
req.setSession(s[1]);
|
||||
req.setUserId(s[1]);
|
||||
req.setAccessToken(s[1]);
|
||||
break;
|
||||
}
|
||||
case "2": {
|
||||
case "2":
|
||||
String[] charators = sl[1].split(";");
|
||||
int len = charators.length;
|
||||
String[] $char = new String[len];
|
||||
@@ -79,12 +79,10 @@ public final class SkinmeAuthenticator extends IAuthenticator {
|
||||
$char[i] = charator[0];
|
||||
user[i] = charator[1];
|
||||
}
|
||||
Selector s = new Selector(null, user, C.i18n("login.choose_charactor"));
|
||||
s.setVisible(true);
|
||||
if (s.sel == Selector.FAILED_TO_SELECT)
|
||||
int index = SwingUtils.select(user, C.i18n("login.choose_charactor"));
|
||||
if (index == -1)
|
||||
throw new AuthenticationException(C.i18n("message.cancelled"));
|
||||
else {
|
||||
int index = s.sel;
|
||||
String character = $char[index];
|
||||
sl = getCharacter(usr, hashCode, character).split(":");
|
||||
String[] s2 = parseType1(sl[1]);
|
||||
@@ -95,7 +93,6 @@ public final class SkinmeAuthenticator extends IAuthenticator {
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
req.setUserType("Legacy");
|
||||
return req;
|
||||
@@ -120,7 +117,7 @@ public final class SkinmeAuthenticator extends IAuthenticator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
public void logOut() {
|
||||
|
||||
}
|
||||
}
|
||||
-11
@@ -17,8 +17,6 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.ServerInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
@@ -108,13 +106,4 @@ public final class UserProfileProvider {
|
||||
private String otherInfo = "";
|
||||
private String clientIdentifier = "";
|
||||
private String userType = "Offline";
|
||||
private ServerInfo server = null;
|
||||
|
||||
public ServerInfo getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public void setServer(ServerInfo server) {
|
||||
this.server = server;
|
||||
}
|
||||
}
|
||||
+12
-9
@@ -21,13 +21,13 @@ import com.google.gson.GsonBuilder;
|
||||
import java.net.Proxy;
|
||||
import java.util.Map;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.utils.views.Selector;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.GameProfile;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.PropertyMap;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.YggdrasilAuthentication;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.UUIDTypeAdapter;
|
||||
import org.jackhuang.hellominecraft.util.ui.SwingUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -57,7 +57,7 @@ public final class YggdrasilAuthenticator extends IAuthenticator {
|
||||
|
||||
if (!ua.isLoggedIn())
|
||||
ua.setPassword(pwd);
|
||||
ua.setUsername(usr);
|
||||
ua.setUserName(usr);
|
||||
ua.logIn();
|
||||
if (!ua.isLoggedIn())
|
||||
throw new AuthenticationException(C.i18n("login.wrong_password"));
|
||||
@@ -69,14 +69,17 @@ public final class YggdrasilAuthenticator extends IAuthenticator {
|
||||
String[] names = new String[profiles.length];
|
||||
for (int i = 0; i < profiles.length; i++)
|
||||
names[i] = profiles[i].name;
|
||||
Selector s = new Selector(null, names, C.i18n("login.choose_charactor"));
|
||||
s.setVisible(true);
|
||||
selectedProfile = profiles[s.sel];
|
||||
username = names[s.sel];
|
||||
int sel = SwingUtils.select(names, C.i18n("login.choose_charactor"));
|
||||
if (sel == -1)
|
||||
throw new AuthenticationException("No selection");
|
||||
selectedProfile = profiles[sel];
|
||||
username = names[sel];
|
||||
} else
|
||||
username = JOptionPane.showInputDialog(C.i18n("login.no_charactor"));
|
||||
else
|
||||
username = selectedProfile.name;
|
||||
if (username == null)
|
||||
throw new AuthenticationException("No player");
|
||||
result.setUserName(username);
|
||||
result.setUserId(selectedProfile == null ? OfflineAuthenticator.getUUIDFromUserName(username) : UUIDTypeAdapter.fromUUID(selectedProfile.id));
|
||||
}
|
||||
@@ -134,7 +137,7 @@ public final class YggdrasilAuthenticator extends IAuthenticator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
public void logOut() {
|
||||
ua.logOut();
|
||||
}
|
||||
}
|
||||
+43
-3
@@ -21,9 +21,49 @@ import java.util.HashMap;
|
||||
|
||||
public class AuthenticationRequest {
|
||||
|
||||
public HashMap<String, Object> agent;
|
||||
public String username, password, clientToken;
|
||||
public boolean requestUser = true;
|
||||
private HashMap<String, Object> agent;
|
||||
private String username, password, clientToken;
|
||||
private boolean requestUser = true;
|
||||
|
||||
public HashMap<String, Object> getAgent() {
|
||||
return agent;
|
||||
}
|
||||
|
||||
public void setAgent(HashMap<String, Object> agent) {
|
||||
this.agent = agent;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUserName(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getClientToken() {
|
||||
return clientToken;
|
||||
}
|
||||
|
||||
public void setClientToken(String clientToken) {
|
||||
this.clientToken = clientToken;
|
||||
}
|
||||
|
||||
public boolean isRequestUser() {
|
||||
return requestUser;
|
||||
}
|
||||
|
||||
public void setRequestUser(boolean requestUser) {
|
||||
this.requestUser = requestUser;
|
||||
}
|
||||
|
||||
public AuthenticationRequest(String username, String password, String clientToken) {
|
||||
agent = new HashMap<>();
|
||||
|
||||
+12
-2
@@ -25,8 +25,9 @@ import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
|
||||
public class GameProfile {
|
||||
|
||||
@@ -46,9 +47,16 @@ public class GameProfile {
|
||||
return id != null && StrUtils.isNotBlank(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 29 * hash + Objects.hashCode(this.id);
|
||||
hash = 29 * hash + Objects.hashCode(this.name);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
System.out.println("hello?");
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
@@ -65,6 +73,8 @@ public class GameProfile {
|
||||
|
||||
@Override
|
||||
public GameProfile deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
if (!(json instanceof JsonObject))
|
||||
throw new JsonParseException("The json element is not a JsonObject.");
|
||||
JsonObject object = (JsonObject) json;
|
||||
UUID id = object.has("id") ? (UUID) context.deserialize(object.get("id"), UUID.class) : null;
|
||||
String name = object.has("name") ? object.getAsJsonPrimitive("name").getAsString() : null;
|
||||
|
||||
+8
-4
@@ -31,10 +31,12 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
|
||||
public class PropertyMap extends HashMap<String, Property> {
|
||||
|
||||
private static final long serialVersionUID = 362498820763181265L;
|
||||
|
||||
public List<Map<String, String>> list() {
|
||||
List<Map<String, String>> properties = new ArrayList<>();
|
||||
for (Property profileProperty : values()) {
|
||||
@@ -51,6 +53,7 @@ public class PropertyMap extends HashMap<String, Property> {
|
||||
for (Map<String, String> propertyMap : list) {
|
||||
String name = propertyMap.get("name");
|
||||
String value = propertyMap.get("value");
|
||||
put(name, new Property(name, value));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
HMCLog.warn("Failed to deserialize properties", t);
|
||||
@@ -76,6 +79,7 @@ public class PropertyMap extends HashMap<String, Property> {
|
||||
JsonObject object = (JsonObject) element;
|
||||
String name = object.getAsJsonPrimitive("name").getAsString();
|
||||
String value = object.getAsJsonPrimitive("value").getAsString();
|
||||
result.put(name, new Property(name, value));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -101,10 +105,10 @@ public class PropertyMap extends HashMap<String, Property> {
|
||||
@Override
|
||||
public JsonElement serialize(PropertyMap src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject result = new JsonObject();
|
||||
for (String key : src.keySet()) {
|
||||
for (PropertyMap.Entry<String, Property> entry : src.entrySet()) {
|
||||
JsonArray values = new JsonArray();
|
||||
values.add(new JsonPrimitive(src.get(key).value));
|
||||
result.add(key, values);
|
||||
values.add(new JsonPrimitive(entry.getValue().value));
|
||||
result.add(entry.getKey(), values);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+37
-4
@@ -19,13 +19,46 @@ package org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil;
|
||||
|
||||
public class RefreshRequest {
|
||||
|
||||
public String clientToken;
|
||||
public String accessToken;
|
||||
public GameProfile selectedProfile;
|
||||
public boolean requestUser = true;
|
||||
private String clientToken;
|
||||
private String accessToken;
|
||||
private GameProfile selectedProfile;
|
||||
private boolean requestUser = true;
|
||||
|
||||
public RefreshRequest(String accessToken, String clientToken) {
|
||||
this.clientToken = clientToken;
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public String getClientToken() {
|
||||
return clientToken;
|
||||
}
|
||||
|
||||
public void setClientToken(String clientToken) {
|
||||
this.clientToken = clientToken;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public GameProfile getSelectedProfile() {
|
||||
return selectedProfile;
|
||||
}
|
||||
|
||||
public void setSelectedProfile(GameProfile selectedProfile) {
|
||||
this.selectedProfile = selectedProfile;
|
||||
}
|
||||
|
||||
public boolean isRequestUser() {
|
||||
return requestUser;
|
||||
}
|
||||
|
||||
public void setRequestUser(boolean requestUser) {
|
||||
this.requestUser = requestUser;
|
||||
}
|
||||
|
||||
}
|
||||
+27
-2
@@ -19,6 +19,31 @@ package org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil;
|
||||
|
||||
public class User {
|
||||
|
||||
public String id;
|
||||
public PropertyMap properties;
|
||||
private String id;
|
||||
private PropertyMap properties;
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(String id, PropertyMap properties) {
|
||||
this.id = id;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public PropertyMap getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(PropertyMap properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
}
|
||||
+16
-10
@@ -28,10 +28,10 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
|
||||
public class YggdrasilAuthentication {
|
||||
|
||||
@@ -67,7 +67,7 @@ public class YggdrasilAuthentication {
|
||||
}
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Get/Set">
|
||||
public void setUsername(String username) {
|
||||
public void setUserName(String username) {
|
||||
if ((isLoggedIn()) && (canPlayOnline()))
|
||||
throw new IllegalStateException("Cannot change username while logged in & online");
|
||||
|
||||
@@ -96,7 +96,10 @@ public class YggdrasilAuthentication {
|
||||
}
|
||||
|
||||
public GameProfile[] getAvailableProfiles() {
|
||||
return profiles;
|
||||
if (profiles == null)
|
||||
return null;
|
||||
else
|
||||
return profiles.clone();
|
||||
}
|
||||
|
||||
public String getAuthenticatedToken() {
|
||||
@@ -140,6 +143,9 @@ public class YggdrasilAuthentication {
|
||||
String jsonResult = input == null ? NetUtils.get(url) : NetUtils.post(url, GSON.toJson(input), "application/json", proxy);
|
||||
Response response = (Response) GSON.fromJson(jsonResult, Response.class);
|
||||
|
||||
if (response == null)
|
||||
throw new AuthenticationException("No valid response here");
|
||||
|
||||
if (StrUtils.isNotBlank(response.error)) {
|
||||
HMCLog.err("Failed to log in, the auth server returned an error: " + response.error + ", message: " + response.errorMessage + ", cause: " + response.cause);
|
||||
if (response.errorMessage.contains("Invalid token"))
|
||||
@@ -151,7 +157,7 @@ public class YggdrasilAuthentication {
|
||||
throw new AuthenticationException(C.i18n("login.changed_client_token"));
|
||||
|
||||
User user = response.user;
|
||||
userid = user != null && user.id != null ? user.id : username;
|
||||
userid = user != null && user.getId() != null ? user.getId() : username;
|
||||
|
||||
isOnline = true;
|
||||
profiles = response.availableProfiles;
|
||||
@@ -159,8 +165,8 @@ public class YggdrasilAuthentication {
|
||||
userProperties.clear();
|
||||
this.accessToken = response.accessToken;
|
||||
|
||||
if (user != null && user.properties != null)
|
||||
userProperties.putAll(user.properties);
|
||||
if (user != null && user.getProperties() != null)
|
||||
userProperties.putAll(user.getProperties());
|
||||
} catch (IOException | IllegalStateException | JsonParseException e) {
|
||||
throw new AuthenticationException(C.i18n("login.failed.connect_authentication_server"), e);
|
||||
}
|
||||
@@ -182,7 +188,7 @@ public class YggdrasilAuthentication {
|
||||
public void loadFromStorage(Map<String, Object> credentials) {
|
||||
logOut();
|
||||
|
||||
setUsername((String) credentials.get(STORAGE_KEY_USER_NAME));
|
||||
setUserName((String) credentials.get(STORAGE_KEY_USER_NAME));
|
||||
|
||||
if (credentials.containsKey(STORAGE_KEY_USER_ID))
|
||||
userid = (String) credentials.get(STORAGE_KEY_USER_ID);
|
||||
|
||||
+12
-8
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -27,17 +27,17 @@ public class BMCLAPIDownloadProvider extends IDownloadProvider {
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getForgeInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.forge.MinecraftForgeVersionList.getInstance();
|
||||
return org.jackhuang.hellominecraft.launcher.core.install.forge.MinecraftForgeVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getLiteLoaderInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.liteloader.LiteLoaderVersionList.getInstance();
|
||||
return org.jackhuang.hellominecraft.launcher.core.install.liteloader.LiteLoaderVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getOptiFineInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.optifine.bmcl.OptiFineBMCLVersionList.getInstance();
|
||||
return org.jackhuang.hellominecraft.launcher.core.install.optifine.bmcl.OptiFineBMCLVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,7 +57,7 @@ public class BMCLAPIDownloadProvider extends IDownloadProvider {
|
||||
|
||||
@Override
|
||||
public String getVersionsListDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/versions/versions.json";
|
||||
return "http://bmclapi2.bangbang93.com/mc/game/version_manifest.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,13 +66,17 @@ public class BMCLAPIDownloadProvider extends IDownloadProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParsedLibraryDownloadURL(String str) {
|
||||
return str == null ? null : str.replace("http://files.minecraftforge.net/maven", "http://bmclapi2.bangbang93.com/maven");
|
||||
public String getParsedDownloadURL(String str) {
|
||||
return str == null ? null
|
||||
: str.replace("https://launchermeta.mojang.com", "http://bmclapi2.bangbang93.com")
|
||||
.replace("https://launcher.mojang.com", "http://bmclapi2.bangbang93.com")
|
||||
.replace("https://libraries.minecraft.net", "http://bmclapi2.bangbang93.com/libraries")
|
||||
.replace("http://files.minecraftforge.net/maven", "http://bmclapi2.bangbang93.com/maven");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToUseSelfURL() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -24,7 +24,7 @@ package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
public class CurseDownloadProvider extends MojangDownloadProvider {
|
||||
|
||||
@Override
|
||||
public String getParsedLibraryDownloadURL(String str) {
|
||||
public String getParsedDownloadURL(String str) {
|
||||
return str == null ? null : str.replace("http://files.minecraftforge.net/maven", "http://ftb.cursecdn.com/FTB2/maven/");
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -18,7 +18,8 @@
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -26,12 +27,13 @@ import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
*/
|
||||
public class DownloadLibraryJob {
|
||||
|
||||
public String url, name;
|
||||
public IMinecraftLibrary lib;
|
||||
public String url;
|
||||
public File path;
|
||||
|
||||
public DownloadLibraryJob(String n, String u, File p) {
|
||||
public DownloadLibraryJob(IMinecraftLibrary n, String u, File p) {
|
||||
url = u;
|
||||
name = n;
|
||||
lib = n;
|
||||
path = IOUtils.tryGetCanonicalFile(p);
|
||||
}
|
||||
}
|
||||
+7
-5
@@ -17,7 +17,8 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -25,9 +26,9 @@ import org.jackhuang.hellominecraft.utils.C;
|
||||
*/
|
||||
public enum DownloadType {
|
||||
|
||||
Mojang(C.i18n("download.mojang"), new MojangDownloadProvider()),
|
||||
BMCL(C.i18n("download.BMCL"), new BMCLAPIDownloadProvider()),
|
||||
RapidData(C.i18n("download.rapid_data"), new RapidDataDownloadProvider()),
|
||||
Mojang("download.mojang", new MojangDownloadProvider()),
|
||||
BMCL("download.BMCL", new BMCLAPIDownloadProvider()),
|
||||
//RapidData("download.rapid_data", new RapidDataDownloadProvider()),
|
||||
Curse("Curse CDN", new CurseDownloadProvider());
|
||||
|
||||
private final String name;
|
||||
@@ -43,7 +44,7 @@ public enum DownloadType {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
return C.i18n(name);
|
||||
}
|
||||
|
||||
private static DownloadType suggestedDownloadType = Mojang;
|
||||
@@ -55,6 +56,7 @@ public enum DownloadType {
|
||||
public static void setSuggestedDownloadType(DownloadType suggestedDownloadType) {
|
||||
if (suggestedDownloadType == null)
|
||||
throw new IllegalArgumentException("download type should not be null.");
|
||||
TaskWindow.downloadSource = suggestedDownloadType.getName();
|
||||
DownloadType.suggestedDownloadType = suggestedDownloadType;
|
||||
}
|
||||
|
||||
|
||||
+12
-4
@@ -17,8 +17,8 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerType;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerType;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -32,7 +32,7 @@ public abstract class IDownloadProvider {
|
||||
return getForgeInstaller();
|
||||
case LiteLoader:
|
||||
return getLiteLoaderInstaller();
|
||||
case Optifine:
|
||||
case OptiFine:
|
||||
return getOptiFineInstaller();
|
||||
default:
|
||||
return null;
|
||||
@@ -55,7 +55,15 @@ public abstract class IDownloadProvider {
|
||||
|
||||
public abstract String getAssetsDownloadURL();
|
||||
|
||||
public abstract String getParsedLibraryDownloadURL(String str);
|
||||
/**
|
||||
* For example, minecraft.json/assetIndex/url or
|
||||
* minecraft.json/downloads/client/url
|
||||
*
|
||||
* @param str baseURL
|
||||
*
|
||||
* @return parsedURL
|
||||
*/
|
||||
public abstract String getParsedDownloadURL(String str);
|
||||
|
||||
public abstract boolean isAllowedToUseSelfURL();
|
||||
}
|
||||
+101
-104
@@ -21,21 +21,22 @@ import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftDownloadServ
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.GameDownloadInfo;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftRemoteVersion;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftRemoteVersions;
|
||||
import rx.Observable;
|
||||
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.util.func.Function;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -53,114 +54,110 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
|
||||
if (mv == null)
|
||||
return downloadLibraries;
|
||||
MinecraftVersion v = mv.resolve(service.version());
|
||||
if (v.libraries != null)
|
||||
for (IMinecraftLibrary l : v.libraries) {
|
||||
l.init();
|
||||
if (l.allow()) {
|
||||
File ff = l.getFilePath(service.baseDirectory());
|
||||
if (!ff.exists()) {
|
||||
String libURL = service.getDownloadType().getProvider().getLibraryDownloadURL() + "/";
|
||||
libURL = service.getDownloadType().getProvider().getParsedLibraryDownloadURL(l.getDownloadURL(libURL, service.getDownloadType()));
|
||||
if (libURL != null)
|
||||
downloadLibraries.add(new DownloadLibraryJob(l.name, libURL, ff));
|
||||
}
|
||||
for (IMinecraftLibrary l : v.getLibraries())
|
||||
if (l != null && l.allow()) {
|
||||
File ff = l.getFilePath(service.baseDirectory());
|
||||
if (!ff.exists()) {
|
||||
String libURL = l.getDownloadInfo().getUrl(service.getDownloadType());
|
||||
if (libURL != null)
|
||||
downloadLibraries.add(new DownloadLibraryJob(l, libURL, ff));
|
||||
}
|
||||
}
|
||||
return downloadLibraries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion downloadMinecraft(String id) {
|
||||
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
|
||||
File vpath = new File(service.baseDirectory(), "versions/" + id);
|
||||
File mvt = new File(vpath, id + ".json");
|
||||
File mvj = new File(vpath, id + ".jar");
|
||||
vpath.mkdirs();
|
||||
mvt.delete();
|
||||
mvj.delete();
|
||||
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(vurl + id + ".json", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".json"))
|
||||
.addTask(new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvj)).setTag(id + ".jar"))
|
||||
.start())
|
||||
try {
|
||||
return C.gson.fromJson(FileUtils.readFileToStringQuietly(mvt), MinecraftVersion.class);
|
||||
} catch (JsonSyntaxException ex) {
|
||||
HMCLog.err("Failed to parse minecraft version json.", ex);
|
||||
public Task downloadMinecraft(String id) {
|
||||
return new TaskInfo("Download Minecraft") {
|
||||
@Override
|
||||
public Collection<Task> getDependTasks() {
|
||||
return Arrays.asList(downloadMinecraftVersionJson(id));
|
||||
}
|
||||
else
|
||||
FileUtils.deleteDirectoryQuietly(vpath);
|
||||
return null;
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
File vpath = new File(service.baseDirectory(), "versions/" + id);
|
||||
if (!areDependTasksSucceeded) {
|
||||
FileUtils.deleteDirectory(vpath);
|
||||
throw new RuntimeException("Cannot continue because of download failing.");
|
||||
}
|
||||
File mvj = new File(vpath, id + ".jar");
|
||||
if (mvj.exists() && !mvj.delete())
|
||||
HMCLog.warn("Failed to delete " + mvj);
|
||||
try {
|
||||
MinecraftVersion mv = C.GSON.fromJson(FileUtils.readFileToStringQuietly(new File(vpath, id + ".json")), MinecraftVersion.class);
|
||||
if (mv == null)
|
||||
throw new JsonSyntaxException("incorrect version");
|
||||
|
||||
afters.add(downloadMinecraftJar(mv, mvj));
|
||||
} catch (JsonSyntaxException ex) {
|
||||
HMCLog.err("Failed to parse minecraft version json.", ex);
|
||||
FileUtils.deleteDirectory(vpath);
|
||||
}
|
||||
}
|
||||
|
||||
Collection<Task> afters = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public Collection<Task> getAfterTasks() {
|
||||
return afters;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class DownloadTypeSwitcher implements Function<Integer, String> {
|
||||
|
||||
String suffix;
|
||||
|
||||
public DownloadTypeSwitcher(String suffix) {
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Integer t) {
|
||||
return DownloadType.values()[t / 2].getProvider().getVersionsDownloadURL() + suffix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean downloadMinecraftJar(String id) {
|
||||
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
|
||||
File vpath = new File(service.baseDirectory(), "versions/" + id);
|
||||
File mvv = new File(vpath, id + ".jar"), moved = null;
|
||||
if (mvv.exists()) {
|
||||
moved = new File(vpath, id + "-renamed.jar");
|
||||
mvv.renameTo(moved);
|
||||
}
|
||||
File mvt = new File(vpath, id + ".jar");
|
||||
vpath.mkdirs();
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".jar"))
|
||||
.start()) {
|
||||
if (moved != null)
|
||||
moved.delete();
|
||||
return true;
|
||||
} else {
|
||||
mvt.delete();
|
||||
if (moved != null)
|
||||
moved.renameTo(mvt);
|
||||
return false;
|
||||
}
|
||||
public Task downloadMinecraftJar(MinecraftVersion mv, File mvj) {
|
||||
GameDownloadInfo i = mv.getClientDownloadInfo();
|
||||
return new FileDownloadTask(i.getUrl(service.getDownloadType()), mvj, i.sha1)
|
||||
.setFailedCallbackReturnsNewURL(new DownloadTypeSwitcher(mv.id + "/" + mv.id + ".jar")).setTag(mv.id + ".jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean downloadMinecraftJarTo(String id, File mvt) {
|
||||
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".jar"))
|
||||
.start())
|
||||
return true;
|
||||
else {
|
||||
mvt.delete();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public Task downloadMinecraftVersionJson(String id) {
|
||||
return new TaskInfo("Download Minecraft Json") {
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
List<MinecraftRemoteVersion> versions = MinecraftRemoteVersions.getRemoteVersions(service.getDownloadType()).justDo();
|
||||
MinecraftRemoteVersion currentVersion = null;
|
||||
for (MinecraftRemoteVersion v : versions)
|
||||
if (id.equals(v.id)) {
|
||||
currentVersion = v;
|
||||
break;
|
||||
}
|
||||
if (currentVersion == null)
|
||||
throw new RuntimeException("Cannot find version: " + id + " in remote repository.");
|
||||
String jsonURL = currentVersion.getUrl(service.getDownloadType());
|
||||
File vpath = new File(service.baseDirectory(), "versions/" + id);
|
||||
File mvt = new File(vpath, id + ".json");
|
||||
if (!vpath.exists() && !vpath.mkdirs())
|
||||
HMCLog.warn("Failed to make directories: " + vpath);
|
||||
if (mvt.exists() && !mvt.delete())
|
||||
HMCLog.warn("Failed to delete " + mvt);
|
||||
|
||||
@Override
|
||||
public boolean downloadMinecraftVersionJson(String id) {
|
||||
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
|
||||
File vpath = new File(service.baseDirectory(), "versions/" + id);
|
||||
File mvv = new File(vpath, id + ".json"), moved = null;
|
||||
if (mvv.exists()) {
|
||||
moved = new File(vpath, id + "-renamed.json");
|
||||
mvv.renameTo(moved);
|
||||
}
|
||||
File mvt = new File(vpath, id + ".json");
|
||||
vpath.mkdirs();
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(vurl + id + ".json", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".json"))
|
||||
.start()) {
|
||||
if (moved != null)
|
||||
moved.delete();
|
||||
return true;
|
||||
} else {
|
||||
mvt.delete();
|
||||
if (moved != null)
|
||||
moved.renameTo(mvt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
afters.add(new FileDownloadTask(jsonURL, mvt).setTag(id + ".json"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<MinecraftRemoteVersion> getRemoteVersions() {
|
||||
return NetUtils.getRx(service.getDownloadType().getProvider().getVersionsListDownloadURL())
|
||||
.map(r -> C.gson.fromJson(r, MinecraftRemoteVersions.class))
|
||||
.filter(r -> r != null && r.versions != null)
|
||||
.flatMap(r -> Observable.from(r.versions));
|
||||
Collection<Task> afters = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public Collection<Task> getAfterTasks() {
|
||||
return afters;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Hello Minecraft!.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -15,7 +15,7 @@
|
||||
* 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.utils.version;
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
/**
|
||||
*
|
||||
Executable → Regular
+10
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Hello Minecraft!.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -15,15 +15,20 @@
|
||||
* 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.assets;
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Contents {
|
||||
public class MinecraftRemoteVersion {
|
||||
|
||||
public String key, eTag, lastModified, storageClass;
|
||||
public long size;
|
||||
public String id, time, releaseTime, type;
|
||||
private String url;
|
||||
|
||||
public String getUrl(DownloadType type) {
|
||||
if (url == null)
|
||||
return type.getProvider().getVersionsDownloadURL() + id + "/" + id + ".json";
|
||||
return url;
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Hello Minecraft!.
|
||||
* 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 java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||
import org.jackhuang.hellominecraft.util.OverridableSwingWorker;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftRemoteVersions {
|
||||
|
||||
public ArrayList<MinecraftRemoteVersion> versions;
|
||||
public MinecraftRemoteLatestVersion latest;
|
||||
|
||||
private static volatile MinecraftRemoteVersions INSTANCE = null;
|
||||
private static final Object INSTANCE_LOCK = new Object();
|
||||
|
||||
public static RemoteVersionsTask getRemoteVersions(DownloadType type) {
|
||||
return new RemoteVersionsTask(type) {
|
||||
@Override
|
||||
public void work() throws Exception {
|
||||
synchronized (INSTANCE_LOCK) {
|
||||
if (INSTANCE != null)
|
||||
send(INSTANCE.versions.toArray(new MinecraftRemoteVersion[INSTANCE.versions.size()]));
|
||||
else
|
||||
super.work();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static RemoteVersionsTask refreshRomoteVersions(DownloadType type) {
|
||||
return new RemoteVersionsTask(type);
|
||||
}
|
||||
|
||||
public static class RemoteVersionsTask extends OverridableSwingWorker<MinecraftRemoteVersion> {
|
||||
|
||||
DownloadType type;
|
||||
|
||||
public RemoteVersionsTask(DownloadType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void work() throws Exception {
|
||||
MinecraftRemoteVersions r = C.GSON.fromJson(NetUtils.get(type.getProvider().getVersionsListDownloadURL()), MinecraftRemoteVersions.class);
|
||||
if (r != null && r.versions != null) {
|
||||
INSTANCE = r;
|
||||
send(r.versions.toArray(new MinecraftRemoteVersion[r.versions.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+19
-8
@@ -17,7 +17,9 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import java.util.Locale;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.util.lang.SupportedLocales;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -27,17 +29,17 @@ public class MojangDownloadProvider extends IDownloadProvider {
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getForgeInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.forge.MinecraftForgeVersionList.getInstance();
|
||||
return org.jackhuang.hellominecraft.launcher.core.install.forge.MinecraftForgeVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getLiteLoaderInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.liteloader.LiteLoaderVersionList.getInstance();
|
||||
return org.jackhuang.hellominecraft.launcher.core.install.liteloader.LiteLoaderVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getOptiFineInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.optifine.vanilla.OptiFineVersionList.getInstance();
|
||||
return org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla.OptiFineVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,7 +59,7 @@ public class MojangDownloadProvider extends IDownloadProvider {
|
||||
|
||||
@Override
|
||||
public String getVersionsListDownloadURL() {
|
||||
return "http://s3.amazonaws.com/Minecraft.Download/versions/versions.json";
|
||||
return "https://launchermeta.mojang.com/mc/game/version_manifest.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,8 +73,17 @@ public class MojangDownloadProvider extends IDownloadProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParsedLibraryDownloadURL(String str) {
|
||||
return str;
|
||||
public String getParsedDownloadURL(String str) {
|
||||
if (str == null)
|
||||
return null;
|
||||
else if (str.contains("scala-swing") || str.contains("scala-xml") || str.contains("scala-parser-combinators"))
|
||||
return str.replace("http://files.minecraftforge.net/maven", "http://ftb.cursecdn.com/FTB2/maven/");
|
||||
else if (str.contains("typesafe") || str.contains("scala"))
|
||||
if (SupportedLocales.NOW_LOCALE.self == Locale.CHINA)
|
||||
return str.replace("http://files.minecraftforge.net/maven", "http://maven.oschina.net/content/groups/public");
|
||||
else
|
||||
return str.replace("http://files.minecraftforge.net/maven", "http://repo1.maven.org/maven2");
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -49,7 +49,7 @@ public class RapidDataDownloadProvider extends MojangDownloadProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParsedLibraryDownloadURL(String str) {
|
||||
public String getParsedDownloadURL(String str) {
|
||||
return str == null ? null : str.replace("http://files.minecraftforge.net/maven", "http://mirrors.rapiddata.org/forge/maven");
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -15,11 +15,11 @@
|
||||
* 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.installers;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.forge.Install;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.forge.Install;
|
||||
|
||||
/**
|
||||
*
|
||||
+2
-2
@@ -15,14 +15,14 @@
|
||||
* 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.installers;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public enum InstallerType {
|
||||
Forge("forge"), Optifine("optifine"), LiteLoader("liteloader");
|
||||
Forge("forge"), OptiFine("optifine"), LiteLoader("liteloader");
|
||||
|
||||
public final String id;
|
||||
|
||||
+25
-3
@@ -15,12 +15,14 @@
|
||||
* 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.installers;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import java.util.Objects;
|
||||
import org.jackhuang.hellominecraft.util.func.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -84,9 +86,29 @@ public abstract class InstallerVersionList implements Consumer<String[]> {
|
||||
public int compareTo(InstallerVersion o) {
|
||||
return selfVersion.compareTo(o.selfVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return selfVersion.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final InstallerVersion other = (InstallerVersion) obj;
|
||||
return Objects.equals(this.selfVersion, other.selfVersion);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class InstallerVersionComparator implements Comparator<InstallerVersion> {
|
||||
public static class InstallerVersionComparator implements Comparator<InstallerVersion>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3276198781795213723L;
|
||||
|
||||
public static final InstallerVersionComparator INSTANCE = new InstallerVersionComparator();
|
||||
|
||||
+7
-4
@@ -15,19 +15,22 @@
|
||||
* 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.installers;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Comparator;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList.InstallerVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList.InstallerVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class InstallerVersionNewerComparator implements Comparator<InstallerVersion> {
|
||||
public class InstallerVersionNewerComparator implements Comparator<InstallerVersion>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 14758562453742645L;
|
||||
|
||||
@Override
|
||||
public int compare(InstallerVersion o1, InstallerVersion o2) {
|
||||
return -o1.compareTo(o2);
|
||||
return o2.compareTo(o1);
|
||||
}
|
||||
}
|
||||
+26
-26
@@ -15,22 +15,22 @@
|
||||
* 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.installers;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftInstallerService;
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList.InstallerVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.forge.ForgeInstaller;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.liteloader.LiteLoaderInstaller;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.liteloader.LiteLoaderVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.optifine.OptiFineInstaller;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.optifine.vanilla.OptiFineDownloadFormatter;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskInfo;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList.InstallerVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.forge.ForgeInstaller;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.liteloader.LiteLoaderInstaller;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.liteloader.LiteLoaderVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.optifine.OptiFineInstaller;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla.OptiFineDownloadFormatter;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
|
||||
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -47,8 +47,8 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
|
||||
switch (type) {
|
||||
case Forge:
|
||||
return downloadForge(installId, v);
|
||||
case Optifine:
|
||||
return downloadOptifine(installId, v);
|
||||
case OptiFine:
|
||||
return downloadOptiFine(installId, v);
|
||||
case LiteLoader:
|
||||
return downloadLiteLoader(installId, v);
|
||||
default:
|
||||
@@ -63,26 +63,26 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
|
||||
public void executeTask() {
|
||||
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "forge-installer.jar");
|
||||
if (v.installer != null)
|
||||
TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(service.getDownloadType().getProvider().getParsedLibraryDownloadURL(v.installer), filepath).setTag("forge"))
|
||||
.addTask(new ForgeInstaller(service, filepath, v))
|
||||
.start();
|
||||
TaskWindow.factory()
|
||||
.append(new FileDownloadTask(service.getDownloadType().getProvider().getParsedDownloadURL(v.installer), filepath).setTag("forge"))
|
||||
.append(new ForgeInstaller(service, filepath))
|
||||
.create();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task downloadOptifine(String installId, InstallerVersion v) {
|
||||
public Task downloadOptiFine(String installId, InstallerVersion v) {
|
||||
return new TaskInfo("OptiFine Downloader") {
|
||||
@Override
|
||||
public void executeTask() {
|
||||
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "optifine-installer.jar");
|
||||
if (v.installer != null) {
|
||||
OptiFineDownloadFormatter task = new OptiFineDownloadFormatter(v.installer);
|
||||
TaskWindow.getInstance().addTask(task)
|
||||
.addTask(new FileDownloadTask(filepath).registerPreviousResult(task).setTag("optifine"))
|
||||
.addTask(new OptiFineInstaller(service, installId, v, filepath))
|
||||
.start();
|
||||
TaskWindow.factory().append(task)
|
||||
.append(new FileDownloadTask(filepath).registerPreviousResult(task).setTag("optifine"))
|
||||
.append(new OptiFineInstaller(service, installId, v, filepath))
|
||||
.create();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -95,9 +95,9 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
|
||||
public void executeTask() {
|
||||
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "liteloader-universal.jar");
|
||||
FileDownloadTask task = (FileDownloadTask) new FileDownloadTask(v.universal, filepath).setTag("LiteLoader");
|
||||
TaskWindow.getInstance()
|
||||
.addTask(task).addTask(new LiteLoaderInstaller(service, installId, (LiteLoaderVersionList.LiteLoaderInstallerVersion) v).registerPreviousResult(task))
|
||||
.start();
|
||||
TaskWindow.factory()
|
||||
.append(task).append(new LiteLoaderInstaller(service, installId, (LiteLoaderVersionList.LiteLoaderInstallerVersion) v).registerPreviousResult(task))
|
||||
.create();
|
||||
}
|
||||
};
|
||||
}
|
||||
+7
-5
@@ -15,14 +15,15 @@
|
||||
* 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.installers;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.utils.system.Compressor;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.system.Compressor;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -40,7 +41,8 @@ public class PackMinecraftInstaller {
|
||||
|
||||
public void install() throws IOException {
|
||||
File file = new File(IOUtils.currentDir(), "HMCL-MERGE-TEMP");
|
||||
file.mkdirs();
|
||||
if (!file.exists() && !file.mkdirs())
|
||||
HMCLog.warn("Failed to make directories: " + file);
|
||||
for (String src1 : src)
|
||||
Compressor.unzip(new File(src1), file);
|
||||
Compressor.zip(file.getAbsolutePath(), dest.getAbsolutePath());
|
||||
Executable
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.install.forge;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallProfile;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.util.MessageBox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ForgeInstaller extends Task {
|
||||
|
||||
public File gameDir;
|
||||
public File forgeInstaller;
|
||||
public IMinecraftService mp;
|
||||
|
||||
public ForgeInstaller(IMinecraftService mp, File forgeInstaller) {
|
||||
this.gameDir = mp.baseDirectory();
|
||||
this.forgeInstaller = forgeInstaller;
|
||||
this.mp = mp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Exception {
|
||||
HMCLog.log("Extracting install profiles...");
|
||||
|
||||
try (ZipFile zipFile = new ZipFile(forgeInstaller)) {
|
||||
ZipEntry entry = zipFile.getEntry("install_profile.json");
|
||||
String content = NetUtils.getStreamContent(zipFile.getInputStream(entry));
|
||||
InstallProfile profile = C.GSON.fromJson(content, InstallProfile.class);
|
||||
File from = new File(gameDir, "versions" + File.separator + profile.install.getMinecraft());
|
||||
if (!from.exists())
|
||||
if (MessageBox.Show(C.i18n("install.no_version_if_intall")) == MessageBox.YES_OPTION) {
|
||||
if (!mp.version().install(profile.install.getMinecraft(), null))
|
||||
throw new IllegalStateException(C.i18n("install.no_version"));
|
||||
} else
|
||||
throw new IllegalStateException(C.i18n("install.no_version"));
|
||||
File to = new File(gameDir, "versions" + File.separator + profile.install.getTarget());
|
||||
if (!to.exists() && !to.mkdirs())
|
||||
HMCLog.warn("Failed to make new version folder " + to);
|
||||
HMCLog.log("Copying jar..." + profile.install.getMinecraft() + ".jar to " + profile.install.getTarget() + ".jar");
|
||||
FileUtils.copyFile(new File(from, profile.install.getMinecraft() + ".jar"),
|
||||
new File(to, profile.install.getTarget() + ".jar"));
|
||||
HMCLog.log("Creating new version profile..." + profile.install.getTarget() + ".json");
|
||||
FileUtils.write(new File(to, profile.install.getTarget() + ".json"), C.GSON.toJson(profile.versionInfo));
|
||||
HMCLog.log("Extracting universal forge pack..." + profile.install.getFilePath());
|
||||
entry = zipFile.getEntry(profile.install.getFilePath());
|
||||
InputStream is = zipFile.getInputStream(entry);
|
||||
MinecraftLibrary forge = new MinecraftLibrary(profile.install.getPath());
|
||||
File file = new File(gameDir, "libraries/" + forge.getDownloadInfo().path);
|
||||
if (file.getParentFile().mkdirs())
|
||||
HMCLog.warn("Failed to make library directory " + file.getParent());
|
||||
try (FileOutputStream fos = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
|
||||
int c;
|
||||
while ((c = is.read()) != -1)
|
||||
bos.write((byte) c);
|
||||
}
|
||||
mp.version().refreshVersions();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("install.forge.install");
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -15,12 +15,12 @@
|
||||
* 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.installers.forge;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.forge;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.PackMinecraftInstaller;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.PackMinecraftInstaller;
|
||||
|
||||
/**
|
||||
*
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.install.forge;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Install {
|
||||
|
||||
private String profileName;
|
||||
private String target;
|
||||
private String path;
|
||||
private String version;
|
||||
private String filePath;
|
||||
private String welcome;
|
||||
private String minecraft;
|
||||
private String mirrorList;
|
||||
private String logo;
|
||||
|
||||
public Install() {
|
||||
}
|
||||
|
||||
public Install(String profileName, String target, String path, String version, String filePath, String welcome, String minecraft, String mirrorList, String logo) {
|
||||
this();
|
||||
this.profileName = profileName;
|
||||
this.target = target;
|
||||
this.path = path;
|
||||
this.version = version;
|
||||
this.filePath = filePath;
|
||||
this.welcome = welcome;
|
||||
this.minecraft = minecraft;
|
||||
this.mirrorList = mirrorList;
|
||||
this.logo = logo;
|
||||
}
|
||||
|
||||
public String getProfileName() {
|
||||
return profileName;
|
||||
}
|
||||
|
||||
public void setProfileName(String profileName) {
|
||||
this.profileName = profileName;
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(String target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
public String getWelcome() {
|
||||
return welcome;
|
||||
}
|
||||
|
||||
public void setWelcome(String welcome) {
|
||||
this.welcome = welcome;
|
||||
}
|
||||
|
||||
public String getMinecraft() {
|
||||
return minecraft;
|
||||
}
|
||||
|
||||
public void setMinecraft(String minecraft) {
|
||||
this.minecraft = minecraft;
|
||||
}
|
||||
|
||||
public String getMirrorList() {
|
||||
return mirrorList;
|
||||
}
|
||||
|
||||
public void setMirrorList(String mirrorList) {
|
||||
this.mirrorList = mirrorList;
|
||||
}
|
||||
|
||||
public String getLogo() {
|
||||
return logo;
|
||||
}
|
||||
|
||||
public void setLogo(String logo) {
|
||||
this.logo = logo;
|
||||
}
|
||||
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.install.forge;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftForgeVersion {
|
||||
|
||||
public String branch, mcversion, jobver, version;
|
||||
public int build;
|
||||
public double modified;
|
||||
public String[][] files;
|
||||
|
||||
public String getBranch() {
|
||||
return branch;
|
||||
}
|
||||
|
||||
public void setBranch(String branch) {
|
||||
this.branch = branch;
|
||||
}
|
||||
|
||||
public String getMCVersion() {
|
||||
return mcversion;
|
||||
}
|
||||
|
||||
public void setMCVersion(String mcversion) {
|
||||
this.mcversion = mcversion;
|
||||
}
|
||||
|
||||
public String getJobver() {
|
||||
return jobver;
|
||||
}
|
||||
|
||||
public void setJobver(String jobver) {
|
||||
this.jobver = jobver;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public int getBuild() {
|
||||
return build;
|
||||
}
|
||||
|
||||
public void setBuild(int build) {
|
||||
this.build = build;
|
||||
}
|
||||
|
||||
public double getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void setModified(double modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
public MinecraftForgeVersion() {
|
||||
}
|
||||
|
||||
public MinecraftForgeVersion(String branch, String mcversion, String jobver, String version, int build, double modified) {
|
||||
this.branch = branch;
|
||||
this.mcversion = mcversion;
|
||||
this.jobver = jobver;
|
||||
this.version = version;
|
||||
this.build = build;
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
}
|
||||
+12
-10
@@ -15,19 +15,19 @@
|
||||
* 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.installers.forge;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.forge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionNewerComparator;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionNewerComparator;
|
||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -35,7 +35,7 @@ import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
*/
|
||||
public class MinecraftForgeVersionList extends InstallerVersionList {
|
||||
|
||||
private static MinecraftForgeVersionList instance;
|
||||
private static volatile MinecraftForgeVersionList instance;
|
||||
|
||||
public static MinecraftForgeVersionList getInstance() {
|
||||
if (instance == null)
|
||||
@@ -51,9 +51,9 @@ public class MinecraftForgeVersionList extends InstallerVersionList {
|
||||
public void refreshList(String[] needed) throws Exception {
|
||||
if (root != null)
|
||||
return;
|
||||
String s = NetUtils.get(DownloadType.getSuggestedDownloadType().getProvider().getParsedLibraryDownloadURL(C.URL_FORGE_LIST));
|
||||
String s = NetUtils.get(DownloadType.getSuggestedDownloadType().getProvider().getParsedDownloadURL(C.URL_FORGE_LIST));
|
||||
|
||||
root = C.gson.fromJson(s, MinecraftForgeVersionRoot.class);
|
||||
root = C.GSON.fromJson(s, MinecraftForgeVersionRoot.class);
|
||||
|
||||
versionMap = new HashMap<>();
|
||||
versions = new ArrayList<>();
|
||||
@@ -70,7 +70,7 @@ public class MinecraftForgeVersionList extends InstallerVersionList {
|
||||
if (!StrUtils.isBlank(v.branch))
|
||||
ver = ver + "-" + v.branch;
|
||||
String filename = root.artifact + "-" + ver + "-" + f[1] + "." + f[0];
|
||||
String url = DownloadType.getSuggestedDownloadType().getProvider().getParsedLibraryDownloadURL(root.webpath + ver + "/" + filename);
|
||||
String url = DownloadType.getSuggestedDownloadType().getProvider().getParsedDownloadURL(root.webpath + ver + "/" + filename);
|
||||
switch (f[1]) {
|
||||
case "installer":
|
||||
iv.installer = url;
|
||||
@@ -81,6 +81,8 @@ public class MinecraftForgeVersionList extends InstallerVersionList {
|
||||
case "changelog":
|
||||
iv.changelog = url;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (StrUtils.isBlank(iv.installer) || StrUtils.isBlank(iv.universal))
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* 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.installers.forge;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.forge;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
+12
-9
@@ -15,18 +15,18 @@
|
||||
* 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.installers.liteloader;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.liteloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.communication.PreviousResultRegistrar;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResultRegistrar;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
|
||||
@@ -75,10 +75,13 @@ public class LiteLoaderInstaller extends Task implements PreviousResultRegistrar
|
||||
mv.mainClass = "net.minecraft.launchwrapper.Launch";
|
||||
mv.minecraftArguments += " --tweakClass " + version.tweakClass;
|
||||
File folder = new File(service.baseDirectory(), "versions/" + mv.id);
|
||||
folder.mkdirs();
|
||||
if (!folder.exists() && folder.mkdirs())
|
||||
HMCLog.warn("Failed to create new liteloader version " + folder);
|
||||
File json = new File(folder, mv.id + ".json");
|
||||
HMCLog.log("Creating new version profile..." + mv.id + ".json");
|
||||
FileUtils.write(json, C.gsonPrettyPrinting.toJson(mv));
|
||||
FileUtils.write(json, C.GSON.toJson(mv));
|
||||
|
||||
service.version().refreshVersions();
|
||||
}
|
||||
|
||||
@Override
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* 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.installers.liteloader;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.liteloader;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* 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.installers.liteloader;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.liteloader;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
|
||||
+12
-9
@@ -15,7 +15,7 @@
|
||||
* 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.installers.liteloader;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.liteloader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -23,13 +23,13 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList.InstallerVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionNewerComparator;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList.InstallerVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionNewerComparator;
|
||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -37,7 +37,7 @@ import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
*/
|
||||
public class LiteLoaderVersionList extends InstallerVersionList {
|
||||
|
||||
private static LiteLoaderVersionList instance;
|
||||
private static volatile LiteLoaderVersionList instance = null;
|
||||
|
||||
public static LiteLoaderVersionList getInstance() {
|
||||
if (instance == null)
|
||||
@@ -55,7 +55,7 @@ public class LiteLoaderVersionList extends InstallerVersionList {
|
||||
if (root != null)
|
||||
return;
|
||||
|
||||
root = C.gson.fromJson(s, LiteLoaderVersionsRoot.class);
|
||||
root = C.GSON.fromJson(s, LiteLoaderVersionsRoot.class);
|
||||
|
||||
versionMap = new HashMap<>();
|
||||
versions = new ArrayList<>();
|
||||
@@ -63,6 +63,8 @@ public class LiteLoaderVersionList extends InstallerVersionList {
|
||||
for (Map.Entry<String, LiteLoaderMCVersions> arr : root.versions.entrySet()) {
|
||||
ArrayList<InstallerVersion> al = new ArrayList<>();
|
||||
LiteLoaderMCVersions mcv = arr.getValue();
|
||||
if (mcv == null || mcv.artefacts == null || mcv.artefacts.get("com.mumfrey:liteloader") == null)
|
||||
continue;
|
||||
for (Map.Entry<String, LiteLoaderVersion> entry : mcv.artefacts.get("com.mumfrey:liteloader").entrySet()) {
|
||||
if ("latest".equals(entry.getKey()))
|
||||
continue;
|
||||
@@ -108,6 +110,7 @@ public class LiteLoaderVersionList extends InstallerVersionList {
|
||||
public LiteLoaderInstallerVersion(String selfVersion, String mcVersion) {
|
||||
super(selfVersion, mcVersion);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.install.liteloader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LiteLoaderVersionsMeta {
|
||||
|
||||
private String description, authors, url;
|
||||
|
||||
public LiteLoaderVersionsMeta() {
|
||||
}
|
||||
|
||||
public LiteLoaderVersionsMeta(String description, String authors, String url) {
|
||||
this();
|
||||
this.description = description;
|
||||
this.authors = authors;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public void setAuthors(String authors) {
|
||||
this.authors = authors;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* 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.installers.liteloader;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.liteloader;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
+21
-15
@@ -15,20 +15,21 @@
|
||||
* 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.installers.optifine;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.optifine;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.communication.PreviousResultRegistrar;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResultRegistrar;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -65,22 +66,27 @@ public class OptiFineInstaller extends Task implements PreviousResultRegistrar<F
|
||||
FileUtils.copyFile(installer, new File(service.baseDirectory(), "libraries/optifine/OptiFine/" + selfId + "/OptiFine-" + selfId + ".jar"));
|
||||
|
||||
mv.id += "-" + selfId;
|
||||
if (new ZipFile(installer).getEntry("optifine/OptiFineTweaker.class") != null) {
|
||||
if (!mv.mainClass.startsWith("net.minecraft.launchwrapper.")) {
|
||||
mv.mainClass = "net.minecraft.launchwrapper.Launch";
|
||||
mv.libraries.add(1, new MinecraftLibrary("net.minecraft:launchwrapper:1.7"));
|
||||
try (ZipFile zipFile = new ZipFile(installer)) {
|
||||
if (zipFile.getEntry("optifine/OptiFineTweaker.class") != null) {
|
||||
if (!mv.mainClass.startsWith("net.minecraft.launchwrapper.")) {
|
||||
mv.mainClass = "net.minecraft.launchwrapper.Launch";
|
||||
mv.libraries.add(1, new MinecraftLibrary("net.minecraft:launchwrapper:1.7"));
|
||||
}
|
||||
mv.minecraftArguments += " --tweakClass optifine.OptiFineTweaker";
|
||||
}
|
||||
mv.minecraftArguments += " --tweakClass optifine.OptiFineTweaker";
|
||||
}
|
||||
File loc = new File(service.baseDirectory(), "versions/" + mv.id);
|
||||
loc.mkdirs();
|
||||
if (!loc.exists() && loc.mkdirs())
|
||||
HMCLog.warn("Failed to make directories: " + loc);
|
||||
File json = new File(loc, mv.id + ".json");
|
||||
FileUtils.writeStringToFile(json, C.gsonPrettyPrinting.toJson(mv, MinecraftVersion.class));
|
||||
FileUtils.writeStringToFile(json, C.GSON.toJson(mv, MinecraftVersion.class));
|
||||
|
||||
service.version().refreshVersions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "Optifine Installer";
|
||||
return "OptiFine Installer";
|
||||
}
|
||||
|
||||
ArrayList<PreviousResult<File>> pre = new ArrayList();
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.install.optifine;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class OptiFineVersion {
|
||||
|
||||
private String dl, ver, date, mirror, mcver;
|
||||
|
||||
public String getDownloadLink() {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public void setDownloadLink(String dl) {
|
||||
this.dl = dl;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return ver;
|
||||
}
|
||||
|
||||
public void setVersion(String ver) {
|
||||
this.ver = ver;
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(String date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getMirror() {
|
||||
return mirror;
|
||||
}
|
||||
|
||||
public void setMirror(String mirror) {
|
||||
this.mirror = mirror;
|
||||
}
|
||||
|
||||
public String getMCVersion() {
|
||||
return mcver;
|
||||
}
|
||||
|
||||
public void setMCVersion(String mcver) {
|
||||
this.mcver = mcver;
|
||||
}
|
||||
}
|
||||
+20
-17
@@ -15,9 +15,10 @@
|
||||
* 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.installers.optifine.bmcl;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.optifine.bmcl;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -25,12 +26,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.optifine.OptiFineVersion;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.optifine.OptiFineVersion;
|
||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -50,6 +51,9 @@ public class OptiFineBMCLVersionList extends InstallerVersionList {
|
||||
public Map<String, List<InstallerVersion>> versionMap;
|
||||
public List<InstallerVersion> versions;
|
||||
|
||||
private static final Type TYPE = new TypeToken<ArrayList<OptiFineVersion>>() {
|
||||
}.getType();
|
||||
|
||||
@Override
|
||||
public void refreshList(String[] needed) throws Exception {
|
||||
String s = NetUtils.get("http://bmclapi.bangbang93.com/optifine/versionlist");
|
||||
@@ -59,22 +63,21 @@ public class OptiFineBMCLVersionList extends InstallerVersionList {
|
||||
|
||||
if (s == null)
|
||||
return;
|
||||
root = C.gson.fromJson(s, new TypeToken<ArrayList<OptiFineVersion>>() {
|
||||
}.getType());
|
||||
root = C.GSON.fromJson(s, TYPE);
|
||||
for (OptiFineVersion v : root) {
|
||||
v.mirror = v.mirror.replace("http://optifine.net/http://optifine.net/", "http://optifine.net/");
|
||||
v.setMirror(v.getMirror().replace("http://optifine.net/http://optifine.net/", "http://optifine.net/"));
|
||||
|
||||
if (StrUtils.isBlank(v.mcver)) {
|
||||
if (StrUtils.isBlank(v.getMCVersion())) {
|
||||
Pattern p = Pattern.compile("OptiFine (.*) HD");
|
||||
Matcher m = p.matcher(v.ver);
|
||||
Matcher m = p.matcher(v.getVersion());
|
||||
while (m.find())
|
||||
v.mcver = m.group(1);
|
||||
v.setMCVersion(m.group(1));
|
||||
}
|
||||
InstallerVersion iv = new InstallerVersion(v.ver, StrUtils.formatVersion(v.mcver));
|
||||
InstallerVersion iv = new InstallerVersion(v.getVersion(), StrUtils.formatVersion(v.getMCVersion()));
|
||||
|
||||
List<InstallerVersion> al = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.mcver));
|
||||
String url = "http://bmclapi.bangbang93.com/optifine/" + iv.selfVersion.replace(" ", "%20");
|
||||
iv.installer = iv.universal = v.mirror;
|
||||
List<InstallerVersion> al = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.getMCVersion()));
|
||||
//String url = "http://bmclapi.bangbang93.com/optifine/" + iv.selfVersion.replace(" ", "%20");
|
||||
iv.installer = iv.universal = v.getMirror();
|
||||
al.add(iv);
|
||||
versions.add(iv);
|
||||
}
|
||||
+5
-5
@@ -15,14 +15,14 @@
|
||||
* 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.installers.optifine.vanilla;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
+18
-18
@@ -15,7 +15,7 @@
|
||||
* 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.installers.optifine.vanilla;
|
||||
package org.jackhuang.hellominecraft.launcher.core.install.optifine.vanilla;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
@@ -29,11 +29,11 @@ import java.util.regex.Pattern;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.optifine.OptiFineVersion;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.optifine.OptiFineVersion;
|
||||
import org.jackhuang.hellominecraft.util.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.util.NetUtils;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -66,12 +66,12 @@ public class OptiFineVersionList extends InstallerVersionList {
|
||||
versionMap = new HashMap<>();
|
||||
versions = new ArrayList<>();
|
||||
|
||||
content = content.replace(" ", " ").replace(">", ">").replace("<", "<");
|
||||
content = content.replace(" ", " ").replace(">", ">").replace("<", "<").replace("<br>", "<br />");
|
||||
|
||||
try {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = factory.newDocumentBuilder();
|
||||
Document doc = db.parse(new ByteArrayInputStream(content.getBytes()));
|
||||
Document doc = db.parse(new ByteArrayInputStream(content.getBytes("UTF-8")));
|
||||
Element r = doc.getDocumentElement();
|
||||
NodeList tables = r.getElementsByTagName("table");
|
||||
for (int i = 0; i < tables.getLength(); i++) {
|
||||
@@ -84,26 +84,26 @@ public class OptiFineVersionList extends InstallerVersionList {
|
||||
for (int j = 0; j < downloadLine.getLength(); j++) {
|
||||
Element td = (Element) downloadLine.item(j);
|
||||
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineMirror"))
|
||||
v.mirror = ((Element) td.getElementsByTagName("a").item(0)).getAttribute("href");
|
||||
v.setMirror(((Element) td.getElementsByTagName("a").item(0)).getAttribute("href"));
|
||||
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineDownload"))
|
||||
v.dl = ((Element) td.getElementsByTagName("a").item(0)).getAttribute("href");
|
||||
v.setDownloadLink(((Element) td.getElementsByTagName("a").item(0)).getAttribute("href"));
|
||||
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineDate"))
|
||||
v.date = td.getTextContent();
|
||||
v.setDate(td.getTextContent());
|
||||
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineFile"))
|
||||
v.ver = td.getTextContent();
|
||||
v.setVersion(td.getTextContent());
|
||||
}
|
||||
if (StrUtils.isBlank(v.mcver)) {
|
||||
if (StrUtils.isBlank(v.getMCVersion())) {
|
||||
Pattern p = Pattern.compile("OptiFine (.*?) ");
|
||||
Matcher m = p.matcher(v.ver);
|
||||
Matcher m = p.matcher(v.getVersion());
|
||||
while (m.find())
|
||||
v.mcver = StrUtils.formatVersion(m.group(1));
|
||||
v.setMCVersion(StrUtils.formatVersion(m.group(1)));
|
||||
}
|
||||
InstallerVersion iv = new InstallerVersion(v.ver, StrUtils.formatVersion(v.mcver));
|
||||
iv.installer = iv.universal = v.mirror;
|
||||
InstallerVersion iv = new InstallerVersion(v.getVersion(), StrUtils.formatVersion(v.getMCVersion()));
|
||||
iv.installer = iv.universal = v.getMirror();
|
||||
root.add(v);
|
||||
versions.add(iv);
|
||||
|
||||
List<InstallerVersion> ivl = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.mcver));
|
||||
List<InstallerVersion> ivl = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.getMCVersion()));
|
||||
ivl.add(iv);
|
||||
}
|
||||
}
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* 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.installers.forge;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallProfile;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList.InstallerVersion;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ForgeInstaller extends Task {
|
||||
|
||||
public File gameDir;
|
||||
public File forgeInstaller;
|
||||
public IMinecraftService mp;
|
||||
public InstallerVersion installerVersion;
|
||||
|
||||
public ForgeInstaller(IMinecraftService mp, File forgeInstaller, InstallerVersion installerVersion) {
|
||||
this.gameDir = mp.baseDirectory();
|
||||
this.forgeInstaller = forgeInstaller;
|
||||
this.mp = mp;
|
||||
this.installerVersion = installerVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Exception {
|
||||
HMCLog.log("Extracting install profiles...");
|
||||
|
||||
ZipFile zipFile = new ZipFile(forgeInstaller);
|
||||
ZipEntry entry = zipFile.getEntry("install_profile.json");
|
||||
String content = NetUtils.getStreamContent(zipFile.getInputStream(entry));
|
||||
InstallProfile profile = C.gsonPrettyPrinting.fromJson(content, InstallProfile.class);
|
||||
|
||||
File from = new File(gameDir, "versions" + File.separator + profile.install.minecraft);
|
||||
if (!from.exists())
|
||||
if (MessageBox.Show(C.i18n("install.no_version_if_intall")) == MessageBox.YES_OPTION) {
|
||||
if (!mp.version().install(profile.install.minecraft, null))
|
||||
throw new IllegalStateException(C.i18n("install.no_version"));
|
||||
} else
|
||||
throw new IllegalStateException(C.i18n("install.no_version"));
|
||||
|
||||
File to = new File(gameDir, "versions" + File.separator + profile.install.target);
|
||||
to.mkdirs();
|
||||
|
||||
HMCLog.log("Copying jar..." + profile.install.minecraft + ".jar to " + profile.install.target + ".jar");
|
||||
FileUtils.copyFile(new File(from, profile.install.minecraft + ".jar"),
|
||||
new File(to, profile.install.target + ".jar"));
|
||||
HMCLog.log("Creating new version profile..." + profile.install.target + ".json");
|
||||
/*
|
||||
* for (MinecraftLibrary library : profile.versionInfo.libraries)
|
||||
* if (library.name.startsWith("net.minecraftforge:forge:"))
|
||||
* library.url = installerVersion.universal;
|
||||
*/
|
||||
FileUtils.write(new File(to, profile.install.target + ".json"), C.gsonPrettyPrinting.toJson(profile.versionInfo));
|
||||
|
||||
HMCLog.log("Extracting universal forge pack..." + profile.install.filePath);
|
||||
|
||||
entry = zipFile.getEntry(profile.install.filePath);
|
||||
InputStream is = zipFile.getInputStream(entry);
|
||||
|
||||
MinecraftLibrary forge = new MinecraftLibrary(profile.install.path);
|
||||
forge.init();
|
||||
File file = new File(gameDir, "libraries/" + forge.formatted);
|
||||
file.getParentFile().mkdirs();
|
||||
try (FileOutputStream fos = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
|
||||
int c;
|
||||
while ((c = is.read()) != -1)
|
||||
bos.write((byte) c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("install.forge.install");
|
||||
}
|
||||
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* 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.installers.forge;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftForgeVersion {
|
||||
|
||||
public String branch, mcversion, jobver, version;
|
||||
public int build;
|
||||
public double modified;
|
||||
public String[][] files;
|
||||
}
|
||||
+28
-29
@@ -17,25 +17,24 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Launcher;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.system.JdkVersion;
|
||||
import org.jackhuang.hellominecraft.util.MathUtils;
|
||||
import org.jackhuang.hellominecraft.util.MessageBox;
|
||||
import org.jackhuang.hellominecraft.util.system.OS;
|
||||
import org.jackhuang.hellominecraft.util.system.Platform;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.Utils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.system.JdkVersion;
|
||||
import org.jackhuang.hellominecraft.utils.MathUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.utils.system.Platform;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -50,6 +49,8 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader {
|
||||
protected final MinecraftVersion version;
|
||||
|
||||
public AbstractMinecraftLoader(LaunchOptions options, IMinecraftService service, String versionId, UserProfileProvider lr) throws GameException {
|
||||
if (service.version().getVersionById(versionId) == null)
|
||||
throw new GameException("No version: " + versionId);
|
||||
this.lr = lr;
|
||||
|
||||
this.options = options;
|
||||
@@ -66,6 +67,9 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader {
|
||||
public void makeHeadCommand(List<String> res) {
|
||||
HMCLog.log("On making head command.");
|
||||
|
||||
if (StrUtils.isNotBlank(options.getWrapper()))
|
||||
res.add(options.getWrapper());
|
||||
|
||||
JdkVersion jv = options.getJava();
|
||||
res.add(options.getJavaDir());
|
||||
|
||||
@@ -78,8 +82,10 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader {
|
||||
if (jv == null || !jv.isEarlyAccess()) {
|
||||
if (OS.os() == OS.WINDOWS)
|
||||
res.add("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump");
|
||||
res.add("-XX:+UseConcMarkSweepGC");
|
||||
res.add("-XX:+CMSIncrementalMode");
|
||||
if (jv != null && jv.getParsedVersion() >= JdkVersion.JAVA_17)
|
||||
res.add("-XX:+UseG1GC");
|
||||
else
|
||||
res.add("-Xincgc");
|
||||
res.add("-XX:-UseAdaptiveSizePolicy");
|
||||
res.add("-XX:-OmitStackTraceInFastThrow");
|
||||
|
||||
@@ -123,12 +129,6 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader {
|
||||
|
||||
if (OS.os() != OS.WINDOWS)
|
||||
res.add("-Duser.home=" + gameDir.getParent());
|
||||
|
||||
if (!options.isCanceledWrapper()) {
|
||||
res.add("-cp");
|
||||
res.add(StrUtils.parseParams("", Utils.getURL(), File.pathSeparator));
|
||||
res.add(Launcher.class.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -150,8 +150,6 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader {
|
||||
}
|
||||
|
||||
String serverIp = options.getServerIp();
|
||||
if (lr.getServer() != null)
|
||||
serverIp = lr.getServer().addr;
|
||||
if (StrUtils.isNotBlank(serverIp)) {
|
||||
String[] args = serverIp.split(":");
|
||||
res.add("--server");
|
||||
@@ -163,15 +161,16 @@ public abstract class AbstractMinecraftLoader implements IMinecraftLoader {
|
||||
if (options.isFullscreen())
|
||||
res.add("--fullscreen");
|
||||
|
||||
if (options.isDebug() && !options.isCanceledWrapper())
|
||||
res.add("-debug");
|
||||
|
||||
if (StrUtils.isNotBlank(options.getProxyHost()) && StrUtils.isNotBlank(options.getProxyPort()) && MathUtils.canParseInt(options.getProxyPort())) {
|
||||
res.add("-proxyHost=" + options.getProxyHost());
|
||||
res.add("-proxyPort=" + options.getProxyPort());
|
||||
res.add("--proxyHost");
|
||||
res.add(options.getProxyHost());
|
||||
res.add("--proxyPort");
|
||||
res.add(options.getProxyPort());
|
||||
if (StrUtils.isNotBlank(options.getProxyUser()) && StrUtils.isNotBlank(options.getProxyPass())) {
|
||||
res.add("-proxyUsername=" + options.getProxyUser());
|
||||
res.add("-proxyPassword=" + options.getProxyPass());
|
||||
res.add("--proxyUser");
|
||||
res.add(options.getProxyUser());
|
||||
res.add("-=proxyPass");
|
||||
res.add(options.getProxyPass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-14
@@ -18,17 +18,17 @@
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import java.util.HashSet;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.LoginInfo;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.ParallelTask;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.system.Compressor;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.tasks.ParallelTask;
|
||||
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.util.system.Compressor;
|
||||
import org.jackhuang.hellominecraft.util.MessageBox;
|
||||
|
||||
public class DefaultGameLauncher extends GameLauncher {
|
||||
|
||||
@@ -39,14 +39,19 @@ public class DefaultGameLauncher extends GameLauncher {
|
||||
|
||||
private void register() {
|
||||
downloadLibrariesEvent.register((sender, t) -> {
|
||||
final TaskWindow.TaskWindowFactory dw = TaskWindow.getInstance();
|
||||
final TaskWindow.TaskWindowFactory dw = TaskWindow.factory();
|
||||
ParallelTask parallelTask = new ParallelTask();
|
||||
for (DownloadLibraryJob s : t)
|
||||
HashSet<String> names = new HashSet<>();
|
||||
for (DownloadLibraryJob s : t) {
|
||||
if (names.contains(s.lib.name))
|
||||
continue;
|
||||
names.add(s.lib.name);
|
||||
parallelTask.addDependsTask(new LibraryDownloadTask(s));
|
||||
dw.addTask(parallelTask);
|
||||
}
|
||||
dw.append(parallelTask);
|
||||
boolean flag = true;
|
||||
if (t.size() > 0)
|
||||
flag = dw.start();
|
||||
flag = dw.create();
|
||||
if (!flag && MessageBox.Show(C.i18n("launch.not_finished_downloading_libraries"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
flag = true;
|
||||
return flag;
|
||||
@@ -56,10 +61,9 @@ public class DefaultGameLauncher extends GameLauncher {
|
||||
return false;
|
||||
for (int i = 0; i < value.decompressFiles.length; i++)
|
||||
try {
|
||||
String[] rules = value.extractRules[i];
|
||||
Compressor.unzip(value.decompressFiles[i], value.decompressTo, t -> !StrUtils.startsWithOne(rules, t), false);
|
||||
Compressor.unzip(value.decompressFiles[i], value.getDecompressTo(), value.extractRules[i]::allow, false);
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Unable to decompress library file: " + value.decompressFiles[i] + " to " + value.decompressTo, ex);
|
||||
HMCLog.err("Unable to decompress library: " + value.decompressFiles[i] + " to " + value.getDecompressTo(), ex);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
+26
-20
@@ -26,8 +26,8 @@ import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||
@@ -36,14 +36,14 @@ import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.DecompressLibraryJob;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.JavaProcess;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
import org.jackhuang.hellominecraft.utils.system.ProcessManager;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.JavaProcess;
|
||||
import org.jackhuang.hellominecraft.util.MessageBox;
|
||||
import org.jackhuang.hellominecraft.util.system.OS;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.EventHandler;
|
||||
import org.jackhuang.hellominecraft.util.system.ProcessManager;
|
||||
|
||||
public class GameLauncher {
|
||||
|
||||
@@ -53,10 +53,11 @@ public class GameLauncher {
|
||||
LoginInfo info;
|
||||
UserProfileProvider result;
|
||||
IAuthenticator login;
|
||||
public final EventHandler<List<DownloadLibraryJob>> downloadLibrariesEvent = new EventHandler(this);
|
||||
public final EventHandler<List<String>> successEvent = new EventHandler(this);
|
||||
public final EventHandler<JavaProcess> launchEvent = new EventHandler(this);
|
||||
public final EventHandler<DecompressLibraryJob> decompressNativesEvent = new EventHandler(this);
|
||||
public final EventHandler<List<DownloadLibraryJob>> downloadLibrariesEvent = new EventHandler<>(this);
|
||||
public final EventHandler<List<String>> successEvent = new EventHandler<>(this);
|
||||
public final EventHandler<JavaProcess> launchEvent = new EventHandler<>(this);
|
||||
public final EventHandler<LaunchingState> launchingStateChangedEvent = new EventHandler<>(this);
|
||||
public final EventHandler<DecompressLibraryJob> decompressNativesEvent = new EventHandler<>(this);
|
||||
|
||||
public GameLauncher(LaunchOptions options, IMinecraftService version, LoginInfo info, IAuthenticator lg) {
|
||||
this.options = options;
|
||||
@@ -76,7 +77,9 @@ public class GameLauncher {
|
||||
}
|
||||
|
||||
public IMinecraftLoader makeLaunchCommand() throws AuthenticationException, GameException {
|
||||
HMCLog.log("Building process");
|
||||
HMCLog.log("Logging in...");
|
||||
launchingStateChangedEvent.execute(LaunchingState.LoggingIn);
|
||||
IMinecraftLoader loader;
|
||||
if (info != null)
|
||||
result = login.login(info);
|
||||
@@ -84,8 +87,9 @@ public class GameLauncher {
|
||||
result = login.loginBySettings();
|
||||
if (result == null)
|
||||
throw new AuthenticationException("Result can not be null.");
|
||||
PluginManager.NOW_PLUGIN.onProcessingLoginResult(result);
|
||||
PluginManager.plugin().onProcessingLoginResult(result);
|
||||
|
||||
launchingStateChangedEvent.execute(LaunchingState.GeneratingLaunchingCodes);
|
||||
loader = service.launch(options, result);
|
||||
|
||||
File file = service.version().getDecompressNativesToLocation(loader.getMinecraftVersion());
|
||||
@@ -93,10 +97,12 @@ public class GameLauncher {
|
||||
FileUtils.cleanDirectoryQuietly(file);
|
||||
|
||||
HMCLog.log("Detecting libraries...");
|
||||
launchingStateChangedEvent.execute(LaunchingState.DownloadingLibraries);
|
||||
if (!downloadLibrariesEvent.execute(service.download().getDownloadLibraries(loader.getMinecraftVersion())))
|
||||
throw new GameException("Failed to download libraries");
|
||||
|
||||
HMCLog.log("Unpacking natives...");
|
||||
launchingStateChangedEvent.execute(LaunchingState.DecompressingNatives);
|
||||
DecompressLibraryJob job = service.version().getDecompressLibraries(loader.getMinecraftVersion());
|
||||
if (!decompressNativesEvent.execute(job))
|
||||
throw new GameException("Failed to decompress natives");
|
||||
@@ -118,7 +124,7 @@ public class GameLauncher {
|
||||
if (StrUtils.isNotBlank(options.getPrecalledCommand())) {
|
||||
Process p = Runtime.getRuntime().exec(options.getPrecalledCommand());
|
||||
try {
|
||||
if (p != null && p.isAlive())
|
||||
if (p.isAlive())
|
||||
p.waitFor();
|
||||
} catch (InterruptedException ex) {
|
||||
HMCLog.warn("Failed to invoke precalled command", ex);
|
||||
@@ -128,10 +134,10 @@ public class GameLauncher {
|
||||
ProcessBuilder builder = new ProcessBuilder(str);
|
||||
if (options.getLaunchVersion() == null || service.baseDirectory() == null)
|
||||
throw new Error("Fucking bug!");
|
||||
builder.directory(service.version().getRunDirectory(options.getLaunchVersion()))
|
||||
builder.redirectErrorStream(true).directory(service.version().getRunDirectory(options.getLaunchVersion()))
|
||||
.environment().put("APPDATA", service.baseDirectory().getAbsolutePath());
|
||||
JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER);
|
||||
HMCLog.log("The game process have been started");
|
||||
HMCLog.log("Have started the process");
|
||||
launchEvent.execute(jp);
|
||||
}
|
||||
|
||||
@@ -150,8 +156,8 @@ public class GameLauncher {
|
||||
service.version().onLaunch();
|
||||
boolean isWin = OS.os() == OS.WINDOWS;
|
||||
File f = new File(launcherName + (isWin ? ".bat" : ".sh"));
|
||||
if (!f.exists())
|
||||
f.createNewFile();
|
||||
if (!f.exists() && !f.createNewFile())
|
||||
HMCLog.warn("Failed to create " + f);
|
||||
BufferedWriter writer;
|
||||
try {
|
||||
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), System.getProperty("sun.jnu.encoding", "UTF-8")));
|
||||
|
||||
+21
-36
@@ -18,10 +18,9 @@
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.GameDirType;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.JdkVersion;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.JdkVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -29,15 +28,13 @@ import org.jackhuang.hellominecraft.utils.system.JdkVersion;
|
||||
*/
|
||||
public class LaunchOptions {
|
||||
|
||||
private String name, versionName, javaArgs, minecraftArgs, maxMemory, permSize, width, height, userProperties, serverIp;
|
||||
private String proxyHost, proxyPort, proxyUser, proxyPass, javaDir, launchVersion;
|
||||
private boolean fullscreen, debug, noJVMArgs, canceledWrapper;
|
||||
private String name, versionName, javaArgs, minecraftArgs, maxMemory, permSize, width, height, serverIp, wrapper;
|
||||
private String proxyHost, proxyPort, proxyUser, proxyPass, javaDir, launchVersion, type, precalledCommand;
|
||||
private boolean fullscreen, noJVMArgs;
|
||||
private JdkVersion java;
|
||||
private File gameDir;
|
||||
private GameDirType gameDirType;
|
||||
|
||||
protected transient IMinecraftService service;
|
||||
|
||||
public String getVersionName() {
|
||||
return versionName;
|
||||
}
|
||||
@@ -98,6 +95,14 @@ public class LaunchOptions {
|
||||
this.maxMemory = maxMemory;
|
||||
}
|
||||
|
||||
public String getWrapper() {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
public void setWrapper(String wrapper) {
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
public String getWidth() {
|
||||
return width;
|
||||
}
|
||||
@@ -114,16 +119,6 @@ public class LaunchOptions {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public String getUserProperties() {
|
||||
if (userProperties == null)
|
||||
return "";
|
||||
return userProperties;
|
||||
}
|
||||
|
||||
public void setUserProperties(String userProperties) {
|
||||
this.userProperties = userProperties;
|
||||
}
|
||||
|
||||
public boolean isFullscreen() {
|
||||
return fullscreen;
|
||||
}
|
||||
@@ -132,14 +127,6 @@ public class LaunchOptions {
|
||||
this.fullscreen = fullscreen;
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
public GameDirType getGameDirType() {
|
||||
return gameDirType;
|
||||
}
|
||||
@@ -172,14 +159,6 @@ public class LaunchOptions {
|
||||
this.minecraftArgs = minecraftArgs;
|
||||
}
|
||||
|
||||
public boolean isCanceledWrapper() {
|
||||
return canceledWrapper;
|
||||
}
|
||||
|
||||
public void setCanceledWrapper(boolean canceledWrapper) {
|
||||
this.canceledWrapper = canceledWrapper;
|
||||
}
|
||||
|
||||
public String getServerIp() {
|
||||
return serverIp;
|
||||
}
|
||||
@@ -220,8 +199,6 @@ public class LaunchOptions {
|
||||
this.proxyPass = proxyPass;
|
||||
}
|
||||
|
||||
private String precalledCommand;
|
||||
|
||||
public String getPrecalledCommand() {
|
||||
return precalledCommand;
|
||||
}
|
||||
@@ -237,4 +214,12 @@ public class LaunchOptions {
|
||||
public void setLaunchVersion(String launchVersion) {
|
||||
this.launchVersion = launchVersion;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
+6
-4
@@ -15,13 +15,15 @@
|
||||
* 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.installers.optifine;
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class OptiFineVersion {
|
||||
|
||||
public String dl, ver, date, mirror, mcver;
|
||||
public enum LaunchingState {
|
||||
LoggingIn,
|
||||
GeneratingLaunchingCodes,
|
||||
DownloadingLibraries,
|
||||
DecompressingNatives
|
||||
}
|
||||
+8
-72
@@ -18,21 +18,10 @@
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Pack200;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.tukaani.xz.XZInputStream;
|
||||
import org.jackhuang.hellominecraft.util.tasks.download.FileDownloadTask;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -49,26 +38,18 @@ public class LibraryDownloadTask extends FileDownloadTask {
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
File packFile = new File(job.path.getParentFile(), job.path.getName() + ".pack.xz");
|
||||
/*
|
||||
* if (job.name.contains("typesafe")) {
|
||||
* download(new URL(job.url + ".pack.xz"), packFile);
|
||||
* unpackLibrary(job.path, packFile);
|
||||
* packFile.delete();
|
||||
* } else {
|
||||
*/
|
||||
if (job.name.startsWith("net.minecraftforge:forge:")) {
|
||||
String[] s = job.name.split(":");
|
||||
String name = job.lib.name;
|
||||
if (name.startsWith("net.minecraftforge:forge:")) {
|
||||
String[] s = name.split(":");
|
||||
if (s.length == 3)
|
||||
job.url = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" + s[2] + "/forge-" + s[2] + "-universal.jar";
|
||||
}
|
||||
if (job.name.startsWith("com.mumfrey:liteloader:")) {
|
||||
String[] s = job.name.split(":");
|
||||
if (name.startsWith("com.mumfrey:liteloader:")) {
|
||||
String[] s = name.split(":");
|
||||
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";
|
||||
}
|
||||
download(new URL(job.url), job.path);
|
||||
//}
|
||||
}
|
||||
|
||||
void download(URL url, File filePath) throws Throwable {
|
||||
@@ -77,54 +58,9 @@ public class LibraryDownloadTask extends FileDownloadTask {
|
||||
super.executeTask();
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedAssignment")
|
||||
public static void unpackLibrary(File output, File input)
|
||||
throws IOException {
|
||||
HMCLog.log("Unpacking " + input);
|
||||
if (output.exists())
|
||||
output.delete();
|
||||
|
||||
byte[] decompressed = IOUtils.readFully(new XZInputStream(new FileInputStream(input)));
|
||||
|
||||
String end = new String(decompressed, decompressed.length - 4, 4);
|
||||
if (!end.equals("SIGN")) {
|
||||
HMCLog.log("Unpacking failed, signature missing " + end);
|
||||
return;
|
||||
}
|
||||
|
||||
int x = decompressed.length;
|
||||
int len = decompressed[(x - 8)] & 0xFF | (decompressed[(x - 7)] & 0xFF) << 8 | (decompressed[(x - 6)] & 0xFF) << 16 | (decompressed[(x - 5)] & 0xFF) << 24;
|
||||
|
||||
File temp = File.createTempFile("art", ".pack");
|
||||
HMCLog.log(" Signed");
|
||||
HMCLog.log(" Checksum Length: " + len);
|
||||
HMCLog.log(" Total Length: " + (decompressed.length - len - 8));
|
||||
HMCLog.log(" Temp File: " + temp.getAbsolutePath());
|
||||
|
||||
byte[] checksums = Arrays.copyOfRange(decompressed, decompressed.length - len - 8, decompressed.length - 8);
|
||||
|
||||
try (OutputStream out = new FileOutputStream(temp)) {
|
||||
out.write(decompressed, 0, decompressed.length - len - 8);
|
||||
}
|
||||
decompressed = null;
|
||||
System.gc();
|
||||
|
||||
try (FileOutputStream jarBytes = new FileOutputStream(output); JarOutputStream jos = new JarOutputStream(jarBytes)) {
|
||||
|
||||
Pack200.newUnpacker().unpack(temp, jos);
|
||||
|
||||
JarEntry checksumsFile = new JarEntry("checksums.sha1");
|
||||
checksumsFile.setTime(0L);
|
||||
jos.putNextEntry(checksumsFile);
|
||||
jos.write(checksums);
|
||||
jos.closeEntry();
|
||||
}
|
||||
temp.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("download") + ": " + job.name;
|
||||
return C.i18n("download") + ": " + job.lib.name;
|
||||
}
|
||||
|
||||
}
|
||||
+28
-103
@@ -17,28 +17,19 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.func.Function;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.OS;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.assets.AssetsIndex;
|
||||
import org.jackhuang.hellominecraft.launcher.core.assets.AssetsObject;
|
||||
import org.jackhuang.hellominecraft.launcher.core.assets.IAssetsHandler;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -46,55 +37,41 @@ import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
*/
|
||||
public class MinecraftLoader extends AbstractMinecraftLoader {
|
||||
|
||||
DownloadType dt;
|
||||
String text;
|
||||
|
||||
public MinecraftLoader(LaunchOptions p, IMinecraftService provider, UserProfileProvider lr) throws GameException {
|
||||
super(p, provider, p.getLaunchVersion(), lr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeSelf(List<String> res) throws GameException {
|
||||
String library = options.isCanceledWrapper() ? "" : "-cp=";
|
||||
for (MinecraftLibrary l : version.libraries) {
|
||||
l.init();
|
||||
StringBuilder library = new StringBuilder("");
|
||||
for (MinecraftLibrary l : version.libraries)
|
||||
if (l.allow() && !l.isRequiredToUnzip())
|
||||
library += l.getFilePath(gameDir).getAbsolutePath() + File.pathSeparator;
|
||||
}
|
||||
library.append(l.getFilePath(gameDir).getAbsolutePath()).append(File.pathSeparator);
|
||||
File f = version.getJar(service.baseDirectory());
|
||||
if (!f.exists())
|
||||
throw new GameException("Minecraft jar does not exists");
|
||||
library += IOUtils.tryGetCanonicalFilePath(f) + File.pathSeparator;
|
||||
library = library.substring(0, library.length() - File.pathSeparator.length());
|
||||
if (options.isCanceledWrapper())
|
||||
res.add("-cp");
|
||||
res.add(library);
|
||||
String mainClass = version.mainClass;
|
||||
res.add((options.isCanceledWrapper() ? "" : "-mainClass=") + mainClass);
|
||||
library.append(IOUtils.tryGetCanonicalFilePath(f)).append(File.pathSeparator);
|
||||
res.add("-cp");
|
||||
res.add(library.toString().substring(0, library.length() - File.pathSeparator.length()));
|
||||
res.add(version.mainClass);
|
||||
|
||||
String[] splitted = StrUtils.tokenize(version.minecraftArguments);
|
||||
|
||||
if (!checkAssetsExist())
|
||||
if (MessageBox.Show(C.i18n("assets.no_assets"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
||||
IAssetsHandler.ASSETS_HANDLER.getList(version, service.asset()).subscribe(a -> {
|
||||
});
|
||||
TaskWindow.getInstance().addTask(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider())).start();
|
||||
}
|
||||
|
||||
String game_assets = reconstructAssets().getAbsolutePath();
|
||||
String game_assets = assetProvider.apply(version);
|
||||
|
||||
for (String t : splitted) {
|
||||
t = t.replace("${auth_player_name}", lr.getUserName());
|
||||
t = t.replace("${auth_session}", lr.getSession());
|
||||
t = t.replace("${auth_uuid}", lr.getUserId());
|
||||
t = t.replace("${version_name}", Main.makeTitle());
|
||||
t = t.replace("${version_name}", options.getVersionName());
|
||||
t = t.replace("${profile_name}", options.getName());
|
||||
t = t.replace("${version_type}", options.getType());
|
||||
t = t.replace("${game_directory}", service.version().getRunDirectory(version.id).getAbsolutePath());
|
||||
t = t.replace("${game_assets}", game_assets);
|
||||
t = t.replace("${assets_root}", service.asset().getAssets().getAbsolutePath());
|
||||
t = t.replace("${auth_access_token}", lr.getAccessToken());
|
||||
t = t.replace("${user_type}", lr.getUserType());
|
||||
t = t.replace("${assets_index_name}", version.getAssets());
|
||||
t = t.replace("${assets_index_name}", version.getAssetsIndex().getId());
|
||||
t = t.replace("${user_properties}", lr.getUserProperties());
|
||||
res.add(t);
|
||||
}
|
||||
@@ -111,7 +88,7 @@ public class MinecraftLoader extends AbstractMinecraftLoader {
|
||||
|
||||
try {
|
||||
if (OS.os() == OS.OSX) {
|
||||
list.add("-Xdock:icon=" + service.asset().getAssetObject(version.assets, "icons/minecraft.icns").getAbsolutePath());
|
||||
list.add("-Xdock:icon=" + service.asset().getAssetObject(version.getAssetsIndex().getId(), "icons/minecraft.icns").getAbsolutePath());
|
||||
list.add("-Xdock:name=Minecraft");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -119,68 +96,16 @@ public class MinecraftLoader extends AbstractMinecraftLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkAssetsExist() {
|
||||
File assetsDir = new File(service.baseDirectory(), "assets");
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectDir = new File(assetsDir, "objects");
|
||||
File indexFile = new File(indexDir, version.getAssets() + ".json");
|
||||
private final Function<MinecraftVersion, String> DEFAULT_ASSET_PROVIDER = t -> {
|
||||
return new File(service.baseDirectory(), "assets").getAbsolutePath();
|
||||
};
|
||||
|
||||
if (!assetsDir.exists() && !indexFile.isFile())
|
||||
return false;
|
||||
private Function<MinecraftVersion, String> assetProvider = DEFAULT_ASSET_PROVIDER;
|
||||
|
||||
try {
|
||||
AssetsIndex index = (AssetsIndex) C.gson.fromJson(FileUtils.readFileToString(indexFile, "UTF-8"), AssetsIndex.class);
|
||||
|
||||
if (index == null)
|
||||
return false;
|
||||
for (Map.Entry entry : index.getFileMap().entrySet())
|
||||
if (!new File(new File(objectDir, ((AssetsObject) entry.getValue()).getHash().substring(0, 2)), ((AssetsObject) entry.getValue()).getHash()).exists())
|
||||
return false;
|
||||
return true;
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private File reconstructAssets() {
|
||||
File assetsDir = new File(service.baseDirectory(), "assets");
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectDir = new File(assetsDir, "objects");
|
||||
String assetVersion = version.getAssets();
|
||||
File indexFile = new File(indexDir, assetVersion + ".json");
|
||||
File virtualRoot = new File(new File(assetsDir, "virtual"), assetVersion);
|
||||
|
||||
if (!indexFile.isFile()) {
|
||||
HMCLog.warn("No assets index file " + virtualRoot + "; can't reconstruct assets");
|
||||
return assetsDir;
|
||||
}
|
||||
|
||||
try {
|
||||
AssetsIndex index = (AssetsIndex) C.gson.fromJson(FileUtils.readFileToString(indexFile, "UTF-8"), AssetsIndex.class);
|
||||
|
||||
if (index == null)
|
||||
return assetsDir;
|
||||
if (index.isVirtual()) {
|
||||
int cnt = 0;
|
||||
HMCLog.log("Reconstructing virtual assets folder at " + virtualRoot);
|
||||
int tot = index.getFileMap().entrySet().size();
|
||||
for (Map.Entry entry : index.getFileMap().entrySet()) {
|
||||
File target = new File(virtualRoot, (String) entry.getKey());
|
||||
File original = new File(new File(objectDir, ((AssetsObject) entry.getValue()).getHash().substring(0, 2)), ((AssetsObject) entry.getValue()).getHash());
|
||||
if (original.exists()) {
|
||||
cnt++;
|
||||
if (!target.isFile())
|
||||
FileUtils.copyFile(original, target, false);
|
||||
}
|
||||
}
|
||||
// If the scale new format existent file is lower then 0.1, use the old format.
|
||||
if (cnt * 10 < tot)
|
||||
return assetsDir;
|
||||
}
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
HMCLog.warn("Failed to create virutal assets.", e);
|
||||
}
|
||||
|
||||
return virtualRoot;
|
||||
public void setAssetProvider(Function<MinecraftVersion, String> assetProvider) {
|
||||
if (assetProvider == null)
|
||||
this.assetProvider = DEFAULT_ASSET_PROVIDER;
|
||||
else
|
||||
this.assetProvider = assetProvider;
|
||||
}
|
||||
}
|
||||
+20
-22
@@ -25,12 +25,11 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftModService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.ModInfo;
|
||||
import org.jackhuang.hellominecraft.utils.code.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.code.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -59,22 +58,18 @@ public class MinecraftModService extends IMinecraftModService {
|
||||
File[] fs = modsFolder.listFiles();
|
||||
if (fs != null)
|
||||
for (File f : fs)
|
||||
if (ModInfo.isFileMod(f)) {
|
||||
ModInfo m = ModInfo.readModInfo(f);
|
||||
if (m != null)
|
||||
mods.add(m);
|
||||
} else if (f.isDirectory()) {
|
||||
if (ModInfo.isFileMod(f))
|
||||
mods.add(ModInfo.readModInfo(f));
|
||||
else if (f.isDirectory()) {
|
||||
File[] ss = f.listFiles();
|
||||
if (ss != null)
|
||||
for (File ff : ss)
|
||||
if (ModInfo.isFileMod(ff)) {
|
||||
ModInfo m = ModInfo.readModInfo(ff);
|
||||
if (m != null)
|
||||
mods.add(m);
|
||||
}
|
||||
if (ModInfo.isFileMod(ff))
|
||||
mods.add(ModInfo.readModInfo(ff));
|
||||
}
|
||||
Collections.sort(mods);
|
||||
return modCache.put(id, mods);
|
||||
modCache.put(id, mods);
|
||||
return mods;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,10 +77,11 @@ public class MinecraftModService extends IMinecraftModService {
|
||||
try {
|
||||
if (!ModInfo.isFileMod(f))
|
||||
return false;
|
||||
if (!modCache.containsKey(id))
|
||||
recacheMods(id);
|
||||
File modsFolder = service.version().getRunDirectory(id, "mods");
|
||||
if (modsFolder == null)
|
||||
return false;
|
||||
modsFolder.mkdirs();
|
||||
if (!modsFolder.exists() && !modsFolder.mkdirs())
|
||||
HMCLog.warn("Failed to make directories: " + modsFolder);
|
||||
File newf = new File(modsFolder, f.getName());
|
||||
FileUtils.copyFile(f, newf);
|
||||
ModInfo i = ModInfo.readModInfo(f);
|
||||
@@ -102,10 +98,12 @@ public class MinecraftModService extends IMinecraftModService {
|
||||
if (rows.length == 0)
|
||||
return;
|
||||
for (Object r : rows)
|
||||
if (r instanceof ModInfo)
|
||||
((ModInfo) r).location.delete();
|
||||
else if (r instanceof Number)
|
||||
getMods(id).get(((Number) r).intValue()).location.delete();
|
||||
if (r instanceof ModInfo) {
|
||||
if (!((ModInfo) r).location.delete())
|
||||
HMCLog.warn("Failed to delete mod" + r);
|
||||
} else if (r instanceof Number)
|
||||
if (!getMods(id).get(((Number) r).intValue()).location.delete())
|
||||
HMCLog.warn("Failed to delete mod " + r + ", maybe not a file?");
|
||||
recacheMods(id);
|
||||
}
|
||||
|
||||
|
||||
+12
-11
@@ -15,20 +15,21 @@
|
||||
* 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;
|
||||
package org.jackhuang.hellominecraft.launcher.core.mod;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -56,7 +57,7 @@ public class ModInfo implements Comparable<ModInfo> {
|
||||
|
||||
@Override
|
||||
public int compareTo(ModInfo o) {
|
||||
return getFileName().toLowerCase().compareTo(o.getFileName().toLowerCase());
|
||||
return getFileName().compareToIgnoreCase(o.getFileName());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -102,12 +103,13 @@ public class ModInfo implements Comparable<ModInfo> {
|
||||
return name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith("litemod");
|
||||
}
|
||||
|
||||
private static final Type TYPE = new TypeToken<List<ModInfo>>() {
|
||||
}.getType();
|
||||
|
||||
private static ModInfo getForgeModInfo(File f, ZipFile jar, ZipEntry entry) throws IOException {
|
||||
ModInfo i = new ModInfo();
|
||||
i.location = f;
|
||||
List<ModInfo> m = C.gson.fromJson(new InputStreamReader(jar.getInputStream(entry)),
|
||||
new TypeToken<List<ModInfo>>() {
|
||||
}.getType());
|
||||
List<ModInfo> m = C.GSON.fromJson(new InputStreamReader(jar.getInputStream(entry), "UTF-8"), TYPE);
|
||||
if (m != null && m.size() > 0) {
|
||||
i = m.get(0);
|
||||
i.location = f;
|
||||
@@ -116,8 +118,7 @@ public class ModInfo implements Comparable<ModInfo> {
|
||||
}
|
||||
|
||||
private static ModInfo getLiteLoaderModInfo(File f, ZipFile jar, ZipEntry entry) throws IOException {
|
||||
ModInfo m = C.gson.fromJson(new InputStreamReader(jar.getInputStream(entry)),
|
||||
ModInfo.class);
|
||||
ModInfo m = C.GSON.fromJson(new InputStreamReader(jar.getInputStream(entry), "UTF-8"), ModInfo.class);
|
||||
if (m == null)
|
||||
m = new ModInfo();
|
||||
m.location = f;
|
||||
+185
-60
@@ -17,25 +17,37 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.mod;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import java.util.zip.ZipFile;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.system.Compressor;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.ZipEngine;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftVersionRequest;
|
||||
import org.jackhuang.hellominecraft.util.func.BiFunction;
|
||||
import org.jackhuang.hellominecraft.util.func.CallbackIO;
|
||||
import org.jackhuang.hellominecraft.util.system.Compressor;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.ZipEngine;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.util.ui.WebPage;
|
||||
import org.jackhuang.hellominecraft.util.MinecraftVersionRequest;
|
||||
import org.jackhuang.hellominecraft.util.tasks.NoShownTaskException;
|
||||
|
||||
/**
|
||||
* A mod pack(*.zip) includes these things:
|
||||
@@ -57,61 +69,169 @@ import org.jackhuang.hellominecraft.utils.version.MinecraftVersionRequest;
|
||||
*/
|
||||
public final class ModpackManager {
|
||||
|
||||
public static void install(File input, IMinecraftService service, String id) throws IOException, FileAlreadyExistsException {
|
||||
File versions = new File(service.baseDirectory(), "versions");
|
||||
File oldFile = new File(versions, "minecraft"), newFile = null;
|
||||
if (oldFile.exists()) {
|
||||
newFile = new File(versions, "minecraft-" + System.currentTimeMillis());
|
||||
if (newFile.isDirectory())
|
||||
FileUtils.deleteDirectory(newFile);
|
||||
else if (newFile.isFile())
|
||||
newFile.delete();
|
||||
oldFile.renameTo(newFile);
|
||||
}
|
||||
/**
|
||||
* Install the compressed modpack.
|
||||
*
|
||||
* @param input modpack.zip
|
||||
* @param service MinecraftService, whose version service only supports
|
||||
* MinecraftVersionManager.
|
||||
* @param id new version id, if null, will use suggested name from
|
||||
* modpack
|
||||
*
|
||||
* @return The installing Task, may take long time, please consider
|
||||
* TaskWindow.
|
||||
*/
|
||||
public static Task install(JFrame parFrame, final File input, final IMinecraftService service, final String idFUCK) {
|
||||
return new Task() {
|
||||
Collection<Task> c = new ArrayList<>();
|
||||
|
||||
File preVersion = new File(versions, id), preVersionRenamed = null;
|
||||
if (preVersion.exists()) {
|
||||
String preId = id + "-" + System.currentTimeMillis();
|
||||
preVersion.renameTo(preVersionRenamed = new File(versions, preId));
|
||||
new File(preVersionRenamed, id + ".json").renameTo(new File(preVersionRenamed, preId + ".json"));
|
||||
new File(preVersionRenamed, id + ".jar").renameTo(new File(preVersionRenamed, preId + ".jar"));
|
||||
}
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
String id = idFUCK;
|
||||
String description = C.i18n("modpack.task.install.will");
|
||||
|
||||
try {
|
||||
AtomicInteger b = new AtomicInteger(0);
|
||||
HMCLog.log("Decompressing modpack");
|
||||
Compressor.unzip(input, versions, t -> {
|
||||
if (t.equals("minecraft/pack.json"))
|
||||
b.incrementAndGet();
|
||||
return true;
|
||||
}, true);
|
||||
if (b.get() < 1)
|
||||
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_json"));
|
||||
File nowFile = new File(versions, id);
|
||||
oldFile.renameTo(nowFile);
|
||||
// Read modpack name and description from `modpack.json`
|
||||
try (ZipFile zip = new ZipFile(input)) {
|
||||
HashMap map = C.GSON.fromJson(new InputStreamReader(zip.getInputStream(zip.getEntry("modpack.json")), "UTF-8"), HashMap.class);
|
||||
if (map != null) {
|
||||
if (id == null)
|
||||
if (map.containsKey("name") && map.get("name") instanceof String)
|
||||
id = (String) map.get("name");
|
||||
if (id != null)
|
||||
description += id;
|
||||
if (map.containsKey("description") && map.get("description") instanceof String)
|
||||
description += "\n" + (String) map.get("description");
|
||||
}
|
||||
if (id == null)
|
||||
throw new IllegalStateException("Illegal modpack id!");
|
||||
}
|
||||
|
||||
File json = new File(nowFile, "pack.json");
|
||||
MinecraftVersion mv = C.gson.fromJson(FileUtils.readFileToString(json), MinecraftVersion.class);
|
||||
if (mv.jar == null)
|
||||
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_jar"));
|
||||
service.download().downloadMinecraftJarTo(mv.jar, new File(nowFile, id + ".jar"));
|
||||
mv.jar = null;
|
||||
FileUtils.writeStringToFile(json, C.gsonPrettyPrinting.toJson(mv));
|
||||
json.renameTo(new File(nowFile, id + ".json"));
|
||||
// Show a window to let the user know that what and how the modpack is.
|
||||
Object msgs[] = new Object[2];
|
||||
msgs[0] = C.i18n("modpack.task.install");
|
||||
msgs[1] = new WebPage(description);
|
||||
((WebPage) msgs[1]).setPreferredSize(new Dimension(800, 350));
|
||||
int result = JOptionPane.showOptionDialog(parFrame, msgs, (String) msgs[0], JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
|
||||
if (result == JOptionPane.NO_OPTION)
|
||||
throw new NoShownTaskException("Operation was canceled by user.");
|
||||
|
||||
if (preVersionRenamed != null) {
|
||||
File presaves = new File(preVersionRenamed, "saves");
|
||||
File saves = new File(nowFile, "saves");
|
||||
if (presaves.exists()) {
|
||||
FileUtils.deleteDirectory(saves);
|
||||
FileUtils.copyDirectory(presaves, saves);
|
||||
File versions = new File(service.baseDirectory(), "versions");
|
||||
|
||||
// `minecraft` folder is the existent root folder of the modpack
|
||||
// Then we will decompress the modpack and there would be a folder named `minecraft`
|
||||
// So if `minecraft` folder does exist, backup it and then restore it.
|
||||
File oldFile = new File(versions, "minecraft"), newFile = null;
|
||||
if (oldFile.exists()) {
|
||||
newFile = new File(versions, "minecraft-" + System.currentTimeMillis());
|
||||
if (newFile.isDirectory())
|
||||
FileUtils.deleteDirectory(newFile);
|
||||
else if (newFile.isFile())
|
||||
if (!newFile.delete())
|
||||
HMCLog.warn("Failed to delete file " + newFile);
|
||||
if (!oldFile.renameTo(newFile))
|
||||
HMCLog.warn("Failed to rename " + oldFile + " to " + newFile);
|
||||
}
|
||||
|
||||
// If the user install the modpack into an existent version, maybe it wants to update the modpack
|
||||
// So backup the game, copy the saved games.
|
||||
File preVersion = new File(versions, id), preVersionRenamed = null;
|
||||
if (preVersion.exists()) {
|
||||
HMCLog.log("Backing up the game");
|
||||
String preId = id + "-" + System.currentTimeMillis();
|
||||
if (!preVersion.renameTo(preVersionRenamed = new File(versions, preId)))
|
||||
HMCLog.warn("Failed to rename pre-version folder " + preVersion + " to a temp folder " + preVersionRenamed);
|
||||
if (!new File(preVersionRenamed, id + ".json").renameTo(new File(preVersionRenamed, preId + ".json")))
|
||||
HMCLog.warn("Failed to rename pre json to new json");
|
||||
|
||||
if (!new File(preVersionRenamed, id + ".jar").renameTo(new File(preVersionRenamed, preId + ".jar")))
|
||||
HMCLog.warn("Failed to rename pre jar to new jar");
|
||||
}
|
||||
|
||||
try {
|
||||
final AtomicInteger b = new AtomicInteger(0);
|
||||
HMCLog.log("Decompressing modpack");
|
||||
Compressor.unzip(input, versions, t -> {
|
||||
if (t.equals("minecraft/pack.json"))
|
||||
b.incrementAndGet();
|
||||
return true;
|
||||
}, true);
|
||||
|
||||
// No pack.json here, illegal modpack.
|
||||
if (b.get() < 1)
|
||||
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_json"));
|
||||
File nowFile = new File(versions, id);
|
||||
if (oldFile.exists() && !oldFile.renameTo(nowFile))
|
||||
HMCLog.warn("Failed to rename incorrect json " + oldFile + " to " + nowFile);
|
||||
|
||||
File json = new File(nowFile, "pack.json");
|
||||
MinecraftVersion mv = C.GSON.fromJson(FileUtils.readFileToString(json), MinecraftVersion.class);
|
||||
if (mv.jar == null)
|
||||
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_jar"));
|
||||
|
||||
c.add(service.download().downloadMinecraftJar(mv, new File(nowFile, id + ".jar")));
|
||||
mv.jar = null;
|
||||
FileUtils.writeStringToFile(json, C.GSON.toJson(mv));
|
||||
if (!json.renameTo(new File(nowFile, id + ".json")))
|
||||
HMCLog.warn("Failed to rename pack.json to new id");
|
||||
|
||||
// Restore the saved game from the old version.
|
||||
if (preVersionRenamed != null) {
|
||||
HMCLog.log("Restoring saves");
|
||||
File presaves = new File(preVersionRenamed, "saves");
|
||||
File saves = new File(nowFile, "saves");
|
||||
if (presaves.exists()) {
|
||||
FileUtils.deleteDirectory(saves);
|
||||
FileUtils.copyDirectory(presaves, saves);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
FileUtils.deleteDirectoryQuietly(oldFile);
|
||||
if (newFile != null)
|
||||
newFile.renameTo(oldFile);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
FileUtils.deleteDirectoryQuietly(oldFile);
|
||||
if (newFile != null)
|
||||
newFile.renameTo(oldFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("modpack.task.install");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task> getAfterTasks() {
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public static final List<String> MODPACK_BLACK_LIST = Arrays.asList(new String[] { "usernamecache.json", "asm", "logs", "backups", "versions", "assets", "usercache.json", "libraries", "crash-reports", "launcher_profiles.json", "NVIDIA", "AMD", "TCNodeTracker", "screenshots", "natives", "native", "$native", "pack.json", "launcher.jar", "minetweaker.log", "launcher.pack.lzma", "hmclmc.log" });
|
||||
public static final List<String> MODPACK_SUGGESTED_BLACK_LIST = Arrays.asList(new String[] { "fonts", "saves", "servers.dat", "options.txt", "optionsof.txt", "journeymap", "optionsshaders.txt", "mods/VoxelMods" });
|
||||
|
||||
/**
|
||||
* < String, Boolean, Boolean >: Folder/File name, Is Directory,
|
||||
* Return 0: non blocked, 1: non shown, 2: suggested, checked.
|
||||
*/
|
||||
public static final BiFunction<String, Boolean, Integer> MODPACK_PREDICATE = (String x, Boolean y) -> {
|
||||
if (ModpackManager.MODPACK_BLACK_LIST_PREDICATE.apply(x, y))
|
||||
return 1;
|
||||
if (ModpackManager.MODPACK_SUGGESTED_BLACK_LIST_PREDICATE.apply(x, y))
|
||||
return 2;
|
||||
return 0;
|
||||
};
|
||||
|
||||
public static final BiFunction<String, Boolean, Boolean> MODPACK_BLACK_LIST_PREDICATE = modpackPredicateMaker(MODPACK_BLACK_LIST);
|
||||
public static final BiFunction<String, Boolean, Boolean> MODPACK_SUGGESTED_BLACK_LIST_PREDICATE = modpackPredicateMaker(MODPACK_SUGGESTED_BLACK_LIST);
|
||||
|
||||
private static BiFunction<String, Boolean, Boolean> modpackPredicateMaker(final List<String> l) {
|
||||
return (String x, Boolean y) -> {
|
||||
for (String s : l)
|
||||
if (y) {
|
||||
if (x.startsWith(s + "/"))
|
||||
return true;
|
||||
} else if (x.equals(s))
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,10 +244,12 @@ public final class ModpackManager {
|
||||
*
|
||||
* @throws IOException if create tmp directory failed
|
||||
*/
|
||||
public static void export(File output, IMinecraftProvider provider, String version, List<String> blacklist) throws IOException, GameException {
|
||||
ArrayList<String> b = new ArrayList<>(Arrays.asList(new String[] { "usernamecache.json", "asm", "logs", "backups", "versions", "assets", "usercache.json", "libraries", "crash-reports", "launcher_profiles.json", "NVIDIA", "TCNodeTracker" }));
|
||||
public static void export(File output, IMinecraftProvider provider, String version, List<String> blacklist, Map modpackJson, CallbackIO<ZipEngine> callback) throws IOException, GameException {
|
||||
final ArrayList<String> b = new ArrayList<>(MODPACK_BLACK_LIST);
|
||||
if (blacklist != null)
|
||||
b.addAll(blacklist);
|
||||
b.add(version + ".jar");
|
||||
b.add(version + ".json");
|
||||
HMCLog.log("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
|
||||
ZipEngine zip = null;
|
||||
try {
|
||||
@@ -143,12 +265,15 @@ public final class ModpackManager {
|
||||
});
|
||||
|
||||
MinecraftVersion mv = provider.getVersionById(version).resolve(provider);
|
||||
mv.runDir = "version";
|
||||
MinecraftVersionRequest r = MinecraftVersionRequest.minecraftVersion(provider.getMinecraftJar(version));
|
||||
if (r.type != MinecraftVersionRequest.OK)
|
||||
throw new FileSystemException(C.i18n("modpack.cannot_read_version") + ": " + MinecraftVersionRequest.getResponse(r));
|
||||
mv.jar = r.version;
|
||||
zip.putTextFile(C.gsonPrettyPrinting.toJson(mv), "minecraft/pack.json");
|
||||
mv.runDir = "version";
|
||||
zip.putTextFile(C.GSON.toJson(mv), "minecraft/pack.json");
|
||||
zip.putTextFile(C.GSON.toJson(modpackJson), "modpack.json");
|
||||
if (callback != null)
|
||||
callback.call(zip);
|
||||
} finally {
|
||||
if (zip != null)
|
||||
zip.closeFile();
|
||||
|
||||
+5
-2
@@ -19,7 +19,8 @@ package org.jackhuang.hellominecraft.launcher.core.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.AssetIndexDownloadInfo;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -44,7 +45,9 @@ public abstract class IMinecraftAssetService extends IMinecraftBasicService {
|
||||
*/
|
||||
public abstract boolean refreshAssetsIndex(String a);
|
||||
|
||||
public abstract boolean downloadMinecraftAssetsIndex(String assetsId);
|
||||
public abstract boolean downloadMinecraftAssetsIndexAsync(AssetIndexDownloadInfo assetsId);
|
||||
|
||||
public abstract Task downloadMinecraftAssetsIndex(AssetIndexDownloadInfo assetsId);
|
||||
|
||||
public abstract File getAssetObject(String assetVersion, String name) throws IOException;
|
||||
}
|
||||
+4
-9
@@ -22,8 +22,7 @@ import java.util.List;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftRemoteVersion;
|
||||
import rx.Observable;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -35,13 +34,11 @@ public abstract class IMinecraftDownloadService extends IMinecraftBasicService {
|
||||
super(service);
|
||||
}
|
||||
|
||||
public abstract MinecraftVersion downloadMinecraft(String id);
|
||||
public abstract Task downloadMinecraft(String id);
|
||||
|
||||
public abstract boolean downloadMinecraftJar(String id);
|
||||
public abstract Task downloadMinecraftJar(MinecraftVersion mv, File f);
|
||||
|
||||
public abstract boolean downloadMinecraftJarTo(String id, File f);
|
||||
|
||||
public abstract boolean downloadMinecraftVersionJson(String id);
|
||||
public abstract Task downloadMinecraftVersionJson(String id);
|
||||
|
||||
/**
|
||||
* Get the libraries that need to download.
|
||||
@@ -50,6 +47,4 @@ public abstract class IMinecraftDownloadService extends IMinecraftBasicService {
|
||||
*/
|
||||
public abstract List<DownloadLibraryJob> getDownloadLibraries(MinecraftVersion mv) throws GameException;
|
||||
|
||||
public abstract Observable<MinecraftRemoteVersion> getRemoteVersions();
|
||||
|
||||
}
|
||||
+4
-4
@@ -17,9 +17,9 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.service;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerType;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerType;
|
||||
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.util.tasks.Task;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -35,7 +35,7 @@ public abstract class IMinecraftInstallerService extends IMinecraftBasicService
|
||||
|
||||
public abstract Task downloadForge(String installId, InstallerVersionList.InstallerVersion v);
|
||||
|
||||
public abstract Task downloadOptifine(String installId, InstallerVersionList.InstallerVersion v);
|
||||
public abstract Task downloadOptiFine(String installId, InstallerVersionList.InstallerVersion v);
|
||||
|
||||
public abstract Task downloadLiteLoader(String installId, InstallerVersionList.InstallerVersion v);
|
||||
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ package org.jackhuang.hellominecraft.launcher.core.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.launcher.core.ModInfo;
|
||||
import org.jackhuang.hellominecraft.launcher.core.mod.ModInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
+16
-9
@@ -21,9 +21,10 @@ import java.io.File;
|
||||
import java.util.Collection;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.DecompressLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.GameDirType;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import org.jackhuang.hellominecraft.util.EventHandler;
|
||||
import org.jackhuang.hellominecraft.util.func.Consumer;
|
||||
import org.jackhuang.hellominecraft.util.func.Predicate;
|
||||
|
||||
/**
|
||||
* Provide everything of the Minecraft of a Profile.
|
||||
@@ -54,6 +55,8 @@ public abstract class IMinecraftProvider {
|
||||
*/
|
||||
public abstract File getRunDirectory(String id);
|
||||
|
||||
public abstract File versionRoot(String id);
|
||||
|
||||
public File getRunDirectory(String id, String subFolder) {
|
||||
return new File(getRunDirectory(id), subFolder);
|
||||
}
|
||||
@@ -91,12 +94,6 @@ public abstract class IMinecraftProvider {
|
||||
*/
|
||||
public abstract File getMinecraftJar(String id);
|
||||
|
||||
protected GameDirType gameDirType = GameDirType.ROOT_FOLDER;
|
||||
|
||||
public void setGameDirType(GameDirType gameDirType) {
|
||||
this.gameDirType = gameDirType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename version
|
||||
*
|
||||
@@ -121,7 +118,7 @@ public abstract class IMinecraftProvider {
|
||||
*
|
||||
* @return the version
|
||||
*/
|
||||
public abstract MinecraftVersion getOneVersion();
|
||||
public abstract MinecraftVersion getOneVersion(Predicate<MinecraftVersion> p);
|
||||
|
||||
/**
|
||||
* All Minecraft version in this profile.
|
||||
@@ -148,9 +145,15 @@ public abstract class IMinecraftProvider {
|
||||
|
||||
/**
|
||||
* Refind the versions in this profile.
|
||||
* Must call onRefreshingVersions, onRefreshedVersions, onLoadedVersion
|
||||
* Events.
|
||||
*/
|
||||
public abstract void refreshVersions();
|
||||
|
||||
public final EventHandler<IMinecraftService> onRefreshingVersions = new EventHandler<>(this),
|
||||
onRefreshedVersions = new EventHandler<>(this);
|
||||
public final EventHandler<String> onLoadedVersion = new EventHandler<>(this);
|
||||
|
||||
/**
|
||||
* Clean redundant files.
|
||||
*/
|
||||
@@ -163,4 +166,8 @@ public abstract class IMinecraftProvider {
|
||||
*/
|
||||
public abstract boolean onLaunch();
|
||||
|
||||
public File baseDirectory() {
|
||||
return service.baseDirectory();
|
||||
}
|
||||
|
||||
}
|
||||
Executable → Regular
+17
-12
@@ -15,31 +15,36 @@
|
||||
* 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.utils.tasks;
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import rx.Observable;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class TaskObservable<T> extends TaskInfo {
|
||||
public class AssetIndexDownloadInfo extends GameDownloadInfo {
|
||||
|
||||
private final Observable<T> r;
|
||||
int totalSize;
|
||||
|
||||
public TaskObservable(String info, Observable<T> r) {
|
||||
super(info);
|
||||
this.r = r;
|
||||
public AssetIndexDownloadInfo() {
|
||||
}
|
||||
|
||||
public TaskObservable(Observable<T> r) {
|
||||
this("TaskObservable", r);
|
||||
public AssetIndexDownloadInfo(String id) {
|
||||
this.id = id;
|
||||
url = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() {
|
||||
r.subscribe(t -> {
|
||||
});
|
||||
public String getCustomizedURL(DownloadType dt) {
|
||||
return dt.getProvider().getIndexesDownloadURL() + id + ".json";
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getTotalSize() {
|
||||
return totalSize;
|
||||
}
|
||||
}
|
||||
+13
-5
@@ -26,12 +26,20 @@ import java.io.File;
|
||||
public class DecompressLibraryJob {
|
||||
|
||||
public File[] decompressFiles;
|
||||
public String[][] extractRules;
|
||||
public File decompressTo;
|
||||
public Extract[] extractRules;
|
||||
private File decompressTo;
|
||||
|
||||
public DecompressLibraryJob(File[] decompressFiles, String[][] extractRules, File decompressTo) {
|
||||
this.decompressFiles = decompressFiles;
|
||||
this.extractRules = extractRules;
|
||||
public DecompressLibraryJob(File[] decompressFiles, Extract[] extractRules, File decompressTo) {
|
||||
this.decompressFiles = decompressFiles.clone();
|
||||
this.extractRules = extractRules.clone();
|
||||
this.decompressTo = decompressTo;
|
||||
}
|
||||
|
||||
public File getDecompressTo() {
|
||||
return decompressTo;
|
||||
}
|
||||
|
||||
public void setDecompressTo(File decompressTo) {
|
||||
this.decompressTo = decompressTo;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,21 +17,30 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Extract extends Object implements Cloneable {
|
||||
public class Extract implements Cloneable {
|
||||
|
||||
String[] exclude;
|
||||
public List<String> exclude = new ArrayList<>();
|
||||
|
||||
public boolean allow(String path) {
|
||||
return !StrUtils.startsWithOne(exclude, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object clone() {
|
||||
Extract e = new Extract();
|
||||
e.exclude = exclude == null ? null : Arrays.copyOf(exclude, exclude.length);
|
||||
return e;
|
||||
@SuppressWarnings("CloneDeclaresCloneNotSupported")
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new InternalError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class GameDownloadInfo implements Cloneable {
|
||||
|
||||
public String sha1;
|
||||
public int size;
|
||||
protected String url;
|
||||
|
||||
/**
|
||||
* Ready for AssetIndexDownloadInfo, and GameDownloadInfo also need this.
|
||||
*/
|
||||
public String id = null;
|
||||
|
||||
/**
|
||||
* Get the game download url.
|
||||
*
|
||||
* @param dt where to download?
|
||||
*
|
||||
* @return the download url
|
||||
*/
|
||||
public String getUrl(DownloadType dt) {
|
||||
return getUrl(dt, dt.getProvider().isAllowedToUseSelfURL());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the game download url.
|
||||
*
|
||||
* @param dt where to download?
|
||||
* @param allowSelf allow this game to be downloaded from its modified url?
|
||||
*
|
||||
* @return the download url
|
||||
*/
|
||||
public String getUrl(DownloadType dt, boolean allowSelf) {
|
||||
if (url != null && allowSelf)
|
||||
return dt.getProvider().getParsedDownloadURL(url);
|
||||
else
|
||||
return getCustomizedURL(dt);
|
||||
}
|
||||
|
||||
protected String getCustomizedURL(DownloadType dt) {
|
||||
return dt.getProvider().getVersionsDownloadURL() + id + "/" + id + ".jar";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new Error(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-6
@@ -18,7 +18,6 @@
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -34,16 +33,14 @@ public abstract class IMinecraftLibrary implements Cloneable {
|
||||
|
||||
public abstract boolean isRequiredToUnzip();
|
||||
|
||||
public abstract String[] getDecompressExtractRules();
|
||||
public abstract Extract getDecompressExtractRules();
|
||||
|
||||
public abstract void init();
|
||||
public abstract LibraryDownloadInfo getDownloadInfo();
|
||||
|
||||
public abstract boolean allow();
|
||||
|
||||
public abstract File getFilePath(File gameDir);
|
||||
|
||||
public abstract String getDownloadURL(String urlBase, DownloadType downloadType);
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof MinecraftLibrary)
|
||||
@@ -59,5 +56,12 @@ public abstract class IMinecraftLibrary implements Cloneable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Object clone();
|
||||
@SuppressWarnings("CloneDeclaresCloneNotSupported")
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new InternalError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable → Regular
+5
-2
@@ -17,11 +17,14 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class OS {
|
||||
public class LibrariesDownloadInfo {
|
||||
|
||||
public String version, name;
|
||||
Map<String, LibraryDownloadInfo> classifiers;
|
||||
LibraryDownloadInfo artifact;
|
||||
}
|
||||
Executable → Regular
+19
-10
@@ -15,21 +15,30 @@
|
||||
* 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.installers.forge;
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Install {
|
||||
public class LibraryDownloadInfo extends GameDownloadInfo {
|
||||
|
||||
public String profileName;
|
||||
public String target;
|
||||
public String path;
|
||||
public String version;
|
||||
public String filePath;
|
||||
public String welcome;
|
||||
public String minecraft;
|
||||
public String mirrorList;
|
||||
public String logo;
|
||||
public String forgeURL;
|
||||
|
||||
@Override
|
||||
public String getUrl(DownloadType dt, boolean allowSelf) {
|
||||
String myURL = (forgeURL == null ? dt.getProvider().getLibraryDownloadURL() : forgeURL) + "/";
|
||||
if (StrUtils.isNotBlank(url) && allowSelf)
|
||||
myURL = url;
|
||||
if (!myURL.endsWith(".jar"))
|
||||
if (path == null)
|
||||
return null;
|
||||
else
|
||||
myURL += path.replace('\\', '/');
|
||||
return myURL;
|
||||
}
|
||||
}
|
||||
+48
-56
@@ -19,11 +19,10 @@ package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.utils.system.Platform;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import java.util.HashMap;
|
||||
import org.jackhuang.hellominecraft.util.system.OS;
|
||||
import org.jackhuang.hellominecraft.util.system.Platform;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -32,30 +31,23 @@ import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
public class MinecraftLibrary extends IMinecraftLibrary {
|
||||
|
||||
public ArrayList<Rules> rules;
|
||||
public String url, formatted = null;
|
||||
//public boolean serverreq=true, clientreq=true;
|
||||
public String[] checksums;
|
||||
public String url;
|
||||
public Natives natives;
|
||||
public Extract extract;
|
||||
public LibrariesDownloadInfo downloads;
|
||||
|
||||
public MinecraftLibrary(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public MinecraftLibrary(ArrayList<Rules> rules, String url, String[] checksums, Natives natives, String name, Extract extract) {
|
||||
public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract, LibraryDownloadInfo downloads) {
|
||||
super(name);
|
||||
this.rules = rules == null ? null : (ArrayList<Rules>) rules.clone();
|
||||
this.url = url;
|
||||
this.checksums = checksums == null ? null : Arrays.copyOf(checksums, checksums.length);
|
||||
this.natives = natives == null ? null : (Natives) natives.clone();
|
||||
this.extract = extract == null ? null : (Extract) extract.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new MinecraftLibrary(rules, url, checksums, natives, name, extract);
|
||||
}
|
||||
|
||||
/**
|
||||
* is the library allowed to load.
|
||||
*
|
||||
@@ -63,19 +55,16 @@ public class MinecraftLibrary extends IMinecraftLibrary {
|
||||
*/
|
||||
@Override
|
||||
public boolean allow() {
|
||||
boolean flag = false;
|
||||
if (rules == null || rules.isEmpty())
|
||||
flag = true;
|
||||
else
|
||||
if (rules != null) {
|
||||
boolean flag = false;
|
||||
for (Rules r : rules)
|
||||
if (r.action.equals("disallow")) {
|
||||
if (r.os != null && (StrUtils.isBlank(r.os.name) || r.os.name.equalsIgnoreCase(OS.os().toString()))) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if (r.os == null || (r.os != null && (StrUtils.isBlank(r.os.name) || r.os.name.equalsIgnoreCase(OS.os().toString()))))
|
||||
if ("disallow".equals(r.action()))
|
||||
return false;
|
||||
else if ("allow".equals(r.action()))
|
||||
flag = true;
|
||||
return flag;
|
||||
return flag;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
private String formatArch(String nati) {
|
||||
@@ -83,13 +72,14 @@ public class MinecraftLibrary extends IMinecraftLibrary {
|
||||
}
|
||||
|
||||
private String getNative() {
|
||||
OS os = OS.os();
|
||||
if (os == OS.WINDOWS)
|
||||
switch (OS.os()) {
|
||||
case WINDOWS:
|
||||
return formatArch(natives.windows);
|
||||
else if (os == OS.OSX)
|
||||
case OSX:
|
||||
return formatArch(natives.osx);
|
||||
else
|
||||
default:
|
||||
return formatArch(natives.linux);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,40 +87,42 @@ public class MinecraftLibrary extends IMinecraftLibrary {
|
||||
return natives != null && allow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
String str = name;
|
||||
String[] s = str.split(":");
|
||||
str = s[0];
|
||||
str = str.replace('.', File.separatorChar);
|
||||
if (natives == null)
|
||||
str += File.separator + s[1] + File.separator + s[2]
|
||||
+ File.separator + s[1] + '-' + s[2] + ".jar";
|
||||
else {
|
||||
str += File.separator + s[1] + File.separator + s[2]
|
||||
+ File.separator + s[1] + '-' + s[2] + '-';
|
||||
str += getNative();
|
||||
str += ".jar";
|
||||
}
|
||||
formatted = str;
|
||||
public String formatName() {
|
||||
String[] s = name.split(":");
|
||||
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)
|
||||
sb.append('-').append(getNative());
|
||||
return sb.append(".jar").toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getFilePath(File gameDir) {
|
||||
return new File(gameDir, "libraries" + File.separatorChar + formatted);
|
||||
return new File(gameDir, "libraries/" + getDownloadInfo().path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadURL(String urlBase, DownloadType downloadType) {
|
||||
if (StrUtils.isNotBlank(url) && downloadType.getProvider().isAllowedToUseSelfURL())
|
||||
urlBase = this.url;
|
||||
if (urlBase.endsWith(".jar"))
|
||||
return urlBase;
|
||||
return urlBase + formatted.replace('\\', '/');
|
||||
public Extract getDecompressExtractRules() {
|
||||
return extract == null ? new Extract() : extract;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDecompressExtractRules() {
|
||||
return extract == null || extract.exclude == null ? new String[0] : extract.exclude;
|
||||
public LibraryDownloadInfo getDownloadInfo() {
|
||||
if (downloads == null)
|
||||
downloads = new LibrariesDownloadInfo();
|
||||
LibraryDownloadInfo info;
|
||||
if (natives != null) {
|
||||
if (downloads.classifiers == null)
|
||||
downloads.classifiers = new HashMap<>();
|
||||
if (!downloads.classifiers.containsKey(getNative()))
|
||||
downloads.classifiers.put(getNative(), info = new LibraryDownloadInfo());
|
||||
else
|
||||
info = downloads.classifiers.get(getNative());
|
||||
} else if (downloads.artifact == null)
|
||||
downloads.artifact = info = new LibraryDownloadInfo();
|
||||
else
|
||||
info = downloads.artifact;
|
||||
if (StrUtils.isBlank(info.path))
|
||||
info.path = formatName();
|
||||
info.forgeURL = this.url;
|
||||
return info;
|
||||
}
|
||||
}
|
||||
+3
-8
@@ -18,7 +18,6 @@
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -35,10 +34,6 @@ public class MinecraftOldLibrary extends MinecraftLibrary {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allow() {
|
||||
return true;
|
||||
@@ -51,12 +46,12 @@ public class MinecraftOldLibrary extends MinecraftLibrary {
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new MinecraftOldLibrary(name);
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadURL(String urlBase, DownloadType downloadType) {
|
||||
return null;
|
||||
public LibraryDownloadInfo getDownloadInfo() {
|
||||
return new LibraryDownloadInfo();
|
||||
}
|
||||
|
||||
}
|
||||
+58
-15
@@ -19,14 +19,17 @@ package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.assets.AssetsIndex;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.asset.AssetsIndex;
|
||||
import org.jackhuang.hellominecraft.util.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.util.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -35,16 +38,19 @@ import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
public class MinecraftVersion implements Cloneable, Comparable<MinecraftVersion> {
|
||||
|
||||
public String minecraftArguments, mainClass, time, id, type, processArguments,
|
||||
releaseTime, assets, jar, inheritsFrom, runDir;
|
||||
releaseTime, jar, inheritsFrom, runDir;
|
||||
protected String assets;
|
||||
public int minimumLauncherVersion;
|
||||
public boolean hidden;
|
||||
public AssetIndexDownloadInfo assetIndex;
|
||||
private Map<String, GameDownloadInfo> downloads;
|
||||
|
||||
public List<MinecraftLibrary> libraries;
|
||||
public ArrayList<MinecraftLibrary> libraries;
|
||||
|
||||
public MinecraftVersion() {
|
||||
}
|
||||
|
||||
public MinecraftVersion(String minecraftArguments, String mainClass, String time, String id, String type, String processArguments, String releaseTime, String assets, String jar, String inheritsFrom, String runDir, int minimumLauncherVersion, List<MinecraftLibrary> libraries, boolean hidden) {
|
||||
public MinecraftVersion(String minecraftArguments, String mainClass, String time, String id, String type, String processArguments, String releaseTime, String assets, String jar, String inheritsFrom, String runDir, int minimumLauncherVersion, List<MinecraftLibrary> libraries, boolean hidden, Map<String, GameDownloadInfo> downloads, AssetIndexDownloadInfo assetIndexDownloadInfo) {
|
||||
this();
|
||||
this.minecraftArguments = minecraftArguments;
|
||||
this.mainClass = mainClass;
|
||||
@@ -59,18 +65,36 @@ public class MinecraftVersion implements Cloneable, Comparable<MinecraftVersion>
|
||||
this.minimumLauncherVersion = minimumLauncherVersion;
|
||||
this.hidden = hidden;
|
||||
this.runDir = runDir;
|
||||
if (assetIndexDownloadInfo == null)
|
||||
this.assetIndex = null;
|
||||
else
|
||||
this.assetIndex = (AssetIndexDownloadInfo) assetIndexDownloadInfo.clone();
|
||||
if (libraries == null)
|
||||
this.libraries = new ArrayList<>();
|
||||
else {
|
||||
this.libraries = new ArrayList<>(libraries.size());
|
||||
for (IMinecraftLibrary library : libraries)
|
||||
this.libraries.add((MinecraftLibrary) library.clone());
|
||||
for (MinecraftLibrary library : libraries)
|
||||
if (library != null)
|
||||
this.libraries.add((MinecraftLibrary) library.clone());
|
||||
}
|
||||
if (downloads == null)
|
||||
this.downloads = null;
|
||||
else {
|
||||
this.downloads = new HashMap<>(downloads.size());
|
||||
for (Map.Entry<String, GameDownloadInfo> entry : downloads.entrySet())
|
||||
this.downloads.put(entry.getKey(), (GameDownloadInfo) entry.getValue().clone());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new MinecraftVersion(minecraftArguments, mainClass, time, id, type, processArguments, releaseTime, assets, jar, inheritsFrom, runDir, minimumLauncherVersion, libraries, hidden);
|
||||
try {
|
||||
MinecraftVersion mv = (MinecraftVersion) super.clone();
|
||||
mv.libraries = (ArrayList<MinecraftLibrary>) mv.libraries.clone();
|
||||
return mv;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
public MinecraftVersion resolve(IMinecraftProvider provider) throws GameException {
|
||||
@@ -97,7 +121,9 @@ public class MinecraftVersion implements Cloneable, Comparable<MinecraftVersion>
|
||||
this.assets != null ? this.assets : parent.assets,
|
||||
this.jar != null ? this.jar : parent.jar,
|
||||
null, this.runDir, parent.minimumLauncherVersion,
|
||||
this.libraries != null ? ArrayUtils.merge(this.libraries, parent.libraries) : parent.libraries, this.hidden);
|
||||
this.libraries != null ? ArrayUtils.merge(this.libraries, parent.libraries) : parent.libraries, this.hidden,
|
||||
this.downloads != null ? this.downloads : parent.downloads,
|
||||
this.assetIndex != null ? this.assetIndex : parent.assetIndex);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -121,12 +147,29 @@ public class MinecraftVersion implements Cloneable, Comparable<MinecraftVersion>
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getAssets() {
|
||||
return assets == null ? AssetsIndex.DEFAULT_ASSET_NAME : assets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MinecraftVersion o) {
|
||||
return id.compareTo(((MinecraftVersion) o).id);
|
||||
return id.compareTo(o.id);
|
||||
}
|
||||
|
||||
public AssetIndexDownloadInfo getAssetsIndex() {
|
||||
if (assetIndex == null)
|
||||
assetIndex = new AssetIndexDownloadInfo((String) Utils.firstNonNull(assets, AssetsIndex.DEFAULT_ASSET_NAME));
|
||||
return assetIndex;
|
||||
}
|
||||
|
||||
public GameDownloadInfo getClientDownloadInfo() {
|
||||
if (downloads == null)
|
||||
downloads = new HashMap<>();
|
||||
if (!downloads.containsKey("client"))
|
||||
downloads.put("client", new GameDownloadInfo());
|
||||
GameDownloadInfo i = downloads.get("client");
|
||||
if (i.id == null)
|
||||
i.id = id;
|
||||
return i;
|
||||
}
|
||||
|
||||
public Set<IMinecraftLibrary> getLibraries() {
|
||||
return libraries == null ? new HashSet() : new HashSet(libraries);
|
||||
}
|
||||
}
|
||||
+110
-110
@@ -24,21 +24,20 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.MCUtils;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.DecompressTask;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import org.jackhuang.hellominecraft.utils.views.SwingUtils;
|
||||
import org.jackhuang.hellominecraft.util.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.util.MessageBox;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.func.Consumer;
|
||||
import org.jackhuang.hellominecraft.util.func.Predicate;
|
||||
import org.jackhuang.hellominecraft.util.ui.SwingUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -67,7 +66,9 @@ public class MinecraftVersionManager extends IMinecraftProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshVersions() {
|
||||
public synchronized void refreshVersions() {
|
||||
onRefreshingVersions.execute(service);
|
||||
|
||||
try {
|
||||
MCUtils.tryWriteProfile(service.baseDirectory());
|
||||
} catch (IOException ex) {
|
||||
@@ -83,72 +84,75 @@ public class MinecraftVersionManager extends IMinecraftProvider {
|
||||
|
||||
File version = new File(service.baseDirectory(), "versions");
|
||||
File[] files = version.listFiles();
|
||||
if (files == null || files.length == 0)
|
||||
return;
|
||||
if (files != null && files.length > 0)
|
||||
for (File dir : files) {
|
||||
String id = dir.getName();
|
||||
File jsonFile = new File(dir, id + ".json");
|
||||
|
||||
for (File dir : files) {
|
||||
String id = dir.getName();
|
||||
File jsonFile = new File(dir, id + ".json");
|
||||
|
||||
if (!dir.isDirectory())
|
||||
continue;
|
||||
boolean ask = false;
|
||||
File[] jsons = null;
|
||||
if (!jsonFile.exists()) {
|
||||
jsons = FileUtils.searchSuffix(dir, "json");
|
||||
if (jsons.length == 1)
|
||||
ask = true;
|
||||
}
|
||||
if (ask) {
|
||||
HMCLog.warn("Found not matched filenames version: " + id + ", json: " + jsons[0].getName());
|
||||
if (MessageBox.Show(String.format(C.i18n("launcher.versions_json_not_matched"), id, jsons[0].getName()), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
jsons[0].renameTo(new File(jsons[0].getParent(), id + ".json"));
|
||||
}
|
||||
if (!jsonFile.exists()) {
|
||||
if (MessageBox.Show(C.i18n("launcher.versions_json_not_matched_cannot_auto_completion", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
FileUtils.deleteDirectoryQuietly(dir);
|
||||
continue;
|
||||
}
|
||||
MinecraftVersion mcVersion;
|
||||
try {
|
||||
mcVersion = C.gson.fromJson(FileUtils.readFileToString(jsonFile), MinecraftVersion.class);
|
||||
if (mcVersion == null)
|
||||
throw new GameException("Wrong json format, got null.");
|
||||
} catch (IOException | GameException e) {
|
||||
HMCLog.warn("Found wrong format json, try to fix it.", e);
|
||||
if (MessageBox.Show(C.i18n("launcher.versions_json_not_formatted", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
||||
service.download().downloadMinecraftVersionJson(id);
|
||||
try {
|
||||
mcVersion = C.gson.fromJson(FileUtils.readFileToString(jsonFile), MinecraftVersion.class);
|
||||
if (mcVersion == null)
|
||||
throw new GameException("Wrong json format, got null.");
|
||||
} catch (IOException | GameException ex) {
|
||||
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", ex);
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
if (!dir.isDirectory())
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
if (!id.equals(mcVersion.id)) {
|
||||
HMCLog.warn("Found: " + dir + ", it contains id: " + mcVersion.id + ", expected: " + id + ", this app will fix this problem.");
|
||||
mcVersion.id = id;
|
||||
FileUtils.writeQuietly(jsonFile, C.gsonPrettyPrinting.toJson(mcVersion));
|
||||
boolean ask = false;
|
||||
File[] jsons = null;
|
||||
if (!jsonFile.exists()) {
|
||||
jsons = FileUtils.searchSuffix(dir, "json");
|
||||
if (jsons.length == 1)
|
||||
ask = true;
|
||||
}
|
||||
if (ask) {
|
||||
HMCLog.warn("Found not matched filenames version: " + id + ", json: " + jsons[0].getName());
|
||||
if (MessageBox.Show(String.format(C.i18n("launcher.versions_json_not_matched"), id, jsons[0].getName()), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
if (!jsons[0].renameTo(new File(jsons[0].getParent(), id + ".json")))
|
||||
HMCLog.warn("Failed to rename version json " + jsons[0]);
|
||||
}
|
||||
if (!jsonFile.exists()) {
|
||||
if (MessageBox.Show(C.i18n("launcher.versions_json_not_matched_cannot_auto_completion", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
FileUtils.deleteDirectoryQuietly(dir);
|
||||
continue;
|
||||
}
|
||||
MinecraftVersion mcVersion;
|
||||
try {
|
||||
mcVersion = C.GSON.fromJson(FileUtils.readFileToString(jsonFile), MinecraftVersion.class);
|
||||
if (mcVersion == null)
|
||||
throw new GameException("Wrong json format, got null.");
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Found wrong format json, try to fix it.", e);
|
||||
if (MessageBox.Show(C.i18n("launcher.versions_json_not_formatted", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
||||
service.download().downloadMinecraftVersionJson(id);
|
||||
try {
|
||||
mcVersion = C.GSON.fromJson(FileUtils.readFileToString(jsonFile), MinecraftVersion.class);
|
||||
if (mcVersion == null)
|
||||
throw new GameException("Wrong json format, got null.");
|
||||
} catch (IOException | GameException | JsonSyntaxException ex) {
|
||||
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", ex);
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
if (!id.equals(mcVersion.id)) {
|
||||
HMCLog.warn("Found: " + dir + ", it contains id: " + mcVersion.id + ", expected: " + id + ", this app will fix this problem.");
|
||||
mcVersion.id = id;
|
||||
FileUtils.writeQuietly(jsonFile, C.GSON.toJson(mcVersion));
|
||||
}
|
||||
|
||||
if (mcVersion.libraries != null)
|
||||
for (MinecraftLibrary ml : mcVersion.libraries)
|
||||
ml.init();
|
||||
versions.put(id, mcVersion);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", e);
|
||||
versions.put(id, mcVersion);
|
||||
onLoadedVersion.execute(id);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
onRefreshedVersions.execute(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File versionRoot(String id) {
|
||||
return new File(service.baseDirectory(), "versions/" + id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVersionFromDisk(String name) {
|
||||
File version = new File(service.baseDirectory(), "versions/" + name);
|
||||
File version = versionRoot(name);
|
||||
if (!version.exists())
|
||||
return true;
|
||||
|
||||
@@ -159,18 +163,20 @@ public class MinecraftVersionManager extends IMinecraftProvider {
|
||||
@Override
|
||||
public boolean renameVersion(String from, String to) {
|
||||
try {
|
||||
File fromJson = new File(service.baseDirectory(), "versions/" + from + "/" + from + ".json");
|
||||
MinecraftVersion mcVersion = C.gson.fromJson(FileUtils.readFileToString(fromJson), MinecraftVersion.class);
|
||||
File fromJson = new File(versionRoot(from), from + ".json");
|
||||
MinecraftVersion mcVersion = C.GSON.fromJson(FileUtils.readFileToString(fromJson), MinecraftVersion.class);
|
||||
mcVersion.id = to;
|
||||
FileUtils.writeQuietly(fromJson, C.gsonPrettyPrinting.toJson(mcVersion));
|
||||
File toDir = new File(service.baseDirectory(), "versions/" + to);
|
||||
new File(service.baseDirectory(), "versions/" + from).renameTo(toDir);
|
||||
FileUtils.writeQuietly(fromJson, C.GSON.toJson(mcVersion));
|
||||
File toDir = versionRoot(to);
|
||||
if (!versionRoot(from).renameTo(toDir))
|
||||
HMCLog.warn("MinecraftVersionManager.RenameVersion: Failed to rename version root " + from + " to " + to);
|
||||
File toJson = new File(toDir, to + ".json");
|
||||
File toJar = new File(toDir, to + ".jar");
|
||||
new File(toDir, from + ".json").renameTo(toJson);
|
||||
if (new File(toDir, from + ".json").renameTo(toJson))
|
||||
HMCLog.warn("MinecraftVersionManager.RenameVersion: Failed to rename json");
|
||||
File newJar = new File(toDir, from + ".jar");
|
||||
if (newJar.exists())
|
||||
newJar.renameTo(toJar);
|
||||
if (newJar.exists() && !newJar.renameTo(toJar))
|
||||
HMCLog.warn("Failed to rename pre jar " + newJar + " to new jar " + toJar);
|
||||
return true;
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
HMCLog.warn("Failed to rename " + from + " to " + to + ", the json of this Minecraft is malformed.", e);
|
||||
@@ -180,29 +186,26 @@ public class MinecraftVersionManager extends IMinecraftProvider {
|
||||
|
||||
@Override
|
||||
public File getRunDirectory(String id) {
|
||||
if ("version".equals(versions.get(id).runDir))
|
||||
return new File(service.baseDirectory(), "versions/" + id + "/");
|
||||
switch (gameDirType) {
|
||||
case VERSION_FOLDER:
|
||||
return new File(service.baseDirectory(), "versions/" + id + "/");
|
||||
default:
|
||||
return service.baseDirectory();
|
||||
}
|
||||
if (getVersionById(id) != null)
|
||||
if ("version".equals(getVersionById(id).runDir))
|
||||
return versionRoot(id);
|
||||
return baseDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean install(String id, Consumer<MinecraftVersion> callback) {
|
||||
MinecraftVersion v = service.download().downloadMinecraft(id);
|
||||
if (!TaskWindow.factory().append(service.download().downloadMinecraft(id)).create())
|
||||
return false;
|
||||
if (callback != null) {
|
||||
File mvt = new File(versionRoot(id), id + ".json");
|
||||
MinecraftVersion v = C.GSON.fromJson(FileUtils.readFileToStringQuietly(mvt), MinecraftVersion.class);
|
||||
if (v == null)
|
||||
return false;
|
||||
callback.accept(v);
|
||||
File mvt = new File(service.baseDirectory(), "versions/" + id + "/" + id + ".json");
|
||||
FileUtils.writeQuietly(mvt, C.gsonPrettyPrinting.toJson(v));
|
||||
FileUtils.writeQuietly(mvt, C.GSON.toJson(v));
|
||||
}
|
||||
if (v != null) {
|
||||
refreshVersions();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
refreshVersions();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -215,15 +218,13 @@ public class MinecraftVersionManager extends IMinecraftProvider {
|
||||
if (v.libraries == null)
|
||||
throw new GameException("Wrong format: minecraft.json");
|
||||
ArrayList<File> unzippings = new ArrayList<>();
|
||||
ArrayList<String[]> extractRules = new ArrayList<>();
|
||||
for (IMinecraftLibrary l : v.libraries) {
|
||||
l.init();
|
||||
ArrayList<Extract> extractRules = new ArrayList<>();
|
||||
for (IMinecraftLibrary l : v.libraries)
|
||||
if (l.isRequiredToUnzip() && v.isAllowedToUnpackNatives()) {
|
||||
unzippings.add(IOUtils.tryGetCanonicalFile(l.getFilePath(service.baseDirectory())));
|
||||
extractRules.add(l.getDecompressExtractRules());
|
||||
}
|
||||
}
|
||||
return new DecompressLibraryJob(unzippings.toArray(new File[0]), extractRules.toArray(new String[0][]), getDecompressNativesToLocation(v));
|
||||
return new DecompressLibraryJob(unzippings.toArray(new File[unzippings.size()]), extractRules.toArray(new Extract[extractRules.size()]), getDecompressNativesToLocation(v));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -240,8 +241,11 @@ public class MinecraftVersionManager extends IMinecraftProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion getOneVersion() {
|
||||
return versions.isEmpty() ? null : versions.values().iterator().next();
|
||||
public MinecraftVersion getOneVersion(Predicate<MinecraftVersion> pred) {
|
||||
for (MinecraftVersion v : versions.values())
|
||||
if (pred == null || pred.apply(v))
|
||||
return v;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -257,22 +261,23 @@ public class MinecraftVersionManager extends IMinecraftProvider {
|
||||
@Override
|
||||
public boolean onLaunch() {
|
||||
File resourcePacks = getResourcePacks();
|
||||
if (!resourcePacks.exists())
|
||||
resourcePacks.mkdirs();
|
||||
if (!resourcePacks.exists() && !resourcePacks.mkdirs())
|
||||
HMCLog.warn("Failed to make resourcePacks: " + resourcePacks);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanFolder() {
|
||||
for (MinecraftVersion s : getVersions()) {
|
||||
FileUtils.deleteDirectoryQuietly(new File(service.baseDirectory(), "versions" + File.separator + s.id + File.separator + s.id + "-natives"));
|
||||
FileUtils.deleteDirectoryQuietly(new File(versionRoot(s.id), s.id + "-natives"));
|
||||
File f = getRunDirectory(s.id);
|
||||
String[] dir = { "logs", "asm", "NVIDIA", "crash-reports", "server-resource-packs", "natives", "native" };
|
||||
String[] dir = { "natives", "native", "$native", "AMD", "crash-reports", "logs", "asm", "NVIDIA", "server-resource-packs", "natives", "native" };
|
||||
for (String str : dir)
|
||||
FileUtils.deleteDirectoryQuietly(new File(f, str));
|
||||
String[] files = { "output-client.log", "usercache.json", "usernamecache.json", "hmclmc.log" };
|
||||
for (String str : files)
|
||||
new File(f, str).delete();
|
||||
if (!new File(f, str).delete())
|
||||
HMCLog.warn("Failed to delete " + str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,9 +285,4 @@ public class MinecraftVersionManager extends IMinecraftProvider {
|
||||
public void initializeMiencraft() {
|
||||
|
||||
}
|
||||
|
||||
private void downloadModpack(String url) throws IOException {
|
||||
File tmp = File.createTempFile("hmcl", ".zip");
|
||||
TaskWindow.getInstance().addTask(new FileDownloadTask(url, tmp)).addTask(new DecompressTask(tmp, service.baseDirectory())).start();
|
||||
}
|
||||
}
|
||||
@@ -26,11 +26,12 @@ public class Natives implements Cloneable {
|
||||
public String windows, osx, linux;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("CloneDeclaresCloneNotSupported")
|
||||
protected Object clone() {
|
||||
Natives n = new Natives();
|
||||
n.windows = windows;
|
||||
n.osx = osx;
|
||||
n.linux = linux;
|
||||
return n;
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new InternalError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-19
@@ -15,39 +15,36 @@
|
||||
* 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.utils;
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.util.HashSet;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
* @param <T> EventArgs
|
||||
*/
|
||||
public class EventHandler<T> {
|
||||
public class OSRestriction {
|
||||
|
||||
HashSet<Event<T>> handlers;
|
||||
Object sender;
|
||||
private String version, name;
|
||||
|
||||
public EventHandler(Object sender) {
|
||||
handlers = new HashSet<>();
|
||||
this.sender = sender;
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void register(Event<T> t) {
|
||||
handlers.add(t);
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public void unregister(Event<T> t) {
|
||||
handlers.remove(t);
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean execute(T x) {
|
||||
boolean flag = true;
|
||||
for (Event<T> t : handlers)
|
||||
if (!t.call(sender, x))
|
||||
flag = false;
|
||||
return flag;
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isCurrentOS() {
|
||||
return StrUtils.isBlank(getName()) || OS.os().name().equalsIgnoreCase(getName());
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,20 @@ package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
*/
|
||||
public class Rules {
|
||||
|
||||
public String action;
|
||||
public OS os;
|
||||
private String action;
|
||||
private OSRestriction os;
|
||||
|
||||
public Rules() {
|
||||
}
|
||||
|
||||
public Rules(String action, OSRestriction os) {
|
||||
this();
|
||||
this.action = action;
|
||||
this.os = os;
|
||||
}
|
||||
|
||||
public String action() {
|
||||
return os == null || os != null && os.isCurrentOS() ? action : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ServerInfo {
|
||||
|
||||
public String name, addr, picurl, type, info, wfjc, tsjs, version, url, depend;
|
||||
public String[] md5;
|
||||
public int port;
|
||||
|
||||
public Icon icon;
|
||||
|
||||
public static final HashMap<String, Icon> CACHE = new HashMap<>();
|
||||
|
||||
public void downloadIcon() {
|
||||
if (icon == null && Utils.isURL(picurl))
|
||||
if (CACHE.containsKey(picurl))
|
||||
icon = CACHE.get(picurl);
|
||||
else
|
||||
try {
|
||||
File tmp = File.createTempFile("HMCLSERVER", ".png");
|
||||
FileDownloadTask.download(picurl, tmp, null);
|
||||
CACHE.put(picurl, icon = new ImageIcon(tmp.getAbsolutePath()));
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException("Failed to download icon", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+42
-14
@@ -15,7 +15,7 @@
|
||||
* 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.settings;
|
||||
package org.jackhuang.hellominecraft.launcher.setting;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
@@ -27,15 +27,15 @@ import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.lookandfeel.Theme;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
import org.jackhuang.hellominecraft.utils.system.JdkVersion;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.util.EventHandler;
|
||||
import org.jackhuang.hellominecraft.util.system.JdkVersion;
|
||||
import org.jackhuang.hellominecraft.util.system.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Config {
|
||||
public final class Config implements Cloneable {
|
||||
|
||||
@SerializedName("last")
|
||||
private String last;
|
||||
@@ -54,6 +54,17 @@ public final class Config {
|
||||
private int theme;
|
||||
@SerializedName("java")
|
||||
private List<JdkVersion> java;
|
||||
@SerializedName("localization")
|
||||
private String localization;
|
||||
@SerializedName("logintype")
|
||||
private int logintype;
|
||||
@SerializedName("downloadtype")
|
||||
private int downloadtype;
|
||||
@SerializedName("configurations")
|
||||
private TreeMap<String, Profile> configurations;
|
||||
@SerializedName("auth")
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
private Map<String, Map> auth;
|
||||
|
||||
public List<JdkVersion> getJava() {
|
||||
return java == null ? java = new ArrayList<>() : java;
|
||||
@@ -61,6 +72,7 @@ public final class Config {
|
||||
|
||||
public transient final EventHandler<Theme> themeChangedEvent = new EventHandler<>(this);
|
||||
public transient final EventHandler<DownloadType> downloadTypeChangedEvent = new EventHandler<>(this);
|
||||
public transient final EventHandler<IAuthenticator> authChangedEvent = new EventHandler<>(this);
|
||||
|
||||
public Theme getTheme() {
|
||||
return Theme.values()[theme];
|
||||
@@ -90,11 +102,14 @@ public final class Config {
|
||||
}
|
||||
|
||||
public String getLast() {
|
||||
if (last == null)
|
||||
last = Settings.DEFAULT_PROFILE;
|
||||
return last;
|
||||
}
|
||||
|
||||
public void setLast(String last) {
|
||||
this.last = last;
|
||||
Settings.onProfileChanged();
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
@@ -131,7 +146,10 @@ public final class Config {
|
||||
}
|
||||
|
||||
public void setLoginType(int logintype) {
|
||||
if (logintype < 0 || logintype >= IAuthenticator.LOGINS.size())
|
||||
return;
|
||||
this.logintype = logintype;
|
||||
authChangedEvent.execute(IAuthenticator.LOGINS.get(logintype));
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
@@ -164,15 +182,6 @@ public final class Config {
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
@SerializedName("logintype")
|
||||
private int logintype;
|
||||
@SerializedName("downloadtype")
|
||||
private int downloadtype;
|
||||
@SerializedName("configurations")
|
||||
private TreeMap<String, Profile> configurations;
|
||||
@SerializedName("auth")
|
||||
private Map<String, Map> auth;
|
||||
|
||||
public Config() {
|
||||
clientToken = UUID.randomUUID().toString();
|
||||
logintype = downloadtype = 0;
|
||||
@@ -226,4 +235,23 @@ public final class Config {
|
||||
this.proxyPassword = proxyPassword;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getLocalization() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
public void setLocalization(String localization) {
|
||||
this.localization = localization;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* 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.setting;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.util.HMCLGameLauncher;
|
||||
import org.jackhuang.hellominecraft.launcher.util.HMCLMinecraftService;
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
|
||||
import org.jackhuang.hellominecraft.launcher.core.MCUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.EventHandler;
|
||||
import org.jackhuang.hellominecraft.util.system.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Profile {
|
||||
|
||||
private String name, selectedMinecraftVersion = "", gameDir;
|
||||
|
||||
private transient IMinecraftService service;
|
||||
private transient HMCLGameLauncher launcher = new HMCLGameLauncher(this);
|
||||
public transient final EventHandler<String> propertyChanged = new EventHandler<>(this);
|
||||
|
||||
public Profile() {
|
||||
this("Default");
|
||||
}
|
||||
|
||||
public Profile(String name) {
|
||||
this.name = name;
|
||||
gameDir = MCUtils.getInitGameDir().getPath();
|
||||
}
|
||||
|
||||
public Profile(String name, Profile v) {
|
||||
this();
|
||||
if (v == null)
|
||||
return;
|
||||
this.name = name;
|
||||
gameDir = v.gameDir;
|
||||
}
|
||||
|
||||
public IMinecraftService service() {
|
||||
if (service == null)
|
||||
service = PluginManager.plugin().provideMinecraftService(this);
|
||||
return service;
|
||||
}
|
||||
|
||||
public HMCLGameLauncher launcher() {
|
||||
return launcher;
|
||||
}
|
||||
|
||||
private transient final VersionSetting defaultVersionSetting = new VersionSetting();
|
||||
|
||||
public VersionSetting getSelectedVersionSetting() {
|
||||
VersionSetting vs = getVersionSetting(getSelectedVersion());
|
||||
if (vs == null)
|
||||
vs = defaultVersionSetting;
|
||||
return vs;
|
||||
}
|
||||
|
||||
public VersionSetting getVersionSetting(String id) {
|
||||
return ((HMCLMinecraftService) service()).getVersionSetting(id);
|
||||
}
|
||||
|
||||
public String getSettingsSelectedMinecraftVersion() {
|
||||
return selectedMinecraftVersion;
|
||||
}
|
||||
|
||||
public String getSelectedVersion() {
|
||||
String v = selectedMinecraftVersion;
|
||||
if (StrUtils.isBlank(v) || service().version().getVersionById(v) == null || service().version().getVersionById(v).hidden) {
|
||||
MinecraftVersion mv = service().version().getOneVersion(t -> !t.hidden);
|
||||
if (mv != null)
|
||||
v = mv.id;
|
||||
if (StrUtils.isNotBlank(v))
|
||||
setSelectedMinecraftVersion(v);
|
||||
}
|
||||
return StrUtils.isBlank(v) ? null : v;
|
||||
}
|
||||
|
||||
public transient final EventHandler<String> selectedVersionChangedEvent = new EventHandler<>(this);
|
||||
|
||||
public void setSelectedMinecraftVersion(String selectedMinecraftVersion) {
|
||||
this.selectedMinecraftVersion = selectedMinecraftVersion;
|
||||
propertyChanged.execute("selectedMinecraftVersion");
|
||||
selectedVersionChangedEvent.execute(selectedMinecraftVersion);
|
||||
}
|
||||
|
||||
public String getGameDir() {
|
||||
if (StrUtils.isBlank(gameDir))
|
||||
gameDir = MCUtils.getInitGameDir().getPath();
|
||||
return IOUtils.addSeparator(gameDir);
|
||||
}
|
||||
|
||||
public String getCanonicalGameDir() {
|
||||
return IOUtils.tryGetCanonicalFolderPath(getGameDirFile());
|
||||
}
|
||||
|
||||
public File getCanonicalGameDirFile() {
|
||||
return IOUtils.tryGetCanonicalFile(getGameDirFile());
|
||||
}
|
||||
|
||||
public File getGameDirFile() {
|
||||
return new File(getGameDir());
|
||||
}
|
||||
|
||||
public Profile setGameDir(String gameDir) {
|
||||
this.gameDir = gameDir;
|
||||
service().version().refreshVersions();
|
||||
propertyChanged.execute("gameDir");
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
propertyChanged.execute("name");
|
||||
}
|
||||
|
||||
public void checkFormat() {
|
||||
gameDir = gameDir.replace('/', OS.os().fileSeparator).replace('\\', OS.os().fileSeparator);
|
||||
}
|
||||
|
||||
public void onSelected() {
|
||||
service().version().refreshVersions();
|
||||
}
|
||||
}
|
||||
+55
-33
@@ -15,26 +15,23 @@
|
||||
* 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.settings;
|
||||
package org.jackhuang.hellominecraft.launcher.setting;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.CollectionUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
import org.jackhuang.hellominecraft.util.CollectionUtils;
|
||||
import org.jackhuang.hellominecraft.util.EventHandler;
|
||||
import org.jackhuang.hellominecraft.util.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.util.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.util.MessageBox;
|
||||
import org.jackhuang.hellominecraft.util.UpdateChecker;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -47,8 +44,7 @@ public final class Settings {
|
||||
public static final File SETTINGS_FILE = new File(IOUtils.currentDir(), "hmcl.json");
|
||||
|
||||
private static final Config SETTINGS;
|
||||
public static final UpdateChecker UPDATE_CHECKER = new UpdateChecker(new VersionNumber(Main.VERSION_FIRST, Main.VERSION_SECOND, Main.VERSION_THIRD),
|
||||
"hmcl");
|
||||
public static final UpdateChecker UPDATE_CHECKER = new UpdateChecker(Main.getVersionNumber(), "hmcl");
|
||||
|
||||
public static Config getInstance() {
|
||||
return SETTINGS;
|
||||
@@ -56,20 +52,16 @@ public final class Settings {
|
||||
|
||||
static {
|
||||
SETTINGS = initSettings();
|
||||
SETTINGS.downloadTypeChangedEvent.register((s, t) -> {
|
||||
DownloadType.setSuggestedDownloadType(t);
|
||||
return true;
|
||||
});
|
||||
SETTINGS.downloadTypeChangedEvent.register(DownloadType::setSuggestedDownloadType);
|
||||
DownloadType.setSuggestedDownloadType(SETTINGS.getDownloadSource());
|
||||
if (!getProfiles().containsKey(DEFAULT_PROFILE))
|
||||
getProfiles().put(DEFAULT_PROFILE, new Profile());
|
||||
|
||||
for (Profile e : getProfiles().values()) {
|
||||
for (Map.Entry<String, Profile> entry : getProfiles().entrySet()) {
|
||||
Profile e = entry.getValue();
|
||||
e.setName(entry.getKey());
|
||||
e.checkFormat();
|
||||
e.propertyChanged.register((sender, t) -> {
|
||||
save();
|
||||
return true;
|
||||
});
|
||||
e.propertyChanged.register(Settings::save);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,17 +73,13 @@ public final class Settings {
|
||||
if (str == null || str.trim().equals(""))
|
||||
HMCLog.log("Settings file is empty, use the default settings.");
|
||||
else {
|
||||
Config d = C.gsonPrettyPrinting.fromJson(str, Config.class);
|
||||
Config d = C.GSON.fromJson(str, Config.class);
|
||||
if (d != null)
|
||||
c = d;
|
||||
}
|
||||
HMCLog.log("Initialized settings.");
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
HMCLog.warn("Something happened wrongly when load settings.", e);
|
||||
if (MessageBox.Show(C.i18n("settings.failed_load"), MessageBox.YES_NO_OPTION) == MessageBox.NO_OPTION) {
|
||||
HMCLog.err("Cancelled loading settings.");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
HMCLog.log("No settings file here, may be first loading.");
|
||||
@@ -100,16 +88,34 @@ public final class Settings {
|
||||
|
||||
public static void save() {
|
||||
try {
|
||||
FileUtils.write(SETTINGS_FILE, C.gsonPrettyPrinting.toJson(SETTINGS));
|
||||
FileUtils.write(SETTINGS_FILE, C.GSON.toJson(SETTINGS));
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Failed to save config", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static Profile getLastProfile() {
|
||||
if (!hasProfile(getInstance().getLast()))
|
||||
getInstance().setLast(DEFAULT_PROFILE);
|
||||
return getProfile(getInstance().getLast());
|
||||
}
|
||||
|
||||
public static Profile getProfile(String name) {
|
||||
if (name == null)
|
||||
return getProfiles().get("Default");
|
||||
return getProfiles().get(name);
|
||||
name = DEFAULT_PROFILE;
|
||||
Profile p = getProfiles().get(name);
|
||||
if (p == null)
|
||||
if (getProfiles().containsKey(DEFAULT_PROFILE))
|
||||
p = getProfiles().get(DEFAULT_PROFILE);
|
||||
else
|
||||
getProfiles().put(DEFAULT_PROFILE, p = new Profile());
|
||||
return p;
|
||||
}
|
||||
|
||||
public static boolean hasProfile(String name) {
|
||||
if (name == null)
|
||||
name = DEFAULT_PROFILE;
|
||||
return getProfiles().containsKey(name);
|
||||
}
|
||||
|
||||
public static Map<String, Profile> getProfiles() {
|
||||
@@ -121,14 +127,14 @@ public final class Settings {
|
||||
}
|
||||
|
||||
public static Collection<Profile> getProfilesFiltered() {
|
||||
return CollectionUtils.map(getProfiles().values(), (t) -> t != null && t.getName() != null);
|
||||
return CollectionUtils.map(getProfiles().values(), t -> t != null && t.getName() != null);
|
||||
}
|
||||
|
||||
public static Profile getOneProfile() {
|
||||
return SETTINGS.getConfigurations().firstEntry().getValue();
|
||||
}
|
||||
|
||||
public static boolean trySetProfile(Profile ver) {
|
||||
public static boolean putProfile(Profile ver) {
|
||||
if (ver == null || ver.getName() == null || getProfiles().containsKey(ver.getName()))
|
||||
return false;
|
||||
getProfiles().put(ver.getName(), ver);
|
||||
@@ -146,4 +152,20 @@ public final class Settings {
|
||||
}
|
||||
return getProfiles().remove(ver) != null;
|
||||
}
|
||||
|
||||
public static final EventHandler<Profile> profileChangedEvent = new EventHandler(null);
|
||||
public static final EventHandler<Void> profileLoadingEvent = new EventHandler(null);
|
||||
|
||||
static void onProfileChanged() {
|
||||
Profile p = getLastProfile();
|
||||
if (p == null)
|
||||
throw new Error("No profiles here, it should not happen");
|
||||
profileChangedEvent.execute(p);
|
||||
p.onSelected();
|
||||
}
|
||||
|
||||
public static void onProfileLoading() {
|
||||
profileLoadingEvent.execute(null);
|
||||
onProfileChanged();
|
||||
}
|
||||
}
|
||||
Executable → Regular
+40
-151
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
* 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
|
||||
@@ -15,36 +15,33 @@
|
||||
* 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.settings;
|
||||
package org.jackhuang.hellominecraft.launcher.setting;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
|
||||
import org.jackhuang.hellominecraft.launcher.core.LauncherVisibility;
|
||||
import org.jackhuang.hellominecraft.launcher.core.MCUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.util.LauncherVisibility;
|
||||
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.GameDirType;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
import org.jackhuang.hellominecraft.utils.system.Java;
|
||||
import org.jackhuang.hellominecraft.utils.system.JdkVersion;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.util.C;
|
||||
import org.jackhuang.hellominecraft.util.EventHandler;
|
||||
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||
import org.jackhuang.hellominecraft.util.Utils;
|
||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.util.system.Java;
|
||||
import org.jackhuang.hellominecraft.util.system.JdkVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Profile {
|
||||
public class VersionSetting {
|
||||
|
||||
private String name, selectedMinecraftVersion = "", javaArgs, minecraftArgs, maxMemory, permSize, width, height, userProperties;
|
||||
private String gameDir, javaDir, precalledCommand, serverIp, java;
|
||||
private boolean fullscreen, debug, noJVMArgs, canceledWrapper;
|
||||
public transient String id;
|
||||
|
||||
private String javaArgs, minecraftArgs, maxMemory, permSize, width, height;
|
||||
private String javaDir, precalledCommand, serverIp, java, wrapper;
|
||||
private boolean fullscreen, noJVMArgs;
|
||||
|
||||
/**
|
||||
* 0 - Close the launcher when the game starts.<br/>
|
||||
@@ -59,32 +56,19 @@ public final class Profile {
|
||||
*/
|
||||
private int gameDirType;
|
||||
|
||||
protected transient IMinecraftService service;
|
||||
public transient final EventHandler<String> propertyChanged = new EventHandler<>(this);
|
||||
|
||||
public Profile() {
|
||||
this("Default");
|
||||
public VersionSetting() {
|
||||
fullscreen = false;
|
||||
launcherVisibility = 1;
|
||||
gameDirType = 0;
|
||||
javaDir = java = minecraftArgs = serverIp = precalledCommand = wrapper = "";
|
||||
}
|
||||
|
||||
public Profile(String name) {
|
||||
this.name = name;
|
||||
gameDir = MCUtils.getInitGameDir().getPath();
|
||||
debug = fullscreen = canceledWrapper = false;
|
||||
launcherVisibility = gameDirType = 0;
|
||||
PluginManager.NOW_PLUGIN.onInitializingProfile(this);
|
||||
javaDir = java = minecraftArgs = serverIp = precalledCommand = "";
|
||||
}
|
||||
|
||||
public void initialize(int gameDirType) {
|
||||
this.gameDirType = gameDirType;
|
||||
}
|
||||
|
||||
public Profile(Profile v) {
|
||||
public VersionSetting(VersionSetting v) {
|
||||
this();
|
||||
if (v == null)
|
||||
return;
|
||||
name = v.name;
|
||||
gameDir = v.gameDir;
|
||||
maxMemory = v.maxMemory;
|
||||
width = v.width;
|
||||
height = v.height;
|
||||
@@ -92,70 +76,16 @@ public final class Profile {
|
||||
fullscreen = v.fullscreen;
|
||||
javaArgs = v.javaArgs;
|
||||
javaDir = v.javaDir;
|
||||
debug = v.debug;
|
||||
minecraftArgs = v.minecraftArgs;
|
||||
permSize = v.permSize;
|
||||
gameDirType = v.gameDirType;
|
||||
canceledWrapper = v.canceledWrapper;
|
||||
noJVMArgs = v.noJVMArgs;
|
||||
launcherVisibility = v.launcherVisibility;
|
||||
precalledCommand = v.precalledCommand;
|
||||
wrapper = v.wrapper;
|
||||
serverIp = v.serverIp;
|
||||
}
|
||||
|
||||
public IMinecraftService service() {
|
||||
if (service == null)
|
||||
service = PluginManager.NOW_PLUGIN.provideMinecraftService(this);
|
||||
return service;
|
||||
}
|
||||
|
||||
public String getSettingsSelectedMinecraftVersion() {
|
||||
return selectedMinecraftVersion;
|
||||
}
|
||||
|
||||
public String getSelectedVersion() {
|
||||
String v = selectedMinecraftVersion;
|
||||
if (StrUtils.isBlank(v) || service.version().getVersionById(v) == null) {
|
||||
v = service.version().getOneVersion().id;
|
||||
if (v != null)
|
||||
setSelectedMinecraftVersion(v);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public transient final EventHandler<String> selectedVersionChangedEvent = new EventHandler<>(this);
|
||||
|
||||
public void setSelectedMinecraftVersion(String selectedMinecraftVersion) {
|
||||
this.selectedMinecraftVersion = selectedMinecraftVersion;
|
||||
propertyChanged.execute("selectedMinecraftVersion");
|
||||
selectedVersionChangedEvent.execute(selectedMinecraftVersion);
|
||||
}
|
||||
|
||||
public String getGameDir() {
|
||||
if (StrUtils.isBlank(gameDir))
|
||||
gameDir = MCUtils.getInitGameDir().getPath();
|
||||
return IOUtils.addSeparator(gameDir);
|
||||
}
|
||||
|
||||
public String getCanonicalGameDir() {
|
||||
return IOUtils.tryGetCanonicalFolderPath(getGameDirFile());
|
||||
}
|
||||
|
||||
public File getCanonicalGameDirFile() {
|
||||
return IOUtils.tryGetCanonicalFile(getGameDirFile());
|
||||
}
|
||||
|
||||
public File getGameDirFile() {
|
||||
return new File(getGameDir());
|
||||
}
|
||||
|
||||
public Profile setGameDir(String gameDir) {
|
||||
this.gameDir = gameDir;
|
||||
service().version().refreshVersions();
|
||||
propertyChanged.execute("gameDir");
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getJavaDir() {
|
||||
Java j = getJava();
|
||||
if (j.getHome() == null)
|
||||
@@ -186,7 +116,7 @@ public final class Profile {
|
||||
java = "Custom";
|
||||
int idx = Java.JAVA.indexOf(new Java(java, null));
|
||||
if (idx == -1) {
|
||||
java = "Default";
|
||||
java = Java.suggestedJava().getName();
|
||||
idx = 0;
|
||||
}
|
||||
return idx;
|
||||
@@ -204,21 +134,6 @@ public final class Profile {
|
||||
propertyChanged.execute("java");
|
||||
}
|
||||
|
||||
public File getFolder(String folder) {
|
||||
if (getSelectedVersion() == null)
|
||||
return new File(getCanonicalGameDirFile(), folder);
|
||||
return service().version().getRunDirectory(getSelectedVersion(), folder);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
propertyChanged.execute("name");
|
||||
}
|
||||
|
||||
public String getJavaArgs() {
|
||||
if (StrUtils.isBlank(javaArgs))
|
||||
return "";
|
||||
@@ -267,17 +182,6 @@ public final class Profile {
|
||||
propertyChanged.execute("height");
|
||||
}
|
||||
|
||||
public String getUserProperties() {
|
||||
if (userProperties == null)
|
||||
return "";
|
||||
return userProperties;
|
||||
}
|
||||
|
||||
public void setUserProperties(String userProperties) {
|
||||
this.userProperties = userProperties;
|
||||
propertyChanged.execute("userProperties");
|
||||
}
|
||||
|
||||
public boolean isFullscreen() {
|
||||
return fullscreen;
|
||||
}
|
||||
@@ -287,15 +191,6 @@ public final class Profile {
|
||||
propertyChanged.execute("fullscreen");
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
propertyChanged.execute("debug");
|
||||
}
|
||||
|
||||
public LauncherVisibility getLauncherVisibility() {
|
||||
return LauncherVisibility.values()[launcherVisibility];
|
||||
}
|
||||
@@ -313,7 +208,6 @@ public final class Profile {
|
||||
|
||||
public void setGameDirType(GameDirType gameDirType) {
|
||||
this.gameDirType = gameDirType.ordinal();
|
||||
service().version().setGameDirType(getGameDirType());
|
||||
propertyChanged.execute("gameDirType");
|
||||
}
|
||||
|
||||
@@ -344,15 +238,6 @@ public final class Profile {
|
||||
propertyChanged.execute("minecraftArgs");
|
||||
}
|
||||
|
||||
public boolean isCanceledWrapper() {
|
||||
return canceledWrapper;
|
||||
}
|
||||
|
||||
public void setCanceledWrapper(boolean canceledWrapper) {
|
||||
this.canceledWrapper = canceledWrapper;
|
||||
propertyChanged.execute("canceledWrapper");
|
||||
}
|
||||
|
||||
public String getPrecalledCommand() {
|
||||
return precalledCommand;
|
||||
}
|
||||
@@ -362,6 +247,15 @@ public final class Profile {
|
||||
propertyChanged.execute("precalledCommand");
|
||||
}
|
||||
|
||||
public String getWrapper() {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
public void setWrapper(String wrapper) {
|
||||
this.wrapper = wrapper;
|
||||
propertyChanged.execute("wrapper");
|
||||
}
|
||||
|
||||
public String getServerIp() {
|
||||
return serverIp;
|
||||
}
|
||||
@@ -371,23 +265,20 @@ public final class Profile {
|
||||
propertyChanged.execute("serverIp");
|
||||
}
|
||||
|
||||
public void checkFormat() {
|
||||
gameDir = gameDir.replace('/', OS.os().fileSeparator).replace('\\', OS.os().fileSeparator);
|
||||
}
|
||||
|
||||
public LaunchOptions createLaunchOptions() {
|
||||
public LaunchOptions createLaunchOptions(File gameDir) {
|
||||
LaunchOptions x = new LaunchOptions();
|
||||
x.setCanceledWrapper(isCanceledWrapper());
|
||||
x.setDebug(isDebug());
|
||||
x.setFullscreen(isFullscreen());
|
||||
x.setGameDir(getCanonicalGameDirFile());
|
||||
x.setWrapper(getWrapper());
|
||||
x.setGameDir(gameDir);
|
||||
x.setGameDirType(getGameDirType());
|
||||
x.setHeight(getHeight());
|
||||
x.setJavaArgs(getJavaArgs());
|
||||
x.setLaunchVersion(getSelectedVersion());
|
||||
x.setLaunchVersion(id);
|
||||
x.setMaxMemory(getMaxMemory());
|
||||
x.setMinecraftArgs(getMinecraftArgs());
|
||||
x.setName(getName());
|
||||
x.setName(Main.shortTitle());
|
||||
x.setType(Main.shortTitle());
|
||||
x.setVersionName(Main.shortTitle());
|
||||
x.setNoJVMArgs(isNoJVMArgs());
|
||||
x.setPermSize(getPermSize());
|
||||
x.setPrecalledCommand(getPrecalledCommand());
|
||||
@@ -396,8 +287,6 @@ public final class Profile {
|
||||
x.setProxyUser(Settings.getInstance().getProxyUserName());
|
||||
x.setProxyPass(Settings.getInstance().getProxyPassword());
|
||||
x.setServerIp(getServerIp());
|
||||
x.setUserProperties(getUserProperties());
|
||||
x.setVersionName(Main.makeTitle());
|
||||
x.setWidth(getWidth());
|
||||
|
||||
String str = getJavaDir();
|
||||
+37
-5
@@ -15,7 +15,7 @@
|
||||
* 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.views;
|
||||
package org.jackhuang.hellominecraft.launcher.ui;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Graphics;
|
||||
@@ -24,7 +24,7 @@ import java.awt.image.BufferedImage;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.Timer;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.launcher.setting.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -51,8 +51,10 @@ public class AnimatedPanel extends JPanel implements Selectable {
|
||||
|
||||
Timer timer;
|
||||
|
||||
boolean animationEnabled = true;
|
||||
|
||||
public void animate() {
|
||||
if (Settings.getInstance().isEnableAnimation()) {
|
||||
if (Settings.getInstance().isEnableAnimation() && animationEnabled) {
|
||||
offsetX = 0;
|
||||
timer.start();
|
||||
}
|
||||
@@ -60,6 +62,10 @@ public class AnimatedPanel extends JPanel implements Selectable {
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
if (!(g instanceof Graphics2D)) {
|
||||
super.paint(g);
|
||||
return;
|
||||
}
|
||||
double pgs = 1 - Math.sin(Math.PI / 2 / ANIMATION_LENGTH * offsetX);
|
||||
if (Math.abs(ANIMATION_LENGTH - offsetX) < 0.1) {
|
||||
super.paint(g);
|
||||
@@ -85,8 +91,34 @@ public class AnimatedPanel extends JPanel implements Selectable {
|
||||
g.drawImage(image, 0, 0, this);
|
||||
}
|
||||
|
||||
boolean selected = false;
|
||||
|
||||
@Override
|
||||
public void onSelected() {
|
||||
animate();
|
||||
public boolean isSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelect() {
|
||||
if (!selected)
|
||||
animate();
|
||||
selected = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLeave() {
|
||||
selected = false;
|
||||
}
|
||||
|
||||
boolean created = false;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
created = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCreated() {
|
||||
return created;
|
||||
}
|
||||
}
|
||||
Loaded 100 of 546 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user