Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an interface for external plugins #48

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

jocopa3
Copy link

@jocopa3 jocopa3 commented Aug 2, 2023

This PR is incomplete, namely UI and API is not finalized. I'm publishing it to receive feedback from others.

Overview

A common request I see from other plugin developers is wanting some way to interface with shortest path but there currently doesn't exist a way to do so. This PR proposes a potential API that can be exposed to external plugins to allow them to make requests while also allowing users to control which paths are visible and prioritize which plugin paths should override other paths.

  • Plugins may now use an API over the event bus to request paths
    • Currently uses a HashMap to transfer data until some form of Plugin Messaging event is added to RuneLite, a la: Add PluginMessage event runelite/runelite#16863
    • Plugins can only modify their own requested paths; they cannot clear/change paths for other plugins.
    • For now, plugins can only request one path at a time. Any new requests overwrite the old one.
    • Similarly, Shortest Path currently only displays one path at a time determined by the priority list and visibility.
    • Shortest Path still processes requests for bookkeeping even if the shortest path plugin is disabled, it just won't do the actual pathfinding unless it's enabled.
    • Shortest Path attempts to respect other plugins requests and provides no option to cancel/clear plugin paths directly, only toggle visibility.
  • Refactored how shortest path handles path finding requests internally; all internal requests for pathfinding go through the same requestPath code path as external plugins.
  • Optimized the startUp and shutDown functions to avoid redundantly loading data in-case the user toggles the plugin on/off.
  • Plugin Panel shows a drag-and-drop list of plugins. Plugins higher-up have a higher priority.
    image
  • Debug Overlay now shows the path owner:
    image

Notes

  • Priority list order is not yet saved. Was wondering if it should be saved at all or reset each time the client starts up
  • All icons for UI are placeholders until I can either make new assets or find some with an agreeable license.
  • Navigation Button currently uses marker.png as the plugin's icon; open to ideas for something better to use.

Video Demo

Video demonstrates that shortest-path's normal functions still work as expected, but also that other plugins (e.x. Quest Helper) can interface with it. Plugins can be re-ordered and paths hidden via the side panel. Shortest Path still tracks request/clear commands even if it's disabled so that the data remains current the next time it's enabled.

2023-08-02.12-45-46.mp4

API

This initial proposal is meant to implement the bare minimum feature-set most people want and that can be easily maintained going forward. Additional features like changing pathfinding options, drawing multiple paths, changing path colors, etc., are out of the intended scope of this PR.

Plugins interface over the EventBus by passing a hashmap of type HashMap<String, Object> containing the required parameters. Any invalid requests or requests with invalid/missing parameters are ignored and a debug message printed. For simplicity, the API is entirely one-way communication and Shortest Path does not send responses or acknowledgements back to requesters. Here is a working example class that external plugins can use directly to interface with shortest path or use as a reference.

Internally, the API side is handled by ShortestPathAPI.java. It validates that the objects received are the correct types and prints debug messages when it receives invalid requests or parameters; these messages can be seen in logs or when RuneLite is run with the --debug argument.

Required Parameters

There are a few parameters that are required in all events:

Key Type Description
plugin Plugin Required. A reference to the plugin making the path requests.
command String Required. Must start with shortestpath: followed by the command.

Commands

  • request-path: Asks shortest path to try and draw a path from the player's position or start point to the target point. The requested path will only be drawn if no other plugin has an active path or the requesting plugin is higher on the user's priority list than other plugins with active paths.
  • clear-path: Clears any paths set by the requesting plugin; does not affect other plugins paths.

Some commands may have additional parameters as listed below.

request-path Command:

Key Type Description
target WorldPoint Required. The world point for where the path ends.
start WorldPoint Optional. The world point that marks where the path should start. If missing or null, then the player's position is used as the start point.
hide-marker Boolean Optional. If the key exists and value is true, shortest path won't draw the target "marker" overlay on the world map. This is useful to plugins like Quest Helper that already draw their own world map marker.

@Skretzo
Copy link
Owner

Skretzo commented Aug 2, 2023

All icons for UI are placeholders until I can either make new assets or find some with an agreeable license.

Both the Screen Markers plugin and the Loot Tracker plugin in core RuneLite have enable/disable icons made by Psikoi that I believe are under RuneLite's BSD-2 license.

@Skretzo
Copy link
Owner

Skretzo commented Aug 2, 2023

Navigation Button currently uses marker.png as the plugin's icon; open to ideas for something better to use.

I like the look of that icon in the panel. It makes sense and I cannot think of anything better at the moment.

hide-marker param now expected to be a valid boolean
Supress unchecked cast warnings
@jocopa3
Copy link
Author

jocopa3 commented Aug 3, 2023

Minor update: hide-marker is now a Boolean type rather than allowing any value. Since it's optional, default behavior is to show the marker, plugins are expected to set hide-marker true to disable the world map marker.

* More consistent variable naming
* Small clean-up in PluginPathManager
components.add(separator);

components.add(makeText("Path Owner:"));
String requester = currentParameters.getRequester().getFullyQualifiedName();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I prefer seeing Shortest Path and Quest Helper instead of shortestpath.ShortestPathPlugin and questhelper.QuestHelperPlugin here, so maybe change this to getName()? Plugin names are not required to be unique, but I think they all are.

@Skretzo
Copy link
Owner

Skretzo commented Jul 20, 2024

runelite/runelite#16863 was added in runelite/runelite@0b12333

@Skretzo Skretzo deleted the branch Skretzo:master September 29, 2024 17:42
@Skretzo Skretzo closed this Sep 29, 2024
@Skretzo Skretzo reopened this Oct 21, 2024
@Skretzo Skretzo deleted the branch Skretzo:master October 27, 2024 21:55
@Skretzo Skretzo closed this Oct 27, 2024
@Skretzo Skretzo reopened this Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants