diff --git a/README.md b/README.md index d50ff5e..a3bd305 100644 --- a/README.md +++ b/README.md @@ -52,3 +52,8 @@ Unconfigurable: - Varp array size was extended to 3500 instead of 2500 - Mouse wheel camera movement (click middle button and move mouse) - Render FPS is set to your monitor's refresh rate + +## Libraries Used + +- JOGL/Gluegen 2.4.0rc +- Google Gson 2.9.0 diff --git a/client/build.gradle b/client/build.gradle index a29bbca..394d215 100644 --- a/client/build.gradle +++ b/client/build.gradle @@ -19,12 +19,14 @@ dependencies { compileOnly project(':deob-annotations') implementation project(':signlink') + implementation 'lib:gson' implementation 'lib:gluegen-rt' implementation 'lib:gluegen-rt-natives-windows-amd64' implementation 'lib:gluegen-rt-natives-windows-i586' implementation 'lib:gluegen-rt-natives-linux-amd64' implementation 'lib:gluegen-rt-natives-linux-i586' implementation 'lib:gluegen-rt-natives-macosx-universal' + implementation 'lib:gluegen-rt-natives-android-aarch64' implementation 'lib:jogl-all' implementation 'lib:jogl-all-natives-windows-amd64' @@ -32,6 +34,7 @@ dependencies { implementation 'lib:jogl-all-natives-linux-amd64' implementation 'lib:jogl-all-natives-linux-i586' implementation 'lib:jogl-all-natives-macosx-universal' + implementation 'lib:jogl-all-natives-android-aarch64' } jar { diff --git a/client/config.json b/client/config.json new file mode 100644 index 0000000..2f79e76 --- /dev/null +++ b/client/config.json @@ -0,0 +1,8 @@ +{ + "ip_management": "test.2009scape.org", + "ip_address": "test.2009scape.org", + "world": 1, + "server_port": 43594, + "wl_port": 5555, + "js5_port": 43593 +} \ No newline at end of file diff --git a/client/src/main/java/rt4/GlobalConfig.java b/client/src/main/java/rt4/GlobalConfig.java index e03e739..133af50 100644 --- a/client/src/main/java/rt4/GlobalConfig.java +++ b/client/src/main/java/rt4/GlobalConfig.java @@ -16,6 +16,8 @@ public class GlobalConfig { @OriginalMember(owner = "client!gm", name = "X", descriptor = "Ljava/math/BigInteger;") public static final BigInteger RSA_EXPONENT = new BigInteger("65537"); + public static String EXTENDED_CONFIG_PATH = "config.json"; + // Server IP public static String DEFAULT_HOSTNAME = "test.2009scape.org"; diff --git a/client/src/main/java/rt4/GlobalJsonConfig.java b/client/src/main/java/rt4/GlobalJsonConfig.java new file mode 100644 index 0000000..70b8437 --- /dev/null +++ b/client/src/main/java/rt4/GlobalJsonConfig.java @@ -0,0 +1,28 @@ +package rt4; + +import com.google.gson.Gson; + +import java.io.FileReader; + +public class GlobalJsonConfig { + public static GlobalJsonConfig instance = null; + + public static void load(String path) { + Gson gson = new Gson(); + + try { + instance = gson.fromJson(new FileReader(path), GlobalJsonConfig.class); + } catch (Exception ex) { + System.err.println("No config.json file, using defaults"); + } + } + + // ---- + + String ip_management; + String ip_address; + int world; + int server_port; + int wl_port; + int js5_port; +} diff --git a/client/src/main/java/rt4/JagString.java b/client/src/main/java/rt4/JagString.java index e4f26a3..70abcaf 100644 --- a/client/src/main/java/rt4/JagString.java +++ b/client/src/main/java/rt4/JagString.java @@ -964,11 +964,11 @@ public final class JagString implements StringInterface { @OriginalMember(owner = "client!na", name = "d", descriptor = "(Z)I") public final int method3154() { - @Pc(7) int local7 = 0; - for (@Pc(14) int local14 = 0; local14 < this.length; local14++) { - local7 = (this.chars[local14] & 0xFF) + (local7 << 5) - local7; + @Pc(7) int hash = 0; + for (@Pc(14) int c = 0; c < this.length; c++) { + hash = (this.chars[c] & 0xFF) + (hash << 5) - hash; } - return local7; + return hash; } @OriginalMember(owner = "client!na", name = "a", descriptor = "(ILjava/awt/FontMetrics;)I") diff --git a/client/src/main/java/rt4/Js5.java b/client/src/main/java/rt4/Js5.java index 21bca28..9d1058b 100644 --- a/client/src/main/java/rt4/Js5.java +++ b/client/src/main/java/rt4/Js5.java @@ -137,9 +137,9 @@ public final class Js5 { } @OriginalMember(owner = "client!ve", name = "a", descriptor = "(Lclient!na;B)I") - public final int getGroupId(@OriginalArg(0) JagString arg0) { + public final int getGroupId(@OriginalArg(0) JagString name) { if (this.method4484()) { - @Pc(16) JagString local16 = arg0.toLowerCase(); + @Pc(16) JagString local16 = name.toLowerCase(); @Pc(27) int local27 = this.aClass70_2.aClass76_1.method2405(local16.method3154()); return this.method4492(local27) ? local27 : -1; } else { diff --git a/client/src/main/java/rt4/LoginManager.java b/client/src/main/java/rt4/LoginManager.java index 7316ac9..ac514fa 100644 --- a/client/src/main/java/rt4/LoginManager.java +++ b/client/src/main/java/rt4/LoginManager.java @@ -243,6 +243,10 @@ public class LoginManager { errors++; } if (step == 1) { + if (GlobalJsonConfig.instance != null) { + client.hostname = GlobalJsonConfig.instance.ip_management; + client.port = GlobalJsonConfig.instance.server_port + client.worldListId; + } Protocol.socketRequest = GameShell.signLink.openSocket(client.hostname, client.port); step = 2; } diff --git a/client/src/main/java/rt4/WorldList.java b/client/src/main/java/rt4/WorldList.java index b93a13d..292301a 100644 --- a/client/src/main/java/rt4/WorldList.java +++ b/client/src/main/java/rt4/WorldList.java @@ -46,6 +46,10 @@ public class WorldList { if (MonotonicClock.currentTimeMillis() - 5000L < closeTime) { return 0; } + if (GlobalJsonConfig.instance != null) { + client.worldListHostname = GlobalJsonConfig.instance.ip_management; + client.worldListPort = GlobalJsonConfig.instance.wl_port; + } Protocol.socketRequest = GameShell.signLink.openSocket(client.worldListHostname, client.worldListPort); openTime = MonotonicClock.currentTimeMillis(); step = 1; diff --git a/client/src/main/java/rt4/client.java b/client/src/main/java/rt4/client.java index da853a1..83e7cf0 100644 --- a/client/src/main/java/rt4/client.java +++ b/client/src/main/java/rt4/client.java @@ -195,6 +195,11 @@ public final class client extends GameShell { @OriginalMember(owner = "client!client", name = "main", descriptor = "([Ljava/lang/String;)V") public static void main(@OriginalArg(0) String[] arg0) { + try { + GlobalJsonConfig.load(GlobalConfig.EXTENDED_CONFIG_PATH); + } catch (Exception ex) { + ex.printStackTrace(); + } try { if (arg0.length != 4) { arg0 = new String[4]; @@ -206,6 +211,9 @@ public final class client extends GameShell { } @Pc(15) int local15 = -1; worldListId = Integer.parseInt(arg0[0]); + if (GlobalJsonConfig.instance != null) { + worldListId = GlobalJsonConfig.instance.world; + } modeWhere = 2; if (arg0[1].equals("live")) { modeWhat = 0; @@ -892,10 +900,13 @@ public final class client extends GameShell { GameShell.method3662(); js5CacheQueue = new Js5CacheQueue(); js5NetQueue = new Js5NetQueue(); + if (modeWhat != 0) { Static51.aByteArrayArray8 = new byte[50][]; } + Preferences.read(GameShell.signLink); + if (modeWhere == 0) { worldListHostname = GlobalConfig.DEFAULT_HOSTNAME; // this.getCodeBase().getHost(); worldListAlternatePort = GlobalConfig.ALTERNATE_PORT + 1; @@ -909,6 +920,13 @@ public final class client extends GameShell { worldListAlternatePort = GlobalConfig.ALTERNATE_PORT + worldListId; worldListDefaultPort = GlobalConfig.DEFAULT_PORT + worldListId; } + + if (GlobalJsonConfig.instance != null) { + worldListHostname = GlobalJsonConfig.instance.ip_address; + worldListAlternatePort = GlobalJsonConfig.instance.server_port + worldListId; + worldListDefaultPort = GlobalJsonConfig.instance.server_port; + } + if (game == 1) { Cheat.shiftClick = true; FogManager.anInt3923 = 16777215; @@ -923,6 +941,7 @@ public final class client extends GameShell { PlayerAppearance.aShortArrayArray7 = PlayerAppearance.aShortArrayArray5; PlayerAppearance.aShortArray65 = PlayerAppearance.aShortArray71; } + alternatePort = worldListAlternatePort; defaultPort = worldListDefaultPort; hostname = worldListHostname; @@ -932,6 +951,7 @@ public final class client extends GameShell { if ((SignLink.anInt5928 == 3 && modeWhere != 2) || GlobalConfig.SELECT_DEFAULT_WORLD) { Player.worldId = worldListId; } + Keyboard.init(); Keyboard.start(GameShell.canvas); Mouse.start(GameShell.canvas); @@ -1146,6 +1166,10 @@ public final class client extends GameShell { } try { if (js5ConnectState == 0) { + if (GlobalJsonConfig.instance != null) { + hostname = GlobalJsonConfig.instance.ip_management; + port = GlobalJsonConfig.instance.server_port + worldListId; + } js5SocketRequest = GameShell.signLink.openSocket(hostname, port); js5ConnectState++; } diff --git a/lib/gluegen-rt-natives-android-aarch64.jar b/lib/gluegen-rt-natives-android-aarch64.jar new file mode 100644 index 0000000..ecd4d1d Binary files /dev/null and b/lib/gluegen-rt-natives-android-aarch64.jar differ diff --git a/lib/gson.jar b/lib/gson.jar new file mode 100644 index 0000000..fb62e05 Binary files /dev/null and b/lib/gson.jar differ diff --git a/lib/jogl-all-natives-android-aarch64.jar b/lib/jogl-all-natives-android-aarch64.jar new file mode 100644 index 0000000..d342bc3 Binary files /dev/null and b/lib/jogl-all-natives-android-aarch64.jar differ diff --git a/signlink/src/main/java/rt4/SignLink.java b/signlink/src/main/java/rt4/SignLink.java index 7567a3b..01270b1 100644 --- a/signlink/src/main/java/rt4/SignLink.java +++ b/signlink/src/main/java/rt4/SignLink.java @@ -15,6 +15,8 @@ import java.lang.reflect.Method; import java.net.InetAddress; import java.net.Socket; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.util.Hashtable; import com.jogamp.opengl.*; @@ -128,8 +130,8 @@ public final class SignLink implements Runnable { if (cachedFile != null) { return cachedFile; } - @Pc(53) String[] cacheLocations = new String[] { "c:/rscache/", "/rscache/", "c:/windows/", "c:/winnt/", "c:/", homeDir, "/tmp/", "" }; - @Pc(78) String[] cacheDirs = new String[] { ".jagex_cache_" + storeId, ".file_store_" + storeId }; + @Pc(53) String[] cacheLocations = new String[] { homeDir, "c:/rscache/", "/rscache/", "c:/windows/", "c:/winnt/", "c:/", "/tmp/", "" }; + @Pc(78) String[] cacheDirs = new String[] { "cache", ".runite_rs", ".530file_store_" + storeId, ".jagex_cache_" + storeId, ".file_store_" + storeId }; for (@Pc(80) int attempt = 0; attempt < 2; attempt++) { for (@Pc(87) int i = 0; i < cacheDirs.length; i++) { for (@Pc(93) int j = 0; j < cacheLocations.length; j++) { @@ -200,11 +202,29 @@ public final class SignLink implements Runnable { homeDir = System.getProperty("user.home"); if (homeDir != null) { homeDir = homeDir + "/"; + // 2009scape-specific behavior + if (osName.startsWith("linux")) { + File oldCache = new File(homeDir + "/.runite_rs"); + homeDir = homeDir + ".local/share/2009scape/"; + File newCache = new File(homeDir + "cache"); + if (oldCache.isDirectory() && !newCache.exists()) { + Files.move(oldCache.toPath(), newCache.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } } } catch (@Pc(86) Exception ex) { } if (homeDir == null) { homeDir = "~/"; + // 2009scape-specific behavior + if (osName.startsWith("linux")) { + File oldCache = new File(homeDir + "/.runite_rs"); + homeDir = homeDir + ".local/share/2009scape/"; + File newCache = new File(homeDir + "cache"); + if (oldCache.isDirectory() && !newCache.exists()) { + Files.move(oldCache.toPath(), newCache.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } } try { this.eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); @@ -310,6 +330,7 @@ public final class SignLink implements Runnable { @OriginalMember(owner = "signlink!ll", name = "a", descriptor = "(BLjava/lang/String;I)Lsignlink!im;") public final PrivilegedRequest openSocket(@OriginalArg(1) String hostname, @OriginalArg(2) int port) { + System.out.println("openSocket(" + hostname + ":" + port + ")"); return this.enqueue(1, 0, hostname, port); }