aboutsummaryrefslogtreecommitdiff
path: root/loader
diff options
context:
space:
mode:
authorsyeyoung <cyoung06@naver.com>2022-11-15 18:20:28 +0900
committersyeyoung <cyoung06@naver.com>2022-11-15 22:35:11 +0900
commit0b4ce8c26a3126530599786d4a31c4bae44f7ec6 (patch)
tree5360891327afbea72cdaca0d3c0f563cb9a3e296 /loader
parent846a2593242e98cb82e64f00382c3b607c93b7d3 (diff)
parent4ab5c2f66b0592600d14486ecf4d1628e6c856dc (diff)
downloadSkyblock-Dungeons-Guide-0b4ce8c26a3126530599786d4a31c4bae44f7ec6.tar.gz
Skyblock-Dungeons-Guide-0b4ce8c26a3126530599786d4a31c4bae44f7ec6.tar.bz2
Skyblock-Dungeons-Guide-0b4ce8c26a3126530599786d4a31c4bae44f7ec6.zip
- Merge Breaking changes.
Signed-off-by: syeyoung <cyoung06@naver.com>
Diffstat (limited to 'loader')
-rwxr-xr-xloader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java11
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java140
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthToken.java17
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthUtil.java70
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/InvalidDungeonsGuideCredentialsException.java8
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/NullToken.java36
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/ResourceManager.java164
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/AuthProvider.java16
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/DgAuth/DgAuth.java46
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/DgAuth/DgAuthUtil.java88
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/NullAuth.java62
-rwxr-xr-xloader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/Authenticator.java257
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/TokenStatus.java27
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/branch/ModDownloader.java302
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/GuiLoadingError.java81
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/IDGLoader.java10
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java8
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java9
-rwxr-xr-xloader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGConnection.java42
-rwxr-xr-xloader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGStreamHandler.java28
-rwxr-xr-xloader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGStreamHandlerFactory.java28
-rwxr-xr-xloader/src/main/resources/mcmod.info6
22 files changed, 731 insertions, 725 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 7cc0f806..921adca9 100755
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
@@ -61,7 +61,7 @@ public class Main
private static Main main;
- private File configDir;
+ private static File configDir;
private DGInterface dgInterface;
private Authenticator authenticator = new Authenticator();
@@ -69,6 +69,10 @@ public class Main
private List<DungeonsGuideReloadListener> listeners = new ArrayList<>();
+ public static File getConfigDir() {
+ return configDir;
+ }
+
public void addDGReloadListener(DungeonsGuideReloadListener dungeonsGuideReloadListener) {
listeners.add(Objects.requireNonNull(dungeonsGuideReloadListener));
}
@@ -111,7 +115,7 @@ public class Main
listener.unloadReference();
}
if (currentLoader != null) {
- currentLoader.unloadJar();
+ currentLoader.unloadDungeonsGuide();
}
currentLoader = null;
}
@@ -126,8 +130,7 @@ public class Main
}
private void partialLoad(IDGLoader newLoader) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
if (dgInterface != null) throw new IllegalStateException("DG is loaded");
- newLoader.loadJar(authenticator);
- dgInterface = newLoader.getInstance();
+ dgInterface = newLoader.loadDungeonsGuide();
currentLoader = newLoader;
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java
new file mode 100644
index 00000000..23d9cf06
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java
@@ -0,0 +1,140 @@
+package kr.syeyoung.dungeonsguide.launcher.auth;
+
+import com.google.common.base.Throwables;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import com.google.gson.JsonObject;
+import com.mojang.authlib.exceptions.AuthenticationException;
+import kr.syeyoung.dungeonsguide.launcher.auth.authprovider.AuthProvider;
+import kr.syeyoung.dungeonsguide.launcher.auth.authprovider.DgAuth.DgAuth;
+import kr.syeyoung.dungeonsguide.launcher.auth.authprovider.DgAuth.DgAuthUtil;
+import kr.syeyoung.dungeonsguide.mod.chat.ChatTransmitter;
+import kr.syeyoung.dungeonsguide.mod.events.impl.AuthChangedEvent;
+import kr.syeyoung.dungeonsguide.mod.stomp.StompManager;
+import lombok.Setter;
+import net.minecraft.client.Minecraft;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.IOException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.util.Objects;
+import java.util.concurrent.*;
+
+
+public class AuthManager {
+ Logger logger = LogManager.getLogger("AuthManger");
+
+ private static AuthManager INSTANCE;
+
+ public static AuthManager getInstance() {
+ if(INSTANCE == null) INSTANCE = new AuthManager();
+ return INSTANCE;
+ }
+
+ @Setter
+ private String baseserverurl = "https://dungeons.guide";
+
+ private AuthToken currentToken = new NullToken();
+
+ public String getToken() {
+ return currentToken.getToken();
+ }
+
+
+ public KeyPair getKeyPair(){
+ return currentToken.getRSAKeyForAuth();
+ }
+
+
+ private volatile boolean initlock = false;
+
+ public void init() {
+ if (initlock) {
+ logger.info("Cannot init AuthManger twice");
+ return;
+ }
+
+ reauth();
+
+ initlock = true;
+
+
+ MinecraftForge.EVENT_BUS.register(this);
+
+ ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("DgAuth Pool").build();
+ final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, namedThreadFactory);
+ scheduler.scheduleAtFixedRate(() -> {
+ if (getToken() != null) {
+ JsonObject obj = DgAuthUtil.getJwtPayload(getToken());
+ if (!obj.get("uuid").getAsString().replace("-", "").equals(Minecraft.getMinecraft().getSession().getPlayerID())) {
+ shouldReAuth = true;
+ }
+ }
+
+
+ }, 10,2000, TimeUnit.MILLISECONDS);
+ }
+
+ boolean shouldReAuth = true;
+ int tickCounter;
+
+ @SubscribeEvent
+ public void onTickClientTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+
+ if (tickCounter % 200 == 0) {
+ tickCounter = 0;
+ reauth();
+ }
+ tickCounter++;
+ }
+
+ public boolean isPlebUser(){
+ return Objects.equals(getInstance().getPlanType(), "OPENSOURCE");
+ }
+
+ public String getPlanType(){
+ if(getToken() == null) return null;
+
+
+ JsonObject jwt = DgAuthUtil.getJwtPayload(getToken());
+
+ if(!jwt.has("plan")) return null;
+
+ return jwt.get("plan").getAsString();
+
+ }
+
+ void reauth() {
+ if (!shouldReAuth) return;
+ shouldReAuth = false;
+ currentToken = new NullToken();
+ try {
+ currentProvider = new DgAuth(baseserverurl).createAuthProvider();
+ if (currentProvider.getToken() == null) {
+ shouldReAuth = true;
+ currentProvider = null;
+ ChatTransmitter.addToQueue("§eDungeons Guide §7:: §r§cDG auth failed, trying again in ten seconds", true);
+ logger.info("DG auth failed, trying again in a second");
+ } else {
+ // RE-AUTHed SUCCESSFULLY HOORAY
+ // for some reason the forge events don't work in pre init, so I call the callback directly
+ StompManager.getInstance().init();
+ MinecraftForge.EVENT_BUS.post(new AuthChangedEvent());
+ }
+ } catch (NoSuchAlgorithmException | AuthenticationException | IOException e) {
+
+ shouldReAuth = true;
+ currentProvider = null;
+ ChatTransmitter.addToQueue("§eDungeons Guide §7:: §r§cDG auth failed, trying again in ten seconds", true);
+ logger.error("Re-auth failed with message {}, trying again in a ten seconds", String.valueOf(Throwables.getRootCause(e)));
+ }
+
+ }
+
+
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthToken.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthToken.java
new file mode 100644
index 00000000..cb7c03da
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthToken.java
@@ -0,0 +1,17 @@
+package kr.syeyoung.dungeonsguide.launcher.auth;
+
+import java.security.KeyPair;
+import java.security.interfaces.RSAKey;
+import java.time.Instant;
+
+public interface AuthToken {
+ boolean isUserVerified();
+ boolean hasFullCapability();
+ boolean isAuthenticated();
+
+ Instant getExpiryInstant();
+
+ KeyPair getRSAKeyForAuth();
+
+ String getToken();
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthUtil.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthUtil.java
new file mode 100644
index 00000000..9ce02643
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthUtil.java
@@ -0,0 +1,70 @@
+package kr.syeyoung.dungeonsguide.launcher.auth;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+
+import javax.crypto.*;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import javax.net.ssl.HttpsURLConnection;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.security.*;
+
+public class AuthUtil {
+ private AuthUtil() {}
+
+ public static KeyPair getKeyPair() throws NoSuchAlgorithmException {
+ KeyPairGenerator a = null;
+ a = KeyPairGenerator.getInstance("RSA");
+ a.initialize(1024);
+ return a.generateKeyPair();
+ }
+
+
+ public static JsonElement getJsonSecured(String u) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException{
+
+ int length = 0;
+ CipherInputStream cipherInputStream = null;
+
+ HttpsURLConnection httpsURLConnection = (HttpsURLConnection) new URL(u).openConnection();
+ httpsURLConnection.setRequestProperty("User-Agent", "DungeonsGuide/1.0");
+ httpsURLConnection.setRequestProperty("Content-Type", "application/json");
+ httpsURLConnection.setRequestMethod("GET");
+ httpsURLConnection.setRequestProperty("Authorization", AuthManager.getInstance().getToken());
+ httpsURLConnection.setDoInput(true);
+ httpsURLConnection.setDoOutput(true);
+
+ InputStream inputStream = httpsURLConnection.getInputStream();
+ byte[] lengthPayload = new byte[4];
+ inputStream.read(lengthPayload);
+ length = ((lengthPayload[0] & 0xFF) << 24) |
+ ((lengthPayload[1] & 0xFF) << 16) |
+ ((lengthPayload[2] & 0xFF) << 8) |
+ ((lengthPayload[3] & 0xFF));
+ while (inputStream.available() < length) ;
+ byte[] keyPayload = new byte[length];
+ inputStream.read(keyPayload);
+
+ Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+ cipher.init(Cipher.DECRYPT_MODE, AuthManager.getInstance().getKeyPair().getPrivate());
+ byte[] AESKey = cipher.doFinal(keyPayload);
+
+ cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ SecretKeySpec secretKeySpec = new SecretKeySpec(AESKey, "AES");
+ IvParameterSpec ivParameterSpec = new IvParameterSpec(AESKey);
+ cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
+ cipherInputStream = new CipherInputStream(inputStream, cipher);
+ cipherInputStream.read(lengthPayload);
+ length = ((lengthPayload[0] & 0xFF) << 24) |
+ ((lengthPayload[1] & 0xFF) << 16) |
+ ((lengthPayload[2] & 0xFF) << 8) |
+ ((lengthPayload[3] & 0xFF));
+
+ httpsURLConnection.disconnect();
+
+ return new JsonParser().parse(new InputStreamReader(cipherInputStream));
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/InvalidDungeonsGuideCredentialsException.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/InvalidDungeonsGuideCredentialsException.java
new file mode 100644
index 00000000..ebe78196
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/InvalidDungeonsGuideCredentialsException.java
@@ -0,0 +1,8 @@
+package kr.syeyoung.dungeonsguide.launcher.auth;
+
+public class InvalidDungeonsGuideCredentialsException extends Throwable {
+
+ public InvalidDungeonsGuideCredentialsException(String message) {
+ super(message);
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/NullToken.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/NullToken.java
new file mode 100644
index 00000000..ddbfe58f
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/NullToken.java
@@ -0,0 +1,36 @@
+package kr.syeyoung.dungeonsguide.launcher.auth;
+
+import java.security.KeyPair;
+import java.time.Instant;
+
+public class NullToken implements AuthToken {
+ @Override
+ public boolean isUserVerified() {
+ return false;
+ }
+
+ @Override
+ public boolean hasFullCapability() {
+ return false;
+ }
+
+ @Override
+ public boolean isAuthenticated() {
+ return false;
+ }
+
+ @Override
+ public Instant getExpiryInstant() {
+ return Instant.MIN;
+ }
+
+ @Override
+ public KeyPair getRSAKeyForAuth() {
+ return null;
+ }
+
+ @Override
+ public String getToken() {
+ return null;
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/ResourceManager.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/ResourceManager.java
new file mode 100644
index 00000000..721b629f
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/ResourceManager.java
@@ -0,0 +1,164 @@
+package kr.syeyoung.dungeonsguide.launcher.auth;
+
+import lombok.Setter;
+import net.minecraftforge.common.MinecraftForge;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.crypto.*;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import javax.net.ssl.HttpsURLConnection;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.*;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class ResourceManager {
+
+ Logger logger = LogManager.getLogger("ResourceManager");
+
+ @Setter
+ private String baseUrl;
+ @Setter
+ private String BASE64_X509ENCODEDKEYSPEC;
+ private final HashMap<String, byte[]> loadedResources = new HashMap<>();
+
+
+ private static ResourceManager instance;
+ public static ResourceManager getInstance() {
+ if(instance == null) {
+ instance = new ResourceManager();
+ MinecraftForge.EVENT_BUS.register(instance);
+ }
+ return instance;
+ }
+
+ private ResourceManager() {
+ }
+
+ public Map<String, byte[]> getResources() {
+ return loadedResources;
+ }
+
+
+ public void downloadAssets(String version) throws InvalidDungeonsGuideCredentialsException {
+ if(AuthManager.getInstance().getToken() == null) throw new InvalidDungeonsGuideCredentialsException("Not Authenticated while downloading assets");
+ try {
+ // version not being null indicates that the user is "premium"
+ // so we download the special version
+ if (version != null)
+ downloadSafe( baseUrl + "/resource/version?v=" + version, true);
+
+ if(!AuthManager.getInstance().isPlebUser()){
+ downloadSafe(baseUrl + "/resource/roomdata", false);
+ } else {
+ logger.error("The current User is a pleb not downloading user data");
+ }
+
+ } catch (Exception t) {
+ t.printStackTrace();
+ }
+
+ }
+
+ private void downloadSafe(String url, boolean isValidateSignature) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, SignatureException, InvalidKeySpecException {
+ HttpsURLConnection dgConnection = (HttpsURLConnection) new URL(url).openConnection();
+ dgConnection.setRequestProperty("User-Agent", "DungeonsGuide/1.0");
+ dgConnection.setRequestProperty("Content-Type", "application/json");
+ dgConnection.setRequestMethod("GET");
+ dgConnection.setRequestProperty("Authorization", AuthManager.getInstance().getToken());
+ dgConnection.setDoInput(true);
+ dgConnection.setDoOutput(true);
+
+ InputStream inputStream = dgConnection.getInputStream();
+ byte[] lengthBytes = new byte[4];
+ inputStream.read(lengthBytes);
+ int length = ((lengthBytes[0] & 0xFF) << 24) |
+ ((lengthBytes[1] & 0xFF) << 16) |
+ ((lengthBytes[2] & 0xFF) << 8) |
+ ((lengthBytes[3] & 0xFF));
+ while (inputStream.available() < length) ;
+ byte[] keyPayload = new byte[length];
+ inputStream.read(keyPayload);
+
+ Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+ cipher.init(Cipher.DECRYPT_MODE, AuthManager.getInstance().getKeyPair().getPrivate());
+ byte[] h = cipher.doFinal(keyPayload);
+
+ cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ SecretKeySpec keySpec = new SecretKeySpec(h, "AES");
+ IvParameterSpec ivSpec = new IvParameterSpec(h);
+ cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
+ CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
+
+ cipherInputStream.read(lengthBytes);
+ length = ((lengthBytes[0] & 0xFF) << 24) |
+ ((lengthBytes[1] & 0xFF) << 16) |
+ ((lengthBytes[2] & 0xFF) << 8) |
+ ((lengthBytes[3] & 0xFF));
+
+ int totalLen = length;
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] buff = new byte[256];
+ while (totalLen > 0) {
+ int len = cipherInputStream.read(buff, 0, Math.min(buff.length, totalLen));
+ totalLen -= len;
+ bos.write(buff, 0, len);
+ }
+ byte[] body = bos.toByteArray();
+
+ byte[] signed;
+ if (isValidateSignature) {
+ cipherInputStream.read(lengthBytes,0 , 4);
+ length = ((lengthBytes[0] & 0xFF) << 24) |
+ ((lengthBytes[1] & 0xFF) << 16) |
+ ((lengthBytes[2] & 0xFF) << 8) |
+ ((lengthBytes[3] & 0xFF));
+
+ totalLen = length;
+ bos = new ByteArrayOutputStream();
+ while (totalLen > 0) {
+ int len = cipherInputStream.read(buff, 0, Math.min(buff.length, totalLen));
+ totalLen -= len;
+ bos.write(buff, 0, len);
+ }
+ signed = bos.toByteArray();
+
+ Signature sign = Signature.getInstance("SHA512withRSA");
+ sign.initVerify(getPublicKey(BASE64_X509ENCODEDKEYSPEC));
+ sign.update(body);
+ boolean truth = sign.verify(signed);
+ if (!truth) throw new SignatureException("DG SIGNATURE FORGED");
+ }
+
+ ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(body));
+ ZipEntry zipEntry;
+ while ((zipEntry=zipInputStream.getNextEntry()) != null) {
+ byte[] buffer = new byte[256];
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ int p;
+ while((p = zipInputStream.read(buffer)) > 0) {
+ byteArrayOutputStream.write(buffer, 0, p);
+ }
+ this.loadedResources.put(zipEntry.getName(), byteArrayOutputStream.toByteArray());
+ }
+ }
+
+
+ public static PublicKey getPublicKey(String base64X509EncodedKeySpec) throws NoSuchAlgorithmException, InvalidKeySpecException {
+ X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decodeBase64(base64X509EncodedKeySpec));
+
+ return KeyFactory.getInstance("RSA").generatePublic(spec);
+ }
+
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/AuthProvider.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/AuthProvider.java
new file mode 100644
index 00000000..d469c729
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/AuthProvider.java
@@ -0,0 +1,16 @@
+package kr.syeyoung.dungeonsguide.launcher.auth.authprovider;
+
+import com.mojang.authlib.exceptions.AuthenticationException;
+
+import java.io.IOException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+
+public interface AuthProvider {
+ String getToken();
+
+ KeyPair getRsaKey();
+
+
+ AuthProvider createAuthProvider() throws NoSuchAlgorithmException, AuthenticationException, IOException;
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/DgAuth/DgAuth.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/DgAuth/DgAuth.java
new file mode 100644
index 00000000..dca9ce33
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/DgAuth/DgAuth.java
@@ -0,0 +1,46 @@
+package kr.syeyoung.dungeonsguide.launcher.auth.authprovider.DgAuth;
+
+import com.mojang.authlib.exceptions.AuthenticationException;
+import kr.syeyoung.dungeonsguide.launcher.auth.AuthUtil;
+import kr.syeyoung.dungeonsguide.launcher.auth.authprovider.AuthProvider;
+
+import java.io.IOException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+
+public class DgAuth implements AuthProvider {
+
+ private final String authServerUrl;
+
+ public DgAuth(String authServerUrl){
+ this.authServerUrl = authServerUrl;
+ }
+
+ private String token;
+ private KeyPair rsaKey;
+
+ @Override
+ public String getToken() {
+ return token;
+ }
+
+ @Override
+ public KeyPair getRsaKey() {
+ return rsaKey;
+ }
+
+
+ @Override
+ public AuthProvider createAuthProvider() throws NoSuchAlgorithmException, AuthenticationException, IOException {
+ this.rsaKey = AuthUtil.getKeyPair();
+
+ String tempToken = DgAuthUtil.requestAuth(this.authServerUrl);
+
+ DgAuthUtil.checkSessionAuthenticity(tempToken);
+
+ this.token = DgAuthUtil.verifyAuth(tempToken, rsaKey.getPublic(), authServerUrl);
+
+ return this;
+ }
+
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/DgAuth/DgAuthUtil.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/DgAuth/DgAuthUtil.java
new file mode 100644
index 00000000..53b57e1a
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/DgAuth/DgAuthUtil.java
@@ -0,0 +1,88 @@
+package kr.syeyoung.dungeonsguide.launcher.auth.authprovider.DgAuth;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.exceptions.AuthenticationException;
+import com.mojang.authlib.minecraft.MinecraftSessionService;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.Session;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.IOUtils;
+
+import javax.net.ssl.HttpsURLConnection;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.URL;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+
+public class DgAuthUtil {
+ private DgAuthUtil(){}
+
+ public static String requestAuth(String baseurl) throws IOException {
+ GameProfile profile = Minecraft.getMinecraft().getSession().getProfile();
+
+ HttpsURLConnection connection = (HttpsURLConnection) new URL(baseurl + "/auth/requestAuth").openConnection();
+ connection.setRequestProperty("User-Agent", "DungeonsGuide/1.0");
+ connection.setRequestProperty("Content-Type", "application/json");
+ connection.setRequestMethod("POST");
+ connection.setDoInput(true);
+ connection.setDoOutput(true);
+
+ connection.getOutputStream().write(("{\"uuid\":\""+profile.getId().toString()+"\",\"nickname\":\""+profile.getName()+"\"}").getBytes());
+ String payload = String.join("\n", IOUtils.readLines(connection.getErrorStream() == null ? connection.getInputStream() : connection.getErrorStream()));
+
+ JsonObject json = (JsonObject) new JsonParser().parse(payload);
+
+ if (!"ok".equals(json.get("status").getAsString())) {
+ return null;
+ }
+ return json.get("data").getAsString();
+ }
+
+ public static void checkSessionAuthenticity(String tempToken) throws NoSuchAlgorithmException, AuthenticationException {
+ JsonObject d = getJwtPayload(tempToken);
+ byte[] sharedSecret = Base64.decodeBase64(d.get("sharedSecret").getAsString());
+ byte[] publicKey =Base64.decodeBase64(d.get("publicKey").getAsString());
+ String hash = calculateServerHash(sharedSecret, publicKey);
+
+ Session session = Minecraft.getMinecraft().getSession();
+ MinecraftSessionService yggdrasilMinecraftSessionService = Minecraft.getMinecraft().getSessionService();
+ yggdrasilMinecraftSessionService.joinServer(session.getProfile(), session.getToken(), hash);
+ }
+
+ public static String verifyAuth(String tempToken, PublicKey clientKey, String baseurl) throws IOException {
+ HttpsURLConnection urlConnection = (HttpsURLConnection) new URL(baseurl + "/auth/authenticate").openConnection();
+ urlConnection.setRequestMethod("POST");
+ urlConnection.setRequestProperty("User-Agent", "DungeonsGuide/1.0");
+ urlConnection.setRequestProperty("Content-Type", "application/json");
+ urlConnection.setDoInput(true);
+ urlConnection.setDoOutput(true);
+
+ urlConnection.getOutputStream().write(("{\"jwt\":\""+tempToken+"\",\"publicKey\":\""+Base64.encodeBase64URLSafeString(clientKey.getEncoded())+"\"}").getBytes());
+ String payload = String.join("\n", IOUtils.readLines(urlConnection.getErrorStream() == null ? urlConnection.getInputStream() : urlConnection.getErrorStream()));
+
+ JsonObject jsonObject = (JsonObject) new JsonParser().parse(payload);
+ if (!"ok".equals(jsonObject.get("status").getAsString())) {
+ return null;
+ }
+ return jsonObject.get("data").getAsString();
+ }
+
+ public static JsonObject getJwtPayload(String jwt) {
+ String midPart = jwt.split("\\.")[1].replace("+", "-").replace("/", "_");
+ String base64Decode = new String(Base64.decodeBase64(midPart)); // padding
+ return (JsonObject) new JsonParser().parse(base64Decode);
+ }
+
+ public static String calculateServerHash(byte[] a, byte[] b) throws NoSuchAlgorithmException {
+ MessageDigest c = MessageDigest.getInstance("SHA-1");
+ c.update("".getBytes());
+ c.update(a);
+ c.update(b);
+ byte[] d = c.digest();
+ return new BigInteger(d).toString(16);
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/NullAuth.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/NullAuth.java
new file mode 100644
index 00000000..303cfb0a
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/authprovider/NullAuth.java
@@ -0,0 +1,62 @@
+package kr.syeyoung.dungeonsguide.launcher.auth.authprovider;
+
+import com.mojang.authlib.exceptions.AuthenticationException;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.IOException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+public class NullAuth implements AuthProvider {
+
+ Logger logger = LogManager.getLogger("NullAuth");
+
+ @Override
+ public String getToken() {
+ return "TOKEN";
+ }
+
+ @Override
+ public KeyPair getRsaKey() {
+ return new KeyPair(new PublicKey() {
+ @Override
+ public String getAlgorithm() {
+ return null;
+ }
+
+ @Override
+ public String getFormat() {
+ return null;
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ return new byte[0];
+ }
+ }, new PrivateKey() {
+ @Override
+ public String getAlgorithm() {
+ return null;
+ }
+
+ @Override
+ public String getFormat() {
+ return null;
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ return new byte[0];
+ }
+ });
+ }
+
+ @Override
+ public AuthProvider createAuthProvider() throws NoSuchAlgorithmException, AuthenticationException, IOException {
+ return new NullAuth();
+ }
+
+}
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
deleted file mode 100755
index ac30c5e3..00000000
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/Authenticator.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.launcher.authentication;
-
-import com.mojang.authlib.exceptions.AuthenticationException;
-import com.mojang.authlib.minecraft.MinecraftSessionService;
-import kr.syeyoung.dungeonsguide.launcher.Main;
-import kr.syeyoung.dungeonsguide.launcher.exceptions.AuthServerException;
-import kr.syeyoung.dungeonsguide.launcher.exceptions.PrivacyPolicyRequiredException;
-import kr.syeyoung.dungeonsguide.launcher.exceptions.TokenExpiredException;
-import lombok.Getter;
-import net.minecraft.client.Minecraft;
-import net.minecraft.util.Session;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.io.IOUtils;
-import org.json.JSONObject;
-import sun.reflect.Reflection;
-
-import javax.crypto.*;
-import java.io.*;
-import java.math.BigInteger;
-import java.net.*;
-import java.security.*;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.X509EncodedKeySpec;
-import java.time.Instant;
-import java.util.UUID;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-public class Authenticator {
- private String dgAccessToken;
- @Getter
- private TokenStatus tokenStatus = TokenStatus.UNAUTHENTICATED;
-
- private final SecureRandom secureRandom = new SecureRandom();
-
- private Lock authenticationLock = new ReentrantLock();
-
- static {
- Reflection.registerFieldsToFilter(Authenticator.class, "dgAccessToken"); // Please do not touch this field. I know there is a way to block it completely, but I won't do it here.
- }
-
- public String getRawToken() {
- return dgAccessToken;
- }
- public String getUnexpiredToken() { // THIS METHOD MAY BLOCK.
- if (tokenStatus != TokenStatus.AUTHENTICATED) throw new IllegalStateException("Token is not available");
- 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().setLastFatalError(t);
- throw new TokenExpiredException(t);
- }
- }
- return dgAccessToken;
- }
-
-
- private byte[] generateSharedSecret() {
- byte[] bts = new byte[32];
- secureRandom.nextBytes(bts);
- return bts;
- }
-
- public String repeatAuthenticate(int tries) {
- int cnt = 0;
- while(true) {
- try {
- reauthenticate();
- break;
- } catch (IOException | AuthenticationException | NoSuchAlgorithmException e) {
- e.printStackTrace();
- if (cnt == tries) throw new RuntimeException(e);
- try {
- Thread.sleep((long) Math.max(Math.pow(2, tries)* 100, 1000 * 10));
- } catch (InterruptedException ex) {}
- }
- cnt++;
- }
- return dgAccessToken;
- }
- public String reauthenticate() throws IOException, AuthenticationException, NoSuchAlgorithmException {
- try {
- authenticationLock.lock();
-
- tokenStatus = TokenStatus.UNAUTHENTICATED;
- dgAccessToken = null;
-
- 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
-
- 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 {
- Cipher cipher = Cipher.getInstance("RSA");
- cipher.init(Cipher.ENCRYPT_MODE, KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(d.getString("publicKey")))));
- encodedSharedSecret = cipher.doFinal(sharedSecret);
- } catch (NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException |
- 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(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.dgAccessToken;
- } finally {
- authenticationLock.unlock();
- }
- }
-
- public String acceptLatestTOS() throws IOException {
- try {
- authenticationLock.lock();
- if (tokenStatus != TokenStatus.PP_REQUIRED) throw new IllegalStateException("Already accepted TOS");
- 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.dgAccessToken;
- } finally {
- authenticationLock.unlock();
- }
- }
-
- public JSONObject getJwtPayload(String jwt) {
- String midPart = jwt.split("\\.")[1].replace("+", "-").replace("/", "_");
- String base64Decode = new String(Base64.decodeBase64(midPart)); // padding
- return new JSONObject(base64Decode);
- }
-
- private String requestAuth(UUID uuid, String nickname) throws IOException {
- HttpURLConnection urlConnection = request("POST", "/auth/v2/requestAuth");
- urlConnection.setRequestProperty("Content-Type", "application/json");
-
- urlConnection.getOutputStream().write(("{\"uuid\":\""+uuid.toString()+"\",\"nickname\":\""+nickname+"\"}").getBytes());
- try (InputStream is = obtainInputStream(urlConnection)) {
- String payload = String.join("\n", IOUtils.readLines(is));
- if (urlConnection.getResponseCode() != 200)
- System.out.println("/auth/requestAuth :: Received " + urlConnection.getResponseCode() + " along with\n" + payload);
-
- JSONObject json = new JSONObject(payload);
-
- if ("Success".equals(json.getString("status"))) {
- return json.getString("data");
- } else {
- throw new AuthServerException(json);
- }
- }
- }
- private JSONObject verifyAuth(String tempToken, byte[] encryptedSecret) throws IOException {
- HttpURLConnection urlConnection = request("POST", "/auth/v2/authenticate");
- urlConnection.setRequestProperty("Content-Type", "application/json");
-
- urlConnection.getOutputStream().write(("{\"jwt\":\""+tempToken+"\",\"sharedSecret\":\""+Base64.encodeBase64String(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 json = new JSONObject(payload);
-
- if ("Success".equals(json.getString("status"))) {
- return json.getJSONObject("data");
- } else {
- throw new AuthServerException(json);
- }
- }
- }
- private JSONObject acceptPrivacyPolicy(String tempToken) throws IOException {
- HttpURLConnection urlConnection = request("POST", "/auth/v2/acceptPrivacyPolicy");
-
- urlConnection.getOutputStream().write(tempToken.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 json = new JSONObject(payload);
-
- if ("Success".equals(json.getString("status"))) {
- return json.getJSONObject("data");
- } else {
- throw new AuthServerException(json);
- }
- }
- }
-
-
- private String calculateServerHash(byte[] a, byte[] b) throws NoSuchAlgorithmException {
- MessageDigest c = MessageDigest.getInstance("SHA-1");
- c.update("".getBytes());
- c.update(a);
- c.update(b);
- byte[] d = c.digest();
- return new BigInteger(d).toString(16);
- }
-
- public InputStream obtainInputStream(HttpURLConnection huc) {
- InputStream inputStream = null;
- try {
- inputStream = huc.getInputStream();
- } catch (Exception e) {
- inputStream = huc.getErrorStream();
- }
- return inputStream;
- }
-
- public HttpURLConnection request(String method, String url) throws IOException {
- HttpURLConnection urlConnection = (HttpURLConnection) new URL(Main.DOMAIN+url).openConnection();
- 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);
- urlConnection.setAllowUserInteraction(true);
- if (tokenStatus == TokenStatus.AUTHENTICATED)
- urlConnection.setRequestProperty("Authorization", "Bearer "+getUnexpiredToken());
- return urlConnection;
- }
-}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/TokenStatus.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/TokenStatus.java
deleted file mode 100644
index a83818b8..00000000
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/authentication/TokenStatus.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.launcher.authentication;
-
-public enum TokenStatus {
- UNAUTHENTICATED,
- BANNED,
- PP_REQUIRED,
- AUTHENTICATED,
- EXPIRED
-}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/branch/ModDownloader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/branch/ModDownloader.java
deleted file mode 100644
index 45eacee5..00000000
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/branch/ModDownloader.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.launcher.branch;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-import kr.syeyoung.dungeonsguide.launcher.authentication.Authenticator;
-import lombok.Getter;
-import net.minecraftforge.fml.common.ProgressManager;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.io.IOUtils;
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-import javax.crypto.*;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.HttpsURLConnection;
-import java.io.*;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.security.*;
-import java.security.cert.CertificateException;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.UUID;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-public class ModDownloader {
- private Authenticator authenticator;
-
- @Getter
- private List<UpdateBranch> accessibleBranches = null;
-
- public ModDownloader(Authenticator authenticator) {
- this.authenticator = authenticator;
- }
-
- public List<UpdateBranch> fetchAccessibleBranches() throws IOException {
- HttpURLConnection urlConnection = authenticator.request("GET", "/updates/");
- try (InputStream is = authenticator.obtainInputStream(urlConnection)) {
- String payload = String.join("\n", IOUtils.readLines(is));
-
- JSONArray jsonArray = new JSONArray(payload);
- List<UpdateBranch> branches = new ArrayList<>();
- for (Object o : jsonArray) {
- if (o instanceof JSONObject) {
- JSONObject branch = (JSONObject) o;
- UpdateBranch updateBranch = new UpdateBranch();
- updateBranch.setId(branch.getLong("id"));
- updateBranch.setName(branch.getString("name"));
- updateBranch.setMetadata(branch.getJSONObject("metadata").getJSONObject("metadataSchema"));
- branches.add(updateBranch);
- }
- }
- return this.accessibleBranches = branches;
- }
- }
-
- public List<Update> fetchUpdates(Long branch, int page) throws IOException {
- HttpURLConnection urlConnection = authenticator.request("GET", "/updates/"+branch+"/");
- try (InputStream is = authenticator.obtainInputStream(urlConnection)) {
- String payload = String.join("\n", IOUtils.readLines(is));
-
- JSONArray jsonArray = new JSONArray(payload);
- List<Update> updates = new ArrayList<>();
- for (Object o : jsonArray) {
- if (o instanceof JSONObject) {
- JSONObject json = (JSONObject) o;
- Update update = new Update();
- update.setId(json.getLong("id"));
- update.setBranchId(json.getLong("branchId"));
- update.setName(json.getString("versionName"));
- update.setUpdateLog(json.getString("updateLog"));
- update.setMetadata(json.getJSONObject("metadata"));
- for (Object assets : json.getJSONObject("assets").getJSONArray("assets")) {
- if (assets instanceof JSONObject) {
- JSONObject a_json = (JSONObject) assets;
- Update.Asset asset = new Update.Asset();
- asset.setName(a_json.getString("name"));
- asset.setSize(a_json.getLong("size"));
- asset.setObjectId(a_json.getString("objectId"));
- asset.setAssetId(UUID.fromString(a_json.getString("assetID")));
- update.getAssets().add(asset);
- }
- }
- updates.add(update);
- }
- }
- return updates;
- }
- }
-
- /*
- pls Close after done
- */
- public InputStream fetchAsset(Update update, UUID assetId) throws IOException {
- HttpURLConnection urlConnection = authenticator.request("GET", "/updates/"+update.getBranchId()+"/"+update.getId()+"/"+assetId.toString());
- try (InputStream is = authenticator.obtainInputStream(urlConnection)) {
- String payload = String.join("\n", IOUtils.readLines(is));
- JSONObject object = new JSONObject(payload);
-
- HttpURLConnection connection = (HttpURLConnection) new URL(object.getString("url")).openConnection();
- connection.setRequestMethod(object.getString("method"));
- urlConnection.setRequestProperty("User-Agent", "DungeonsGuide/1.0");
- urlConnection.setDoInput(true);
- urlConnection.setDoOutput(true);
- urlConnection.setAllowUserInteraction(true);
- return authenticator.obtainInputStream(connection);
- }
- }
-
-
-
-
-
-
- private ProgressManager.ProgressBar progressBar;
-
- private PublicKey dgPublicKey;
- private PublicKey getDGPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
- if (dgPublicKey != null) return dgPublicKey;
- X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decodeBase64("MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxO89qtwG67jNucQ9Y44c" +
- "IUs/B+5BeJPs7G+RG2gfs4/2+tzF/c1FLDc33M7yKw8aKk99vsBUY9Oo8gxxiEPB" +
- "JitP/qfon2THp94oM77ZTpHlmFoqbZMcKGZVI8yfvEL4laTM8Hw+qh5poQwtpEbK" +
- "Xo47AkxygxJasUnykER2+aSTZ6kWU2D4xiNtFA6lzqN+/oA+NaYfPS0amAvyVlHR" +
- "n/8IuGkxb5RrlqVssQstFnxsJuv88qdGSEqlcKq2tLeg9hb8eCnl2OFzvXmgbVER" +
- "0JaV+4Z02fVG1IlR3Xo1mSit7yIU6++3usRCjx2yfXpnGGJUW5pe6YETjNew3ax+" +
- "FAZ4GePWCdmS7FvBnbbABKo5pE06ZTfDUTCjQlAJQiUgoF6ntMJvQAXPu48Vr8q/" +
- "mTcuZWVnI6CDgyE7nNq3WNoq3397sBzxRohMxuqzl3T19zkfPKF05iV2Ju1HQMW5" +
- "I119bYrmVD240aGESZc20Sx/9g1BFpNzQbM5PGUlWJ0dhLjl2ge4ip2hHciY3OEY" +
- "p2Qy2k+xEdenpKdL+WMRimCQoO9gWe2Tp4NmP5dppDXZgPjXqjZpnGs0Uxs+fXqW" +
- "cwlg3MbX3rFl9so/fhVf4p9oXZK3ve7z5D6XSSDRYECvsKIa08WAxJ/U6n204E/4" +
- "xUF+3ZgFPdzZGn2PU7SsnOsCAwEAAQ=="));
- return dgPublicKey = KeyFactory.getInstance("RSA").generatePublic(spec);
- }
-
-
-
-
- private KeyPair rsaKey;
- private KeyPair getKeyPair() {
- KeyPairGenerator a = null;
- try {
- a = KeyPairGenerator.getInstance("RSA");
- } catch (NoSuchAlgorithmException b) { }
- a.initialize(1024);
- this.rsaKey = a.generateKeyPair();
- return this.rsaKey;
- }
-
-
- private final HashMap<String, byte[]> loadedResources = new HashMap<String, byte[]>();
-
- public HashMap<String, byte[]> getResources() {
- return loadedResources;
- }
-
- private void downloadSafe(String dgToken, String url, boolean isValidateSignature) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, CertificateException, KeyStoreException, KeyManagementException, SignatureException, InvalidKeySpecException {
- HttpsURLConnection dgConnection = (HttpsURLConnection) new URL(url).openConnection();
- dgConnection.setRequestProperty("User-Agent", "DungeonsGuide/1.0");
- dgConnection.setRequestProperty("Content-Type", "application/json");
- dgConnection.setRequestMethod("GET");
- dgConnection.setRequestProperty("Authorization", dgToken);
- dgConnection.setDoInput(true);
- dgConnection.setDoOutput(true);
-
- InputStream inputStream = dgConnection.getInputStream();
- byte[] lengthBytes = new byte[4];
- inputStream.read(lengthBytes);
- int length = ((lengthBytes[0] & 0xFF) << 24) |
- ((lengthBytes[1] & 0xFF) << 16) |
- ((lengthBytes[2] & 0xFF) << 8) |
- ((lengthBytes[3] & 0xFF));
- while (inputStream.available() < length) ;
- byte[] keyPayload = new byte[length];
- inputStream.read(keyPayload);
-
- Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- cipher.init(Cipher.DECRYPT_MODE, this.rsaKey.getPrivate());
- byte[] h = cipher.doFinal(keyPayload);
-
- cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- SecretKeySpec keySpec = new SecretKeySpec(h, "AES");
- IvParameterSpec ivSpec = new IvParameterSpec(h);
- cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
- CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
-
- cipherInputStream.read(lengthBytes);
- length = ((lengthBytes[0] & 0xFF) << 24) |
- ((lengthBytes[1] & 0xFF) << 16) |
- ((lengthBytes[2] & 0xFF) << 8) |
- ((lengthBytes[3] & 0xFF));
-
- int totalLen = length;
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] buff = new byte[256];
- while (totalLen > 0) {
- int len = cipherInputStream.read(buff, 0, Math.min(buff.length, totalLen));
- totalLen -= len;
- bos.write(buff, 0, len);
- }
- byte[] body = bos.toByteArray();
-
- byte[] signed = null;
- if (isValidateSignature) {
- progressBar.step("Validating Signature");
- cipherInputStream.read(lengthBytes,0 , 4);
- length = ((lengthBytes[0] & 0xFF) << 24) |
- ((lengthBytes[1] & 0xFF) << 16) |
- ((lengthBytes[2] & 0xFF) << 8) |
- ((lengthBytes[3] & 0xFF));
-
- totalLen = length;
- bos = new ByteArrayOutputStream();
- while (totalLen > 0) {
- int len = cipherInputStream.read(buff, 0, Math.min(buff.length, totalLen));
- totalLen -= len;
- bos.write(buff, 0, len);
- }
- signed = bos.toByteArray();
-
- Signature sign = Signature.getInstance("SHA512withRSA");
- sign.initVerify(getDGPublicKey());
- sign.update(body);
- boolean truth = sign.verify(signed);
- if (!truth) throw new SignatureException("DG SIGNATURE FORGED");
- }
-
- ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(body));
- ZipEntry zipEntry;
- while ((zipEntry=zipInputStream.getNextEntry()) != null) {
- byte[] buffer = new byte[256];
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- int p = 0;
- while((p = zipInputStream.read(buffer)) > 0) {
- byteArrayOutputStream.write(buffer, 0, p);
- }
- this.loadedResources.put(zipEntry.getName(), byteArrayOutputStream.toByteArray());
- }
- dgConnection.disconnect();
- }
-
- public JsonElement getJsonSecured(String u) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, CertificateException, KeyStoreException, KeyManagementException {
- HttpsURLConnection httpsURLConnection = (HttpsURLConnection) new URL(u).openConnection();
- httpsURLConnection.setRequestProperty("User-Agent", "DungeonsGuide/1.0");
- httpsURLConnection.setRequestProperty("Content-Type", "application/json");
- httpsURLConnection.setRequestMethod("GET");
- httpsURLConnection.setRequestProperty("Authorization", authenticator.getUnexpiredToken());
- httpsURLConnection.setDoInput(true);
- httpsURLConnection.setDoOutput(true);
-
- InputStream inputStream = httpsURLConnection.getInputStream();
- byte[] lengthPayload = new byte[4];
- inputStream.read(lengthPayload);
- int length = ((lengthPayload[0] & 0xFF) << 24) |
- ((lengthPayload[1] & 0xFF) << 16) |
- ((lengthPayload[2] & 0xFF) << 8) |
- ((lengthPayload[3] & 0xFF));
- while (inputStream.available() < length) ;
- byte[] keyPayload = new byte[length];
- inputStream.read(keyPayload);
-
- Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- cipher.init(Cipher.DECRYPT_MODE, this.rsaKey.getPrivate());
- byte[] AESKey = cipher.doFinal(keyPayload);
-
- cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- SecretKeySpec secretKeySpec = new SecretKeySpec(AESKey, "AES");
- IvParameterSpec ivParameterSpec = new IvParameterSpec(AESKey);
- cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
- CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
- cipherInputStream.read(lengthPayload);
- length = ((lengthPayload[0] & 0xFF) << 24) |
- ((lengthPayload[1] & 0xFF) << 16) |
- ((lengthPayload[2] & 0xFF) << 8) |
- ((lengthPayload[3] & 0xFF));
- JsonElement l = new JsonParser().parse(new InputStreamReader(cipherInputStream));
- httpsURLConnection.disconnect();
- return l;
- }
-}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/GuiLoadingError.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/GuiLoadingError.java
index f7cc5972..f699b1d7 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/GuiLoadingError.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/GuiLoadingError.java
@@ -18,64 +18,34 @@
package kr.syeyoung.dungeonsguide.launcher.gui;
-import kr.syeyoung.dungeonsguide.launcher.util.QRCodeGenerator;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
-import net.minecraft.client.renderer.GlStateManager;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.WorldRenderer;
-import net.minecraft.client.renderer.texture.DynamicTexture;
-import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
-import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.FMLCommonHandler;
import org.lwjgl.opengl.GL11;
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Base64;
-import java.util.zip.GZIPOutputStream;
+import java.io.PrintStream;
public class GuiLoadingError extends GuiScreen {
- private String stacktrace;
- private Throwable throwable;
+ static Throwable cause;
+ private final String stacktrace;
+ private final GuiScreen originalGUI;
+ public GuiLoadingError(GuiScreen originalGUI) {
- private DynamicTexture texture;
- private ResourceLocation location;
- private BufferedImage qrCode;
- private Runnable clear;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ PrintStream printStream = new PrintStream(byteArrayOutputStream);
+ cause.printStackTrace(printStream);
+ this.stacktrace = byteArrayOutputStream.toString();
- public GuiLoadingError(Throwable t, Runnable clear) {
- this.throwable = t;
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- t.printStackTrace(pw);
- stacktrace = sw.toString();
-
-
- try {
- qrCode = QRCodeGenerator.generateQRCode(stacktrace.getBytes());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- texture = new DynamicTexture(qrCode.getWidth(), qrCode.getHeight());
- location = Minecraft.getMinecraft().getTextureManager().getDynamicTextureLocation("dg/errorqr", texture);
-
- qrCode.getRGB(0,0,qrCode.getWidth(), qrCode.getHeight(), texture.getTextureData(), 0, qrCode.getWidth());
-
- texture.updateDynamicTexture();
- this.clear = clear;
+ this.originalGUI = originalGUI;
}
@Override
public void initGui() {
ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
- this.buttonList.add(new GuiButton(0, sr.getScaledWidth()/2-100,sr.getScaledHeight()-40 ,"Close Minecraft"));
- this.buttonList.add(new GuiButton(1, sr.getScaledWidth()/2-100,sr.getScaledHeight()-70 ,"Play Without DG"));
- clear.run();
+ this.buttonList.add(new GuiButton(0, sr.getScaledWidth()/2-100,sr.getScaledHeight()-70 ,"Close Minecraft"));
+ this.buttonList.add(new GuiButton(1, sr.getScaledWidth()/2-100,sr.getScaledHeight()-40 ,"Play Without DG"));
}
@Override
@@ -84,7 +54,7 @@ public class GuiLoadingError extends GuiScreen {
if (button.id == 0) {
FMLCommonHandler.instance().exitJava(-1,true);
} else if (button.id == 1) {
- Minecraft.getMinecraft().displayGuiScreen(null);
+ Minecraft.getMinecraft().displayGuiScreen(originalGUI);
}
}
@@ -94,8 +64,8 @@ public class GuiLoadingError extends GuiScreen {
ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
- fontRenderer.drawString("DungeonsGuide has ran into unknown error while loading itself", (sr.getScaledWidth()-fontRenderer.getStringWidth("DungeonsGuide has ran into unknown error while loading itself"))/2,40,0xFFFF0000);
- fontRenderer.drawString("Please contact DungeonsGuide support with this screen", (sr.getScaledWidth()-fontRenderer.getStringWidth("Please contact DungeonsGuide support with this screen"))/2, (int) (40+fontRenderer.FONT_HEIGHT*1.5),0xFFFF0000);
+ fontRenderer.drawString("DungeonsGuide has ran into error while loading itself", (sr.getScaledWidth()-fontRenderer.getStringWidth("DungeonsGuide has ran into error while loading itself"))/2,40,0xFFFF0000);
+ fontRenderer.drawString("Please contact DungeonsGuide support with this screen", (sr.getScaledWidth()-fontRenderer.getStringWidth("Please contact developer with this screen"))/2, (int) (40+fontRenderer.FONT_HEIGHT*1.5),0xFFFF0000);
int tenth = sr.getScaledWidth() / 10;
@@ -108,27 +78,6 @@ public class GuiLoadingError extends GuiScreen {
}
GL11.glDisable(GL11.GL_SCISSOR_TEST);
-
- GlStateManager.pushMatrix();
- GlStateManager.scale(1.0/sr.getScaleFactor(), 1.0/sr.getScaleFactor(), 1);
- GlStateManager.translate(0, Minecraft.getMinecraft().displayHeight - qrCode.getHeight() * 3, 0);
- Tessellator tessellator = Tessellator.getInstance();
- WorldRenderer worldrenderer = tessellator.getWorldRenderer();
- float f = 0.0F;
- Minecraft.getMinecraft().getTextureManager().bindTexture(this.location);
- GlStateManager.enableBlend();
- GlStateManager.tryBlendFuncSeparate(1, 771, 0, 1);
- GlStateManager.disableAlpha();
- worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
- worldrenderer.pos(0, qrCode.getHeight()*3, 0).tex(0.0D, 1.0D).endVertex();
- worldrenderer.pos(qrCode.getWidth()*3, qrCode.getHeight()*3, 0).tex(1.0D, 1.0D).endVertex();
- worldrenderer.pos(qrCode.getWidth()*3, 0, 0).tex(1.0D, 0.0D).endVertex();
- worldrenderer.pos(0, 0, 0).tex(0.0D, 0.0D).endVertex();
- tessellator.draw();
- GlStateManager.enableAlpha();
- GlStateManager.disableBlend();
- GlStateManager.popMatrix();
-
super.drawScreen(mouseX, mouseY, partialTicks);
}
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 53d9b70d..820ce0c8 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
@@ -19,21 +19,17 @@
package kr.syeyoung.dungeonsguide.launcher.loader;
import kr.syeyoung.dungeonsguide.launcher.DGInterface;
-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 loadDungeonsGuide() throws InstantiationException, IllegalAccessException, ClassNotFoundException;
DGInterface getInstance();
- void unloadJar() throws ReferenceLeakedException;
+ void unloadDungeonsGuide() throws ReferenceLeakedException;
boolean isUnloadable();
boolean isLoaded();
- String strategyName();
+ String branchName();
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 0b6cf124..fff63a07 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
@@ -20,7 +20,6 @@ package kr.syeyoung.dungeonsguide.launcher.loader;
import kr.syeyoung.dungeonsguide.launcher.DGInterface;
import kr.syeyoung.dungeonsguide.launcher.Main;
-import kr.syeyoung.dungeonsguide.launcher.authentication.Authenticator;
import kr.syeyoung.dungeonsguide.launcher.exceptions.ReferenceLeakedException;
import java.io.InputStream;
@@ -84,7 +83,7 @@ public class JarLoader implements IDGLoader {
private JarClassLoader classLoader;
@Override
- public void loadJar(Authenticator authenticator) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+ public DGInterface loadDungeonsGuide() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
if (dgInterface != null) throw new IllegalStateException("Already loaded");
classLoader = new JarClassLoader(new URL[] {
@@ -93,6 +92,7 @@ public class JarLoader implements IDGLoader {
dgInterface = (DGInterface) classLoader.loadClassResolve("kr.syeyoung.dungeonsguide.DungeonsGuide", true).newInstance();
phantomReference = new PhantomReference<>(classLoader, refQueue);
+ return dgInterface;
}
@Override
@@ -101,7 +101,7 @@ public class JarLoader implements IDGLoader {
}
@Override
- public void unloadJar() throws ReferenceLeakedException {
+ public void unloadDungeonsGuide() throws ReferenceLeakedException {
classLoader = null;
dgInterface.unload();
dgInterface = null;
@@ -123,7 +123,7 @@ public class JarLoader implements IDGLoader {
}
@Override
- public String strategyName() {
+ public String branchName() {
return "jar";
}
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 1338138d..01159b34 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
@@ -19,7 +19,6 @@
package kr.syeyoung.dungeonsguide.launcher.loader;
import kr.syeyoung.dungeonsguide.launcher.DGInterface;
-import kr.syeyoung.dungeonsguide.launcher.authentication.Authenticator;
import kr.syeyoung.dungeonsguide.launcher.exceptions.ReferenceLeakedException;
import java.io.InputStream;
@@ -28,9 +27,9 @@ public class LocalLoader implements IDGLoader {
private DGInterface dgInterface;
@Override
- public void loadJar(Authenticator authenticator) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+ public DGInterface loadDungeonsGuide() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
if (dgInterface != null) throw new IllegalStateException("Already loaded");
- dgInterface = (DGInterface) Class.forName("kr.syeyoung.dungeonsguide.DungeonsGuide").newInstance();
+ return dgInterface = (DGInterface) Class.forName("kr.syeyoung.dungeonsguide.DungeonsGuide").newInstance();
}
@Override
@@ -39,7 +38,7 @@ public class LocalLoader implements IDGLoader {
}
@Override
- public void unloadJar() throws ReferenceLeakedException {
+ public void unloadDungeonsGuide() throws ReferenceLeakedException {
throw new UnsupportedOperationException();
}
@Override
@@ -53,7 +52,7 @@ public class LocalLoader implements IDGLoader {
}
@Override
- public String strategyName() {
+ public String branchName() {
return "local";
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGConnection.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGConnection.java
index 649dfdc5..5a310738 100755
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGConnection.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGConnection.java
@@ -1,35 +1,37 @@
/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero 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 free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ * 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 Affero General Public License for more details.
*
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package kr.syeyoung.dungeonsguide.launcher.url;
-import kr.syeyoung.dungeonsguide.launcher.authentication.Authenticator;
+import kr.syeyoung.dungeonsguide.launcher.auth.ResourceManager;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class DGConnection extends URLConnection {
- private final Authenticator authenticator;
- protected DGConnection(URL url, Authenticator a) {
+
+ protected DGConnection(URL url) {
super(url);
connected = false;
- this.authenticator = a;
}
@Override
@@ -37,10 +39,10 @@ public class DGConnection extends URLConnection {
}
@Override
public InputStream getInputStream() throws IOException {
- if (authenticator != null) {
+ if (ResourceManager.getInstance().getResources() != null) {
String path = url.getPath().substring(1);
-// if (!authenticator.getResources().containsKey(path)) throw new FileNotFoundException();
-// return new ByteArrayInputStream(authenticator.getResources().get(path));
+ if (!ResourceManager.getInstance().getResources().containsKey(path)) throw new FileNotFoundException();
+ return new ByteArrayInputStream(ResourceManager.getInstance().getResources().get(path));
}
throw new FileNotFoundException();
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGStreamHandler.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGStreamHandler.java
index 82ddff18..456e7f8c 100755
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGStreamHandler.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGStreamHandler.java
@@ -1,24 +1,23 @@
/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero 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 free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ * 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 Affero General Public License for more details.
*
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package kr.syeyoung.dungeonsguide.launcher.url;
-import kr.syeyoung.dungeonsguide.launcher.authentication.Authenticator;
import lombok.AllArgsConstructor;
import java.io.IOException;
@@ -28,9 +27,8 @@ import java.net.URLStreamHandler;
@AllArgsConstructor
public class DGStreamHandler extends URLStreamHandler {
- private final Authenticator auth;
@Override
protected URLConnection openConnection(URL url) throws IOException {
- return new DGConnection(url, this.auth);
+ return new DGConnection(url);
}
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGStreamHandlerFactory.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGStreamHandlerFactory.java
index a7b50046..a7eefa37 100755
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGStreamHandlerFactory.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/url/DGStreamHandlerFactory.java
@@ -1,24 +1,23 @@
/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero 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 free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ * 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 Affero General Public License for more details.
*
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package kr.syeyoung.dungeonsguide.launcher.url;
-import kr.syeyoung.dungeonsguide.launcher.authentication.Authenticator;
import lombok.AllArgsConstructor;
import java.net.URLStreamHandler;
@@ -26,11 +25,10 @@ import java.net.URLStreamHandlerFactory;
@AllArgsConstructor
public class DGStreamHandlerFactory implements URLStreamHandlerFactory {
- private final Authenticator auth;
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
if ("z".equals(protocol)) {
- return new DGStreamHandler(this.auth);
+ return new DGStreamHandler();
}
return null;
}
diff --git a/loader/src/main/resources/mcmod.info b/loader/src/main/resources/mcmod.info
index 70df65aa..2e1a5e46 100755
--- a/loader/src/main/resources/mcmod.info
+++ b/loader/src/main/resources/mcmod.info
@@ -4,10 +4,10 @@
"name": "Skyblock Dungeons Guide",
"description": "A mod to help dungeon players to find and solve secrets and puzzles most efficiently.",
"version": "${version}",
- "mcversion": "${mcversion}",
- "url": "",
+ "mcversion": "1.8.9",
+ "url": "https://discord.gg/dg",
"updateUrl": "",
- "authorList": ["syeyoung"],
+ "authorList": ["syeyoung", "kokoniara"],
"credits": "The guild Jerry's Crew, for nothing.",
"logoFile": "",
"screenshots": [],