mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Add optional reason to kick/ban commands
And enhance `SV_IsBanned` to return ban reason and update `SV_DirectConnect` to display it
This commit is contained in:
parent
1e2a331518
commit
f164e889cc
2 changed files with 205 additions and 44 deletions
|
@ -342,6 +342,7 @@ Kick a user off of the server FIXME: move to game
|
|||
static void SV_Kick_f( void ) {
|
||||
client_t *cl;
|
||||
int i;
|
||||
char *reason = NULL;
|
||||
|
||||
// make sure server is running
|
||||
if ( !com_sv_running->integer ) {
|
||||
|
@ -349,11 +350,16 @@ static void SV_Kick_f( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( Cmd_Argc() != 2 ) {
|
||||
Com_Printf ("Usage: kick <player name>\nkick all = kick everyone\nkick allbots = kick all bots\n");
|
||||
if ( Cmd_Argc() < 2 ) {
|
||||
Com_Printf ("Usage: kick <player name> [reason]\nkick all = kick everyone\nkick allbots = kick all bots\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if there's a reason provided
|
||||
if ( Cmd_Argc() >= 3 ) {
|
||||
reason = Cmd_ArgsFrom(2);
|
||||
}
|
||||
|
||||
cl = SV_GetPlayerByHandle();
|
||||
if ( !cl ) {
|
||||
if ( !Q_stricmp(Cmd_Argv(1), "all") ) {
|
||||
|
@ -387,7 +393,25 @@ static void SV_Kick_f( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Check if there's a reason provided
|
||||
if ( reason ) {
|
||||
// Send the kick message to the client
|
||||
SV_NET_OutOfBandPrint(&svs.netprofile, cl->netchan.remoteAddress, "droperror\nKicked from server for:\n%s", reason);
|
||||
|
||||
// Print the kick to all clients
|
||||
SV_SendServerCommand(NULL, "print \"" HUD_MESSAGE_WHITE "%s was kicked for %s\n\"", cl->name, reason);
|
||||
|
||||
SV_DropClient( cl, va("was kicked for %s", reason) );
|
||||
} else {
|
||||
// Send the kick message to the client
|
||||
SV_NET_OutOfBandPrint(&svs.netprofile, cl->netchan.remoteAddress, "droperror\nKicked from server");
|
||||
|
||||
// Print the kick to all clients
|
||||
SV_SendServerCommand( NULL, "print \"" HUD_MESSAGE_WHITE "%s was kicked\n\"", cl->name );
|
||||
|
||||
SV_DropClient( cl, "was kicked" );
|
||||
}
|
||||
|
||||
cl->lastPacketTime = svs.time; // in case there is a funny zombie
|
||||
}
|
||||
/*
|
||||
|
@ -425,11 +449,12 @@ static void SV_KickAll_f( void ) {
|
|||
==================
|
||||
SV_KickNum_f
|
||||
|
||||
Kick a user off of the server
|
||||
Kick a user off of the server, optionally with a reason
|
||||
==================
|
||||
*/
|
||||
static void SV_KickNum_f( void ) {
|
||||
client_t *cl;
|
||||
char *reason = NULL;
|
||||
|
||||
// make sure server is running
|
||||
if ( !com_sv_running->integer ) {
|
||||
|
@ -437,8 +462,8 @@ static void SV_KickNum_f( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( Cmd_Argc() != 2 ) {
|
||||
Com_Printf ("Usage: %s <client number>\n", Cmd_Argv(0));
|
||||
if ( Cmd_Argc() < 2 ) {
|
||||
Com_Printf ("Usage: %s <client number> [reason]\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -451,7 +476,30 @@ static void SV_KickNum_f( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Check if there's a reason provided
|
||||
if ( Cmd_Argc() >= 3 ) {
|
||||
reason = Cmd_ArgsFrom(2);
|
||||
}
|
||||
|
||||
// Check if there's a reason provided
|
||||
if ( reason ) {
|
||||
// Send the kick message to the client
|
||||
SV_NET_OutOfBandPrint(&svs.netprofile, cl->netchan.remoteAddress, "droperror\nKicked from server for:\n%s", reason);
|
||||
|
||||
// Print the kick to all clients
|
||||
SV_SendServerCommand(NULL, "print \"" HUD_MESSAGE_WHITE "%s was kicked for %s\n\"", cl->name, reason);
|
||||
|
||||
SV_DropClient( cl, va("was kicked for %s", reason) );
|
||||
} else {
|
||||
// Send the kick message to the client
|
||||
SV_NET_OutOfBandPrint(&svs.netprofile, cl->netchan.remoteAddress, "droperror\nKicked from server");
|
||||
|
||||
// Print the kick to all clients
|
||||
SV_SendServerCommand( NULL, "print \"" HUD_MESSAGE_WHITE "%s was kicked\n\"", cl->name );
|
||||
|
||||
SV_DropClient( cl, "was kicked" );
|
||||
}
|
||||
|
||||
cl->lastPacketTime = svs.time; // in case there is a funny zombie
|
||||
}
|
||||
|
||||
|
@ -580,7 +628,7 @@ static void SV_RehashBans_f(void)
|
|||
{
|
||||
int index, filelen;
|
||||
fileHandle_t readfrom;
|
||||
char *textbuf, *curpos, *maskpos, *newlinepos, *endpos;
|
||||
char *textbuf, *curpos, *maskpos, *newlinepos, *endpos, *reasonpos;
|
||||
char filepath[MAX_QPATH];
|
||||
|
||||
// make sure server is running
|
||||
|
@ -623,12 +671,29 @@ static void SV_RehashBans_f(void)
|
|||
maskpos++;
|
||||
|
||||
// find the end of the subnet specifier
|
||||
for(newlinepos = maskpos; newlinepos < endpos && *newlinepos != '\n'; newlinepos++);
|
||||
for(newlinepos = maskpos; newlinepos < endpos && *newlinepos != '\n' && *newlinepos != ':'; newlinepos++);
|
||||
|
||||
if(newlinepos >= endpos)
|
||||
break;
|
||||
|
||||
if(*newlinepos == ':') {
|
||||
// We have a reason
|
||||
*newlinepos = '\0';
|
||||
reasonpos = newlinepos + 1;
|
||||
|
||||
// Find the end of the reason string
|
||||
for(newlinepos = reasonpos; newlinepos < endpos && *newlinepos != '\n'; newlinepos++);
|
||||
|
||||
if(newlinepos >= endpos)
|
||||
break;
|
||||
|
||||
*newlinepos = '\0';
|
||||
Q_strncpyz(serverBans[index].reason, reasonpos, sizeof(serverBans[index].reason));
|
||||
} else {
|
||||
// No reason
|
||||
*newlinepos = '\0';
|
||||
serverBans[index].reason[0] = '\0';
|
||||
}
|
||||
|
||||
if(NET_StringToAdr(curpos + 2, &serverBans[index].ip, NA_UNSPEC))
|
||||
{
|
||||
|
@ -676,15 +741,21 @@ static void SV_WriteBans(void)
|
|||
|
||||
if((writeto = FS_SV_FOpenFileWrite(filepath)))
|
||||
{
|
||||
char writebuf[128];
|
||||
char writebuf[128 + MAX_REASON_LENGTH];
|
||||
serverBan_t *curban;
|
||||
|
||||
for(index = 0; index < serverBansCount; index++)
|
||||
{
|
||||
curban = &serverBans[index];
|
||||
|
||||
if(curban->reason[0]) {
|
||||
Com_sprintf(writebuf, sizeof(writebuf), "%d %s %d:%s\n",
|
||||
curban->isexception, NET_AdrToString(curban->ip), curban->subnet, curban->reason);
|
||||
} else {
|
||||
Com_sprintf(writebuf, sizeof(writebuf), "%d %s %d\n",
|
||||
curban->isexception, NET_AdrToString(curban->ip), curban->subnet);
|
||||
}
|
||||
|
||||
FS_Write(writebuf, strlen(writebuf), writeto);
|
||||
}
|
||||
|
||||
|
@ -771,10 +842,13 @@ Ban a user from being able to play on this server based on his ip address.
|
|||
static void SV_AddBanToList(qboolean isexception)
|
||||
{
|
||||
char *banstring;
|
||||
char *reason = NULL;
|
||||
char addy2[NET_ADDRSTRMAXLEN];
|
||||
netadr_t ip;
|
||||
int index, argc, mask;
|
||||
serverBan_t *curban;
|
||||
client_t *cl = NULL;
|
||||
qboolean isdigit_only;
|
||||
|
||||
// make sure server is running
|
||||
if ( !com_sv_running->integer ) {
|
||||
|
@ -784,9 +858,9 @@ static void SV_AddBanToList(qboolean isexception)
|
|||
|
||||
argc = Cmd_Argc();
|
||||
|
||||
if(argc < 2 || argc > 3)
|
||||
if ( argc < 2 )
|
||||
{
|
||||
Com_Printf ("Usage: %s (ip[/subnet] | clientnum [subnet])\n", Cmd_Argv(0));
|
||||
Com_Printf ("Usage: %s (ip[/subnet] | clientnum [subnet] [reason])\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -798,9 +872,13 @@ static void SV_AddBanToList(qboolean isexception)
|
|||
|
||||
banstring = Cmd_Argv(1);
|
||||
|
||||
// Get optional reason - can be at arg 2 for IP bans or arg 3 for client num bans
|
||||
if(strchr(banstring, '.') || strchr(banstring, ':'))
|
||||
{
|
||||
// This is an ip address, not a client num.
|
||||
// IP address ban
|
||||
if(argc >= 3) {
|
||||
reason = Cmd_ArgsFrom(2);
|
||||
}
|
||||
|
||||
if(SV_ParseCIDRNotation(&ip, &mask, banstring))
|
||||
{
|
||||
|
@ -810,10 +888,7 @@ static void SV_AddBanToList(qboolean isexception)
|
|||
}
|
||||
else
|
||||
{
|
||||
client_t *cl;
|
||||
|
||||
// client num.
|
||||
|
||||
// client num ban
|
||||
cl = SV_GetPlayerByNum();
|
||||
|
||||
if ( !cl )
|
||||
|
@ -824,8 +899,19 @@ static void SV_AddBanToList(qboolean isexception)
|
|||
|
||||
ip = cl->netchan.remoteAddress;
|
||||
|
||||
if(argc == 3)
|
||||
if(argc >= 3)
|
||||
{
|
||||
// Check if second argument is all digits (CIDR notation)
|
||||
isdigit_only = qtrue;
|
||||
for(index = 0; Cmd_Argv(2)[index]; index++) {
|
||||
if(Cmd_Argv(2)[index] < '0' || Cmd_Argv(2)[index] > '9') {
|
||||
isdigit_only = qfalse;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(isdigit_only) {
|
||||
// Second arg is CIDR mask
|
||||
mask = atoi(Cmd_Argv(2));
|
||||
|
||||
if(ip.type == NA_IP)
|
||||
|
@ -838,10 +924,21 @@ static void SV_AddBanToList(qboolean isexception)
|
|||
if(mask < 1 || mask > 128)
|
||||
mask = 128;
|
||||
}
|
||||
|
||||
// Get optional reason after subnet
|
||||
if(argc >= 4) {
|
||||
reason = Cmd_ArgsFrom(3);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
// Second arg is start of reason
|
||||
reason = Cmd_ArgsFrom(2);
|
||||
mask = (ip.type == NA_IP6) ? 128 : 32;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mask = (ip.type == NA_IP6) ? 128 : 32;
|
||||
}
|
||||
}
|
||||
|
||||
if(ip.type != NA_IP && ip.type != NA_IP6)
|
||||
{
|
||||
|
@ -896,12 +993,47 @@ static void SV_AddBanToList(qboolean isexception)
|
|||
serverBans[serverBansCount].subnet = mask;
|
||||
serverBans[serverBansCount].isexception = isexception;
|
||||
|
||||
if(reason) {
|
||||
Q_strncpyz(serverBans[serverBansCount].reason, reason, sizeof(serverBans[serverBansCount].reason));
|
||||
} else {
|
||||
serverBans[serverBansCount].reason[0] = '\0';
|
||||
}
|
||||
|
||||
serverBansCount++;
|
||||
|
||||
SV_WriteBans();
|
||||
|
||||
Com_Printf("Added %s: %s/%d\n", isexception ? "ban exception" : "ban",
|
||||
NET_AdrToString(ip), mask);
|
||||
// Find and kick any connected clients matching the banned IP
|
||||
for(index = 0; index < sv_maxclients->integer; index++) {
|
||||
client_t *kickcl = &svs.clients[index];
|
||||
|
||||
if(!kickcl->state)
|
||||
continue;
|
||||
|
||||
if ( NET_CompareBaseAdrMask(kickcl->netchan.remoteAddress, ip, mask) ) {
|
||||
if ( reason ) {
|
||||
SV_NET_OutOfBandPrint(&svs.netprofile, kickcl->netchan.remoteAddress,
|
||||
"droperror\nYou have been banned from this server for:\n%s", reason);
|
||||
|
||||
SV_SendServerCommand(NULL, "print \"" HUD_MESSAGE_WHITE "%s was banned for %s\n\"", kickcl->name, reason);
|
||||
|
||||
SV_DropClient(kickcl, va("was banned for %s", reason));
|
||||
} else {
|
||||
SV_NET_OutOfBandPrint(&svs.netprofile, kickcl->netchan.remoteAddress,
|
||||
"droperror\nYou have been banned from this server");
|
||||
|
||||
SV_SendServerCommand(NULL, "print \"" HUD_MESSAGE_WHITE "%s was banned\n\"", kickcl->name);
|
||||
|
||||
SV_DropClient(kickcl, "was banned");
|
||||
}
|
||||
kickcl->lastPacketTime = svs.time;
|
||||
}
|
||||
}
|
||||
|
||||
Com_Printf("Added %s: %s/%d%s%s\n", isexception ? "ban exception" : "ban",
|
||||
NET_AdrToString(ip), mask,
|
||||
reason ? " with reason: " : "",
|
||||
reason ? reason : "");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1023,8 +1155,14 @@ static void SV_ListBans_f(void)
|
|||
{
|
||||
count++;
|
||||
|
||||
Com_Printf("Ban #%d: %s/%d\n", count,
|
||||
Com_Printf("Ban #%d: %s/%d", count,
|
||||
NET_AdrToString(ban->ip), ban->subnet);
|
||||
|
||||
if(ban->reason[0]) {
|
||||
Com_Printf(" - Reason: %s", ban->reason);
|
||||
}
|
||||
|
||||
Com_Printf("\n");
|
||||
}
|
||||
}
|
||||
// List all exceptions
|
||||
|
@ -1035,8 +1173,14 @@ static void SV_ListBans_f(void)
|
|||
{
|
||||
count++;
|
||||
|
||||
Com_Printf("Except #%d: %s/%d\n", count,
|
||||
Com_Printf("Except #%d: %s/%d", count,
|
||||
NET_AdrToString(ban->ip), ban->subnet);
|
||||
|
||||
if(ban->reason[0]) {
|
||||
Com_Printf(" - Reason: %s", ban->reason);
|
||||
}
|
||||
|
||||
Com_Printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1816,6 +1960,8 @@ void SV_AddOperatorCommands(void) {
|
|||
Cmd_AddCommand("kickall", SV_KickAll_f);
|
||||
Cmd_AddCommand("kicknum", SV_KickNum_f);
|
||||
Cmd_AddCommand("clientkick", SV_KickNum_f); // Legacy command
|
||||
Cmd_AddCommand("clientkickr", SV_KickNum_f); // Legacy command with reason
|
||||
Cmd_AddCommand("kickr", SV_KickNum_f); // Legacy command with reason
|
||||
Cmd_AddCommand("status", SV_Status_f);
|
||||
Cmd_AddCommand("serverinfo", SV_Serverinfo_f);
|
||||
Cmd_AddCommand("systeminfo", SV_Systeminfo_f);
|
||||
|
|
|
@ -196,18 +196,23 @@ void SV_AuthorizeIpPacket( netadr_t from ) {
|
|||
SV_IsBanned
|
||||
|
||||
Check whether a certain address is banned
|
||||
Returns the reason string if available
|
||||
==================
|
||||
*/
|
||||
|
||||
static qboolean SV_IsBanned(netadr_t *from, qboolean isexception)
|
||||
static qboolean SV_IsBanned(netadr_t *from, qboolean isexception, char *reason, int reason_size)
|
||||
{
|
||||
int index;
|
||||
serverBan_t *curban;
|
||||
|
||||
if(reason && reason_size > 0) {
|
||||
reason[0] = '\0';
|
||||
}
|
||||
|
||||
if(!isexception)
|
||||
{
|
||||
// If this is a query for a ban, first check whether the client is excepted
|
||||
if(SV_IsBanned(from, qtrue))
|
||||
if(SV_IsBanned(from, qtrue, NULL, 0))
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -217,10 +222,15 @@ static qboolean SV_IsBanned(netadr_t *from, qboolean isexception)
|
|||
|
||||
if(curban->isexception == isexception)
|
||||
{
|
||||
if(NET_CompareBaseAdrMask(curban->ip, *from, curban->subnet))
|
||||
if(NET_CompareBaseAdrMask(curban->ip, *from, curban->subnet)) {
|
||||
// Copy the ban reason if available and a buffer was provided
|
||||
if(reason && reason_size > 0 && curban->reason[0]) {
|
||||
Q_strncpyz(reason, curban->reason, reason_size);
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
@ -333,13 +343,18 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
qboolean compat = qfalse;
|
||||
#endif
|
||||
challenge_t* ch;
|
||||
char banReason[MAX_REASON_LENGTH];
|
||||
|
||||
Com_DPrintf ("SVC_DirectConnect ()\n");
|
||||
|
||||
// Check whether this client is banned.
|
||||
if(SV_IsBanned(&from, qfalse))
|
||||
if(SV_IsBanned(&from, qfalse, banReason, sizeof(banReason)))
|
||||
{
|
||||
if(banReason[0]) {
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "droperror\nYou are banned from this server.\nReason: %s\n", banReason);
|
||||
} else {
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "droperror\nYou are banned from this server.\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue