From eaecce86d73dd6810168f418c36155422f67addc Mon Sep 17 00:00:00 2001 From: syeyoung Date: Tue, 4 May 2021 13:13:43 +0900 Subject: deobfuscate --- LICENSE | 12 +- gradlew.bat | 2 +- .../kr/syeyoung/dungeonsguide/Authenticator.java | 295 +++++++++++++++++++++ .../kr/syeyoung/dungeonsguide/DGInterface.java | 28 ++ .../kr/syeyoung/dungeonsguide/DungeonsGuide.java | 217 +++++++++++++++ src/main/java/kr/syeyoung/dungeonsguide/Main.java | 145 ++++++++++ .../dungeonsguide/RichPresenceManager.java | 8 +- src/main/java/kr/syeyoung/dungeonsguide/a.java | 145 ---------- src/main/java/kr/syeyoung/dungeonsguide/b.java | 295 --------------------- src/main/java/kr/syeyoung/dungeonsguide/c.java | 28 -- .../commands/CommandDungeonsGuide.java | 24 +- src/main/java/kr/syeyoung/dungeonsguide/d/a.java | 49 ---- src/main/java/kr/syeyoung/dungeonsguide/d/b.java | 35 --- src/main/java/kr/syeyoung/dungeonsguide/d/c.java | 36 --- .../dungeonsguide/dungeon/DungeonContext.java | 15 +- .../dungeonsguide/dungeon/MapProcessor.java | 34 ++- .../dungeon/doorfinder/CatacombDataProvider.java | 4 +- .../doorfinder/CatacombMasterDataProvider.java | 4 +- .../roomfinder/DungeonRoomInfoRegistry.java | 1 - src/main/java/kr/syeyoung/dungeonsguide/e.java | 227 ---------------- .../eventlistener/DungeonListener.java | 28 +- .../eventlistener/FeatureListener.java | 54 ++-- .../eventlistener/PacketListener.java | 7 +- .../impl/advanced/FeatureDebuggableMap.java | 10 +- .../impl/advanced/FeatureRoomCoordDisplay.java | 7 +- .../impl/advanced/FeatureRoomDebugInfo.java | 11 +- .../features/impl/boss/FeatureAutoReparty.java | 19 +- .../features/impl/boss/FeatureBossHealth.java | 16 +- .../features/impl/boss/FeatureBoxRealLivid.java | 12 +- .../features/impl/boss/FeatureChestPrice.java | 5 +- .../features/impl/boss/FeatureCurrentPhase.java | 6 +- .../features/impl/boss/FeatureHideAnimals.java | 11 +- .../features/impl/boss/FeatureTerracotaTimer.java | 5 +- .../impl/boss/FeatureThornBearPercentage.java | 11 +- .../impl/boss/FeatureThornSpiritBowTimer.java | 4 +- .../features/impl/boss/FeatureWarningOnPortal.java | 4 +- .../impl/boss/terminal/FeatureSimonSaysSolver.java | 4 +- .../features/impl/dungeon/FeatureBoxBats.java | 6 +- .../impl/dungeon/FeatureBoxSkelemaster.java | 6 +- .../features/impl/dungeon/FeatureBoxStarMobs.java | 5 +- .../dungeon/FeatureDungeonCurrentRoomSecrets.java | 12 +- .../impl/dungeon/FeatureDungeonDeaths.java | 17 +- .../features/impl/dungeon/FeatureDungeonMap.java | 13 +- .../impl/dungeon/FeatureDungeonMilestone.java | 13 +- .../impl/dungeon/FeatureDungeonRealTime.java | 15 -- .../impl/dungeon/FeatureDungeonSBTime.java | 13 +- .../features/impl/dungeon/FeatureDungeonScore.java | 12 +- .../impl/dungeon/FeatureDungeonSecrets.java | 16 +- .../features/impl/dungeon/FeatureDungeonTombs.java | 10 +- .../features/impl/dungeon/FeatureHideNameTags.java | 7 +- .../features/impl/dungeon/FeaturePlayerESP.java | 20 +- .../dungeon/FeaturePressAnyKeyToCloseChest.java | 7 +- .../impl/dungeon/FeatureWarnLowHealth.java | 16 +- .../impl/dungeon/FeatureWatcherWarning.java | 11 +- .../impl/etc/FeatureAutoAcceptReparty.java | 15 +- .../features/impl/etc/FeatureCooldownCounter.java | 6 +- .../impl/etc/FeatureDecreaseExplosionSound.java | 4 +- .../features/impl/etc/FeatureDisableMessage.java | 4 +- .../features/impl/etc/FeaturePenguins.java | 8 +- .../features/impl/etc/FeatureUpdateAlarm.java | 4 - .../impl/etc/ability/FeatureAbilityCooldown.java | 4 +- .../features/impl/secret/FeatureActions.java | 12 +- .../impl/secret/FeatureFreezePathfind.java | 20 +- .../impl/secret/FeatureMechanicBrowse.java | 5 +- .../impl/secret/FeatureSoulRoomWarning.java | 27 +- .../dungeonsguide/party/PartyInviteViewer.java | 14 +- .../syeyoung/dungeonsguide/party/PartyManager.java | 18 +- .../dungeonsguide/resources/DGTexturePack.java | 11 +- .../roomedit/panes/GeneralEditPane.java | 5 +- .../roomprocessor/GeneralRoomProcessor.java | 18 +- .../bombdefuse/RoomProcessorBombDefuseSolver.java | 6 +- .../chambers/color/ColorRightProcessor.java | 6 - .../bossfight/BossfightProcessorThorn.java | 8 +- .../syeyoung/dungeonsguide/url/DGConnection.java | 49 ++++ .../dungeonsguide/url/DGStreamHandler.java | 36 +++ .../dungeonsguide/url/DGStreamHandlerFactory.java | 37 +++ .../kr/syeyoung/dungeonsguide/utils/AhUtils.java | 5 +- 77 files changed, 1001 insertions(+), 1338 deletions(-) create mode 100755 src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java create mode 100755 src/main/java/kr/syeyoung/dungeonsguide/DGInterface.java create mode 100755 src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuide.java create mode 100755 src/main/java/kr/syeyoung/dungeonsguide/Main.java delete mode 100755 src/main/java/kr/syeyoung/dungeonsguide/a.java delete mode 100755 src/main/java/kr/syeyoung/dungeonsguide/b.java delete mode 100755 src/main/java/kr/syeyoung/dungeonsguide/c.java delete mode 100755 src/main/java/kr/syeyoung/dungeonsguide/d/a.java delete mode 100755 src/main/java/kr/syeyoung/dungeonsguide/d/b.java delete mode 100755 src/main/java/kr/syeyoung/dungeonsguide/d/c.java delete mode 100755 src/main/java/kr/syeyoung/dungeonsguide/e.java create mode 100755 src/main/java/kr/syeyoung/dungeonsguide/url/DGConnection.java create mode 100755 src/main/java/kr/syeyoung/dungeonsguide/url/DGStreamHandler.java create mode 100755 src/main/java/kr/syeyoung/dungeonsguide/url/DGStreamHandlerFactory.java diff --git a/LICENSE b/LICENSE index 0ad25db4..2aad3fa5 100644 --- a/LICENSE +++ b/LICENSE @@ -111,7 +111,7 @@ is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that +Component, and (Authenticator) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component @@ -202,7 +202,7 @@ terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. - b) The work must carry prominent notices stating that it is + Authenticator) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". @@ -242,7 +242,7 @@ in one of these ways: Corresponding Source fixed on a durable physical medium customarily used for software interchange. - b) Convey the object code in, or embodied in, a physical product + Authenticator) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product @@ -353,7 +353,7 @@ that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or - b) Requiring preservation of specified reasonable legal notices or + Authenticator) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or @@ -403,7 +403,7 @@ paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright +finally terminates your license, and (Authenticator) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. @@ -516,7 +516,7 @@ to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily +conveyed by you (or copies made from those copies), or (Authenticator) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. diff --git a/gradlew.bat b/gradlew.bat index f9553162..c1a768de 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -76,7 +76,7 @@ if "%ERRORLEVEL%"=="0" goto mainEnd rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +exit /Authenticator 1 :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java b/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java new file mode 100755 index 00000000..44e0908c --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java @@ -0,0 +1,295 @@ +/* + * 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 . + */ + +package kr.syeyoung.dungeonsguide; + +import com.google.gson.JsonElement; +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 net.minecraftforge.fml.common.ProgressManager; +import org.apache.commons.codec.binary.Base64; + +import javax.crypto.*; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import javax.net.ssl.*; +import java.io.*; +import java.math.BigInteger; +import java.net.*; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashMap; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +public class Authenticator { + private KeyPair rsaKey; + private String token; + private final ProgressManager.ProgressBar progressBar; + + public String getToken() { + return token; + } + + 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 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); + } + + public Authenticator(ProgressManager.ProgressBar progressBar) { + this.progressBar = progressBar; + progressBar.step("Generating KeyPair"); + getKeyPair(); + } + + public String authenticateAndDownload(String version) throws IOException, AuthenticationException, NoSuchAlgorithmException, CertificateException, KeyStoreException, KeyManagementException, InvalidKeySpecException, SignatureException { + Session session = Minecraft.getMinecraft().getSession(); + String sessionToken = session.getToken(); + + progressBar.step("Authenticating (1/2)"); + String tempToken = requestAuth(session.getProfile()); + MinecraftSessionService yggdrasilMinecraftSessionService = Minecraft.getMinecraft().getSessionService(); + JsonObject d = getJwtPayload(tempToken); + String hash = calculateServerHash(Base64.decodeBase64(d.get("sharedSecret").getAsString()), + Base64.decodeBase64(d.get("publicKey").getAsString())); + yggdrasilMinecraftSessionService.joinServer(session.getProfile(), sessionToken, hash); + progressBar.step("Authenticating (2/2)"); + this.token = verifyAuth(tempToken, this.rsaKey.getPublic()); + try { + progressBar.step("Downloading Jar"); + if (version != null) + downloadSafe(this.token, "https://dungeons.guide/resource/version?v=" + version, true); + progressBar.step("Downloading Rooms"); + downloadSafe(this.token, "https://dungeons.guide/resource/roomdata", false); + } catch (Throwable t) { + t.printStackTrace(); + } + return this.token; + } + + public 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); + } + + + + private String requestAuth(GameProfile profile) throws IOException, NoSuchAlgorithmException, CertificateException, KeyStoreException, KeyManagementException { + HttpsURLConnection connection = (HttpsURLConnection) new URL("https://dungeons.guide/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()); + InputStreamReader inputStreamReader = new InputStreamReader(connection.getInputStream()); + JsonObject json = (JsonObject) new JsonParser().parse(inputStreamReader); + if (!"ok".equals(json.get("status").getAsString())) { + return null; + } + return json.get("data").getAsString(); + } + private String verifyAuth(String tempToken, PublicKey clientKey) throws IOException { + HttpsURLConnection urlConnection = (HttpsURLConnection) new URL("https://dungeons.guide/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()); + urlConnection.getResponseCode(); + InputStreamReader reader = new InputStreamReader(urlConnection.getInputStream()); + JsonObject jsonObject = (JsonObject) new JsonParser().parse(reader); + if (!"ok".equals(jsonObject.get("status").getAsString())) { + return null; + } + return jsonObject.get("data").getAsString(); + } + + private final HashMap loadedResources = new HashMap(); + + public HashMap 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", this.token); + 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; + } + + public 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/src/main/java/kr/syeyoung/dungeonsguide/DGInterface.java b/src/main/java/kr/syeyoung/dungeonsguide/DGInterface.java new file mode 100755 index 00000000..0529f0a6 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/DGInterface.java @@ -0,0 +1,28 @@ +/* + * 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 . + */ + +package kr.syeyoung.dungeonsguide; + +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; + +public interface DGInterface { + void init(FMLInitializationEvent event); + + void pre(FMLPreInitializationEvent event); +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuide.java b/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuide.java new file mode 100755 index 00000000..c1d3e4ea --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuide.java @@ -0,0 +1,217 @@ +/* + * 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 . + */ + +package kr.syeyoung.dungeonsguide; + +import com.google.common.collect.Sets; +import kr.syeyoung.dungeonsguide.commands.*; +import kr.syeyoung.dungeonsguide.config.Config; +import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoomInfoRegistry; +import kr.syeyoung.dungeonsguide.eventlistener.DungeonListener; +import kr.syeyoung.dungeonsguide.eventlistener.FeatureListener; +import kr.syeyoung.dungeonsguide.eventlistener.PacketListener; +import kr.syeyoung.dungeonsguide.events.StompConnectedEvent; +import kr.syeyoung.dungeonsguide.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.party.PartyInviteViewer; +import kr.syeyoung.dungeonsguide.party.PartyManager; +import kr.syeyoung.dungeonsguide.resources.DGTexturePack; +import kr.syeyoung.dungeonsguide.stomp.CloseListener; +import kr.syeyoung.dungeonsguide.stomp.StompClient; +import kr.syeyoung.dungeonsguide.stomp.StompInterface; +import kr.syeyoung.dungeonsguide.utils.AhUtils; +import lombok.Getter; +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResourcePack; +import net.minecraft.launchwrapper.LaunchClassLoader; +import net.minecraft.util.IChatComponent; +import net.minecraftforge.client.ClientCommandHandler; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.fml.common.ProgressManager; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.relauncher.ReflectionHelper; +import org.apache.commons.io.IOUtils; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.*; +import java.net.URI; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public class DungeonsGuide implements DGInterface, CloseListener { + + private SkyblockStatus skyblockStatus; + + private static DungeonsGuide dungeonsGuide; + + + @Getter + private final Authenticator authenticator; + + @Getter + private StompInterface stompConnection; + + public DungeonsGuide(Authenticator authenticator) { + this.authenticator = authenticator; + } + + public static void sendDebugChat(IChatComponent iChatComponent) { + if (FeatureRegistry.DEBUG.isEnabled()) + Minecraft.getMinecraft().thePlayer.addChatMessage(iChatComponent); + } + @Getter + CommandReparty commandReparty; + + + private final String stompURL = "wss://dungeons.guide/ws"; +// private String stompURL = "ws://localhost/ws"; + public void init(FMLInitializationEvent event) { + ProgressManager.ProgressBar progressbar = ProgressManager.push("DungeonsGuide", 4); + + + try { + Set invalid = ReflectionHelper.getPrivateValue(LaunchClassLoader.class, (LaunchClassLoader) Main.class.getClassLoader(), "invalidClasses"); + ((LaunchClassLoader) Main.class.getClassLoader()).clearNegativeEntries(Sets.newHashSet("org.slf4j.LoggerFactory")); + for (String s : invalid) { + System.out.println(s+" in invalid"); + } + invalid.clear(); + } catch (Throwable t) { + t.printStackTrace(); + } + + progressbar.step("Registering Events & Commands"); + dungeonsGuide = this; + skyblockStatus = new SkyblockStatus(); + + CommandDungeonsGuide commandDungeonsGuide; + MinecraftForge.EVENT_BUS.register(new DungeonListener()); + ClientCommandHandler.instance.registerCommand(commandDungeonsGuide = new CommandDungeonsGuide()); + MinecraftForge.EVENT_BUS.register(commandDungeonsGuide); + + commandReparty = new CommandReparty(); + if (FeatureRegistry.ETC_REPARTY.isEnabled()) + ClientCommandHandler.instance.registerCommand(commandReparty); + + MinecraftForge.EVENT_BUS.register(commandReparty); + MinecraftForge.EVENT_BUS.register(new FeatureListener()); + MinecraftForge.EVENT_BUS.register(new PacketListener()); + MinecraftForge.EVENT_BUS.register(new Keybinds()); + + RichPresenceManager.INSTANCE.setup(); + MinecraftForge.EVENT_BUS.register(RichPresenceManager.INSTANCE); + MinecraftForge.EVENT_BUS.register(PartyManager.INSTANCE); + MinecraftForge.EVENT_BUS.register(PartyInviteViewer.INSTANCE); + + AhUtils.registerTimer(); + + progressbar.step("Downloading Roomdatas"); + try { + DungeonRoomInfoRegistry.loadAll(configDir); + } catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | IOException | NoSuchAlgorithmException | InvalidAlgorithmParameterException e) { + e.printStackTrace(); + } + Keybinds.register(); + + progressbar.step("Opening connection"); + try { + stompConnection = new StompClient(new URI(stompURL), authenticator.getToken(), this); + MinecraftForge.EVENT_BUS.post(new StompConnectedEvent(stompConnection)); + } catch (Exception e) { + throw new RuntimeException(e); + } + + + progressbar.step("Loading Config"); + try { + Config.loadConfig( null ); + } catch (IOException e) { + e.printStackTrace(); + } + + + ProgressManager.pop(progressbar); + } + public void pre(FMLPreInitializationEvent event) { + configDir = new File(event.getModConfigurationDirectory(),"dungeonsguide"); + File configFile = new File(configDir, "config.json"); + if (!configFile.exists()) { + configDir.mkdirs(); + } + Config.f = configFile; + Minecraft.getMinecraft().getFramebuffer().enableStencil(); + + try { + List resourcePackList = ReflectionHelper.getPrivateValue(Minecraft.class, Minecraft.getMinecraft(),"defaultResourcePacks", "aA", "field_110449_ao"); + resourcePackList.add(new DGTexturePack(authenticator)); + } catch (Throwable t){ + t.printStackTrace(); + } + } + private void copy(InputStream inputStream, File f) throws IOException { + FileOutputStream fos = new FileOutputStream(f); + IOUtils.copy(inputStream, fos); + fos.flush(); + fos.close(); + inputStream.close(); + } + + private void combineConfig(Configuration saved, Configuration newest) { + } + + @Getter + private File configDir; + + + public SkyblockStatus getSkyblockStatus() { + return skyblockStatus; + } + + public static DungeonsGuide getDungeonsGuide() { + return dungeonsGuide; + } + ScheduledExecutorService ex = Executors.newScheduledThreadPool(2); + @Override + public void onClose(int code, String reason, boolean remote) { + System.out.println("Stomp Connection closed, trying to reconnect - "+reason+ " - "+code); + connectStomp(); + } + + public void connectStomp() { + ex.schedule(new Runnable() { + @Override + public void run() { + try { + stompConnection = new StompClient(new URI(stompURL), authenticator.getToken(), DungeonsGuide.this); + MinecraftForge.EVENT_BUS.post(new StompConnectedEvent(stompConnection)); + } catch (Exception e) { + e.printStackTrace(); + } + } + }, 5L, TimeUnit.SECONDS); + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/Main.java b/src/main/java/kr/syeyoung/dungeonsguide/Main.java new file mode 100755 index 00000000..10d20b2f --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/Main.java @@ -0,0 +1,145 @@ +/* + * 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 . + */ + +package kr.syeyoung.dungeonsguide; + +import com.mojang.authlib.exceptions.AuthenticationException; +import kr.syeyoung.dungeonsguide.url.DGStreamHandlerFactory; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiErrorScreen; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.launchwrapper.LaunchClassLoader; +import net.minecraftforge.fml.client.CustomModLoadingErrorDisplayException; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.Mod.EventHandler; +import net.minecraftforge.fml.common.ProgressManager; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.*; +import java.net.URL; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.spec.InvalidKeySpecException; + +@Mod(modid = Main.MOD_ID, version = Main.VERSION) +public class Main +{ + public static final String MOD_ID = "skyblock_dungeons_guide"; + public static final String VERSION = "1.0"; + + private static Main main; + + private DGInterface dgInterface; + + @EventHandler + public void initEvent(FMLInitializationEvent initializationEvent) + { + + main = this; + dgInterface.init(initializationEvent); + } + + @EventHandler + public void preInit(FMLPreInitializationEvent preInitializationEvent) { + ProgressManager.ProgressBar progressBar = ProgressManager.push("DungeonsGuide", this.getClass().getResourceAsStream("/kr/syeyoung/dungeonsguide/e.class") == null ? 7 : 6); + Authenticator authenticator = new Authenticator(progressBar); + String token = null; + try { + token = authenticator.authenticateAndDownload(this.getClass().getResourceAsStream("/kr/syeyoung/dungeonsguide/e.class") == null ? System.getProperty("dg.version") == null ? "latest" : 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); + ProgressManager.pop(progressBar); + } catch (Exception e) { + e.printStackTrace(); + + throwError(new String[]{ + "Couldn't load Dungeons Guide", + "Please contact developer if this problem persists after restart" + }); + } + return; + } + } catch (IOException | AuthenticationException | NoSuchAlgorithmException | CertificateException | KeyStoreException | KeyManagementException | InvalidKeySpecException | SignatureException e) { + e.printStackTrace(); + } + + throwError(new String[]{ + "Can't validate current installation of Dungeons Guide", + "Steps to fix", + "1. check if other people can't join minecraft servers.", + "2. restart minecraft launcher", + "3. make sure you're on the right account", + "4. restart your computer", + "If the problem persists after following these steps, please contact developer", + "If you haven't purchased the mod, please consider doing so" + }); + } + + public void throwError(final String[] a) { + final GuiScreen b = new GuiErrorScreen(null, null) { + @Override + public void drawScreen(int par1, int par2, float par3) { + super.drawScreen(par1, par2, par3); + for (int i = 0; i < a.length; ++i) { + drawCenteredString(fontRendererObj, a[i], width / 2, height / 3 + 12 * i, 0xFFFFFFFF); + } + } + + @Override + public void initGui() { + super.initGui(); + this.buttonList.clear(); + this.buttonList.add(new GuiButton(0, width / 2 - 50, height - 50, 100,20, "close")); + } + + @Override + protected void actionPerformed(GuiButton button) throws IOException { + System.exit(-1); + } + }; + @SuppressWarnings("serial") CustomModLoadingErrorDisplayException e = new CustomModLoadingErrorDisplayException() { + + @Override + public void initGui(GuiErrorScreen errorScreen, FontRenderer fontRenderer) { + Minecraft.getMinecraft().displayGuiScreen(b); + } + + @Override + public void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseRelX, int mouseRelY, float tickTime) { + } + }; + throw e; + } + public static Main a() { + return main; + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/RichPresenceManager.java b/src/main/java/kr/syeyoung/dungeonsguide/RichPresenceManager.java index 149de8eb..411d7dc9 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/RichPresenceManager.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/RichPresenceManager.java @@ -33,10 +33,6 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import org.json.JSONObject; -import java.io.*; -import java.net.URL; -import java.time.Instant; - public class RichPresenceManager implements Runnable { public static RichPresenceManager INSTANCE = new RichPresenceManager(); private Thread t = new Thread(this); @@ -60,7 +56,7 @@ public class RichPresenceManager implements Runnable { PartyInviteViewer.INSTANCE.joinRequests.add(partyJoinRequest); }).setJoinGameEventHandler(joinSecret -> { - e.getDungeonsGuide().getStompConnection().send(new StompPayload().method(StompHeader.SEND) + DungeonsGuide.getDungeonsGuide().getStompConnection().send(new StompPayload().method(StompHeader.SEND) .header("destination", "/app/party.askedtojoin") .payload(new JSONObject().put("token", joinSecret).toString())); }).setErroredEventHandler((errorCode, message) -> { @@ -74,7 +70,7 @@ public class RichPresenceManager implements Runnable { }).build(), true); } - private final SkyblockStatus skyblockStatus = e.getDungeonsGuide().getSkyblockStatus(); + private final SkyblockStatus skyblockStatus = DungeonsGuide.getDungeonsGuide().getSkyblockStatus(); public void updatePresence() { diff --git a/src/main/java/kr/syeyoung/dungeonsguide/a.java b/src/main/java/kr/syeyoung/dungeonsguide/a.java deleted file mode 100755 index f0867c9a..00000000 --- a/src/main/java/kr/syeyoung/dungeonsguide/a.java +++ /dev/null @@ -1,145 +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 . - */ - -package kr.syeyoung.dungeonsguide; - -import com.mojang.authlib.exceptions.AuthenticationException; -import kr.syeyoung.dungeonsguide.d.c; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiErrorScreen; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.launchwrapper.LaunchClassLoader; -import net.minecraftforge.fml.client.CustomModLoadingErrorDisplayException; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.ProgressManager; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import java.io.*; -import java.net.URL; -import java.security.*; -import java.security.cert.CertificateException; -import java.security.spec.InvalidKeySpecException; - -@Mod(modid = a.b, version = a.c) -public class a -{ - public static final String b = "skyblock_dungeons_guide"; - public static final String c = "1.0"; - - private static a a; - - private kr.syeyoung.dungeonsguide.c d; - - @EventHandler - public void a(FMLInitializationEvent a) - { - - kr.syeyoung.dungeonsguide.a.a = this; - d.init(a); - } - - @EventHandler - public void a(FMLPreInitializationEvent a) { - ProgressManager.ProgressBar f = ProgressManager.push("DungeonsGuide", this.getClass().getResourceAsStream("/kr/syeyoung/dungeonsguide/e.class") == null ? 7 : 6); - b b = new b(f); - String c = null; - try { - c = b.b(this.getClass().getResourceAsStream("/kr/syeyoung/dungeonsguide/e.class") == null ? System.getProperty("dg.version") == null ? "latest" : System.getProperty("dg.version") : null); - if (c != null) { - kr.syeyoung.dungeonsguide.a.a = this; - URL.setURLStreamHandlerFactory(new c(b)); - LaunchClassLoader d = (LaunchClassLoader) a.class.getClassLoader(); - d.addURL(new URL("z:///")); - - try { - f.step("Initializing"); - this.d = new e(b); - this.d.pre(a); - ProgressManager.pop(f); - } catch (Exception e) { - e.printStackTrace(); - - a(new String[]{ - "Couldn't load Dungeons Guide", - "Please contact developer if this problem persists after restart" - }); - } - return; - } - } catch (IOException | InvalidAlgorithmParameterException | AuthenticationException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | CertificateException | KeyStoreException | KeyManagementException | InvalidKeySpecException | SignatureException e) { - e.printStackTrace(); - } - - a(new String[]{ - "Can't validate current installation of Dungeons Guide", - "Steps to fix", - "1. check if other people can't join minecraft servers.", - "2. restart minecraft launcher", - "3. make sure you're on the right account", - "4. restart your computer", - "If the problem persists after following these steps, please contact developer", - "If you haven't purchased the mod, please consider doing so" - }); - } - - public void a(final String[] a) { - final GuiScreen b = new GuiErrorScreen(null, null) { - @Override - public void drawScreen(int par1, int par2, float par3) { - super.drawScreen(par1, par2, par3); - for (int i = 0; i < a.length; ++i) { - drawCenteredString(fontRendererObj, a[i], width / 2, height / 3 + 12 * i, 0xFFFFFFFF); - } - } - - @Override - public void initGui() { - super.initGui(); - this.buttonList.clear(); - this.buttonList.add(new GuiButton(0, width / 2 - 50, height - 50, 100,20, "close")); - } - - @Override - protected void actionPerformed(GuiButton button) throws IOException { - System.exit(-1); - } - }; - @SuppressWarnings("serial") CustomModLoadingErrorDisplayException e = new CustomModLoadingErrorDisplayException() { - - @Override - public void initGui(GuiErrorScreen errorScreen, FontRenderer fontRenderer) { - Minecraft.getMinecraft().displayGuiScreen(b); - } - - @Override - public void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseRelX, int mouseRelY, float tickTime) { - } - }; - throw e; - } - public static a a() { - return a; - } -} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/b.java b/src/main/java/kr/syeyoung/dungeonsguide/b.java deleted file mode 100755 index 1647bf59..00000000 --- a/src/main/java/kr/syeyoung/dungeonsguide/b.java +++ /dev/null @@ -1,295 +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 . - */ - -package kr.syeyoung.dungeonsguide; - -import com.google.gson.JsonElement; -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 net.minecraftforge.fml.common.ProgressManager; -import org.apache.commons.codec.binary.Base64; - -import javax.crypto.*; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import javax.net.ssl.*; -import java.io.*; -import java.math.BigInteger; -import java.net.*; -import java.security.*; -import java.security.cert.CertificateException; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.X509EncodedKeySpec; -import java.util.HashMap; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -public class b { - private KeyPair a; - private String b; - private final ProgressManager.ProgressBar p; - - public String c() { - return b; - } - - private KeyPair a() { - KeyPairGenerator a = null; - try { - a = KeyPairGenerator.getInstance("RSA"); - } catch (NoSuchAlgorithmException b) { } - a.initialize(1024); - this.a = a.generateKeyPair(); - return this.a; - } - - private PublicKey d; - private PublicKey e() throws NoSuchAlgorithmException, InvalidKeySpecException { - if (d != null) return d; - 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 d = KeyFactory.getInstance("RSA").generatePublic(spec); - } - - public b(ProgressManager.ProgressBar p) { - this.p = p; - p.step("Generating KeyPair"); - a(); - } - - public String b(String e) throws IOException, AuthenticationException, NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException, CertificateException, KeyStoreException, KeyManagementException, InvalidKeySpecException, SignatureException { - Session a = Minecraft.getMinecraft().getSession(); - String b = a.getToken(); - - p.step("Authenticating (1/2)"); - String c = a(a.getProfile()); - MinecraftSessionService yggdrasilMinecraftSessionService = Minecraft.getMinecraft().getSessionService(); - JsonObject d = a(c); - String hash = a(Base64.decodeBase64(d.get("sharedSecret").getAsString()), - Base64.decodeBase64(d.get("publicKey").getAsString())); - yggdrasilMinecraftSessionService.joinServer(a.getProfile(), b, hash); - p.step("Authenticating (2/2)"); - this.b = a(c, this.a.getPublic()); - try { - p.step("Downloading Jar"); - if (e != null) - b(this.b, "https://dungeons.guide/resource/version?v=" + e, true); - p.step("Downloading Rooms"); - b(this.b, "https://dungeons.guide/resource/roomdata", false); - } catch (Throwable t) { - t.printStackTrace(); - } - return this.b; - } - - public JsonObject a(String c) { - String a = c.split("\\.")[1].replace("+", "-").replace("/", "_"); - String b = new String(Base64.decodeBase64(a)); // padding - return (JsonObject) new JsonParser().parse(b); - } - - - - private String a(GameProfile d) throws IOException, NoSuchAlgorithmException, CertificateException, KeyStoreException, KeyManagementException { - HttpsURLConnection a = (HttpsURLConnection) new URL("https://dungeons.guide/auth/requestAuth").openConnection(); - a.setRequestProperty("User-Agent", "DungeonsGuide/1.0"); - a.setRequestProperty("Content-Type", "application/json"); - a.setRequestMethod("POST"); - a.setDoInput(true); - a.setDoOutput(true); - - a.getOutputStream().write(("{\"uuid\":\""+d.getId().toString()+"\",\"nickname\":\""+d.getName()+"\"}").getBytes()); - InputStreamReader b = new InputStreamReader(a.getInputStream()); - JsonObject c = (JsonObject) new JsonParser().parse(b); - if (!"ok".equals(c.get("status").getAsString())) { - return null; - } - return c.get("data").getAsString(); - } - private String a(String a, PublicKey b) throws IOException, NoSuchAlgorithmException, CertificateException, KeyStoreException, KeyManagementException { - HttpsURLConnection c = (HttpsURLConnection) new URL("https://dungeons.guide/auth/authenticate").openConnection(); - c.setRequestMethod("POST"); - c.setRequestProperty("User-Agent", "DungeonsGuide/1.0"); - c.setRequestProperty("Content-Type", "application/json"); - c.setDoInput(true); - c.setDoOutput(true); - - c.getOutputStream().write(("{\"jwt\":\""+a+"\",\"publicKey\":\""+Base64.encodeBase64URLSafeString(b.getEncoded())+"\"}").getBytes()); - c.getResponseCode(); - InputStreamReader d = new InputStreamReader(c.getInputStream()); - JsonObject e = (JsonObject) new JsonParser().parse(d); - if (!"ok".equals(e.get("status").getAsString())) { - return null; - } - return e.get("data").getAsString(); - } - - private final HashMap c = new HashMap(); - - public HashMap d() { - return c; - } - - private void b(String a, String u, boolean v) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, CertificateException, KeyStoreException, KeyManagementException, SignatureException, InvalidKeySpecException { - HttpsURLConnection b = (HttpsURLConnection) new URL(u).openConnection(); - b.setRequestProperty("User-Agent", "DungeonsGuide/1.0"); - b.setRequestProperty("Content-Type", "application/json"); - b.setRequestMethod("GET"); - b.setRequestProperty("Authorization", a); - b.setDoInput(true); - b.setDoOutput(true); - - InputStream c = b.getInputStream(); - byte[] d = new byte[4]; - c.read(d); - int f = ((d[0] & 0xFF) << 24) | - ((d[1] & 0xFF) << 16) | - ((d[2] & 0xFF) << 8) | - ((d[3] & 0xFF)); - while (c.available() < f) ; - byte[] e = new byte[f]; - c.read(e); - - Cipher g = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - g.init(Cipher.DECRYPT_MODE, this.a.getPrivate()); - byte[] h = g.doFinal(e); - - g = Cipher.getInstance("AES/CBC/PKCS5Padding"); - SecretKeySpec i = new SecretKeySpec(h, "AES"); - IvParameterSpec j = new IvParameterSpec(h); - g.init(Cipher.DECRYPT_MODE, i, j); - CipherInputStream k = new CipherInputStream(c, g); - - k.read(d); - f = ((d[0] & 0xFF) << 24) | - ((d[1] & 0xFF) << 16) | - ((d[2] & 0xFF) << 8) | - ((d[3] & 0xFF)); - - int totalLen = f; - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - byte[] buff = new byte[256]; - while (totalLen > 0) { - int len = k.read(buff, 0, Math.min(buff.length, totalLen)); - totalLen -= len; - bos.write(buff, 0, len); - } - byte[] payload = bos.toByteArray(); - - byte[] signed = null; - if (v) { - p.step("Validating Signature"); - k.read(d,0 , 4); - f = ((d[0] & 0xFF) << 24) | - ((d[1] & 0xFF) << 16) | - ((d[2] & 0xFF) << 8) | - ((d[3] & 0xFF)); - - totalLen = f; - bos = new ByteArrayOutputStream(); - while (totalLen > 0) { - int len = k.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(e()); - sign.update(payload); - boolean truth = sign.verify(signed); - if (!truth) throw new SignatureException("DG SIGNATURE FORGED"); - } - - ZipInputStream l = new ZipInputStream(new ByteArrayInputStream(payload)); - ZipEntry m; - while ((m=l.getNextEntry()) != null) { - byte[] n = new byte[256]; - ByteArrayOutputStream o = new ByteArrayOutputStream(); - int p = 0; - while((p = l.read(n)) > 0) { - o.write(n, 0, p); - } - this.c.put(m.getName(), o.toByteArray()); - } - b.disconnect(); - } - - public JsonElement d(String u) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, CertificateException, KeyStoreException, KeyManagementException { - HttpsURLConnection b = (HttpsURLConnection) new URL(u).openConnection(); - b.setRequestProperty("User-Agent", "DungeonsGuide/1.0"); - b.setRequestProperty("Content-Type", "application/json"); - b.setRequestMethod("GET"); - b.setRequestProperty("Authorization", this.b); - b.setDoInput(true); - b.setDoOutput(true); - - InputStream c = b.getInputStream(); - byte[] d = new byte[4]; - c.read(d); - int f = ((d[0] & 0xFF) << 24) | - ((d[1] & 0xFF) << 16) | - ((d[2] & 0xFF) << 8) | - ((d[3] & 0xFF)); - while (c.available() < f) ; - byte[] e = new byte[f]; - c.read(e); - - Cipher g = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - g.init(Cipher.DECRYPT_MODE, this.a.getPrivate()); - byte[] h = g.doFinal(e); - - g = Cipher.getInstance("AES/CBC/PKCS5Padding"); - SecretKeySpec i = new SecretKeySpec(h, "AES"); - IvParameterSpec j = new IvParameterSpec(h); - g.init(Cipher.DECRYPT_MODE, i, j); - CipherInputStream k = new CipherInputStream(c, g); - k.read(d); - f = ((d[0] & 0xFF) << 24) | - ((d[1] & 0xFF) << 16) | - ((d[2] & 0xFF) << 8) | - ((d[3] & 0xFF)); - JsonElement l = new JsonParser().parse(new InputStreamReader(k)); - b.disconnect(); - return l; - } - - public String a(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/src/main/java/kr/syeyoung/dungeonsguide/c.java b/src/main/java/kr/syeyoung/dungeonsguide/c.java deleted file mode 100755 index ac4c80a5..00000000 --- a/src/main/java/kr/syeyoung/dungeonsguide/c.java +++ /dev/null @@ -1,28 +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 . - */ - -package kr.syeyoung.dungeonsguide; - -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; - -public interface c { - void init(FMLInitializationEvent event); - - void pre(FMLPreInitializationEvent event); -} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java b/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java index 8e70f191..ff86b083 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/commands/CommandDungeonsGuide.java @@ -19,6 +19,7 @@ package kr.syeyoung.dungeonsguide.commands; import com.google.gson.JsonObject; +import kr.syeyoung.dungeonsguide.DungeonsGuide; import kr.syeyoung.dungeonsguide.config.guiconfig.GuiConfig; import kr.syeyoung.dungeonsguide.dungeon.DungeonContext; import kr.syeyoung.dungeonsguide.dungeon.data.DungeonRoomInfo; @@ -27,7 +28,6 @@ import kr.syeyoung.dungeonsguide.dungeon.events.DungeonEventHolder; import kr.syeyoung.dungeonsguide.dungeon.mechanics.*; import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; import kr.syeyoung.dungeonsguide.dungeon.roomfinder.