From 24f7bfbf5fd31f4a3b9d50828bd8646d8958ceef Mon Sep 17 00:00:00 2001 From: Ceikry Date: Sun, 25 Sep 2022 17:48:10 -0500 Subject: [PATCH] Add support for inserting new right click options, add woah's timer --- client/src/main/java/plugin/Plugin.java | 6 + .../main/java/plugin/PluginRepository.java | 7 + client/src/main/java/plugin/api/API.java | 21 +++ .../main/java/plugin/api/MiniMenuAction.java | 12 +- .../main/java/plugin/api/MiniMenuEntry.java | 2 +- .../main/java/plugin/api/MiniMenuType.java | 3 +- client/src/main/java/rt4/LoginManager.java | 3 + client/src/main/java/rt4/MiniMenu.java | 14 +- .../src/main/kotlin/LoginTimer/plugin.kt | 145 ++++++++++++++++++ 9 files changed, 208 insertions(+), 5 deletions(-) create mode 100644 plugin-playground/src/main/kotlin/LoginTimer/plugin.kt diff --git a/client/src/main/java/plugin/Plugin.java b/client/src/main/java/plugin/Plugin.java index 31123ea..e2c0f16 100644 --- a/client/src/main/java/plugin/Plugin.java +++ b/client/src/main/java/plugin/Plugin.java @@ -95,4 +95,10 @@ public abstract class Plugin { * @param entry the entry */ public void DrawMiniMenu(MiniMenuEntry entry) {} + + /** + * Called by the client code when we generate the MiniMenu + * @param currentEntries + */ + public void OnMiniMenuCreate(MiniMenuEntry[] currentEntries) {} } diff --git a/client/src/main/java/plugin/PluginRepository.java b/client/src/main/java/plugin/PluginRepository.java index 599aff9..e7a3793 100644 --- a/client/src/main/java/plugin/PluginRepository.java +++ b/client/src/main/java/plugin/PluginRepository.java @@ -1,5 +1,6 @@ package plugin; +import plugin.api.API; import plugin.api.MiniMenuEntry; import plugin.api.MiniMenuType; import rt4.*; @@ -24,6 +25,8 @@ public class PluginRepository { loadedPlugins.put(info, plugin); } + public static int lastMiniMenu; + public static void reloadPlugins() { loadedPlugins.clear(); Init(); @@ -134,4 +137,8 @@ public class PluginRepository { public static void DrawMiniMenu(MiniMenuEntry entry) { loadedPlugins.values().forEach((plugin) -> plugin.DrawMiniMenu(entry)); } + + public static void OnMiniMenuCreate() { + loadedPlugins.values().forEach((plugin) -> plugin.OnMiniMenuCreate(API.GetMiniMenuEntries())); + } } diff --git a/client/src/main/java/plugin/api/API.java b/client/src/main/java/plugin/api/API.java index ba7efdc..dd44381 100644 --- a/client/src/main/java/plugin/api/API.java +++ b/client/src/main/java/plugin/api/API.java @@ -15,6 +15,9 @@ import static rt4.MathUtils.clamp; * @author ceikry */ public class API { + public static Runnable[] miniMenuCustomActions = new Runnable[10]; + public static int customMiniMenuIndex = 0; + public static void DrawText(FontType fontType, FontColor color, TextModifier mod, String text, int screenX, int screenY) { JagString js = JagString.of(text); @@ -205,4 +208,22 @@ public class API { } return entries.toArray(new MiniMenuEntry[]{}); } + + public static MiniMenuEntry InsertMiniMenuEntry(String verb, String subject, Runnable onClick) { + if (customMiniMenuIndex == 10) { + return null; + } + + MiniMenuEntry entry = new MiniMenuEntry(MiniMenu.size); + entry.setVerb(verb); + entry.setSubject(subject); + MiniMenu.actions[MiniMenu.size] = (short) (9990 + customMiniMenuIndex); + miniMenuCustomActions[customMiniMenuIndex++] = onClick; + MiniMenu.size++; + return entry; + } + + public static void UpdateMenuSize(int size) { + MiniMenu.size = size; + } } diff --git a/client/src/main/java/plugin/api/MiniMenuAction.java b/client/src/main/java/plugin/api/MiniMenuAction.java index d104459..276feee 100644 --- a/client/src/main/java/plugin/api/MiniMenuAction.java +++ b/client/src/main/java/plugin/api/MiniMenuAction.java @@ -29,7 +29,17 @@ public enum MiniMenuAction { LOC_3(49), LOC_4(46), LOC_5(1001), - LOC_EXAMINE(1004) + LOC_EXAMINE(1004), + CUSTOM_1(9990), + CUSTOM_2(9991), + CUSTOM_3(9992), + CUSTOM_4(9993), + CUSTOM_5(9994), + CUSTOM_6(9995), + CUSTOM_7(9996), + CUSTOM_8(9997), + CUSTOM_9(9998), + CUSTOM_10(9999), ; public final short actionCode; diff --git a/client/src/main/java/plugin/api/MiniMenuEntry.java b/client/src/main/java/plugin/api/MiniMenuEntry.java index cff7f7d..8210ac6 100644 --- a/client/src/main/java/plugin/api/MiniMenuEntry.java +++ b/client/src/main/java/plugin/api/MiniMenuEntry.java @@ -33,7 +33,7 @@ public class MiniMenuEntry { if (color.equals("ffff00")) return MiniMenuType.NPC; if (color.equals("ffffff")) return MiniMenuType.PLAYER; if (color.equals("ff9040")) return MiniMenuType.OBJ; - else return MiniMenuType.TILE; + else return MiniMenuType.CUSTOM; } public String getVerb() { diff --git a/client/src/main/java/plugin/api/MiniMenuType.java b/client/src/main/java/plugin/api/MiniMenuType.java index 5a45741..f2f3076 100644 --- a/client/src/main/java/plugin/api/MiniMenuType.java +++ b/client/src/main/java/plugin/api/MiniMenuType.java @@ -6,5 +6,6 @@ public enum MiniMenuType { LOCATION, TILE, OBJ, - OBJSTACK + OBJSTACK, + CUSTOM } diff --git a/client/src/main/java/rt4/LoginManager.java b/client/src/main/java/rt4/LoginManager.java index 4a90426..a8e2270 100644 --- a/client/src/main/java/rt4/LoginManager.java +++ b/client/src/main/java/rt4/LoginManager.java @@ -1445,6 +1445,9 @@ public class LoginManager { } else { SoftwareRaster.method2503(); } + if (!Cs1ScriptRunner.aBoolean108) { + PluginRepository.OnMiniMenuCreate(); + } MiniMenu.sort(); if (Cs1ScriptRunner.aBoolean108) { if (InterfaceList.aBoolean298) { diff --git a/client/src/main/java/rt4/MiniMenu.java b/client/src/main/java/rt4/MiniMenu.java index ed81362..224e3a9 100644 --- a/client/src/main/java/rt4/MiniMenu.java +++ b/client/src/main/java/rt4/MiniMenu.java @@ -4,6 +4,7 @@ import org.openrs2.deob.annotation.OriginalArg; import org.openrs2.deob.annotation.OriginalMember; import org.openrs2.deob.annotation.Pc; import plugin.PluginRepository; +import plugin.api.API; import plugin.api.MiniMenuEntry; public class MiniMenu { @@ -388,7 +389,7 @@ public class MiniMenu { while (!sorted) { sorted = true; for (@Pc(13) int i = 0; i < size - 1; i++) { - if (actions[i] < 1000 && actions[i + 1] > 1000) { + if ((actions[i] < 1000 && actions[i + 1] > 1000) || (actions[i] > 7000 && actions[i + 1] > actions[i])) { @Pc(41) JagString local41 = opBases[i]; sorted = false; opBases[i] = opBases[i + 1]; @@ -433,7 +434,12 @@ public class MiniMenu { @OriginalMember(owner = "client!wa", name = "a", descriptor = "(IZ)Lclient!na;") public static JagString getOp(@OriginalArg(0) int i) { - return opBases[i].length() > 0 ? JagString.concatenate(new JagString[]{ops[i], LocalizedText.MINISEPARATOR, opBases[i]}) : ops[i]; + try { + return opBases[i].length() > 0 ? JagString.concatenate(new JagString[]{ops[i], LocalizedText.MINISEPARATOR, opBases[i]}) : ops[i]; + } catch (NullPointerException npe) { + int ui = 4; + return JagString.EMPTY; + } } @OriginalMember(owner = "client!i", name = "p", descriptor = "(II)V") @@ -1130,6 +1136,10 @@ public class MiniMenu { Protocol.outboundBuffer.ip2add(local36); } } + if (actionCode >= 7990 && actionCode <= 7999) { + int index = actionCode - 7990; + API.miniMenuCustomActions[index].run(); + } if (anInt5014 != 0) { anInt5014 = 0; InterfaceList.redraw(InterfaceList.getComponent(MiniMap.anInt5062)); diff --git a/plugin-playground/src/main/kotlin/LoginTimer/plugin.kt b/plugin-playground/src/main/kotlin/LoginTimer/plugin.kt new file mode 100644 index 0000000..2273bf3 --- /dev/null +++ b/plugin-playground/src/main/kotlin/LoginTimer/plugin.kt @@ -0,0 +1,145 @@ +package LoginTimer + +import plugin.Plugin +import plugin.annotations.PluginMeta +import plugin.api.API +import plugin.api.MiniMenuEntry +import rt4.Component +import rt4.JagString +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter +import java.util.concurrent.TimeUnit + +/** + * Timer/SysTime that goes over the report abuse button + * @author Woah + */ +@PluginMeta( + author = "Woahscam, Ceikry", + description = "Displays the session time played, system time, or no time over the \"Report Abuse\" button.", + version = 1.2 +) +class plugin : Plugin() { + + private val COMPONENT_REPORT_ABUSE = 49217565 + private val DEFAULT_TIME_MODE = 0 + private val PLAY_TIME_TIME_MODE = 1 + private val LOCAL_TIME_TIME_MODE = 2 + private val TIME_MODE_EMPTY = 3 + private val TIME_MODE_INITIALIZATION = 4 + + private var timeMode = TIME_MODE_INITIALIZATION + private var initTime: Long = 0 + private var displayMessageCounter = 0 + + private var component: Component? = null + + override fun Init() { + timeMode = TIME_MODE_INITIALIZATION + initTime = System.currentTimeMillis() + displayMessageCounter = 0 + } + + override fun Draw(timeDelta: Long) { + if (component == null) + return + when (timeMode) { + DEFAULT_TIME_MODE -> { + if (component != null) { + if (component?.id == COMPONENT_REPORT_ABUSE) { + component?.text = JagString.parse("Report Abuse") + timeMode = TIME_MODE_EMPTY + } + } + } + PLAY_TIME_TIME_MODE -> { + val passedTime = System.currentTimeMillis() - initTime + val hrs = TimeUnit.MILLISECONDS.toHours(passedTime).toInt() % 24 + val min = TimeUnit.MILLISECONDS.toMinutes(passedTime).toInt() % 60 + val sec = TimeUnit.MILLISECONDS.toSeconds(passedTime).toInt() % 60 + val timeInHHMMSS = String.format("%02d:%02d:%02d", hrs, min, sec); + if (component != null) { + if (component?.id == COMPONENT_REPORT_ABUSE) { + component?.text = JagString.parse(timeInHHMMSS) + } + } + } + LOCAL_TIME_TIME_MODE -> { + val now = LocalDateTime.now() + val formatter = DateTimeFormatter.ofPattern("HH:mm:ss") + val formattedTime = now.format(formatter) + if (component != null) { + if (component?.id == COMPONENT_REPORT_ABUSE) { + component?.text = JagString.parse(formattedTime) + } + } + } + TIME_MODE_EMPTY -> { /*Nothing*/ } + TIME_MODE_INITIALIZATION -> { + val now = LocalDateTime.now() + val formatter = DateTimeFormatter.ofPattern("HH") + val formattedTime = now.format(formatter) + if (component != null) { + if (component?.id == COMPONENT_REPORT_ABUSE) { + val hour = formattedTime.toInt() + val welcomeString = when (hour) { + in 0..11 -> "Good morning!" + in 12..17 -> "Good afternoon!" + in 17..23 -> "Good evening!" + else -> { "Hello!" } + } + component?.text = JagString.parse(welcomeString) + if (displayMessageCounter in 0..400) { + displayMessageCounter++ + } + if (displayMessageCounter > 400 && displayMessageCounter != -1) { + displayMessageCounter = -1 + timeMode = PLAY_TIME_TIME_MODE + } + } + } + } + else -> { + timeMode = DEFAULT_TIME_MODE + } + } + } + + // This is done in the main component draw so the users who plain in SD will have their time updated + // Without having to interact with the interface + override fun ComponentDraw(componentIndex: Int, component: Component?, screenX: Int, screenY: Int) { + if (component?.id == COMPONENT_REPORT_ABUSE) + this.component = component + } + + override fun ProcessCommand(commandStr: String, args: Array?) { + if (commandStr.equals("::playedtime", ignoreCase = true)) { + timeMode = 1 + } else if (commandStr.equals("::systime", ignoreCase = true)) { + timeMode = 2 + } else if (commandStr.equals("::notime", ignoreCase = true)) { + timeMode = 0 + } + } + + override fun OnMiniMenuCreate(currentEntries: Array) { + API.customMiniMenuIndex = 0; + var hasReportAbuse = false + for (entry in currentEntries) { + if (entry.verb == "Report Abuse") + hasReportAbuse = true + } + + if (hasReportAbuse) { + API.InsertMiniMenuEntry("Play Time", "") { + timeMode = PLAY_TIME_TIME_MODE + } + API.InsertMiniMenuEntry("Local Time", "") { + timeMode = LOCAL_TIME_TIME_MODE + } + API.InsertMiniMenuEntry("Disable Timer", "") { + timeMode = DEFAULT_TIME_MODE + } + } + } +} \ No newline at end of file