Skip to content

2.0.41#1607

Merged
chsami merged 23 commits intomainfrom
development
Nov 15, 2025
Merged

2.0.41#1607
chsami merged 23 commits intomainfrom
development

Conversation

@chsami
Copy link
Owner

@chsami chsami commented Nov 15, 2025

No description provided.

Felanbird and others added 23 commits November 7, 2025 08:10
Game objects new simplified api
Co-authored-by: Jamy Cuijpers <hello@jamycuijpers.com>
Co-authored-by: Kenneth Tubman <ken@kentubman5.com>
This is faster as it allows the gpu to allocate a new buffer instead of having to copy over the previous buffer contents
The apple opengl driver seems to have a really bad time emulating this on metal
# Conflicts:
#	cache/pom.xml
#	pom.xml
#	runelite-api/pom.xml
#	runelite-client/pom.xml
#	runelite-jshell/pom.xml
#	runelite-maven-plugin/pom.xml
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 15, 2025

Walkthrough

This pull request contains a parent POM version bump from 1.12.3 to 1.12.4 across six modules (pom.xml, cache, runelite-api, runelite-client, runelite-jshell, runelite-maven-plugin) and updates the microbot.version property from 2.0.40 to 2.0.41. It introduces new microbot tile object utility classes (Rs2TileObjectApi, Rs2TileObjectModel, TileObjectType), adds a generic ClientThread.invoke() helper method, expands ConfigProfile field visibility and setter accessibility, modifies GPU rendering logic and texture coordinate handling, removes several deprecated Script APIs, and updates game content data including Discord event types, hunter area creatures, and slayer task display names.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.86% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive No description was provided by the author, but given the clear version bump intent evident from the changes, this is inconclusive without explicit context. Add a brief description explaining the version bump and highlighting major changes like the microbot.version update to 2.0.41 and the new tile object utilities.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title '2.0.41' refers to a version bump, which is the primary change across multiple pom.xml files and microbot.version property.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java (1)

47-53: Inconsistent getter/setter logic for activeProfile.

The @Setter on activeProfile generates a setter that modifies the field, but getActiveProfile() returns Microbot.getConfigManager().getProfile() instead of reading from activeProfile. This breaks the getter/setter contract—any code that calls the setter will have no effect since the getter ignores the field completely.

Either remove the unused activeProfile field and its @Setter, or update getActiveProfile() to return it:

-	@Setter
-	public static ConfigProfile activeProfile = null;
-
 	public static ConfigProfile getActiveProfile() {
 		return Microbot.getConfigManager().getProfile();
-
 	}

Or if the field is intentionally meant to override the config manager:

 	public static ConfigProfile getActiveProfile() {
+		if (activeProfile != null) {
+			return activeProfile;
+		}
 		return Microbot.getConfigManager().getProfile();
-
 	}
runelite-client/src/main/java/net/runelite/client/plugins/gpu/VBO.java (1)

56-64: destroy() bypasses explicit flush required for non-static mapped buffers

For non-GL_STATIC_DRAW usage, map() sets GL_MAP_FLUSH_EXPLICIT_BIT, and unmap() correctly calls glFlushMappedBufferRange before glUnmapBuffer. However, destroy() still performs a raw glUnmapBuffer without any flush when mapped is true, so the semantics differ depending on whether the caller uses unmap() or calls destroy() while mapped. That inconsistency can result in lost writes or undefined behavior for dynamically updated buffers destroyed while still mapped.

To keep the logic consistent, have destroy() delegate to unmap() instead of open-coding the unmap sequence:

-	void destroy()
-	{
-		if (mapped)
-		{
-			glBindBuffer(GL_ARRAY_BUFFER, bufId);
-			glUnmapBuffer(GL_ARRAY_BUFFER);
-			glBindBuffer(GL_ARRAY_BUFFER, 0);
-			mapped = false;
-		}
-		glDeleteBuffers(bufId);
-		bufId = 0;
-	}
+	void destroy()
+	{
+		if (mapped)
+		{
+			unmap();
+		}
+
+		glDeleteBuffers(bufId);
+		bufId = 0;
+	}

Also applies to: 90-93

runelite-client/src/main/java/net/runelite/client/plugins/fairyring/FairyRingPlugin.java (1)

