Repository: runelite/runelite (java)

Issue:
Screenshot plugin's automatic boss kill screenshotting not working for Yama
### Type

Incorrect behavior

### Operating System

Windows

### OS Version

Windows 11

### Bug description

The screenshot plugin does not automatically screenshot Yama kc. This should be due to the screenshot plugin using a regex for checking for boss kc, but Yama's kc message is slightly different:

https://github.com/runelite/runelite/blob/fd52b7109540f1894806090df200c918002b2d7c/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java#L98C1-L98C136


### Screenshots or videos

![Image](https://github.com/user-attachments/assets/85620033-ced6-40f2-981e-5b5306b4e956)

### RuneLite version

RuneLite version: 1.11.8
Launcher version: 2.6.7

### Logs

_No response_

Pull request description:
screenshot: match yama kc message
Updates the boss kc message pattern to also match the Yama kc message.

Fixes #19006

Tested by @DominickCobb-rs [here](https://discord.com/channels/301497432909414422/419891709883973642/1373726604194222103)


Patch:
diff --git a/runelite-client/src/main/java/net/runelite/client/game/LootManager.java b/runelite-client/src/main/java/net/runelite/client/game/LootManager.java
index 321848a4c..082cf4a9b 100644
--- a/runelite-client/src/main/java/net/runelite/client/game/LootManager.java
+++ b/runelite-client/src/main/java/net/runelite/client/game/LootManager.java
@@ -66,6 +66,7 @@ import net.runelite.client.eventbus.Subscribe;
 import net.runelite.client.events.ServerNpcLoot;
 import net.runelite.client.events.NpcLootReceived;
 import net.runelite.client.events.PlayerLootReceived;
+import net.runelite.client.util.Text;
 
 @Singleton
 @Slf4j
@@ -288,6 +289,11 @@ public class LootManager
 			log.debug("loottracker_add_loot npc={} event={} item={} qty={}", npcId, eventId, itemId, qty);
 
 			NPCComposition npcComposition = client.getNpcDefinition(npcId);
+			String name = Text.removeTags(npcComposition.getName());
+			if (name.isEmpty() || "null".equals(name))
+			{
+				return;
+			}
 
 			if (scriptEventId != eventId)
 			{
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java
index 16b4ef477..3356d41e4 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java
@@ -1139,10 +1139,14 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
 		final int height = bufferProvider.getHeight();
 
 		GL43C.glBindBuffer(GL43C.GL_PIXEL_UNPACK_BUFFER, interfacePbo);
-		GL43C.glMapBuffer(GL43C.GL_PIXEL_UNPACK_BUFFER, GL43C.GL_WRITE_ONLY)
-			.asIntBuffer()
-			.put(pixels, 0, width * height);
-		GL43C.glUnmapBuffer(GL43C.GL_PIXEL_UNPACK_BUFFER);
+		ByteBuffer interfaceBuf = GL43C.glMapBuffer(GL43C.GL_PIXEL_UNPACK_BUFFER, GL43C.GL_WRITE_ONLY);
+		if (interfaceBuf != null)
+		{
+			interfaceBuf
+				.asIntBuffer()
+				.put(pixels, 0, width * height);
+			GL43C.glUnmapBuffer(GL43C.GL_PIXEL_UNPACK_BUFFER);
+		}
 		GL43C.glBindTexture(GL43C.GL_TEXTURE_2D, interfaceTexture);
 		GL43C.glTexSubImage2D(GL43C.GL_TEXTURE_2D, 0, 0, 0, width, height, GL43C.GL_BGRA, GL43C.GL_UNSIGNED_INT_8_8_8_8_REV, 0);
 		GL43C.glBindBuffer(GL43C.GL_PIXEL_UNPACK_BUFFER, 0);
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java
index 569ff4d43..7e44f5b07 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java
@@ -95,7 +95,7 @@ public class ScreenshotPlugin extends Plugin
 	private static final Pattern NUMBER_PATTERN = Pattern.compile("([,0-9]+)");
 	private static final Pattern LEVEL_UP_PATTERN = Pattern.compile(".*Your ([a-zA-Z]+) (?:level is|are)? now (\\d+)\\.");
 	private static final Pattern LEVEL_UP_MESSAGE_PATTERN = Pattern.compile("Congratulations, you've (just advanced your (?<skill>[a-zA-Z]+) level\\. You are now level (?<level>\\d+)|reached the highest possible (?<skill99>[a-zA-Z]+) level of 99)\\.");
-	private static final Pattern BOSSKILL_MESSAGE_PATTERN = Pattern.compile("Your (.+) kill count is: ?<col=[0-9a-f]{6}>([0-9,]+)</col>");
+	private static final Pattern BOSSKILL_MESSAGE_PATTERN = Pattern.compile("Your (.+) (?:kill|success) count is: ?<col=[0-9a-f]{6}>([0-9,]+)</col>");
 	private static final Pattern VALUABLE_DROP_PATTERN = Pattern.compile(".*Valuable drop: ([^<>]+?\\(((?:\\d+,?)+) coins\\))(?:</col>)?");
 	private static final Pattern UNTRADEABLE_DROP_PATTERN = Pattern.compile(".*Untradeable drop: ([^<>]+)(?:</col>)?");
 	private static final Pattern DUEL_END_PATTERN = Pattern.compile("You have now (won|lost) ([0-9,]+) duels?\\.");


Test patch:
diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java
index 392609d9d..15f3abffa 100644
--- a/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java
+++ b/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java
@@ -553,6 +553,17 @@ public class ScreenshotPluginTest
 		verify(screenshotPlugin).takeScreenshot("Nightmare(1130)", "Boss Kills");
 	}
 
+	@Test
+	public void testYamaKillCount()
+	{
+		when(screenshotConfig.screenshotBossKills()).thenReturn(true);
+
+		ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Yama success count is: <col=ff0000>227</col>", null, 0);
+		screenshotPlugin.onChatMessage(chatMessage);
+
+		verify(screenshotPlugin).takeScreenshot("Yama(227)", "Boss Kills");
+	}
+
 	@Test
 	public void testEchoBossKillCount()
 	{