aboutsummaryrefslogtreecommitdiff
path: root/loader/src
diff options
context:
space:
mode:
Diffstat (limited to 'loader/src')
-rwxr-xr-xloader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java86
-rwxr-xr-xloader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/Authenticator.java75
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java3
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java38
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java8
5 files changed, 93 insertions, 117 deletions
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
index c279d812..1df59f83 100755
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
@@ -30,7 +30,6 @@ import kr.syeyoung.dungeonsguide.launcher.loader.IDGLoader;
import kr.syeyoung.dungeonsguide.launcher.loader.JarLoader;
import kr.syeyoung.dungeonsguide.launcher.loader.LocalLoader;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.IReloadableResourceManager;
@@ -95,8 +94,7 @@ public class Main
}
} catch (Exception e) {
e.printStackTrace();
- lastError = e;
- tryOpenError();
+ setLastFatalError(e);
}
}
}
@@ -114,11 +112,8 @@ public class Main
}
currentLoader = null;
}
- public void load(IDGLoader newLoader) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
- if (dgInterface != null) throw new IllegalStateException("DG is loaded");
- newLoader.loadJar(authenticator);
- dgInterface = newLoader.getInstance();
- currentLoader = newLoader;
+ private void load(IDGLoader newLoader) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+ partialLoad(newLoader);
dgInterface.init(configDir);
@@ -138,11 +133,11 @@ public class Main
unload();
load(newLoader);
} catch (Exception e) {
- e.printStackTrace();
- lastError = e;
dgInterface = null;
currentLoader = null;
- tryOpenError();
+
+ e.printStackTrace();
+ setLastFatalError(e);
}
}
@@ -209,83 +204,44 @@ public class Main
@EventHandler
public void preInit(FMLPreInitializationEvent preInitializationEvent) {
+ // setup static variables
main = this;
configDir = preInitializationEvent.getModConfigurationDirectory();
- ProgressManager.ProgressBar bar = null;
+
+ // setup preinit progress bar for well, progress bar!
+ ProgressManager.ProgressBar bar = ProgressManager.push("DungeonsGuide", 2);
try {
- bar = ProgressManager.push("DungeonsGuide",2);
+ // Try authenticate
bar.step("Authenticating...");
authenticator.repeatAuthenticate(5);
+
+ // If authentication succeeds, obtain loader and partially load dungeons guide
File f = new File(preInitializationEvent.getModConfigurationDirectory(), "loader.cfg");
Configuration configuration = new Configuration(f);
- bar.step("Instantiating...");
+ bar.step("Instantiating...");
partialLoad(obtainLoader(configuration));
+ // Save config because... well to generate it
configuration.save();
} catch (Throwable t) {
- t.printStackTrace();
- lastError = t;
dgInterface = null;
currentLoader = null;
- tryOpenError();
+
+ t.printStackTrace();
+ setLastFatalError(t);
} finally {
- if (bar != null) {
- while(bar.getStep() < bar.getSteps()) bar.step("");
- ProgressManager.pop(bar);
- }
+ while(bar.getStep() < bar.getSteps()) bar.step("");
+ ProgressManager.pop(bar);
}
((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(a -> {
if (dgInterface != null) dgInterface.onResourceReload(a);
});
-// try {
-// token = authenticator.authenticateAndDownload(this.getClass().getResourceAsStream("/kr/syeyoung/dungeonsguide/DungeonsGuide.class") == null ? System.getProperty("dg.version") == null ? "nlatest" : System.getProperty("dg.version") : null);
-// if (token != null) {
-// main = this;
-// URL.setURLStreamHandlerFactory(new DGStreamHandlerFactory(authenticator));
-// LaunchClassLoader classLoader = (LaunchClassLoader) Main.class.getClassLoader();
-// classLoader.addURL(new URL("z:///"));
-//
-// try {
-// progressBar.step("Initializing");
-// this.dgInterface = new DungeonsGuide(authenticator);
-// this.dgInterface.pre(preInitializationEvent);
-// while (progressBar.getStep() < progressBar.getSteps())
-// progressBar.step("random-"+progressBar.getStep());
-// ProgressManager.pop(progressBar);
-// isLoaded = true;
-// } catch (Throwable e) {
-// cause = e;
-// ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-// PrintStream printStream = new PrintStream(byteArrayOutputStream);
-// e.printStackTrace(printStream);
-// stacktrace = new String(byteArrayOutputStream.toByteArray());
-//
-// while (progressBar.getStep() < progressBar.getSteps())
-// progressBar.step("random-"+progressBar.getStep());
-// ProgressManager.pop(progressBar);
-//
-// e.printStackTrace();
-// }
-// }
-// } catch (IOException | AuthenticationException | NoSuchAlgorithmException | CertificateException | KeyStoreException | KeyManagementException | InvalidKeySpecException | SignatureException e) {
-// cause = e;
-// ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-// PrintStream printStream = new PrintStream(byteArrayOutputStream);
-// e.printStackTrace(printStream);
-// stacktrace = new String(byteArrayOutputStream.toByteArray());
-//
-// while (progressBar.getStep() < progressBar.getSteps())
-// progressBar.step("random-"+progressBar.getStep());
-// ProgressManager.pop(progressBar);
-//
-// e.printStackTrace();
-// }
}
- public void setLastError(Throwable t) {
+ public void setLastFatalError(Throwable t) {
lastError = t;
tryOpenError();
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/Authenticator.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/Authenticator.java
index 627a058f..d06e3a39 100755
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/Authenticator.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/Authenticator.java
@@ -33,7 +33,6 @@ import org.json.JSONObject;
import sun.reflect.Reflection;
import javax.crypto.*;
-import javax.net.ssl.*;
import java.io.*;
import java.math.BigInteger;
import java.net.*;
@@ -46,7 +45,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Authenticator {
- private String token;
+ private String dgAccessToken;
private Instant validThru;
@Getter
private TokenStatus tokenStatus = TokenStatus.UNAUTHENTICATED;
@@ -60,21 +59,21 @@ public class Authenticator {
}
public String getRawToken() {
- return token;
+ return dgAccessToken;
}
public String getUnexpiredToken() {
if (tokenStatus != TokenStatus.AUTHENTICATED) throw new IllegalStateException("Token is not available");
- long expiry = getJwtPayload(token).getLong("exp");
+ long expiry = getJwtPayload(dgAccessToken).getLong("exp");
if (System.currentTimeMillis() >= expiry-2000 || tokenStatus == TokenStatus.EXPIRED) {
tokenStatus = TokenStatus.EXPIRED;
try {
repeatAuthenticate(5);
} catch (Throwable t) {
- Main.getMain().setLastError(t);
+ Main.getMain().setLastFatalError(t);
throw new TokenExpiredException(t);
}
}
- return token;
+ return dgAccessToken;
}
@@ -99,25 +98,24 @@ public class Authenticator {
}
cnt++;
}
- return token;
+ return dgAccessToken;
}
public String reauthenticate() throws IOException, AuthenticationException, NoSuchAlgorithmException {
try {
authenticationLock.lock();
- MinecraftSessionService yggdrasilMinecraftSessionService = Minecraft.getMinecraft().getSessionService();
- Session session = Minecraft.getMinecraft().getSession();
-
tokenStatus = TokenStatus.UNAUTHENTICATED;
- token = null;
- token = requestAuth(session.getProfile().getId(), session.getProfile().getName());
- JSONObject d = getJwtPayload(token);
+ dgAccessToken = null;
- byte[] sharedSecret = generateSharedSecret();
+ MinecraftSessionService yggdrasilMinecraftSessionService = Minecraft.getMinecraft().getSessionService();
+ Session SECURE_USER_SESSION = Minecraft.getMinecraft().getSession();
+ dgAccessToken = requestAuth(SECURE_USER_SESSION.getProfile().getId(), SECURE_USER_SESSION.getProfile().getName()); // id: uuid, name: username
- String hash = calculateServerHash(sharedSecret,
- Base64.decodeBase64(d.getString("publicKey")));
+ JSONObject d = getJwtPayload(dgAccessToken);
+ byte[] sharedSecret = generateSharedSecret(); // Notice.... shared secret is generated on the client side unlike dg 3.0. Yep, I was a stupid when making 3.0.
+
+ String hash = calculateServerHash(sharedSecret, Base64.decodeBase64(d.getString("publicKey"))); // Public Key here is server's public key.
byte[] encodedSharedSecret;
try {
@@ -128,17 +126,19 @@ public class Authenticator {
InvalidKeySpecException |
InvalidKeyException e) {
throw new RuntimeException(e);
- }
+ } // Server connection is SSL but I still encrypt it using publicKey. Additional layer of security considering the request goes through cloudflare. (it's not like I don't trust cloudflare, but idk)
- yggdrasilMinecraftSessionService.joinServer(session.getProfile(), session.getToken(), hash); // Sent to "MOJANG" Server.
- JSONObject furtherStuff = verifyAuth(token, encodedSharedSecret);
- token = furtherStuff.getString("jwt");
+ yggdrasilMinecraftSessionService.joinServer(SECURE_USER_SESSION.getProfile(), SECURE_USER_SESSION.getToken(), hash); // Sent to "MOJANG" Server.
+
+ JSONObject furtherStuff = verifyAuth(dgAccessToken, encodedSharedSecret);
+
+ dgAccessToken = furtherStuff.getString("jwt");
if ("TOS_PRIVACY_POLICY_ACCEPT_REQUIRED".equals(furtherStuff.getString("result"))) {
tokenStatus = TokenStatus.PP_REQUIRED;
throw new PrivacyPolicyRequiredException();
}
tokenStatus = TokenStatus.AUTHENTICATED;
- return this.token;
+ return this.dgAccessToken;
} finally {
authenticationLock.unlock();
}
@@ -148,14 +148,14 @@ public class Authenticator {
try {
authenticationLock.lock();
if (tokenStatus != TokenStatus.PP_REQUIRED) throw new IllegalStateException("Already accepted TOS");
- JSONObject furtherStuff = acceptPrivacyPolicy(token);
- token = furtherStuff.getString("jwt");
+ JSONObject furtherStuff = acceptPrivacyPolicy(dgAccessToken);
+ dgAccessToken = furtherStuff.getString("jwt");
if ("TOS_PRIVACY_POLICY_ACCEPT_REQUIRED".equals(furtherStuff.getString("result"))) {
tokenStatus = TokenStatus.PP_REQUIRED;
throw new PrivacyPolicyRequiredException();
}
tokenStatus = TokenStatus.AUTHENTICATED;
- return this.token;
+ return this.dgAccessToken;
} finally {
authenticationLock.unlock();
}
@@ -186,20 +186,22 @@ public class Authenticator {
}
}
}
- private JSONObject verifyAuth(String tempToken, byte[] secret) throws IOException {
+ private JSONObject verifyAuth(String tempToken, byte[] encryptedSecret) throws IOException {
HttpURLConnection urlConnection = request("POST", "/auth/v2/authenticate");
- urlConnection.getOutputStream().write(("{\"jwt\":\""+tempToken+"\",\"sharedSecret\":\""+Base64.encodeBase64URLSafeString(secret)+"}").getBytes());
+ urlConnection.getOutputStream().write(("{\"jwt\":\""+tempToken+"\",\"sharedSecret\":\""+Base64.encodeBase64URLSafeString(encryptedSecret)+"}").getBytes());
try (InputStream is = obtainInputStream(urlConnection)) {
String payload = String.join("\n", IOUtils.readLines(is));
if (urlConnection.getResponseCode() != 200)
System.out.println("/auth/authenticate :: Received " + urlConnection.getResponseCode() + " along with\n" + payload);
- JSONObject jsonObject = new JSONObject(payload);
- if (!"Success".equals(jsonObject.getString("status"))) {
- throw new AuthServerException(jsonObject);
+ JSONObject json = new JSONObject(payload);
+
+ if ("Success".equals(json.getString("status"))) {
+ return json.getJSONObject("data");
+ } else {
+ throw new AuthServerException(json);
}
- return jsonObject.getJSONObject("data");
}
}
private JSONObject acceptPrivacyPolicy(String tempToken) throws IOException {
@@ -211,11 +213,13 @@ public class Authenticator {
if (urlConnection.getResponseCode() != 200)
System.out.println("/auth/authenticate :: Received " + urlConnection.getResponseCode() + " along with\n" + payload);
- JSONObject jsonObject = new JSONObject(payload);
- if (!"Success".equals(jsonObject.getString("status"))) {
- throw new AuthServerException(jsonObject);
+ JSONObject json = new JSONObject(payload);
+
+ if ("Success".equals(json.getString("status"))) {
+ return json.getJSONObject("data");
+ } else {
+ throw new AuthServerException(json);
}
- return jsonObject.getJSONObject("data");
}
}
@@ -238,9 +242,10 @@ public class Authenticator {
}
return inputStream;
}
+
public HttpURLConnection request(String method, String url) throws IOException {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(Main.DOMAIN+url).openConnection();
- urlConnection.setRequestMethod(method);
+ urlConnection.setRequestMethod(method); // TODO: setup SSL certificate here, because.... SOME PEOPLE HAVE THAT ISSUE, I HAVE NO IDEA WHY THEY DONT HAVE CLOUDFLARE CERTS INSTALLED ON THEM
urlConnection.setRequestProperty("User-Agent", "DungeonsGuide/1.0");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java
index ceff437e..53d9b70d 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java
@@ -23,6 +23,8 @@ import kr.syeyoung.dungeonsguide.launcher.authentication.Authenticator;
import kr.syeyoung.dungeonsguide.launcher.exceptions.ReferenceLeakedException;
import net.minecraftforge.common.config.Configuration;
+import java.io.InputStream;
+
public interface IDGLoader {
void loadJar(Authenticator authenticator) throws InstantiationException, IllegalAccessException, ClassNotFoundException;
DGInterface getInstance();
@@ -33,4 +35,5 @@ public interface IDGLoader {
boolean isLoaded();
String strategyName();
+ String version();
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java
index 2012412a..0b6cf124 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java
@@ -23,6 +23,7 @@ import kr.syeyoung.dungeonsguide.launcher.Main;
import kr.syeyoung.dungeonsguide.launcher.authentication.Authenticator;
import kr.syeyoung.dungeonsguide.launcher.exceptions.ReferenceLeakedException;
+import java.io.InputStream;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
@@ -46,30 +47,27 @@ public class JarLoader implements IDGLoader {
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
- // First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
- long t0 = System.nanoTime();
- if (c == null) {
- // If still not found, then invoke findClass in order
- // to find the class.
- long t1 = System.nanoTime();
- c = findClass(name);
-
- // this is the defining class loader; record the stats
- sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
- sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
- sun.misc.PerfCounter.getFindClasses().increment();
- }
try {
- if (getParent() != null && c == null) {
- c = getParent().loadClass(name);
+ if (c == null) {
+ long t0 = System.nanoTime();
+ c = findClass(name);
+
+ sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t0);
+ sun.misc.PerfCounter.getFindClasses().increment();
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
+ if (getParent() != null && c == null) {
+ long t0 = System.nanoTime();
+ c = getParent().loadClass(name);
+ long t1 = System.nanoTime();
+ sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
+ }
}
if (resolve) {
resolveClass(c);
@@ -83,11 +81,13 @@ public class JarLoader implements IDGLoader {
}
}
+ private JarClassLoader classLoader;
+
@Override
public void loadJar(Authenticator authenticator) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
if (dgInterface != null) throw new IllegalStateException("Already loaded");
- JarClassLoader classLoader = new JarClassLoader(new URL[] {
+ classLoader = new JarClassLoader(new URL[] {
Main.class.getResource("/mod.jar")
}, this.getClass().getClassLoader());
@@ -102,6 +102,7 @@ public class JarLoader implements IDGLoader {
@Override
public void unloadJar() throws ReferenceLeakedException {
+ classLoader = null;
dgInterface.unload();
dgInterface = null;
System.gc();// pls do
@@ -125,4 +126,9 @@ public class JarLoader implements IDGLoader {
public String strategyName() {
return "jar";
}
+
+ @Override
+ public String version() {
+ return "unknown"; // maybe read the thing...
+ }
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java
index 67c43ad5..1338138d 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java
@@ -22,6 +22,8 @@ import kr.syeyoung.dungeonsguide.launcher.DGInterface;
import kr.syeyoung.dungeonsguide.launcher.authentication.Authenticator;
import kr.syeyoung.dungeonsguide.launcher.exceptions.ReferenceLeakedException;
+import java.io.InputStream;
+
public class LocalLoader implements IDGLoader {
private DGInterface dgInterface;
@@ -40,7 +42,6 @@ public class LocalLoader implements IDGLoader {
public void unloadJar() throws ReferenceLeakedException {
throw new UnsupportedOperationException();
}
-
@Override
public boolean isUnloadable() {
return false;
@@ -55,4 +56,9 @@ public class LocalLoader implements IDGLoader {
public String strategyName() {
return "local";
}
+
+ @Override
+ public String version() {
+ return "unknown";
+ }
}