diff --git a/deobfuscator/build.gradle b/deobfuscator/build.gradle index 177d98c81a..0d61c904d6 100644 --- a/deobfuscator/build.gradle +++ b/deobfuscator/build.gradle @@ -1,4 +1,8 @@ import org.apache.tools.ant.filters.ReplaceTokens +import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler +import java.nio.file.Files +import java.nio.file.Paths +import java.util.zip.ZipFile plugins { id "com.github.hauner.jarTest" version "1.0.1" @@ -6,6 +10,30 @@ plugins { description = 'Deobfuscator' +def deobfuscatedJar = "${rootPath}/runescape-client/build/libs/rs-client-${project.version}.jar" + +def unzipFile(String file, String dest) +{ + def zipFile = new ZipFile(file) + + zipFile.entries().each { it -> + def path = Paths.get(dest + File.separator + it.name) + if (it.directory) + { + Files.createDirectories(path) + } + else + { + def parentDir = path.getParent() + if (!Files.exists(parentDir)) + { + Files.createDirectories(parentDir) + } + Files.copy(zipFile.getInputStream(it), path) + } + } +} + configurations { deobjars } @@ -48,3 +76,42 @@ processTestResources { ]) } } + +task gamepackUpdate { + dependsOn ":deobfuscator:build" + dependsOn ":rs-client:build" + + doLast { + def path = sourceSets.main.runtimeClasspath + def loader = new URLClassLoader(path.collect { f -> f.toURI().toURL() } as URL[]) + def downloader = loader.loadClass('net.runelite.gamepack.Downloader') + def clientVersion = loader.loadClass('net.runelite.deob.clientver.ClientVersionMain') + def deob = loader.loadClass('net.runelite.deob.Deob') + def mappings = loader.loadClass('net.runelite.deob.updater.UpdateMappings') + + String gamepack = downloader.gamepack() + int version = clientVersion.version(gamepack) + + String gamepackVersion = gamepack.replace("gamepack.jar", "gamepack-" + version + ".jar") + String gamepackDeob = gamepack.replace("gamepack.jar", "gamepack-" + version + "-deob.jar") + String gamepackMappings = gamepack.replace("gamepack.jar", "gamepack-" + version + "-updated-mappings.jar") + String gamepackMappingsDecomp = gamepackMappings.replace(".jar", "-decomp") + String gamepackMappingsFern = gamepackMappingsDecomp + File.separator + gamepackMappings.split("/gamepack/")[1] + + if (version == -1 || version == rsversion) + { + return + } + + deob.main(gamepackVersion, gamepackDeob) + mappings.main(deobfuscatedJar, gamepackDeob, gamepackMappings) + + new File(gamepackMappingsDecomp).mkdirs() + ConsoleDecompiler.main(gamepackMappings, gamepackMappingsDecomp) + + unzipFile(gamepackMappingsFern, gamepackMappingsDecomp) + new File(gamepackMappingsFern).delete() + + loader.close() + } +} diff --git a/deobfuscator/src/main/java/net/runelite/deob/Deob.java b/deobfuscator/src/main/java/net/runelite/deob/Deob.java index bea8f623d3..06b9b176dc 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/Deob.java +++ b/deobfuscator/src/main/java/net/runelite/deob/Deob.java @@ -30,8 +30,6 @@ import java.io.IOException; import net.runelite.asm.ClassGroup; import net.runelite.asm.execution.Execution; import net.runelite.deob.deobfuscators.CastNull; -import net.runelite.deob.deobfuscators.StaticShouldBeInstance; -import net.runelite.deob.deobfuscators.constparam.ConstantParameter; import net.runelite.deob.deobfuscators.EnumDeobfuscator; import net.runelite.deob.deobfuscators.FieldInliner; import net.runelite.deob.deobfuscators.IllegalStateExceptions; @@ -39,6 +37,7 @@ import net.runelite.deob.deobfuscators.Lvt; import net.runelite.deob.deobfuscators.Order; import net.runelite.deob.deobfuscators.RenameUnique; import net.runelite.deob.deobfuscators.RuntimeExceptions; +import net.runelite.deob.deobfuscators.StaticShouldBeInstance; import net.runelite.deob.deobfuscators.UnreachedCode; import net.runelite.deob.deobfuscators.UnusedClass; import net.runelite.deob.deobfuscators.UnusedFields; @@ -49,6 +48,7 @@ import net.runelite.deob.deobfuscators.arithmetic.MultiplicationDeobfuscator; import net.runelite.deob.deobfuscators.arithmetic.MultiplyOneDeobfuscator; import net.runelite.deob.deobfuscators.arithmetic.MultiplyZeroDeobfuscator; import net.runelite.deob.deobfuscators.cfg.ControlFlowDeobfuscator; +import net.runelite.deob.deobfuscators.constparam.ConstantParameter; import net.runelite.deob.deobfuscators.exprargorder.ExprArgOrder; import net.runelite.deob.deobfuscators.menuaction.MenuActionDeobfuscator; import net.runelite.deob.deobfuscators.transformers.ClientErrorTransformer; diff --git a/deobfuscator/src/main/java/net/runelite/deob/clientver/ClientVersionMain.java b/deobfuscator/src/main/java/net/runelite/deob/clientver/ClientVersionMain.java index 5b16f13bc7..9b22c68308 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/clientver/ClientVersionMain.java +++ b/deobfuscator/src/main/java/net/runelite/deob/clientver/ClientVersionMain.java @@ -25,6 +25,7 @@ package net.runelite.deob.clientver; +import com.google.common.io.Files; import java.io.File; import java.io.IOException; @@ -36,4 +37,24 @@ public class ClientVersionMain ClientVersion cv = new ClientVersion(jar); System.out.println(cv.getVersion()); } + + public static int version(String loc) + { + File jar = new File(loc); + ClientVersion cv = new ClientVersion(jar); + try + { + int version = cv.getVersion(); + + Files.move(jar, new File(loc.replace("gamepack.jar", "gamepack-" + version + ".jar"))); + + return version; + } + catch (IOException e) + { + e.printStackTrace(); + } + + return -1; + } } diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/UpdateMappings.java b/deobfuscator/src/main/java/net/runelite/deob/updater/UpdateMappings.java index 0514ae7afa..456eef2c8f 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/updater/UpdateMappings.java +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/UpdateMappings.java @@ -96,7 +96,7 @@ public class UpdateMappings JarUtil.loadJar(new File(args[0])), JarUtil.loadJar(new File(args[1])) ); - u.update(); + u.update(); u.save(new File(args[2])); } } diff --git a/deobfuscator/src/main/java/net/runelite/gamepack/Checker.java b/deobfuscator/src/main/java/net/runelite/gamepack/Checker.java new file mode 100644 index 0000000000..cf36651cef --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/gamepack/Checker.java @@ -0,0 +1,166 @@ +package net.runelite.gamepack; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +public class Checker +{ + private static final String GAME_URL = "http://oldschool1.runescape.com/"; + private static final Split[] splits = { + new Split("document.write('archive=", 1), + new Split(" ');", 0) + }; + + static String getGamePack() + { + URL url; + try + { + url = new URL(GAME_URL); + } + catch (MalformedURLException e) + { + e.printStackTrace(); + return null; + } + + String content; + try + { + content = getContent(url); + } + catch (IOException e) + { + e.printStackTrace(); + return null; + } + + for (Split split : splits) + { + String[] str = splitAtFirst(content, split.splitAt); + content = str[split.index]; + } + + return content; + } + + private static String[] splitAtFirst(String subject, String splitAt) + { + if (subject == null || subject.length() == 0) + { + return new String[]{"", ""}; + } + + if (splitAt == null || splitAt.length() == 0) + { + return new String[]{subject, ""}; + } + + char[] subjectArray = subject.toCharArray(); + char[] split = splitAt.toCharArray(); + + StringBuilder builder = null; + for (int i = 0; i < subjectArray.length; i++) + { + char c = subjectArray[i]; + + if (builder == null && c == split[0]) + { + builder = new StringBuilder(); + } + + if (builder != null) + { + builder.append(c); + + if (startsWith(splitAt, builder.toString())) + { + if (builder.length() == splitAt.length()) + { + return new String[]{subject.substring(0, i - builder.length() + 1), subject.substring(i + 1)}; + } + } + else + { + builder = null; + } + } + } + + return new String[]{subject, ""}; + } + + private static boolean startsWith(String subject, String start) + { + if (subject == null || subject.length() == 0 || start == null || start.length() == 0 || start.length() > subject.length()) + { + return false; + } + + char[] c1 = subject.toCharArray(); + char[] c2 = start.toCharArray(); + for (int i = 0; i < c2.length; i++) + { + if (c1[i] != c2[i]) + { + return false; + } + } + + return true; + } + + private static String getContent(URL url) throws IOException + { + BufferedReader rd = null; + + try + { + URLConnection conn = url.openConnection(); + + if (conn instanceof HttpURLConnection) + { + ((HttpURLConnection) conn).setInstanceFollowRedirects(false); + } + + HttpURLConnection.setFollowRedirects(false); + + rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); + StringBuilder sb = new StringBuilder(); + + String line; + while ((line = rd.readLine()) != null) + { + sb.append(line); + sb.append('\n'); + } + + return sb.toString(); + + } + finally + { + if (rd != null) + { + rd.close(); + } + } + } + + public static class Split + { + public int index; + String splitAt; + + Split(String splitAt, int index) + { + this.splitAt = splitAt; + this.index = index; + } + } +} \ No newline at end of file diff --git a/deobfuscator/src/main/java/net/runelite/gamepack/Downloader.java b/deobfuscator/src/main/java/net/runelite/gamepack/Downloader.java new file mode 100644 index 0000000000..350454ac8b --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/gamepack/Downloader.java @@ -0,0 +1,61 @@ +package net.runelite.gamepack; + + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class Downloader +{ + private static final String REPLACE = "%archive%"; + private static final String GAMEPACK_URL = "http://oldschool1.runescape.com/" + REPLACE; + + private static String getGamepackUrl() + { + String archive = Checker.getGamePack(); + return archive == null ? "" : GAMEPACK_URL.replace(REPLACE, archive); + } + + public static String gamepack() + { + Path path = Paths.get(System.getProperty("user.home"), "gamepack"); + final File folder = new File(String.valueOf(path)); + + if (!folder.exists()) + { + folder.mkdir(); + } + + downloadLatest(folder); + + return path + File.separator + "gamepack.jar"; + } + + private static void downloadLatest(File folder) + { + File output = new File(folder, "gamepack.jar"); + + try + { + URL url = new URL(getGamepackUrl()); + + final URLDownloader downloader = new URLDownloader(url, output); + downloader.download(); + + try + { + Thread.sleep(100); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/deobfuscator/src/main/java/net/runelite/gamepack/URLDownloader.java b/deobfuscator/src/main/java/net/runelite/gamepack/URLDownloader.java new file mode 100644 index 0000000000..07d74fcf70 --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/gamepack/URLDownloader.java @@ -0,0 +1,35 @@ +package net.runelite.gamepack; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; + +class URLDownloader +{ + private URL url; + private File output; + + URLDownloader(URL url, File output) + { + this.url = url; + this.output = output; + } + + void download() throws IOException + { + this.downloadFromURL(); + } + + private void downloadFromURL() throws IOException + { + ReadableByteChannel rbc = Channels.newChannel(url.openStream()); + FileOutputStream fos = new FileOutputStream(output); + + FileChannel channel = fos.getChannel(); + channel.transferFrom(rbc, 0, Long.MAX_VALUE); + } +} \ No newline at end of file