From 622bc8da4e9c820464703f1e1644ec5b5f40b495 Mon Sep 17 00:00:00 2001 From: jenz Date: Mon, 20 Jul 2026 23:08:44 +0200 Subject: [PATCH] AI slop update that enables current leaders with rcon access to write clients to the leader file or remove them again from it --- Leader2/scripting/Leader2.sp | 282 +++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) diff --git a/Leader2/scripting/Leader2.sp b/Leader2/scripting/Leader2.sp index 564bb57..7af4f7a 100644 --- a/Leader2/scripting/Leader2.sp +++ b/Leader2/scripting/Leader2.sp @@ -1030,6 +1030,13 @@ public void LeaderMenu(int client) AddMenuItem(menu, "ping", "Ping Menu"); AddMenuItem(menu, "beacon", "Toggle Beacon"); + // RCON-only options + if (CheckCommandAccess(client, "", ADMFLAG_RCON, false)) + { + AddMenuItem(menu, "addleader", "[RCON] Add Leader to File"); + AddMenuItem(menu, "removeleader", "[RCON] Remove Leader from File"); + } + SetMenuExitButton(menu, true); DisplayMenu(menu, client, MENU_TIME_FOREVER); } @@ -1046,6 +1053,23 @@ public int LeaderMenu_Handler(Handle menu, MenuAction action, int client, int po char info[32]; GetMenuItem(menu, position, info, sizeof(info)); + if(StrEqual(info, "addleader")) + { + if(CheckCommandAccess(client, "", ADMFLAG_RCON, false)) + { + AddLeaderMenu(client); + } + } + + if(StrEqual(info, "removeleader")) + { + if(CheckCommandAccess(client, "", ADMFLAG_RCON, false)) + { + RemoveLeaderMenu(client); + } + } + + if(StrEqual(info, "resign")) { RemoveLeader(client); @@ -1070,7 +1094,260 @@ public int LeaderMenu_Handler(Handle menu, MenuAction action, int client, int po delete menu; } } + return 0; +} +//---------------------------------------------------------------------------------------------------- +// Purpose: RCON - shows connected players to add to the leaders file +//---------------------------------------------------------------------------------------------------- +public void AddLeaderMenu(int client) +{ + Handle menu = CreateMenu(AddLeaderMenu_Handler); + SetMenuTitle(menu, "Select a player to ADD as Leader"); + + char info[12], display[MAX_NAME_LENGTH]; + bool any = false; + + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientInGame(i) && !IsFakeClient(i)) + { + any = true; + IntToString(GetClientUserId(i), info, sizeof(info)); + GetClientName(i, display, sizeof(display)); + AddMenuItem(menu, info, display); + } + } + + if(!any) + { + AddMenuItem(menu, "", "No players connected", ITEMDRAW_DISABLED); + } + + SetMenuExitBackButton(menu, true); + SetMenuExitButton(menu, true); + DisplayMenu(menu, client, MENU_TIME_FOREVER); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public int AddLeaderMenu_Handler(Handle menu, MenuAction action, int client, int position) +{ + if(action == MenuAction_Select) + { + if(!CheckCommandAccess(client, "", ADMFLAG_RCON, false)) + { + PrintToChat(client, "[SM] You no longer have access to this."); + return 0; + } + + char info[12]; + GetMenuItem(menu, position, info, sizeof(info)); + + int target = GetClientOfUserId(StringToInt(info)); + if(target == 0) + { + PrintToChat(client, "[SM] That player is no longer available."); + } + else + { + AddLeaderToFile(client, target); + } + + LeaderMenu(client); + } + else if(action == MenuAction_End) + { + delete menu; + } + else if(action == MenuAction_Cancel && position == MenuCancel_ExitBack) + { + LeaderMenu(client); + } + + return 0; +} + + +//AI slop +//---------------------------------------------------------------------------------------------------- +// Purpose: RCON - shows connected players to remove from the leaders file +//---------------------------------------------------------------------------------------------------- +public void RemoveLeaderMenu(int client) +{ + Handle menu = CreateMenu(RemoveLeaderMenu_Handler); + SetMenuTitle(menu, "Select a player to REMOVE as Leader"); + + char info[12], display[MAX_NAME_LENGTH]; + bool any = false; + + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientInGame(i) && !IsFakeClient(i)) + { + any = true; + IntToString(GetClientUserId(i), info, sizeof(info)); + GetClientName(i, display, sizeof(display)); + AddMenuItem(menu, info, display); + } + } + + if(!any) + { + AddMenuItem(menu, "", "No players connected", ITEMDRAW_DISABLED); + } + + SetMenuExitBackButton(menu, true); + SetMenuExitButton(menu, true); + DisplayMenu(menu, client, MENU_TIME_FOREVER); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public int RemoveLeaderMenu_Handler(Handle menu, MenuAction action, int client, int position) +{ + if(action == MenuAction_Select) + { + if(!CheckCommandAccess(client, "", ADMFLAG_RCON, false)) + { + PrintToChat(client, "[SM] You no longer have access to this."); + return 0; + } + + char info[12]; + GetMenuItem(menu, position, info, sizeof(info)); + + int target = GetClientOfUserId(StringToInt(info)); + if(target == 0) + { + PrintToChat(client, "[SM] That player is no longer available."); + } + else + { + RemoveLeaderFromFile(client, target); + } + + LeaderMenu(client); + } + else if(action == MenuAction_End) + { + delete menu; + } + else if(action == MenuAction_Cancel && position == MenuCancel_ExitBack) + { + LeaderMenu(client); + } + + return 0; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: Appends a targets SteamID2 to the leaders file with their name as a comment +//---------------------------------------------------------------------------------------------------- +public void AddLeaderToFile(int admin, int target) +{ + char sAuth[64], sName[MAX_NAME_LENGTH]; + if(!GetClientAuthId(target, AuthId_Steam2, sAuth, sizeof(sAuth))) + { + PrintToChat(admin, "[SM] Could not resolve a SteamID for that player yet, try again in a moment."); + return; + } + GetClientName(target, sName, sizeof(sName)); + + if(IsPossibleLeader(target)) + { + PrintToChat(admin, "[SM] %N is already in the leaders file.", target); + return; + } + + File fFile = OpenFile(g_sDataFile, "a"); + if(!fFile) + { + PrintToChat(admin, "[SM] Failed to open the leaders file for writing."); + return; + } + + fFile.WriteLine("\"%s\" //%s", sAuth, sName); + fFile.Close(); + + UpdateLeaders(); + + PrintToChatAll("[SM] %N added %N to the leaders list.", admin, target); + LogAction(admin, target, "\"%L\" added \"%L\" to the leaders file", admin, target); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: Removes a targets SteamID2 line from the leaders file, if present +//---------------------------------------------------------------------------------------------------- +public void RemoveLeaderFromFile(int admin, int target) +{ + char sAuth[64]; + if(!GetClientAuthId(target, AuthId_Steam2, sAuth, sizeof(sAuth))) + { + PrintToChat(admin, "[SM] Could not resolve a SteamID for that player yet, try again in a moment."); + return; + } + + File fRead = OpenFile(g_sDataFile, "rt"); + if(!fRead) + { + PrintToChat(admin, "[SM] Failed to open the leaders file for reading."); + return; + } + + ArrayList lines = new ArrayList(ByteCountToCells(255)); + char line[255]; + bool found = false; + + while(!fRead.EndOfFile() && fRead.ReadLine(line, sizeof(line))) + { + // Only skip the first line that actually contains this SteamID (inside the quotes) + if(!found && StrContains(line, sAuth) != -1) + { + found = true; + continue; + } + lines.PushString(line); + } + fRead.Close(); + + if(!found) + { + delete lines; + PrintToChat(admin, "[SM] %N was not found in the leaders file.", target); + return; + } + + File fWrite = OpenFile(g_sDataFile, "wt"); + if(!fWrite) + { + delete lines; + PrintToChat(admin, "[SM] Failed to open the leaders file for writing."); + return; + } + + int count = lines.Length; + for(int i = 0; i < count; i++) + { + lines.GetString(i, line, sizeof(line)); + fWrite.WriteLine(line); + } + fWrite.Close(); + delete lines; + + UpdateLeaders(); + + PrintToChatAll("[SM] %N removed %N from the leaders list.", admin, target); + LogAction(admin, target, "\"%L\" removed \"%L\" from the leaders file", admin, target); + + // If the person removed is the current leader, kick them out of the role too + if(target == leaderClient) + { + RemoveLeader(target); + PrintToChatAll("[SM] %N is no longer a valid leader and has been removed from the leader role.", target); + } } //---------------------------------------------------------------------------------------------------- @@ -1191,6 +1468,7 @@ public int SpriteMenu_Handler(Handle menu, MenuAction action, int client, int po LeaderMenu(client); } } + return 0; } //---------------------------------------------------------------------------------------------------- @@ -1320,6 +1598,7 @@ public int PingMenu_Handler(Handle menu, MenuAction action, int client, int posi LeaderMenu(client); } } + return 0; } //---------------------------------------------------------------------------------------------------- @@ -1353,6 +1632,7 @@ public Action Event_PlayerDeath(Handle event, char[] name, bool dontBroadcast) PrintToChatAll("[SM] The leader has died!"); RemoveLeader(client); } + return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- @@ -1413,6 +1693,7 @@ public Action Event_RoundEnd(Handle event, char[] name, bool dontBroadcast) pingEntity1 = -1; pingEntity2 = -1; pingEntity3 = -1; + return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- @@ -1463,6 +1744,7 @@ public int Native_CurrentLeader(Handle plugin, int numParams) public int Native_SetLeader(Handle plugin, int numParams) { SetLeader(GetNativeCell(1)); + return 0; } //---------------------------------------------------------------------------------------------------- // Purpose: