diff options
7 files changed, 154 insertions, 163 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java b/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java index bf1a05a9..9fc16054 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/Authenticator.java @@ -104,36 +104,4 @@ public class Authenticator { byte[] result = md.digest(); return new BigInteger(result).toString(16); } - public InputStream getInputStream(String resource) throws IOException, BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException { - System.out.println("loading "+resource); - - HttpURLConnection huc = (HttpURLConnection) new URL(DOMAIN+"resource/resource?class="+ URLEncoder.encode(resource)).openConnection(); - huc.setRequestProperty("User-Agent", "DungeonsGuide/1.0"); - huc.setRequestProperty("Content-Type", "application/json"); - huc.setRequestProperty("Authorization", token); - huc.setDoInput(true); - huc.setDoOutput(true); - - InputStream inputStream = huc.getInputStream(); - byte[] bytes = new byte[4]; - inputStream.read(bytes); - int len = ((bytes[0] & 0xFF) << 24) | - ((bytes[1] & 0xFF) << 16) | - ((bytes[2] & 0xFF) << 8 ) | - ((bytes[3] & 0xFF)); - while(inputStream.available() < len); - byte[] pubKey = new byte[len]; - inputStream.read(pubKey); - - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - byte[] byteEncrypted = pubKey; - cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); - byte[] bytePlain = cipher.doFinal(byteEncrypted); - - cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - SecretKeySpec keySpec = new SecretKeySpec(bytePlain, "AES"); - IvParameterSpec ivSpec = new IvParameterSpec(bytePlain); - cipher.init(Cipher.DECRYPT_MODE,keySpec,ivSpec); - return new CipherInputStream(inputStream, cipher); - } } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuideMain.java b/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuideMain.java index 91724399..2ffa1cc7 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuideMain.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/DungeonsGuideMain.java @@ -1,12 +1,13 @@ package kr.syeyoung.dungeonsguide; import com.mojang.authlib.exceptions.AuthenticationException; +import kr.syeyoung.dungeonsguide.customurl.DGURLStreamHandlerFactory; import lombok.Getter; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiErrorScreen; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.util.IChatComponent; +import net.minecraft.launchwrapper.LaunchClassLoader; import net.minecraftforge.fml.client.CustomModLoadingErrorDisplayException; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; @@ -14,6 +15,7 @@ import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import java.io.*; +import java.net.URL; import java.security.NoSuchAlgorithmException; @Mod(modid = DungeonsGuideMain.MODID, version = DungeonsGuideMain.VERSION) @@ -22,7 +24,7 @@ public class DungeonsGuideMain public static final String MODID = "skyblock_dungeons_guide"; public static final String VERSION = "0.1"; - private static DungeonsGuideMain DungeonsGuideMain; + private static DungeonsGuideMain dungeonsGuideMain; private DungeonsGuideInterface dungeonsGuideInterface; @@ -30,14 +32,13 @@ public class DungeonsGuideMain public void init(FMLInitializationEvent event) { - DungeonsGuideMain = this; + dungeonsGuideMain = this; dungeonsGuideInterface.init(event); } @Getter private Authenticator authenticator; - private NetworkClassLoader classLoader; @EventHandler public void pre(FMLPreInitializationEvent event) { authenticator = new Authenticator(); @@ -45,31 +46,14 @@ public class DungeonsGuideMain try { token = authenticator.authenticate(); if (token != null) { - classLoader = new NetworkClassLoader(authenticator, DungeonsGuideMain.class.getClassLoader()); + URL.setURLStreamHandlerFactory(new DGURLStreamHandlerFactory(authenticator)); + LaunchClassLoader launchClassLoader = (LaunchClassLoader) DungeonsGuideMain.class.getClassLoader(); + launchClassLoader.addURL(new URL("dungeonsguide:///")); - Class skyblockStatusCls = null; try { - skyblockStatusCls = classLoader.findClass("kr.syeyoung.dungeonsguide.DungeonsGuide"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - - error(new String[]{ - "Couldn't load Dungeons Guide", - "Please contact developer if this problem persists after restart" - }); - return; - } - try { - dungeonsGuideInterface = (DungeonsGuideInterface) skyblockStatusCls.newInstance(); + dungeonsGuideInterface = new DungeonsGuide(); dungeonsGuideInterface.pre(event); - } catch (InstantiationException e) { - e.printStackTrace(); - - error(new String[]{ - "Couldn't load Dungeons Guide", - "Please contact developer if this problem persists after restart" - }); - } catch (IllegalAccessException e) { + } catch (Exception e) { e.printStackTrace(); error(new String[]{ @@ -127,6 +111,6 @@ public class DungeonsGuideMain throw e; } public static DungeonsGuideMain getDungeonsGuideMain() { - return DungeonsGuideMain; + return dungeonsGuideMain; } } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/NetworkClassLoader.java b/src/main/java/kr/syeyoung/dungeonsguide/NetworkClassLoader.java deleted file mode 100644 index 119dc27d..00000000 --- a/src/main/java/kr/syeyoung/dungeonsguide/NetworkClassLoader.java +++ /dev/null @@ -1,74 +0,0 @@ -package kr.syeyoung.dungeonsguide; - -import com.google.common.io.Files; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.xml.bind.DatatypeConverter; -import java.io.*; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -public class NetworkClassLoader extends ClassLoader { - Authenticator authenticator; - - public NetworkClassLoader(Authenticator authenticator, ClassLoader parent) { - super(parent); - this.authenticator = authenticator; - } - - @Override - public Class findClass(String name) throws ClassNotFoundException { - byte[] b = new byte[0]; - try { - b = loadClassFromFile(name); - return defineClass(name, b, 0, b.length); - } catch (FileNotFoundException ignored) { - } catch(BadPaddingException e) { - e.printStackTrace(); - } catch (InvalidAlgorithmParameterException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); - } catch (NoSuchPaddingException e) { - e.printStackTrace(); - } catch (InvalidKeyException e) { - e.printStackTrace(); - } - throw new ClassNotFoundException(); - } - - private byte[] loadClassFromFile(String fileName) throws BadPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException { - InputStream inputStream = authenticator.getInputStream(fileName.replace('.', '/')+ ".class"); - - byte[] bytes = new byte[4]; - inputStream.read(bytes); - int length = ((bytes[0] & 0xFF) << 24) | - ((bytes[1] & 0xFF) << 16) | - ((bytes[2] & 0xFF) << 8 ) | - ((bytes[3] & 0xFF)); - - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - int totalLen = 0; - try { - byte[] buffer = new byte[128]; - int read = 0; - while ( (read = inputStream.read(buffer)) != -1 ) { - totalLen += read; - byteStream.write(buffer, 0, read); - if (totalLen >= length) break;; - } - } catch (Exception ignored) {} - byte[] byte1 = byteStream.toByteArray(); - byte[] byte2 = new byte[(int) length]; - System.arraycopy(byte1, 0, byte2, 0, byte2.length); - inputStream.close(); - return byte2; - } -} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/customurl/DGURLConnection.java b/src/main/java/kr/syeyoung/dungeonsguide/customurl/DGURLConnection.java new file mode 100644 index 00000000..5335f7b3 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/customurl/DGURLConnection.java @@ -0,0 +1,97 @@ +package kr.syeyoung.dungeonsguide.customurl; + +import kr.syeyoung.dungeonsguide.Authenticator; +import lombok.SneakyThrows; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; + +public class DGURLConnection extends URLConnection { + private Authenticator authenticator; + protected DGURLConnection(URL url, Authenticator authenticator) { + super(url); + this.authenticator = authenticator; + try { + connect(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static final String DOMAIN = "http://localhost:8080/"; + + @SneakyThrows + @Override + public void connect() throws IOException { + this.connected = true; + + System.out.println("loading "+url.getPath()); + + HttpURLConnection huc = (HttpURLConnection) new URL(DOMAIN+"resource/resource?class="+ URLEncoder.encode(url.getPath())).openConnection(); + huc.setRequestProperty("User-Agent", "DungeonsGuide/1.0"); + huc.setRequestProperty("Content-Type", "application/json"); + huc.setRequestProperty("Authorization", authenticator.getToken()); + huc.setDoInput(true); + huc.setDoOutput(true); + + InputStream inputStream = huc.getInputStream(); + byte[] bytes = new byte[4]; + inputStream.read(bytes); + int len = ((bytes[0] & 0xFF) << 24) | + ((bytes[1] & 0xFF) << 16) | + ((bytes[2] & 0xFF) << 8 ) | + ((bytes[3] & 0xFF)); + while(inputStream.available() < len); + byte[] pubKey = new byte[len]; + inputStream.read(pubKey); + + Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + byte[] byteEncrypted = pubKey; + cipher.init(Cipher.DECRYPT_MODE, authenticator.getKeyPair().getPrivate()); + byte[] bytePlain = cipher.doFinal(byteEncrypted); + + cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKeySpec keySpec = new SecretKeySpec(bytePlain, "AES"); + IvParameterSpec ivSpec = new IvParameterSpec(bytePlain); + cipher.init(Cipher.DECRYPT_MODE,keySpec,ivSpec); + CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher); + + int length = ((bytes[0] & 0xFF) << 24) | + ((bytes[1] & 0xFF) << 16) | + ((bytes[2] & 0xFF) << 8 ) | + ((bytes[3] & 0xFF)); + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + int totalLen = 0; + try { + byte[] buffer = new byte[128]; + int read = 0; + while ( (read = cipherInputStream.read(buffer)) != -1 ) { + totalLen += read; + byteStream.write(buffer, 0, read); + if (totalLen >= length) break;; + } + } catch (Exception ignored) {} + byte[] byte1 = byteStream.toByteArray(); + byte[] byte2 = new byte[(int) length]; + System.arraycopy(byte1, 0, byte2, 0, byte2.length); + cipherInputStream.close(); + inputStream.close(); + this.inputStream = new ByteArrayInputStream(byte2); + } + private InputStream inputStream; + + @Override + public InputStream getInputStream() throws IOException { + return inputStream; + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/customurl/DGURLStreamHandler.java b/src/main/java/kr/syeyoung/dungeonsguide/customurl/DGURLStreamHandler.java new file mode 100644 index 00000000..0a8f53a9 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/customurl/DGURLStreamHandler.java @@ -0,0 +1,19 @@ +package kr.syeyoung.dungeonsguide.customurl; + +import kr.syeyoung.dungeonsguide.Authenticator; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +public class DGURLStreamHandler extends URLStreamHandler { + private Authenticator authenticator; + public DGURLStreamHandler(Authenticator authenticator) { + this.authenticator = authenticator; + } + @Override + protected URLConnection openConnection(URL url) throws IOException { + return new DGURLConnection(url, authenticator); + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/customurl/DGURLStreamHandlerFactory.java b/src/main/java/kr/syeyoung/dungeonsguide/customurl/DGURLStreamHandlerFactory.java new file mode 100644 index 00000000..15defa5e --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/customurl/DGURLStreamHandlerFactory.java @@ -0,0 +1,21 @@ +package kr.syeyoung.dungeonsguide.customurl; + +import kr.syeyoung.dungeonsguide.Authenticator; + +import java.net.URLStreamHandler; +import java.net.URLStreamHandlerFactory; + +public class DGURLStreamHandlerFactory implements URLStreamHandlerFactory { + private Authenticator authenticator; + public DGURLStreamHandlerFactory(Authenticator authenticator) { + this.authenticator = authenticator; + } + @Override + public URLStreamHandler createURLStreamHandler(String s) { + if ("dungeonsguide".equals(s)) { + return new DGURLStreamHandler(authenticator); + } + + return null; + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/roomfinder/DungeonRoomInfoRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/roomfinder/DungeonRoomInfoRegistry.java index 6f5ac4ce..04dac612 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/roomfinder/DungeonRoomInfoRegistry.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/roomfinder/DungeonRoomInfoRegistry.java @@ -4,11 +4,13 @@ import kr.syeyoung.dungeonsguide.Authenticator; import kr.syeyoung.dungeonsguide.DungeonsGuide; import kr.syeyoung.dungeonsguide.DungeonsGuideMain; import kr.syeyoung.dungeonsguide.dungeon.data.DungeonRoomInfo; +import org.apache.commons.io.IOUtils; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.io.*; +import java.net.URL; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -67,38 +69,12 @@ public class DungeonRoomInfoRegistry { registered.clear(); shapeMap.clear(); uuidMap.clear(); - Authenticator authenticator = DungeonsGuideMain.getDungeonsGuideMain().getAuthenticator(); - InputStream inputStream = authenticator.getInputStream("roomdata/datas.txt"); - byte[] bytes = new byte[4]; - inputStream.read(bytes); - - int length = ((bytes[0] & 0xFF) << 24) | - ((bytes[1] & 0xFF) << 16) | - ((bytes[2] & 0xFF) << 8 ) | - ((bytes[3] & 0xFF)); - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - int totalLen = 0; - try { - byte[] buffer = new byte[128]; - int read = 0; - while ( (read = inputStream.read(buffer)) != -1 ) { - totalLen += read; - byteStream.write(buffer, 0, read); - if (totalLen >= length) break;; - } - } catch (Exception ignored) {} - byte[] byte1 = byteStream.toByteArray(); - byte[] byte2 = new byte[(int) length]; - System.arraycopy(byte1, 0, byte2, 0, byte2.length); - inputStream.close(); - - String names = new String(byte2); - - for (String name : names.split("\n")) { + URL url = new URL("dungeonsguide:///roomdata/data.txt"); + List<String> lines = IOUtils.readLines(url.openConnection().getInputStream()); + for (String name : lines) { if (name.endsWith(".roomdata")) continue; try { - InputStream fis = authenticator.getInputStream(name); - fis.read(new byte[4]); + InputStream fis = new URL("dungeonsguide:///"+name).openStream(); ObjectInputStream ois = new ObjectInputStream(fis); DungeonRoomInfo dri = (DungeonRoomInfo) ois.readObject(); ois.close(); |