Use auth strings when banning from menu

When an admin initiates a ban from a BaseBans GUI menu, track players by
their AuthId (SteamID) instead of userid, so that the admin is able to
target players who disconnect after that menu was constructed.

If the target player is still connected, use their userid to ban the
same as before this commit.

If the target has disconnected, write a ban using their stored AuthId
value, as with "sm_addban".

This commit also revertss the `(admin==0)` check from PrepareBan that
was mistakenly added by bf7212889b,
because it would prevent banning from server/RCON (client index 0).
This commit is contained in:
Rain 2023-10-15 19:56:51 +03:00
parent bf7212889b
commit f9ec38103a
No known key found for this signature in database
GPG Key ID: 83230CA2EA4B534E
2 changed files with 155 additions and 68 deletions

View File

@ -54,6 +54,7 @@ enum struct PlayerInfo {
int banTargetUserId; int banTargetUserId;
int banTime; int banTime;
int isWaitingForChatReason; int isWaitingForChatReason;
char banTargetAuthId[MAX_AUTHID_LENGTH];
} }
PlayerInfo playerinfo[MAXPLAYERS+1]; PlayerInfo playerinfo[MAXPLAYERS+1];
@ -386,7 +387,7 @@ public Action OnClientSayCommand(int client, const char[] command, const char[]
if(playerinfo[client].isWaitingForChatReason) if(playerinfo[client].isWaitingForChatReason)
{ {
playerinfo[client].isWaitingForChatReason = false; playerinfo[client].isWaitingForChatReason = false;
PrepareBan(client, playerinfo[client].banTargetUserId, playerinfo[client].banTime, sArgs); PrepareBan(client, playerinfo[client].banTargetUserId, playerinfo[client].banTargetAuthId, playerinfo[client].banTime, sArgs);
return Plugin_Stop; return Plugin_Stop;
} }

View File

@ -31,23 +31,18 @@
* Version: $Id$ * Version: $Id$
*/ */
void PrepareBan(int adminClient, int banTargetUserId, int time, const char[] reason) // Because GetTargetName will return either client name, or client authid,
// and we need to be able to fit whichever is larger to a buffer.
#if MAX_AUTHID_LENGTH > MAX_NAME_LENGTH
#define MAX_TARGETNAME_LENGTH MAX_AUTHID_LENGTH
#else
#define MAX_TARGETNAME_LENGTH MAX_NAME_LENGTH
#endif
void PrepareBan(int adminClient, int banTargetUserId, const char[] banTargetAuthId, int time, const char[] reason)
{ {
if (adminClient == 0) char name[MAX_TARGETNAME_LENGTH];
{ GetTargetName(banTargetUserId, banTargetAuthId, name, sizeof(name));
PrintToServer("[SM] %t", "Player no longer available");
return;
}
int target = GetClientOfUserId(banTargetUserId);
if (target == 0)
{
PrintToChat(adminClient, "[SM] %t", "Player no longer available");
return;
}
char name[MAX_NAME_LENGTH];
GetClientName(target, name, sizeof(name));
if (!time) if (!time)
{ {
@ -72,15 +67,30 @@ void PrepareBan(int adminClient, int banTargetUserId, int time, const char[] rea
} }
} }
LogAction(adminClient, target, "\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", adminClient, target, time, reason); int target = GetClientOfAuthId(banTargetAuthId);
// Ban & kick if target is connected, else record the ban with authid
if (reason[0] == '\0') if (target != 0)
{ {
BanClient(target, time, BANFLAG_AUTO, "Banned", "Banned", "sm_ban", adminClient); LogAction(adminClient, target, "\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", adminClient, target, time, reason);
BanClient(target, time, BANFLAG_AUTO,
(reason[0] == '\0') ? "Banned" : reason,
(reason[0] == '\0') ? "Banned" : reason,
"sm_ban", adminClient);
} }
else else
{ {
BanClient(target, time, BANFLAG_AUTO, reason, reason, "sm_ban", adminClient); LogAction(adminClient,
target,
"\"%L\" added ban (minutes \"%d\") (id \"%s\") (reason \"%s\")",
adminClient,
time,
banTargetAuthId,
reason);
BanIdentity(banTargetAuthId, time, BANFLAG_AUTHID,
(reason[0] == '\0') ? "Banned" : reason,
"sm_addban", adminClient);
} }
} }
@ -93,24 +103,20 @@ void DisplayBanTargetMenu(int client)
menu.SetTitle(title); menu.SetTitle(title);
menu.ExitBackButton = CheckCommandAccess(client, "sm_admin", ADMFLAG_GENERIC, false); menu.ExitBackButton = CheckCommandAccess(client, "sm_admin", ADMFLAG_GENERIC, false);
AddTargetsToMenu2(menu, client, COMMAND_FILTER_NO_BOTS|COMMAND_FILTER_CONNECTED); AddTargetsToMenuByAuthId(menu, client, COMMAND_FILTER_NO_BOTS|COMMAND_FILTER_CONNECTED, AuthId_Steam2);
menu.Display(client, MENU_TIME_FOREVER); menu.Display(client, MENU_TIME_FOREVER);
} }
void DisplayBanTimeMenu(int client) void DisplayBanTimeMenu(int client)
{ {
int target = GetClientOfUserId(playerinfo[client].banTargetUserId); char targetName[MAX_TARGETNAME_LENGTH];
if (target == 0) GetTargetName(playerinfo[client].banTargetUserId, playerinfo[client].banTargetAuthId, targetName, sizeof(targetName));
{
PrintToChat(client, "[SM] %t", "Player no longer available");
return;
}
Menu menu = new Menu(MenuHandler_BanTimeList); Menu menu = new Menu(MenuHandler_BanTimeList);
char title[100]; char title[100];
Format(title, sizeof(title), "%T: %N", "Ban player", client, target); Format(title, sizeof(title), "%T: %s", "Ban player", client, targetName);
menu.SetTitle(title); menu.SetTitle(title);
menu.ExitBackButton = true; menu.ExitBackButton = true;
@ -127,17 +133,13 @@ void DisplayBanTimeMenu(int client)
void DisplayBanReasonMenu(int client) void DisplayBanReasonMenu(int client)
{ {
int target = GetClientOfUserId(playerinfo[client].banTargetUserId); char name[MAX_TARGETNAME_LENGTH];
if (target == 0) GetTargetName(playerinfo[client].banTargetUserId, playerinfo[client].banTargetAuthId, name, sizeof(name));
{
PrintToChat(client, "[SM] %t", "Player no longer available");
return;
}
Menu menu = new Menu(MenuHandler_BanReasonList); Menu menu = new Menu(MenuHandler_BanReasonList);
char title[100]; char title[100];
Format(title, sizeof(title), "%T: %N", "Ban reason", client, target); Format(title, sizeof(title), "%T: %s", "Ban reason", client, name);
menu.SetTitle(title); menu.SetTitle(title);
menu.ExitBackButton = true; menu.ExitBackButton = true;
@ -210,10 +212,10 @@ public int MenuHandler_BanReasonList(Menu menu, MenuAction action, int param1, i
else else
{ {
char info[64]; char info[64];
menu.GetItem(param2, info, sizeof(info)); menu.GetItem(param2, info, sizeof(info));
PrepareBan(param1, playerinfo[param1].banTargetUserId, playerinfo[param1].banTime, info); PrepareBan(param1, playerinfo[param1].banTargetUserId, playerinfo[param1].banTargetAuthId, playerinfo[param1].banTime, info);
} }
} }
@ -235,25 +237,13 @@ public int MenuHandler_BanPlayerList(Menu menu, MenuAction action, int param1, i
} }
else if (action == MenuAction_Select) else if (action == MenuAction_Select)
{ {
char info[32], name[32]; char name[32];
int userid, target; menu.GetItem(param2, playerinfo[param1].banTargetAuthId, sizeof(PlayerInfo::banTargetAuthId), _, name, sizeof(name));
menu.GetItem(param2, info, sizeof(info), _, name, sizeof(name)); int target = GetClientOfAuthId(playerinfo[param1].banTargetAuthId);
userid = StringToInt(info); playerinfo[param1].banTargetUserId = (target == 0) ? 0 : GetClientUserId(target);
if ((target = GetClientOfUserId(userid)) == 0) DisplayBanTimeMenu(param1);
{
PrintToChat(param1, "[SM] %t", "Player no longer available");
}
else if (!CanUserTarget(param1, target))
{
PrintToChat(param1, "[SM] %t", "Unable to target");
}
else
{
playerinfo[param1].banTargetUserId = userid;
DisplayBanTimeMenu(param1);
}
} }
return 0; return 0;
@ -274,19 +264,12 @@ public int MenuHandler_BanTimeList(Menu menu, MenuAction action, int param1, int
} }
else if (action == MenuAction_Select) else if (action == MenuAction_Select)
{ {
if (GetClientOfUserId(playerinfo[param1].banTargetUserId) == 0) char info[32];
{
PrintToChat(param1, "[SM] %t", "Player no longer available");
}
else
{
char info[32];
menu.GetItem(param2, info, sizeof(info)); menu.GetItem(param2, info, sizeof(info));
playerinfo[param1].banTime = StringToInt(info); playerinfo[param1].banTime = StringToInt(info);
DisplayBanReasonMenu(param1); DisplayBanReasonMenu(param1);
}
} }
return 0; return 0;
@ -333,9 +316,112 @@ public Action Command_Ban(int client, int args)
} }
playerinfo[client].banTargetUserId = GetClientUserId(target); playerinfo[client].banTargetUserId = GetClientUserId(target);
GetClientAuthId(target, AuthId_Steam2, playerinfo[client].banTargetAuthId, sizeof(PlayerInfo::banTargetAuthId));
int time = StringToInt(s_time); int time = StringToInt(s_time);
PrepareBan(client, playerinfo[client].banTargetUserId, time, Arguments[len]); PrepareBan(client, playerinfo[client].banTargetUserId, playerinfo[client].banTargetAuthId, time, Arguments[len]);
return Plugin_Handled; return Plugin_Handled;
} }
int GetClientOfAuthId(const char[] authid, AuthIdType authIdType=AuthId_Steam2)
{
char compareId[MAX_AUTHID_LENGTH];
for (int client = 1; client <= MaxClients; client++)
{
if (!IsClientInGame(client) || !IsClientAuthorized(client))
{
continue;
}
if (!GetClientAuthId(client, authIdType, compareId, sizeof(compareId)))
{
continue;
}
if (StrEqual(compareId, authid))
{
return client;
}
}
return 0;
}
void GetTargetName(int userid, const char[] authid, char[] out, int maxlen)
{
int client = GetClientOfUserId(userid);
if (client)
{
Format(out, maxlen, "%N", client);
}
else
{
// if client was not in game, use their authid as the name instead
strcopy(out, maxlen, authid);
}
}
/**
* Adds targets to an admin menu.
*
* Each client is displayed as: name (authid)
* Each item contains the authid as a string for its info.
*
* @param menu Menu Handle.
* @param source_client Source client, or 0 to ignore immunity.
* @param flags COMMAND_FILTER flags from commandfilters.inc.
* @return Number of clients added.
*/
int AddTargetsToMenuByAuthId(Menu menu, int source_client, int flags, AuthIdType authIdType)
{
char authid[MAX_AUTHID_LENGTH];
char name[MAX_NAME_LENGTH];
char display[sizeof(name) + sizeof(authid) + 3];
int num_clients;
for (int i = 1; i <= MaxClients; i++)
{
if (!IsClientConnected(i) || IsClientInKickQueue(i))
{
continue;
}
if (((flags & COMMAND_FILTER_NO_BOTS) == COMMAND_FILTER_NO_BOTS)
&& IsFakeClient(i))
{
continue;
}
if (((flags & COMMAND_FILTER_CONNECTED) != COMMAND_FILTER_CONNECTED)
&& !IsClientInGame(i))
{
continue;
}
if (((flags & COMMAND_FILTER_ALIVE) == COMMAND_FILTER_ALIVE)
&& !IsPlayerAlive(i))
{
continue;
}
if (((flags & COMMAND_FILTER_DEAD) == COMMAND_FILTER_DEAD)
&& IsPlayerAlive(i))
{
continue;
}
if ((source_client && ((flags & COMMAND_FILTER_NO_IMMUNITY) != COMMAND_FILTER_NO_IMMUNITY))
&& !CanUserTarget(source_client, i))
{
continue;
}
GetClientAuthId(i, authIdType, authid, sizeof(authid));
GetClientName(i, name, sizeof(name));
Format(display, sizeof(display), "%s (%s)", name, authid);
menu.AddItem(authid, display);
num_clients++;
}
return num_clients;
}