diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1e31de51..65f3e8b7 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2637,40 +2637,27 @@ static void CL_ConnectToServer(void) } #ifndef NONET -typedef struct banreason_s -{ - char *reason; - struct banreason_s *prev; //-1 - struct banreason_s *next; //+1 -} banreason_t; - -static banreason_t *reasontail = NULL; //last entry, use prev -static banreason_t *reasonhead = NULL; //1st entry, use next - static void Command_ShowBan(void) //Print out ban list { size_t i; - const char *address, *mask; - banreason_t *reasonlist = reasonhead; + const char *address, *mask, *reason; if (I_GetBanAddress) CONS_Printf(M_GetText("Ban List:\n")); else return; - for (i = 0;(address = I_GetBanAddress(i)) != NULL;i++) + for (i = 0; (address = I_GetBanAddress(i)) != NULL; i++) { if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL) CONS_Printf("%s: %s ", sizeu1(i+1), address); else CONS_Printf("%s: %s/%s ", sizeu1(i+1), address, mask); - if (reasonlist && reasonlist->reason) - CONS_Printf("(%s)\n", reasonlist->reason); + if (I_GetBanReason && (reason = I_GetBanReason(i)) != NULL) + CONS_Printf("(%s)\n", reason); else CONS_Printf("\n"); - - if (reasonlist) reasonlist = reasonlist->next; } if (i == 0 && !address) @@ -2681,13 +2668,10 @@ void D_SaveBan(void) { FILE *f; size_t i; - banreason_t *reasonlist = reasonhead; - const char *address, *mask; + const char *address, *mask, *reason; + const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt"); - if (!reasonhead) - return; - - f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "w"); + f = fopen(path, "w"); if (!f) { @@ -2695,66 +2679,36 @@ void D_SaveBan(void) return; } - for (i = 0;(address = I_GetBanAddress(i)) != NULL;i++) + for (i = 0; (address = I_GetBanAddress(i)) != NULL; i++) { if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL) fprintf(f, "%s 0", address); else fprintf(f, "%s %s", address, mask); - if (reasonlist && reasonlist->reason) - fprintf(f, " %s\n", reasonlist->reason); + if (I_GetBanReason && (reason = I_GetBanReason(i)) != NULL) + fprintf(f, " %s\n", reason); else - fprintf(f, " %s\n", "NA"); - - if (reasonlist) reasonlist = reasonlist->next; + fprintf(f, " %s\n", "No reason given"); } fclose(f); } -static void Ban_Add(const char *reason) -{ - banreason_t *reasonlist = malloc(sizeof(*reasonlist)); - - if (!reasonlist) - return; - if (!reason) - reason = "NA"; - - reasonlist->next = NULL; - reasonlist->reason = Z_StrDup(reason); - if ((reasonlist->prev = reasontail) == NULL) - reasonhead = reasonlist; - else - reasontail->next = reasonlist; - reasontail = reasonlist; -} - static void Command_ClearBans(void) { - banreason_t *temp; - if (!I_ClearBans) return; I_ClearBans(); D_SaveBan(); - reasontail = NULL; - while (reasonhead) - { - temp = reasonhead->next; - Z_Free(reasonhead->reason); - free(reasonhead); - reasonhead = temp; - } } static void Ban_Load_File(boolean warning) { FILE *f; size_t i; - const char *address, *mask; + const char *address, *mask, *reason; char buffer[MAX_WADPATH]; f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r"); @@ -2766,22 +2720,17 @@ static void Ban_Load_File(boolean warning) return; } - if (I_ClearBans) - Command_ClearBans(); - else - { - fclose(f); - return; - } + I_ClearBans(); for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++) { address = strtok(buffer, " \t\r\n"); mask = strtok(NULL, " \t\r\n"); + reason = strtok(NULL, "\r\n"); I_SetBanAddress(address, mask); - - Ban_Add(strtok(NULL, "\r\n")); + if (I_SetBanReason) + I_SetBanReason(reason); } fclose(f); @@ -3140,54 +3089,37 @@ static void Command_Ban(void) XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH]; UINT8 *p = buf; const SINT8 pn = nametonum(COM_Argv(1)); - const INT32 node = playernode[(INT32)pn]; if (pn == -1 || pn == 0) return; WRITEUINT8(p, pn); - if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now + if (COM_Argc() == 2) { - CONS_Alert(CONS_WARNING, M_GetText("Ban failed. Invalid node?\n")); - WRITEUINT8(p, KICK_MSG_GO_AWAY); + WRITEUINT8(p, KICK_MSG_BANNED); SendNetXCmd(XD_KICK, &buf, 2); } else { - if (server) // only the server is allowed to do this right now + size_t i, j = COM_Argc(); + char message[MAX_REASONLENGTH]; + + //Steal from the motd code so you don't have to put the reason in quotes. + strlcpy(message, COM_Argv(2), sizeof message); + for (i = 3; i < j; i++) { - Ban_Add(COM_Argv(2)); - D_SaveBan(); // save the ban list + strlcat(message, " ", sizeof message); + strlcat(message, COM_Argv(i), sizeof message); } - if (COM_Argc() == 2) - { - WRITEUINT8(p, KICK_MSG_BANNED); - SendNetXCmd(XD_KICK, &buf, 2); - } - else - { - size_t i, j = COM_Argc(); - char message[MAX_REASONLENGTH]; - - //Steal from the motd code so you don't have to put the reason in quotes. - strlcpy(message, COM_Argv(2), sizeof message); - for (i = 3; i < j; i++) - { - strlcat(message, " ", sizeof message); - strlcat(message, COM_Argv(i), sizeof message); - } - - WRITEUINT8(p, KICK_MSG_CUSTOM_BAN); - WRITESTRINGN(p, message, MAX_REASONLENGTH); - SendNetXCmd(XD_KICK, &buf, p - buf); - } + WRITEUINT8(p, KICK_MSG_CUSTOM_BAN); + WRITESTRINGN(p, message, MAX_REASONLENGTH); + SendNetXCmd(XD_KICK, &buf, p - buf); } } else CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); - } static void Command_BanIP(void) @@ -3208,7 +3140,6 @@ static void Command_BanIP(void) else reason = COM_Argv(2); - if (I_SetBanAddress && I_SetBanAddress(address, NULL)) { if (reason) @@ -3216,7 +3147,8 @@ static void Command_BanIP(void) else CONS_Printf("Banned IP address %s\n", address); - Ban_Add(reason); + if (I_SetBanReason) + I_SetBanReason(reason); D_SaveBan(); } else @@ -3357,16 +3289,21 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) //CONS_Printf("\x82%s ", player_names[pnum]); - // If a verified admin banned someone, the server needs to know about it. - // If the playernum isn't zero (the server) then the server needs to record the ban. - if (server && playernum && (msg == KICK_MSG_BANNED || msg == KICK_MSG_CUSTOM_BAN)) + // Save bans here. Used to be split between here and the actual command, depending on + // whenever the server did it or a remote admin did it, but it's simply more convenient + // to keep it all in one place. + if (server && (msg == KICK_MSG_BANNED || msg == KICK_MSG_CUSTOM_BAN)) { if (I_Ban && !I_Ban(playernode[(INT32)pnum])) - CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n")); -#ifndef NONET + { + CONS_Alert(CONS_WARNING, M_GetText("Ban failed. Invalid node?\n")); + } else - Ban_Add(reason); -#endif + { + if (I_SetBanReason) + I_SetBanReason(reason); + D_SaveBan(); + } } if (msg == KICK_MSG_PLAYER_QUIT) diff --git a/src/d_net.c b/src/d_net.c index d974d6cf..b28aab7a 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -79,7 +79,9 @@ void (*I_ClearBans)(void) = NULL; const char *(*I_GetNodeAddress) (INT32 node) = NULL; const char *(*I_GetBanAddress) (size_t ban) = NULL; const char *(*I_GetBanMask) (size_t ban) = NULL; +const char *(*I_GetBanReason) (size_t ban) = NULL; boolean (*I_SetBanAddress) (const char *address, const char *mask) = NULL; +boolean (*I_SetBanReason) (const char *reason) = NULL; boolean *bannednode = NULL; diff --git a/src/i_net.h b/src/i_net.h index 0e17077b..3608d81b 100644 --- a/src/i_net.h +++ b/src/i_net.h @@ -145,7 +145,9 @@ extern void (*I_ClearBans)(void); extern const char *(*I_GetNodeAddress) (INT32 node); extern const char *(*I_GetBanAddress) (size_t ban); extern const char *(*I_GetBanMask) (size_t ban); +extern const char *(*I_GetBanReason) (size_t ban); extern boolean (*I_SetBanAddress) (const char *address,const char *mask); +extern boolean (*I_SetBanReason) (const char *reason); extern boolean *bannednode; /// \brief Called by D_SRB2Main to be defined by extern network driver diff --git a/src/i_tcp.c b/src/i_tcp.c index d4bf5b87..75e3aaa6 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -235,6 +235,7 @@ typedef struct { mysockaddr_t address; UINT8 mask; + char *reason; // TODO: timestamp, for tempbans! } banned_t; @@ -498,6 +499,16 @@ static const char *SOCK_GetBanMask(size_t ban) return NULL; } +static const char *SOCK_GetBanReason(size_t ban) +{ +#ifdef NONET + (void)ban; + return NULL; +#else + return banned[ban].reason; +#endif +} + #ifndef NONET static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) { @@ -1521,6 +1532,23 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask) #endif } +static boolean SOCK_SetBanReason(const char *reason) +{ +#ifdef NONET + (void)reason; + return false; +#else + + if (!reason) + { + reason = "No reason given"; + } + + banned[numbans - 1].reason = Z_StrDup(reason); + return true; +#endif +} + static void SOCK_ClearBans(void) { numbans = 0; @@ -1617,7 +1645,9 @@ boolean I_InitTcpNetwork(void) I_GetNodeAddress = SOCK_GetNodeAddress; I_GetBanAddress = SOCK_GetBanAddress; I_GetBanMask = SOCK_GetBanMask; + I_GetBanReason = SOCK_GetBanReason; I_SetBanAddress = SOCK_SetBanAddress; + I_SetBanReason = SOCK_SetBanReason; bannednode = SOCK_bannednode; return ret;