185-201: Guard against null MESLAYERINPUT before calling toLowerCase()

client.getVarcStrValue(VarClientID.MESLAYERINPUT) can be null; calling toLowerCase() on it will throw an NPE and break the fairy ring filter logic.

A minimal null‑safe fix using the existing Guava Strings import:

-			var filter = client.getVarcStrValue(VarClientID.MESLAYERINPUT).toLowerCase();
+			String filter = Strings.nullToEmpty(client.getVarcStrValue(VarClientID.MESLAYERINPUT)).toLowerCase();

This preserves current behavior while avoiding crashes when the search box is empty/uninitialized.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c67b88e and cb33886.

⛔ Files ignored due to path filters (3)
  • runelite-client/src/main/resources/net/runelite/client/plugins/gpu/geom.glsl is excluded by !**/*.glsl
  • runelite-client/src/main/resources/net/runelite/client/plugins/gpu/uv.glsl is excluded by !**/*.glsl
  • runelite-client/src/main/resources/net/runelite/client/plugins/gpu/vert.glsl is excluded by !**/*.glsl
📒 Files selected for processing (26)
  • cache/pom.xml (1 hunks)
  • pom.xml (1 hunks)
  • runelite-api/pom.xml (1 hunks)
  • runelite-client/pom.xml (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/config/ConfigProfile.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/fairyring/FairyRingPlugin.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/FacePrioritySorter.java (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java (4 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java (7 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/VBO.java (4 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/Zone.java (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/Script.java (0 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/gameobject/Rs2GameObject.java (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectApi.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/TileObjectType.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/runecraft/EssencePouchOverlay.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java (2 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/worldmap/HunterAreaLocation.java (1 hunks)
  • runelite-jshell/pom.xml (1 hunks)
  • runelite-maven-plugin/pom.xml (1 hunks)
💤 Files with no reviewable changes (1)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/Script.java
🧰 Additional context used
📓 Path-based instructions (5)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java

📄 CodeRabbit inference engine (AGENTS.md)

runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java: Place all gameplay automation code under runelite-client/src/main/java/net/runelite/client/plugins/microbot
Prefix configuration interfaces with the plugin name (e.g., ExampleConfig) within microbot plugins

Files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/TileObjectType.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/gameobject/Rs2GameObject.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectApi.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/**/*.java

📄 CodeRabbit inference engine (AGENTS.md)

Keep runnable examples under .../microbot/example

Files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
**/*.java

📄 CodeRabbit inference engine (AGENTS.md)

**/*.java: Use tabs for indentation, follow the brace placement style exemplified in MicrobotPlugin.java, and keep lines under 120 characters
Use UpperCamelCase for types and lowerCamelCase for members

Files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java
  • runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java
  • runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/TileObjectType.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/gameobject/Rs2GameObject.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/FacePrioritySorter.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/VBO.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectApi.java
  • runelite-client/src/main/java/net/runelite/client/plugins/worldmap/HunterAreaLocation.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
  • runelite-client/src/main/java/net/runelite/client/plugins/runecraft/EssencePouchOverlay.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java
  • runelite-client/src/main/java/net/runelite/client/config/ConfigProfile.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/Zone.java
  • runelite-client/src/main/java/net/runelite/client/plugins/fairyring/FairyRingPlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java
  • runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java
**/pom.xml

📄 CodeRabbit inference engine (AGENTS.md)

Target Java 11 via maven-compiler-plugin using 11 in all module POMs

Files:

  • runelite-jshell/pom.xml
  • runelite-maven-plugin/pom.xml
  • cache/pom.xml
  • runelite-api/pom.xml
  • pom.xml
  • runelite-client/pom.xml
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/**/*.java

📄 CodeRabbit inference engine (AGENTS.md)

Put shared helpers under .../microbot/util

