diff --git a/runelite-api/src/main/java/net/runelite/api/ScriptID.java b/runelite-api/src/main/java/net/runelite/api/ScriptID.java
index 9d056b34e4..2a4693a2c2 100644
--- a/runelite-api/src/main/java/net/runelite/api/ScriptID.java
+++ b/runelite-api/src/main/java/net/runelite/api/ScriptID.java
@@ -194,4 +194,13 @@ public final class ScriptID
*/
@ScriptArguments(integer = 2)
public static final int XPDROP_DISABLED = 2091;
+
+ /**
+ * Attempts to kick the specified player from the Clan Chat
+ *
+ * - String Players in-game name
+ *
+ */
+ @ScriptArguments(string = 1)
+ public static final int CLAN_SEND_KICK = 215;
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java
index 393008f7fe..9a99c5654f 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatConfig.java
@@ -137,4 +137,15 @@ public interface ClanChatConfig extends Config
{
return false;
}
+
+ @ConfigItem(
+ keyName = "confirmKicks",
+ name = "Confirm Kicks",
+ description = "Shows a chat prompt to confirm kicks",
+ position = 9
+ )
+ default boolean confirmKicks()
+ {
+ return false;
+ }
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java
index 00779cb51c..d632ae490a 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/clanchat/ClanChatPlugin.java
@@ -28,6 +28,7 @@ package net.runelite.client.plugins.clanchat;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Runnables;
import com.google.inject.Provides;
import java.awt.Color;
import java.awt.image.BufferedImage;
@@ -72,6 +73,7 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.ClanManager;
import net.runelite.client.game.SpriteManager;
+import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import static net.runelite.client.ui.JagexColors.CHAT_CLAN_NAME_OPAQUE_BACKGROUND;
@@ -112,6 +114,9 @@ public class ClanChatPlugin extends Plugin
@Inject
private ClientThread clientThread;
+ @Inject
+ private ChatboxPanelManager chatboxPanelManager;
+
private List chats = new ArrayList<>();
private List clanMembers = new ArrayList<>();
private ClanChatIndicator clanMemberCounter;
@@ -122,6 +127,8 @@ public class ClanChatPlugin extends Plugin
private Map activityBuffer = new HashMap<>();
private int clanJoinedTick;
+ private boolean kickConfirmed = false;
+
@Provides
ClanChatConfig getConfig(ConfigManager configManager)
{
@@ -504,14 +511,37 @@ public class ClanChatPlugin extends Plugin
@Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
{
- if (!scriptCallbackEvent.getEventName().equalsIgnoreCase("clanchatInput"))
+ switch (scriptCallbackEvent.getEventName())
{
- return;
- }
+ case "clanchatInput":
+ {
+ final int[] intStack = client.getIntStack();
+ final int size = client.getIntStackSize();
+ intStack[size - 1] = config.clanTabChat() ? 1 : 0;
+ break;
+ }
+ case "confirmClanKick":
+ {
+ if (!config.confirmKicks() || kickConfirmed)
+ {
+ break;
+ }
- final int[] intStack = client.getIntStack();
- final int size = client.getIntStackSize();
- intStack[size - 1] = config.clanTabChat() ? 1 : 0;
+ // Set a flag so the script doesn't instantly kick them
+ final int[] intStack = client.getIntStack();
+ final int size = client.getIntStackSize();
+ intStack[size - 1] = 1;
+
+ // Get name of player we are trying to kick
+ final String[] stringStack = client.getStringStack();
+ final int stringSize = client.getStringStackSize();
+ final String kickPlayerName = stringStack[stringSize - 1];
+
+ // Show a chatbox panel confirming the kick
+ clientThread.invokeLater(() -> confirmKickPlayer(kickPlayerName));
+ break;
+ }
+ }
}
int getClanAmount()
@@ -623,4 +653,19 @@ public class ClanChatPlugin extends Plugin
clanMemberCounter = new ClanChatIndicator(image, this);
infoBoxManager.addInfoBox(clanMemberCounter);
}
+
+ private void confirmKickPlayer(final String kickPlayerName)
+ {
+ chatboxPanelManager.openTextMenuInput("Attempting to kick: " + kickPlayerName)
+ .option("1. Confirm kick", () ->
+ clientThread.invoke(() ->
+ {
+ kickConfirmed = true;
+ client.runScript(ScriptID.CLAN_SEND_KICK, kickPlayerName);
+ kickConfirmed = false;
+ })
+ )
+ .option("2. Cancel", Runnables::doNothing)
+ .build();
+ }
}
diff --git a/runelite-client/src/main/scripts/ClanSendKick.hash b/runelite-client/src/main/scripts/ClanSendKick.hash
new file mode 100644
index 0000000000..e1fb1db404
--- /dev/null
+++ b/runelite-client/src/main/scripts/ClanSendKick.hash
@@ -0,0 +1 @@
+9B3B448D76D57F6D63C9CDA06E58695F6DEBE91F9EDF2D2C4876E064D1067FD6
\ No newline at end of file
diff --git a/runelite-client/src/main/scripts/ClanSendKick.rs2asm b/runelite-client/src/main/scripts/ClanSendKick.rs2asm
new file mode 100644
index 0000000000..1da495029f
--- /dev/null
+++ b/runelite-client/src/main/scripts/ClanSendKick.rs2asm
@@ -0,0 +1,34 @@
+.id 215
+.int_stack_count 0
+.string_stack_count 1
+.int_var_count 0
+.string_var_count 1
+; callback "confirmClanKick"
+; Used by the ClanChat plugin to show a chatbox panel confirming the requested kick
+; Also requires the "confirmKicks" option of ClanChatConfig to be enabled
+ invoke 1942
+ iconst 1
+ if_icmpeq LABEL4
+ jump CONFIRM_KICK ; Jump to our new label instead
+LABEL4:
+ sconst "You can't kick players from your team during Wilderness Wars."
+ mes
+ return
+LABEL7:
+ sconst "-Attempting to kick player from friends chat..."
+ iconst 2
+ invoke 96
+ sload 0
+ clan_kickuser
+ jump LABEL73
+LABEL73:
+ return
+CONFIRM_KICK:
+ sload 0 ; Username we are trying to kick
+ iconst 0 ; Modified if we are confirming the kick inside the plugin
+ sconst "confirmClanKick"
+ runelite_callback
+ pop_string ; Pop username
+ iconst 0 ; Compare against zero
+ if_icmpgt LABEL73 ; Early return for chatbox panel confirmation
+ jump LABEL7