diff --git a/client/build.gradle b/client/build.gradle index 394d215..b559543 100644 --- a/client/build.gradle +++ b/client/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'application' + id 'org.jetbrains.kotlin.jvm' version '1.4.10' } mainClassName = 'rt4.client' @@ -35,6 +36,8 @@ dependencies { implementation 'lib:jogl-all-natives-linux-i586' implementation 'lib:jogl-all-natives-macosx-universal' implementation 'lib:jogl-all-natives-android-aarch64' + + runtime 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10' } jar { @@ -42,4 +45,5 @@ jar { attributes 'Main-Class': "$mainClassName" } from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } } + duplicatesStrategy = DuplicatesStrategy.INCLUDE } diff --git a/client/src/main/java/plugin/Plugin.java b/client/src/main/java/plugin/Plugin.java index c9fc977..fd09102 100644 --- a/client/src/main/java/plugin/Plugin.java +++ b/client/src/main/java/plugin/Plugin.java @@ -37,8 +37,10 @@ public abstract class Plugin { /** * OnXPUpdate() is called when the client receives an XP update packet. This includes at login. + * @param skill - the skill ID being updated + * @param xp - the new total XP for the skill. */ - public void OnXPUpdate() {} + public void OnXPUpdate(int skill, int xp) {} /** * Update() is called once per tick, aka once every 600ms. @@ -81,4 +83,9 @@ public abstract class Plugin { * @param value the value the varp is being set to. */ public void OnVarpUpdate(int id, int value) {} + + /** + * OnLogout is called when the client logs out. This should be used to clear player-relevant plugin state. + */ + public void OnLogout() {} } diff --git a/client/src/main/java/plugin/PluginRepository.java b/client/src/main/java/plugin/PluginRepository.java index 4f2e7d5..89fa1e3 100644 --- a/client/src/main/java/plugin/PluginRepository.java +++ b/client/src/main/java/plugin/PluginRepository.java @@ -103,4 +103,12 @@ public class PluginRepository { public static void OnVarpUpdate(int id, int value) { loadedPlugins.values().forEach((plugin) -> plugin.OnVarpUpdate(id, value)); } + + public static void OnXPUpdate(int skill, int xp) { + loadedPlugins.values().forEach((plugin) -> plugin.OnXPUpdate(skill, xp)); + } + + public static void OnLogout() { + loadedPlugins.values().forEach(Plugin::OnLogout); + } } diff --git a/client/src/main/java/plugin/api/API.java b/client/src/main/java/plugin/api/API.java index 157ddb1..2db5ca8 100644 --- a/client/src/main/java/plugin/api/API.java +++ b/client/src/main/java/plugin/api/API.java @@ -1,6 +1,10 @@ package plugin.api; import rt4.*; +import rt4.DisplayMode; +import rt4.Font; + +import java.awt.*; /** * API used for writing plugins, so dozens of plugins don't break when we rename shit :) @@ -8,7 +12,7 @@ import rt4.*; */ public class API { public static void DrawText(FontType fontType, FontColor color, TextModifier mod, String text, int screenX, int screenY) { - JagString js = JagString.parse(text); + JagString js = JagString.of(text); Font font; switch (fontType) { @@ -51,4 +55,60 @@ public class API { public static boolean IsHD() { return GlRenderer.enabled; } + + public static Sprite GetSprite(int spriteId) { + Sprite rawSprite = null; + + if (client.js5Archive8.isFileReady(spriteId)) { + rawSprite = SpriteLoader.loadSprites(spriteId, client.js5Archive8); + } + + return rawSprite; + } + + public static WindowMode GetWindowMode() { + int mode = DisplayMode.getWindowMode(); + switch(mode) { + case 2: + return WindowMode.RESIZABLE; + case 3: + return WindowMode.FULLSCREEN; + default: + return WindowMode.FIXED; + } + } + + public static Dimension GetWindowDimensions() { + return new Dimension(GameShell.canvasWidth, GameShell.canvasHeight); + } + + public static void FillRect(int x, int y, int width, int height, int color, int alpha) { + if (IsHD()) { + if (alpha != 0) + GlRaster.fillRectAlpha(x,y,width,height,color,alpha); + else + GlRaster.fillRect(x,y,width,height,color); + } else { + if (alpha != 0) + SoftwareRaster.fillRectAlpha(x,y,width,height,color,alpha); + else + SoftwareRaster.fillRect(x,y,width,height,color); + } + } + + public static void DrawRect(int x, int y, int width, int height, int color) { + if (IsHD()) { + GlRaster.drawRect(x, y, width, height, color); + } else { + SoftwareRaster.drawRect(x, y, width, height, color); + } + } + + public static void ClipRect(int x, int y, int width, int height) { + if (IsHD()) { + GlRaster.setClip(x,y,width,height); + } else { + SoftwareRaster.setClip(x,y,width,height); + } + } } diff --git a/client/src/main/java/plugin/api/FontColor.java b/client/src/main/java/plugin/api/FontColor.java index 8b6a772..a7e43e7 100644 --- a/client/src/main/java/plugin/api/FontColor.java +++ b/client/src/main/java/plugin/api/FontColor.java @@ -12,6 +12,6 @@ public class FontColor { } public static FontColor fromColor(Color color) { - return new FontColor(color.getRed() << 16 + color.getGreen() << 8 + color.getBlue()); + return new FontColor((color.getRed() << 16) + (color.getGreen() << 8) + color.getBlue()); } } diff --git a/client/src/main/java/plugin/api/WindowMode.java b/client/src/main/java/plugin/api/WindowMode.java new file mode 100644 index 0000000..f4b2a1b --- /dev/null +++ b/client/src/main/java/plugin/api/WindowMode.java @@ -0,0 +1,7 @@ +package plugin.api; + +public enum WindowMode { + FIXED, + RESIZABLE, + FULLSCREEN +} diff --git a/client/src/main/java/rt4/Cheat.java b/client/src/main/java/rt4/Cheat.java index 9f046f2..8a42f14 100644 --- a/client/src/main/java/rt4/Cheat.java +++ b/client/src/main/java/rt4/Cheat.java @@ -102,7 +102,7 @@ public class Cheat { @OriginalMember(owner = "client!en", name = "a", descriptor = "(IIIB)V") public static void teleport(@OriginalArg(0) int arg0, @OriginalArg(1) int arg1, @OriginalArg(2) int arg2) { - @Pc(66) JagString local66 = JagString.concatenate(new JagString[]{aClass100_521, JagString.parseInt(arg2), Cs1ScriptRunner.aClass100_760, JagString.parseInt(arg0 >> 6), Cs1ScriptRunner.aClass100_760, JagString.parseInt(arg1 >> 6), Cs1ScriptRunner.aClass100_760, JagString.parseInt(arg0 & 0x3F), Cs1ScriptRunner.aClass100_760, JagString.parseInt(arg1 & 0x3F)}); + @Pc(66) JagString local66 = JagString.concatenate(new JagString[]{aClass100_521, JagString.parseInt(arg2), JagString.aClass100_760, JagString.parseInt(arg0 >> 6), JagString.aClass100_760, JagString.parseInt(arg1 >> 6), JagString.aClass100_760, JagString.parseInt(arg0 & 0x3F), JagString.aClass100_760, JagString.parseInt(arg1 & 0x3F)}); local66.print(); execute(local66); } diff --git a/client/src/main/java/rt4/Cs1ScriptRunner.java b/client/src/main/java/rt4/Cs1ScriptRunner.java index 8639838..0bf1897 100644 --- a/client/src/main/java/rt4/Cs1ScriptRunner.java +++ b/client/src/main/java/rt4/Cs1ScriptRunner.java @@ -34,22 +34,6 @@ public class Cs1ScriptRunner { public static final int anInt671 = 0x332d25; @OriginalMember(owner = "client!pg", name = "V", descriptor = "I") public static final int anInt4504 = 50; - @OriginalMember(owner = "client!wa", name = "pb", descriptor = "Lclient!na;") - public static final JagString aClass100_556 = JagString.parse("
"); - @OriginalMember(owner = "client!ed", name = "H", descriptor = "Lclient!na;") - public static final JagString aClass100_375 = JagString.parse("<)4col> x"); - @OriginalMember(owner = "client!je", name = "db", descriptor = "Lclient!na;") - public static final JagString aClass100_589 = JagString.parse(" "); - @OriginalMember(owner = "client!uf", name = "s", descriptor = "Lclient!na;") - public static final JagString aClass100_1043 = JagString.parse(" "); - @OriginalMember(owner = "client!wj", name = "b", descriptor = "Lclient!na;") - public static final JagString aClass100_1101 = JagString.parse(" "); - @OriginalMember(owner = "client!mi", name = "R", descriptor = "Lclient!na;") - public static final JagString aClass100_760 = JagString.parse(")1"); - @OriginalMember(owner = "client!sj", name = "w", descriptor = "Lclient!na;") - public static final JagString aClass100_978 = JagString.parse("<)4col>"); - @OriginalMember(owner = "client!jb", name = "c", descriptor = "Lclient!na;") - public static final JagString aClass100_583 = JagString.parse("(Y<)4col>"); @OriginalMember(owner = "client!th", name = "m", descriptor = "[Lclient!be;") public static Component[] aClass13Array13; @OriginalMember(owner = "client!k", name = "j", descriptor = "I") @@ -776,7 +760,7 @@ public class Cs1ScriptRunner { local1934 = MiniMenu.NULL; } if ((local1989.stackable == 1 || component.objCount != 1) && component.objCount != -1) { - local1934 = JagString.concatenate(new JagString[]{MiniMenu.aClass100_32, local1934, aClass100_375, method1548(component.objCount)}); + local1934 = JagString.concatenate(new JagString[]{MiniMenu.aClass100_32, local1934, JagString.aClass100_375, method1548(component.objCount)}); } } if (aClass13_10 == component) { @@ -1018,9 +1002,9 @@ public class Cs1ScriptRunner { local2611 = ObjTypeList.get(component.objTypes[local276] - 1); @Pc(3159) JagString local3159; if (local2611.stackable != 1 && component.objCounts[local276] == 1) { - local3159 = JagString.concatenate(new JagString[]{MiniMenu.aClass100_32, local2611.name, aClass100_978}); + local3159 = JagString.concatenate(new JagString[]{MiniMenu.aClass100_32, local2611.name, JagString.aClass100_978}); } else { - local3159 = JagString.concatenate(new JagString[]{MiniMenu.aClass100_32, local2611.name, aClass100_375, method1548(component.objCounts[local276])}); + local3159 = JagString.concatenate(new JagString[]{MiniMenu.aClass100_32, local2611.name, JagString.aClass100_375, method1548(component.objCounts[local276])}); } local556 = local123 + memory * (component.invMarginX + 115); objId = (component.invMarginY + 12) * local468 + local114; @@ -1045,7 +1029,7 @@ public class Cs1ScriptRunner { local3297 = interpolate(component, local3297); @Pc(3325) JagString local3325; while (local3297.length() > 0) { - cardMemory = local3297.indexOf(aClass100_556); + cardMemory = local3297.indexOf(JagString.aClass100_556); if (cardMemory == -1) { local3325 = local3297; local3297 = JagString.EMPTY; @@ -1083,7 +1067,7 @@ public class Cs1ScriptRunner { objId = local556 + local3299.lineHeight + 2; local3297 = interpolate(component, local3297); while (local3297.length() > 0) { - local563 = local3297.indexOf(aClass100_556); + local563 = local3297.indexOf(JagString.aClass100_556); if (local563 == -1) { local3325 = local3297; local3297 = JagString.EMPTY; @@ -1257,14 +1241,14 @@ public class Cs1ScriptRunner { public static JagString method1548(@OriginalArg(1) int arg0) { @Pc(9) JagString local9 = JagString.parseInt(arg0); for (@Pc(21) int local21 = local9.length() - 3; local21 > 0; local21 -= 3) { - local9 = JagString.concatenate(new JagString[]{local9.substring(local21, 0), aClass100_760, local9.substring(local21)}); + local9 = JagString.concatenate(new JagString[]{local9.substring(local21, 0), JagString.aClass100_760, local9.substring(local21)}); } if (local9.length() > 9) { - return JagString.concatenate(new JagString[]{aClass100_1043, local9.substring(local9.length() - 8, 0), LocalizedText.MILLION_SHORT, MiniMenu.OPEN_PARENTHESIS, local9, aClass100_583}); + return JagString.concatenate(new JagString[]{JagString.aClass100_1043, local9.substring(local9.length() - 8, 0), LocalizedText.MILLION_SHORT, MiniMenu.OPEN_PARENTHESIS, local9, JagString.aClass100_583}); } else if (local9.length() > 6) { - return JagString.concatenate(new JagString[]{aClass100_589, local9.substring(local9.length() - 4, 0), LocalizedText.THOUSAND_SHORT, MiniMenu.OPEN_PARENTHESIS, local9, aClass100_583}); + return JagString.concatenate(new JagString[]{JagString.aClass100_589, local9.substring(local9.length() - 4, 0), LocalizedText.THOUSAND_SHORT, MiniMenu.OPEN_PARENTHESIS, local9, JagString.aClass100_583}); } else { - return JagString.concatenate(new JagString[]{aClass100_1101, local9, aClass100_978}); + return JagString.concatenate(new JagString[]{JagString.aClass100_1101, local9, JagString.aClass100_978}); } } diff --git a/client/src/main/java/rt4/DateUtil.java b/client/src/main/java/rt4/DateUtil.java index 8933053..6def766 100644 --- a/client/src/main/java/rt4/DateUtil.java +++ b/client/src/main/java/rt4/DateUtil.java @@ -12,16 +12,6 @@ public final class DateUtil { @OriginalMember(owner = "client!cl", name = "K", descriptor = "Ljava/util/Calendar;") public static final Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - @OriginalMember(owner = "client!fn", name = "Z", descriptor = "Lclient!na;") - public static final JagString aClass100_461 = JagString.parse(")1 "); - @OriginalMember(owner = "client!wb", name = "a", descriptor = "Lclient!na;") - public static final JagString aClass100_1089 = JagString.parse(")2"); - @OriginalMember(owner = "client!dm", name = "j", descriptor = "Lclient!na;") - public static final JagString SPACE = JagString.parse(" "); - @OriginalMember(owner = "client!vh", name = "c", descriptor = "Lclient!na;") - public static final JagString COLON = JagString.parse(":"); - @OriginalMember(owner = "client!ee", name = "a", descriptor = "Lclient!na;") - public static final JagString TIMEZONE = JagString.parse(" GMT"); @OriginalMember(owner = "client!km", name = "tc", descriptor = "Lclient!na;") private static final JagString DEC = JagString.parse("Dec"); @@ -104,6 +94,6 @@ public final class DateUtil { @Pc(36) int local36 = calendar.get(Calendar.HOUR_OF_DAY); @Pc(40) int local40 = calendar.get(Calendar.MINUTE); @Pc(44) int local44 = calendar.get(Calendar.SECOND); - return JagString.concatenate(new JagString[]{DAYS[local13 - 1], aClass100_461, JagString.parseInt(local17 / 10), JagString.parseInt(local17 % 10), aClass100_1089, MONTHS[local21], aClass100_1089, JagString.parseInt(local32), SPACE, JagString.parseInt(local36 / 10), JagString.parseInt(local36 % 10), COLON, JagString.parseInt(local40 / 10), JagString.parseInt(local40 % 10), COLON, JagString.parseInt(local44 / 10), JagString.parseInt(local44 % 10), TIMEZONE}); + return JagString.concatenate(new JagString[]{DAYS[local13 - 1], JagString.aClass100_461, JagString.parseInt(local17 / 10), JagString.parseInt(local17 % 10), JagString.aClass100_1089, MONTHS[local21], JagString.aClass100_1089, JagString.parseInt(local32), JagString.SPACE, JagString.parseInt(local36 / 10), JagString.parseInt(local36 % 10), JagString.COLON, JagString.parseInt(local40 / 10), JagString.parseInt(local40 % 10), JagString.COLON, JagString.parseInt(local44 / 10), JagString.parseInt(local44 % 10), JagString.TIMEZONE}); } } diff --git a/client/src/main/java/rt4/DisplayMode.java b/client/src/main/java/rt4/DisplayMode.java index e892fde..06cfcb9 100644 --- a/client/src/main/java/rt4/DisplayMode.java +++ b/client/src/main/java/rt4/DisplayMode.java @@ -75,7 +75,7 @@ public final class DisplayMode { } @OriginalMember(owner = "client!pm", name = "a", descriptor = "(ZIZIZII)V") - public static void setWindowMode(@OriginalArg(0) boolean arg0, @OriginalArg(1) int arg1, @OriginalArg(2) boolean arg2, @OriginalArg(3) int arg3, @OriginalArg(5) int arg4, @OriginalArg(6) int arg5) { + public static void setWindowMode(@OriginalArg(0) boolean arg0, @OriginalArg(1) int arg1, @OriginalArg(2) boolean arg2, @OriginalArg(3) int mode, @OriginalArg(5) int arg4, @OriginalArg(6) int arg5) { if (arg2) { GlRenderer.quit(); } @@ -92,7 +92,7 @@ public final class DisplayMode { } } if (arg1 == 3 && GameShell.fullScreenFrame == null) { - setWindowMode(true, Preferences.favoriteWorlds, true, arg3, -1, -1); + setWindowMode(true, Preferences.favoriteWorlds, true, mode, -1, -1); return; } @Pc(85) Container local85; @@ -146,7 +146,7 @@ public final class DisplayMode { GameShell.canvas.setLocation(GameShell.leftMargin, GameShell.topMargin); } } - if (arg1 == 0 && arg3 > 0) { + if (arg1 == 0 && mode > 0) { GlRenderer.createAndDestroyContext(GameShell.canvas); } if (arg2 && arg1 > 0) { @@ -167,7 +167,7 @@ public final class DisplayMode { } catch (@Pc(277) Exception local277) { } GameShell.method2704(); - if (arg3 == 0) { + if (mode == 0) { SoftwareRaster.frameBuffer = FrameBuffer.create(503, 765, GameShell.canvas); } else { SoftwareRaster.frameBuffer = null; @@ -185,10 +185,10 @@ public final class DisplayMode { } } if (!GlRenderer.enabled && arg1 > 0) { - setWindowMode(true, 0, true, arg3, -1, -1); + setWindowMode(true, 0, true, mode, -1, -1); return; } - if (arg1 > 0 && arg3 == 0) { + if (arg1 > 0 && mode == 0) { GameShell.thread.setPriority(5); SoftwareRaster.frameBuffer = null; SoftwareModel.method4580(); @@ -197,7 +197,7 @@ public final class DisplayMode { Rasteriser.setBrightness(0.7F); } LoginManager.method4637(); - } else if (arg1 == 0 && arg3 > 0) { + } else if (arg1 == 0 && mode > 0) { GameShell.thread.setPriority(1); SoftwareRaster.frameBuffer = FrameBuffer.create(503, 765, GameShell.canvas); SoftwareModel.method4583(); diff --git a/client/src/main/java/rt4/JagString.java b/client/src/main/java/rt4/JagString.java index fb8be2d..449090e 100644 --- a/client/src/main/java/rt4/JagString.java +++ b/client/src/main/java/rt4/JagString.java @@ -19,13 +19,39 @@ public final class JagString implements StringInterface { @OriginalMember(owner = "client!pi", name = "Q", descriptor = "Lclient!na;") public static final JagString aClass100_853 = parse("null"); @OriginalMember(owner = "client!t", name = "C", descriptor = "Lclient!na;") - public static final JagString aClass100_994 = parse(")3"); + public static final JagString PERIOD = parse(")3"); @OriginalMember(owner = "client!vk", name = "a", descriptor = "[I") public static final int[] anIntArray471 = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 73, 74, 76, 78, 83, 84, 85, 86, 91, 92, 93, 94, 95, 97, 103, 104, 105, 106, 107, 108, 113, 114, 115, 116, 118, 119, 120, 121, 122, 123, 124, 125, 133, 134, 136, 138, 143, 144, 145, 146, 151, 152, 153, 154, 155, 157, 163, 164, 165, 166, 168, 169, 174, 175, 176, 177, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 97, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 157, 215, 216, 117, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 66, 66, 66, 66, 66, 66, 65, 75, 79, 79, 79, 79, 87, 87, 87, 87, 77, 96, 98, 98, 98, 98, 98, 250, 251, 109, 109, 109, 109, 117, 252, 167, 126, 126, 126, 126, 126, 126, 125, 135, 139, 139, 139, 139, 147, 147, 147, 147, 137, 156, 158, 158, 158, 158, 158, 253, 254, 170, 170, 170, 170, 178, 255, 178}; @OriginalMember(owner = "client!sh", name = "e", descriptor = "Lclient!na;") public static final JagString aClass100_967 = parse(""); @OriginalMember(owner = "client!dm", name = "n", descriptor = "Lclient!na;") public static final JagString PERCENT_SIGN = parse("(U"); + @OriginalMember(owner = "client!wa", name = "pb", descriptor = "Lclient!na;") + public static final JagString aClass100_556 = parse("
"); + @OriginalMember(owner = "client!ed", name = "H", descriptor = "Lclient!na;") + public static final JagString aClass100_375 = parse("<)4col> x"); + @OriginalMember(owner = "client!je", name = "db", descriptor = "Lclient!na;") + public static final JagString aClass100_589 = parse(" "); + @OriginalMember(owner = "client!uf", name = "s", descriptor = "Lclient!na;") + public static final JagString aClass100_1043 = parse(" "); + @OriginalMember(owner = "client!wj", name = "b", descriptor = "Lclient!na;") + public static final JagString aClass100_1101 = parse(" "); + @OriginalMember(owner = "client!mi", name = "R", descriptor = "Lclient!na;") + public static final JagString aClass100_760 = parse(")1"); + @OriginalMember(owner = "client!sj", name = "w", descriptor = "Lclient!na;") + public static final JagString aClass100_978 = parse("<)4col>"); + @OriginalMember(owner = "client!jb", name = "c", descriptor = "Lclient!na;") + public static final JagString aClass100_583 = parse("(Y<)4col>"); + @OriginalMember(owner = "client!fn", name = "Z", descriptor = "Lclient!na;") + public static final JagString aClass100_461 = parse(")1 "); + @OriginalMember(owner = "client!wb", name = "a", descriptor = "Lclient!na;") + public static final JagString aClass100_1089 = parse(")2"); + @OriginalMember(owner = "client!dm", name = "j", descriptor = "Lclient!na;") + public static final JagString SPACE = parse(" "); + @OriginalMember(owner = "client!vh", name = "c", descriptor = "Lclient!na;") + public static final JagString COLON = parse(":"); + @OriginalMember(owner = "client!ee", name = "a", descriptor = "Lclient!na;") + public static final JagString TIMEZONE = parse(" GMT"); @OriginalMember(owner = "client!li", name = "w", descriptor = "Lclient!sc;") public static HashTable aClass133_13; @OriginalMember(owner = "client!na", name = "T", descriptor = "[B") @@ -203,7 +229,7 @@ public final class JagString implements StringInterface { @OriginalMember(owner = "client!oi", name = "a", descriptor = "(II)Lclient!na;") public static JagString formatIp(@OriginalArg(0) int arg0) { - return concatenate(new JagString[]{parseInt(arg0 >> 24 & 0xFF), aClass100_994, parseInt(arg0 >> 16 & 0xFF), aClass100_994, parseInt(arg0 >> 8 & 0xFF), aClass100_994, parseInt(arg0 & 0xFF)}); + return concatenate(new JagString[]{parseInt(arg0 >> 24 & 0xFF), PERIOD, parseInt(arg0 >> 16 & 0xFF), PERIOD, parseInt(arg0 >> 8 & 0xFF), PERIOD, parseInt(arg0 & 0xFF)}); } @OriginalMember(owner = "client!nb", name = "a", descriptor = "(II)Lclient!na;") @@ -215,18 +241,21 @@ public final class JagString implements StringInterface { return str; } + /** + * @return A JagString consisting of the actual bytes in the provided string. + */ @OriginalMember(owner = "client!sj", name = "a", descriptor = "(Ljava/lang/String;I)Lclient!na;") - public static JagString method3952(@OriginalArg(0) String arg0) { - @Pc(14) byte[] local14 = arg0.getBytes(StandardCharsets.ISO_8859_1); - @Pc(23) JagString local23 = new JagString(); - local23.chars = local14; - local23.length = 0; - for (@Pc(31) int local31 = 0; local31 < local14.length; local31++) { - if (local14[local31] != 0) { - local14[local23.length++] = local14[local31]; + public static JagString of(@OriginalArg(0) String string) { + @Pc(14) byte[] bytes = string.getBytes(StandardCharsets.ISO_8859_1); + @Pc(23) JagString js = new JagString(); + js.chars = bytes; + js.length = 0; + for (@Pc(31) int i = 0; i < bytes.length; i++) { + if (bytes[i] != 0) { + bytes[js.length++] = bytes[i]; } } - return local23; + return js; } @OriginalMember(owner = "client!gn", name = "a", descriptor = "(BI)Lclient!na;") @@ -983,7 +1012,7 @@ public final class JagString implements StringInterface { public final JagString fromParameters(@OriginalArg(1) Applet arg0) { @Pc(19) String local19 = new String(this.chars, 0, this.length); @Pc(23) String local23 = arg0.getParameter(local19); - return local23 == null ? null : method3952(local23); + return local23 == null ? null : of(local23); } @OriginalMember(owner = "client!na", name = "d", descriptor = "(Z)I") diff --git a/client/src/main/java/rt4/LoginManager.java b/client/src/main/java/rt4/LoginManager.java index 58dbba3..dc7eff6 100644 --- a/client/src/main/java/rt4/LoginManager.java +++ b/client/src/main/java/rt4/LoginManager.java @@ -3,6 +3,7 @@ package rt4; import org.openrs2.deob.annotation.OriginalArg; import org.openrs2.deob.annotation.OriginalMember; import org.openrs2.deob.annotation.Pc; +import plugin.PluginRepository; import java.io.IOException; import java.net.Socket; @@ -690,6 +691,7 @@ public class LoginManager { Protocol.verifyId = 0; VarpDomain.reset(); InterfaceList.method1596(true); + PluginRepository.OnLogout(); } @OriginalMember(owner = "client!k", name = "a", descriptor = "(IIIIZIZ)V") diff --git a/client/src/main/java/rt4/Protocol.java b/client/src/main/java/rt4/Protocol.java index 0c3aef4..ebd2de3 100644 --- a/client/src/main/java/rt4/Protocol.java +++ b/client/src/main/java/rt4/Protocol.java @@ -3,6 +3,7 @@ package rt4; import org.openrs2.deob.annotation.OriginalArg; import org.openrs2.deob.annotation.OriginalMember; import org.openrs2.deob.annotation.Pc; +import plugin.PluginRepository; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -967,7 +968,7 @@ public class Protocol { } else if (opcode == ServerProt.MESSAGE_GAME) { @Pc(245) JagString message = inboundBuffer.gjstr(); if (message.endsWith(TRADEREQ)) { - JagString name = message.substring(message.indexOf(DateUtil.COLON), 0); + JagString name = message.substring(message.indexOf(JagString.COLON), 0); long name37 = name.encode37(); boolean ignored = false; for (int i = 0; i < IgnoreList.size; i++) { @@ -980,7 +981,7 @@ public class Protocol { Chat.add(name, 4, LocalizedText.TRADEREQ); } } else if (message.endsWith(CHALREQ)) { - JagString name = message.substring(message.indexOf(DateUtil.COLON), 0); + JagString name = message.substring(message.indexOf(JagString.COLON), 0); long name37 = name.encode37(); boolean ignored = false; for (int i = 0; i < IgnoreList.size; i++) { @@ -990,11 +991,11 @@ public class Protocol { } } if (!ignored && Player.inTutorialIsland == 0) { - JagString local506 = message.substring(message.length() - 9, message.indexOf(DateUtil.COLON) + 1); + JagString local506 = message.substring(message.length() - 9, message.indexOf(JagString.COLON) + 1); Chat.add(name, 8, local506); } } else if (message.endsWith(ASSISTREQ)) { - JagString name = message.substring(message.indexOf(DateUtil.COLON), 0); + JagString name = message.substring(message.indexOf(JagString.COLON), 0); long name37 = name.encode37(); boolean ignored = false; for (int i = 0; i < IgnoreList.size; i++) { @@ -1020,7 +1021,7 @@ public class Protocol { Chat.add(JagString.EMPTY, 13, name); } } else if (message.endsWith(DUELSTAKE)) { - JagString name = message.substring(message.indexOf(DateUtil.COLON), 0); + JagString name = message.substring(message.indexOf(JagString.COLON), 0); long name37 = name.encode37(); boolean ignored = false; for (int i = 0; i < IgnoreList.size; i++) { @@ -1033,7 +1034,7 @@ public class Protocol { Chat.add(name, 14, JagString.EMPTY); } } else if (message.endsWith(DUELFRIEND)) { - JagString name = message.substring(message.indexOf(DateUtil.COLON), 0); + JagString name = message.substring(message.indexOf(JagString.COLON), 0); long name37 = name.encode37(); boolean ignored = false; for (int local277 = 0; local277 < IgnoreList.size; local277++) { @@ -1046,7 +1047,7 @@ public class Protocol { Chat.add(name, 15, JagString.EMPTY); } } else if (message.endsWith(aClass100_916)) { - JagString name = message.substring(message.indexOf(DateUtil.COLON), 0); + JagString name = message.substring(message.indexOf(JagString.COLON), 0); long name37 = name.encode37(); boolean ignored = false; for (int i = 0; i < IgnoreList.size; i++) { @@ -1059,7 +1060,7 @@ public class Protocol { Chat.add(name, 16, JagString.EMPTY); } } else if (message.endsWith(aClass100_770)) { - JagString name = message.substring(message.indexOf(DateUtil.COLON), 0); + JagString name = message.substring(message.indexOf(JagString.COLON), 0); long name37 = name.encode37(); boolean ignored = false; for (int i = 0; i < IgnoreList.size; i++) { @@ -1069,7 +1070,7 @@ public class Protocol { } } if (!ignored && Player.inTutorialIsland == 0) { - JagString local506 = message.substring(message.length() - 9, message.indexOf(DateUtil.COLON) + 1); + JagString local506 = message.substring(message.length() - 9, message.indexOf(JagString.COLON) + 1); Chat.add(name, 21, local506); } } else { @@ -1459,6 +1460,7 @@ public class Protocol { PlayerSkillXpTable.baseLevels[skill] = i + 2; } } + PluginRepository.OnXPUpdate(skill, xp); PlayerSkillXpTable.updatedStats[PlayerSkillXpTable.updatedStatsWriterIndex++ & 0x1F] = skill; opcode = -1; return true; diff --git a/client/src/main/java/rt4/client.java b/client/src/main/java/rt4/client.java index dd87073..eee446d 100644 --- a/client/src/main/java/rt4/client.java +++ b/client/src/main/java/rt4/client.java @@ -776,7 +776,7 @@ public final class client extends GameShell { } else if (gameState == 30) { LoginManager.method1841(); } else if (gameState == 40) { - Fonts.drawTextOnScreen(false, JagString.concatenate(new JagString[]{LocalizedText.CONLOST, Cs1ScriptRunner.aClass100_556, LocalizedText.ATTEMPT_TO_REESTABLISH})); + Fonts.drawTextOnScreen(false, JagString.concatenate(new JagString[]{LocalizedText.CONLOST, JagString.aClass100_556, LocalizedText.ATTEMPT_TO_REESTABLISH})); } if (GlRenderer.enabled && gameState != 0) { GlRenderer.swapBuffers(); @@ -1020,7 +1020,7 @@ public final class client extends GameShell { } mainLoadPrimaryText = LocalizedText.GAME0_LOADING; if (modeWhere != 0) { - Cheat.displayFps = true; + //Cheat.displayFps = true; } } diff --git a/plugin-playground/build.gradle b/plugin-playground/build.gradle index 3000054..e993027 100644 --- a/plugin-playground/build.gradle +++ b/plugin-playground/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java' + id 'org.jetbrains.kotlin.jvm' version '1.4.10' } version 'unspecified' @@ -15,6 +16,7 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' implementation(rootProject.project("client")) + compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10' } test { @@ -63,4 +65,6 @@ task buildPlugins(type: Copy, dependsOn: classes) { def pluginsPath = rootProject.project("client").projectDir.absolutePath + File.separator + "plugins" from "build/classes/java/main" into pluginsPath + from "build/classes/kotlin/main" + into pluginsPath } \ No newline at end of file diff --git a/plugin-playground/src/main/java/VarpLogPlugin/plugin.java b/plugin-playground/src/main/java/VarpLogPlugin/plugin.java index a78ebe7..32c5431 100644 --- a/plugin-playground/src/main/java/VarpLogPlugin/plugin.java +++ b/plugin-playground/src/main/java/VarpLogPlugin/plugin.java @@ -8,7 +8,7 @@ import java.util.ArrayList; import java.util.Date; public class plugin extends Plugin { - boolean isEnabled; + boolean isEnabled = false; int MAX_VISIBLE_UPDATES = 5; diff --git a/plugin-playground/src/main/kotlin/XPDropPlugin/plugin.kt b/plugin-playground/src/main/kotlin/XPDropPlugin/plugin.kt new file mode 100644 index 0000000..f206877 --- /dev/null +++ b/plugin-playground/src/main/kotlin/XPDropPlugin/plugin.kt @@ -0,0 +1,171 @@ +package XPDropPlugin; + +import plugin.Plugin +import plugin.api.* +import java.awt.Color +import kotlin.math.ceil + +/** + * Displays some simple XP drops. + * @author Ceikry + */ +class plugin : Plugin() { + private val displayTimeout = 10000L // 10 seconds + private val drawStart = 175 + private val drawPadding = 25 + private val drawClear = 60 + private val lastXp = IntArray(24) + private var totalXp = 0 + private val activeGains = ArrayList() + private var lastGain = 0L + + override fun Draw(deltaTime: Long) { + if (System.currentTimeMillis() - lastGain >= displayTimeout && activeGains.isEmpty()) + return + + drawTotalXPBox() + + val removeList = ArrayList() + var posX = API.GetWindowDimensions().width / 2 + + if (API.GetWindowMode() == WindowMode.FIXED) + posX += 60 + + for(gain in activeGains) { + gain.currentPos -= ceil(deltaTime / 20.0).toInt() + if (gain.currentPos <= drawClear) { + removeList.add(gain) + totalXp += gain.xp + } else if (gain.currentPos <= drawStart){ + val sprite = API.GetSprite(getSpriteArchive(gain.skill)) + sprite?.render(posX - 25, gain.currentPos - 20) + API.DrawText( + FontType.SMALL, + FontColor.fromColor(Color.WHITE), + TextModifier.LEFT, + addCommas(gain.xp.toString()), + posX, + gain.currentPos + ) + } + } + + activeGains.removeAll(removeList.toSet()) + } + + override fun OnXPUpdate(skill: Int, xp: Int) { + if (xp == lastXp[skill]) return + + val gain = xp - lastXp[skill] + if (gain <= 0) return + + lastXp[skill] = xp + + val currentTail = try { + activeGains.last().currentPos + } catch (e: Exception) { + drawStart - drawPadding + } + + activeGains.add(XPGain(skill, gain, currentTail + drawPadding)) + lastGain = System.currentTimeMillis() + } + + override fun OnLogout() { + lastGain = 0L + for (i in 0 until 24) lastXp[i] = 0 + totalXp = 0 + activeGains.clear() + } + + private fun drawTotalXPBox() { + var posX = API.GetWindowDimensions().width / 2 + val posY = API.GetWindowDimensions().height / 4 + + if (API.GetWindowMode() == WindowMode.FIXED) + posX += 60 + + API.ClipRect(0, 0, posX * 2, posY * 4) + + val horizontal = API.GetSprite(822) + val horizontalTop = API.GetSprite(820) + val tlCorner = API.GetSprite(824) + val blCorner = API.GetSprite(826) + val trCorner = API.GetSprite(825) + val brCorner = API.GetSprite(827) + val bg = API.GetSprite(657) + + bg?.render(posX - 77, 10) + API.FillRect(posX - 75, 5, 140, 30, 0, 64) + + blCorner?.render(posX - 77, 10) + tlCorner?.render(posX - 77, 5) + trCorner?.render(posX + 41, 5) + brCorner?.render(posX + 41, 10) + + horizontalTop?.render(posX - 45, -8) + horizontal?.render(posX - 45, 22) + horizontalTop?.render(posX - 15, -8) + horizontal?.render(posX - 15, 22) + horizontalTop?.render(posX + 9, -8) + horizontal?.render(posX + 9, 22) + + API.DrawText( + FontType.SMALL, + FontColor.fromColor(Color.WHITE), + TextModifier.LEFT, + "Total Xp: ${addCommas(totalXp.toString())}", + posX - 65, + 28 + ) + } + + data class XPGain(val skill: Int, val xp: Int, var currentPos: Int) + + fun addCommas(num: String): String{ + var newString = "" + if(num.length > 9){ + return "Lots!" + } + var counter = 1 + num.reversed().forEach { + if(counter % 3 == 0 && counter != num.length){ + newString += "$it," + } else { + newString += it + } + counter++ + } + return newString.reversed() + } + + fun getSpriteArchive(skillId: Int): Int{ + return when(skillId) { + 0 -> 197 + 1 -> 199 + 2 -> 198 + 3 -> 203 + 4 -> 200 + 5 -> 201 + 6 -> 202 + 7 -> 212 + 8 -> 214 + 9 -> 208 + 10 -> 211 + 11 -> 213 + 12 -> 207 + 13 -> 210 + 14 -> 209 + 15 -> 205 + 16 -> 204 + 17 -> 206 + 18 -> 216 + 19 -> 217 + 20 -> 215 + 21 -> 220 + 22 -> 221 + 23 -> 222 + else -> 222 + } + } +} diff --git a/plugin-playground/src/main/kotlin/XPDropPlugin/plugin.properties b/plugin-playground/src/main/kotlin/XPDropPlugin/plugin.properties new file mode 100644 index 0000000..1e4001d --- /dev/null +++ b/plugin-playground/src/main/kotlin/XPDropPlugin/plugin.properties @@ -0,0 +1,3 @@ +AUTHOR='Ceikry' +DESCRIPTION='Displays some pretty awesome XP drops :)' +VERSION=-1.1