Files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/TileObjectType.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/gameobject/Rs2GameObject.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectApi.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/**/*.java : Put shared helpers under .../microbot/util
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java : Place all gameplay automation code under runelite-client/src/main/java/net/runelite/client/plugins/microbot
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/@(!(util|example))/**/*.java : For new automation scripts, reuse the scheduler pattern demonstrated in ExampleScript

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/**/*.java : Keep runnable examples under .../microbot/example

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java : Prefix configuration interfaces with the plugin name (e.g., ExampleConfig) within microbot plugins

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
  • runelite-client/src/main/java/net/runelite/client/plugins/fairyring/FairyRingPlugin.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java : Place all gameplay automation code under runelite-client/src/main/java/net/runelite/client/plugins/microbot

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/TileObjectType.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/gameobject/Rs2GameObject.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectApi.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/**/*.java : Put shared helpers under .../microbot/util

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/gameobject/Rs2GameObject.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectApi.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
  • runelite-client/pom.xml
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.java : When adding panel controls or overlays, update the Microbot navigation panel setup in MicrobotPlugin and provide default config values

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
📚 Learning: 2025-09-03T03:59:10.180Z
Learnt from: g-mason0
Repo: chsami/Microbot PR: 1462
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/ui/MicrobotPluginHubPanel.java:343-344
Timestamp: 2025-09-03T03:59:10.180Z
Learning: In MicrobotPluginManager, the public methods installPlugin(), removePlugin(), and update() already use executor.submit() internally to perform their operations asynchronously, making them non-blocking on the EDT. These are wrapper methods that delegate to the actual implementation methods (install(), remove(), refresh()) via the executor.

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java
📚 Learning: 2025-08-25T15:51:39.272Z
Learnt from: runsonmypc
Repo: chsami/Microbot PR: 1417
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/agility/AgilityScript.java:13-13
Timestamp: 2025-08-25T15:51:39.272Z
Learning: Both net.runelite.api.ItemID and net.runelite.api.gameval.ItemID are valid import paths in the RuneLite codebase. The microbot plugins consistently use net.runelite.api.ItemID as their established pattern.

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java
📚 Learning: 2025-08-25T15:51:52.157Z
Learnt from: runsonmypc
Repo: chsami/Microbot PR: 1417
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/agility/AgilityScript.java:284-291
Timestamp: 2025-08-25T15:51:52.157Z
Learning: In RuneLite's ItemID class, both PIEDISH and PIE_DISH constants exist and are valid, both referring to item ID 2313. The gameval package uses PIEDISH while the regular api package uses PIE_DISH, so either naming convention can be used.

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java
📚 Learning: 2025-08-25T06:50:43.493Z
Learnt from: Voxsylvae
Repo: chsami/Microbot PR: 1415
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/agility/MicroAgilityPrePostScheduleRequirements.java:218-226
Timestamp: 2025-08-25T06:50:43.493Z
Learning: In MicroAgilityPrePostScheduleRequirements.java, the deprecated ItemID constants NATURERUNE and FIRERUNE should be replaced with NATURE_RUNE and FIRE_RUNE respectively when using the gameval package ItemID class.

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java
  • runelite-client/src/main/java/net/runelite/client/plugins/worldmap/HunterAreaLocation.java
  • runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/test/java/**/*.java : Write JUnit 4 tests (junit:4.12) under matching package paths

Applied to files:

  • runelite-maven-plugin/pom.xml
  • runelite-api/pom.xml
  • runelite-client/pom.xml
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/target/*.jar : Distributable JARs should be produced in runelite-client/target/

Applied to files:

  • runelite-maven-plugin/pom.xml
  • runelite-api/pom.xml
  • pom.xml
  • runelite-client/pom.xml
📚 Learning: 2025-08-25T23:06:30.871Z
Learnt from: g-mason0
Repo: chsami/Microbot PR: 1425
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/herbrun/HerbrunScript.java:137-144
Timestamp: 2025-08-25T23:06:30.871Z
Learning: In RuneLite's ClientThread API, runOnClientThreadOptional() IS a blocking synchronous method when called from other threads. It uses FutureTask.get(10000, TimeUnit.MILLISECONDS) which blocks the calling thread (such as a Script's executor service thread) until the client thread task completes or times out. The method does not return immediately to the calling thread - it waits for completion.

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/callback/ClientThread.java
📚 Learning: 2025-08-23T16:17:37.615Z
Learnt from: g-mason0
Repo: chsami/Microbot PR: 1423
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.java:366-389
Timestamp: 2025-08-23T16:17:37.615Z
Learning: The ScheduledExecutorService injected into MicrobotPluginManager (and other RuneLite classes) is configured as a single-threaded executor via Executors.newSingleThreadScheduledExecutor() at RuneLiteModule.java line 130, wrapped in ExecutorServiceExceptionLogger. This ensures all async tasks execute sequentially, preventing race conditions.

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/test/java/**/*.java : Mirror production package structure for tests under runelite-client/src/test/java

Applied to files:

  • runelite-api/pom.xml
  • runelite-client/pom.xml
📚 Learning: 2025-08-31T19:19:07.691Z
Learnt from: chsami
Repo: chsami/Microbot PR: 1455
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotVersionChecker.java:112-132
Timestamp: 2025-08-31T19:19:07.691Z
Learning: The Microbot project uses only numeric versioning (e.g., "1.2.3") without any alphanumeric suffixes like "-beta" or "-alpha", so simple integer parsing of version segments is safe.

Applied to files:

  • runelite-client/pom.xml
🧬 Code graph analysis (4)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExamplePlugin.java (2)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java (1)
  • Slf4j (25-84)
runelite-client/src/main/java/net/runelite/client/plugins/Plugin.java (1)
  • Plugin (33-80)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java (2)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectApi.java (1)
  • Rs2TileObjectApi (19-102)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java (1)
  • Rs2TileObjectModel (23-265)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectApi.java (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/gameobject/Rs2GameObject.java (1)
  • Rs2GameObject (36-2012)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/equipment/Rs2Equipment.java (1)
  • Rs2Equipment (25-392)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/gameobject/Rs2GameObject.java (1)
  • Rs2GameObject (36-2012)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/menu/NewMenuEntry.java (1)
  • NewMenuEntry (11-317)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build
  • GitHub Check: Build
🔇 Additional comments (10)
runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java (1)

93-93: LGTM - Data updates are consistent.

The region ID update for Tempoross and the rename from PVP Arena to Emir's Arena follow the existing enum pattern correctly. No logical inconsistencies detected.

Also applies to: 306-306

runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java (1)

101-101: LGTM - Consistency improvement.

The plural display name now matches the plural enum constant GOBLINS, aligning with the pattern used by other task enums.

pom.xml (1)

31-31: LGTM!

Version bump is consistent across the project modules.

cache/pom.xml (1)

32-32: LGTM!

Parent version update aligns with the root POM.

runelite-client/pom.xml (2)

32-32: LGTM!

Parent version bump is consistent with the project-wide update.


44-44: LGTM!

Microbot version update aligns with the PR title and release objectives.

runelite-maven-plugin/pom.xml (1)

32-32: LGTM!

Parent version update is consistent with the multi-module version bump.

runelite-api/pom.xml (1)

32-32: LGTM!

Parent version update maintains consistency across modules.

runelite-jshell/pom.xml (1)

33-33: LGTM!

Parent version update completes the consistent multi-module version bump.

runelite-client/src/main/java/net/runelite/client/plugins/runecraft/EssencePouchOverlay.java (1)

255-256: LGTM!

The remaining durability calculation and special handling for COLOSSAL pouches is logically consistent with the existing enum structure and degradation system.

Comment on lines +39 to +46
@Setter
public String name;
@Getter
@Setter(AccessLevel.PACKAGE)
private String password;
@Setter
public String password;
@Getter
@Setter(AccessLevel.PACKAGE)
private String bankPin;
@Setter
public String bankPin;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Inconsistent field visibility and redundant @Setter annotations.

Making these fields public while also adding @Setter is redundant—public fields can be modified directly without setters. More critically, exposing sensitive fields like password and bankPin as public breaks encapsulation and creates security concerns.

This is inconsistent with other fields in the class (e.g., discordWebhookUrl on line 58 remains private with @Setter, following proper encapsulation). If external modification is needed, use private fields with public setters (via @Setter), not public fields with @Setter.

Consider reverting these fields to private:

 	@Getter
 	@Setter
-    public String name;
+    private String name;
 	@Getter
 	@Setter
-	public String password;
+	private String password;
 	@Getter
 	@Setter
-    public String bankPin;
+    private String bankPin;

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In runelite-client/src/main/java/net/runelite/client/config/ConfigProfile.java
around lines 39-46, the fields are declared public while also annotated with
@Setter which is redundant and exposes sensitive data; change the visibility of
name, password and bankPin to private and keep the appropriate Lombok
annotations (e.g., @Getter and @Setter) on them instead of leaving them public,
and remove any duplicate or unnecessary @Setter annotations so sensitive fields
remain encapsulated and modifiers are consistent with other fields in the class.

Comment on lines +54 to +55
@Setter
public boolean isMember;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Inconsistent field visibility and redundant @Setter annotation.

Same issue as above: making isMember public while adding @Setter is redundant and inconsistent with the encapsulation pattern used for other fields in this class.

Consider reverting to private:

 	@Getter
 	@Setter
-    public boolean isMember;
+    private boolean isMember;

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In runelite-client/src/main/java/net/runelite/client/config/ConfigProfile.java
around lines 54-55, the field isMember is declared public with a @Setter which
is redundant and breaks encapsulation; change the field to private (matching
other fields) and remove the field-level @Setter annotation so the class follows
the same visibility/encapsulation pattern and uses the class-level or
conventional accessors instead.

Comment on lines +40 to +52
var tileObjects = Microbot.getClientThread().invoke(() -> {
// List<Rs2TileObjectModel> _tileObjects = Rs2TileObjectApi.getObjectsStream().filter(x -> x.getName() != null && !x.getName().isEmpty() && x.getName() != "null").collect(Collectors.toList());
Rs2TileObjectModel test = Rs2TileObjectApi.getNearest(tile -> tile.getName() != null && tile.getName().toLowerCase().contains("tree"));
endTime.set(System.currentTimeMillis());
System.out.println("Retrieved " + test.getName() + " game objects in " + (endTime.get() - startTime) + " ms");

/*for (Rs2TileObjectModel rs2TileObjectModel: _tileObjects) {
var name = rs2TileObjectModel.getName(); // Access name to simulate some processing
System.out.println("Object Name: " + name);
}
*/
return Rs2TileObjectApi.getObjectsStream().collect(Collectors.toList());
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle getNearest(...) possibly returning null before dereferencing

Rs2TileObjectApi.getNearest(...) returns null when no tile object matches the predicate, but the code unconditionally calls test.getName(), which can throw an NPE:

Rs2TileObjectModel test = Rs2TileObjectApi.getNearest(
    tile -> tile.getName() != null && tile.getName().toLowerCase().contains("tree")
);
endTime.set(System.currentTimeMillis());
System.out.println("Retrieved " + test.getName() + " game objects in " + (endTime.get() - startTime) + " ms");

Consider guarding the access:

-                    Rs2TileObjectModel test = Rs2TileObjectApi.getNearest(tile -> tile.getName() != null && tile.getName().toLowerCase().contains("tree"));
-                    endTime.set(System.currentTimeMillis());
-                    System.out.println("Retrieved " + test.getName() + " game objects in " + (endTime.get() - startTime) + " ms");
+                    Rs2TileObjectModel test = Rs2TileObjectApi.getNearest(
+                        tile -> tile.getName() != null && tile.getName().toLowerCase().contains("tree")
+                    );
+                    endTime.set(System.currentTimeMillis());
+                    if (test != null) {
+                        System.out.println("Retrieved " + test.getName() + " game objects in " + (endTime.get() - startTime) + " ms");
+                    } else {
+                        System.out.println("No matching tile objects found in " + (endTime.get() - startTime) + " ms");
+                    }

This keeps the perf test useful while avoiding a crash when no "tree" objects are present.

🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
around lines 40 to 52, the call to Rs2TileObjectApi.getNearest(...) can return
null but the code unconditionally calls test.getName(), risking an NPE; update
the code to null-check the returned Rs2TileObjectModel before dereferencing (or
use Optional if available), e.g., assign the result to test, then if test !=
null log its name and time, otherwise log a suitable "no matching object"
message (still record endTime) and proceed to return the objects list so the
perf test does not crash when no "tree" is found.

Comment on lines +95 to +106
public String getName() {
return Microbot.getClientThread().invoke(() -> {
ObjectComposition composition = Microbot.getClient().getObjectDefinition(tileObject.getId());
if(composition.getImpostorIds() != null)
{
composition = composition.getImpostor();
}
if(composition == null)
return null;
return Rs2UiHelper.stripColTags(composition.getName());
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid NPE in getName() when getObjectDefinition returns null

getName() calls composition.getImpostorIds() before checking whether composition itself is null, so a missing object definition will throw:

ObjectComposition composition = Microbot.getClient().getObjectDefinition(tileObject.getId());
if(composition.getImpostorIds() != null)
{
    composition = composition.getImpostor();
}
if(composition == null)
    return null;

Reorder the checks to handle null safely:

-            ObjectComposition composition = Microbot.getClient().getObjectDefinition(tileObject.getId());
-            if(composition.getImpostorIds() != null)
-            {
-                composition = composition.getImpostor();
-            }
-            if(composition == null)
-                return null;
+            ObjectComposition composition = Microbot.getClient().getObjectDefinition(tileObject.getId());
+            if (composition == null) {
+                return null;
+            }
+            if (composition.getImpostorIds() != null) {
+                composition = composition.getImpostor();
+            }
+            if (composition == null) {
+                return null;
+            }

This preserves existing behavior while preventing a null dereference.

🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
around lines 95–106, the method calls composition.getImpostorIds() before
verifying composition is non-null which can cause an NPE when
getObjectDefinition returns null; update the method to check if composition ==
null immediately after retrieving it and return null if so, then only afterwards
inspect composition.getImpostorIds() and assign composition =
composition.getImpostor() as needed, and finally return the stripped name (or
null) to preserve existing behavior while avoiding the null dereference.

Comment on lines +143 to +152
public ObjectComposition getObjectComposition() {
return Microbot.getClientThread().invoke(() -> {
ObjectComposition composition = Microbot.getClient().getObjectDefinition(tileObject.getId());
if(composition.getImpostorIds() != null)
{
composition = composition.getImpostor();
}
return composition;
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Same null‑ordering issue in getObjectComposition()

getObjectComposition() has the same pattern and can also NPE when getObjectDefinition returns null:

ObjectComposition composition = Microbot.getClient().getObjectDefinition(tileObject.getId());
if(composition.getImpostorIds() != null)
{
    composition = composition.getImpostor();
}
return composition;

Reorder as in getName():

-        return Microbot.getClientThread().invoke(() -> {
-            ObjectComposition composition = Microbot.getClient().getObjectDefinition(tileObject.getId());
-            if(composition.getImpostorIds() != null)
-            {
-                composition = composition.getImpostor();
-            }
-            return composition;
-        });
+        return Microbot.getClientThread().invoke(() -> {
+            ObjectComposition composition = Microbot.getClient().getObjectDefinition(tileObject.getId());
+            if (composition == null) {
+                return null;
+            }
+            if (composition.getImpostorIds() != null) {
+                composition = composition.getImpostor();
+            }
+            return composition;
+        });

This aligns both methods and avoids a crash when an object definition is missing.

🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
around lines 143 to 152, getObjectComposition() may NPE if
getObjectDefinition(...) returns null because the code calls
composition.getImpostorIds() before checking composition; change the order to
first check for composition == null and return null (or handle accordingly),
then only if composition is non-null check composition.getImpostorIds() and call
composition.getImpostor() when appropriate so the method mirrors the null-safe
ordering used in getName().

JELLIES("Jellies", ItemID.SLAYERGUIDE_JELLY, "Jelly"),
JUNGLE_HORROR("Jungle horrors", ItemID.ARCEUUS_CORPSE_HORROR_INITIAL),
KALPHITE("Kalphite", ItemID.POH_KALPHITE_SOLDIER),
KALPHITE("Kalphites", ItemID.POH_KALPHITE_SOLDIER),
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent plurality between enum constant and display name.

The enum constant KALPHITE is singular, but the display name is now "Kalphites" (plural). This breaks the pattern established by other tasks where the enum constant plurality matches the display name (e.g., GOBLINS"Goblins", BANDITS"Bandits").

Consider either renaming the enum constant to KALPHITES or keeping the display name as "Kalphite" to maintain consistency.

@chsami chsami merged commit e058c01 into main Nov 15, 2025
3 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Nov 30, 2025
@coderabbitai coderabbitai bot mentioned this pull request Feb 3, 2026
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.

8 participants