diff --git a/src/d_clisrv.c b/src/d_clisrv.c index b6a46a8fd..cc87ff24b 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3625,6 +3625,9 @@ void D_ClientServerInit(void) RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer); RegisterNetXCmd(XD_REMOVEPLAYER, Got_RemovePlayer); RegisterNetXCmd(XD_ADDBOT, Got_AddBot); + RegisterNetXCmd(XD_SAY, Got_Saycmd); + RegisterNetXCmd(XD_REQSAY, Got_RequestSaycmd); + #ifdef DUMPCONSISTENCY CV_RegisterVar(&cv_dumpconsistency); #endif diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 0f351c201..44fc30368 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -65,6 +65,7 @@ #include "k_race.h" #include "g_party.h" #include "k_vote.h" +#include "hu_stuff.h" // HU_ flags #ifdef SRB2_CONFIG_ENABLE_WEBM_MOVIES #include "m_avrecorder.h" @@ -579,7 +580,6 @@ size_t schedule_len = 0; // Automation commands char *automate_commands[AEV__MAX]; - const char *automate_names[AEV__MAX] = { "RoundStart", // AEV_ROUNDSTART @@ -589,6 +589,8 @@ const char *automate_names[AEV__MAX] = UINT32 livestudioaudience_timer = 90; +static tic_t stop_spamming[MAXPLAYERS]; + /// \warning Keep this up-to-date if you add/remove/rename net text commands const char *netxcmdnames[MAXNETXCMD - 1] = { @@ -632,6 +634,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "AUTOMATE", // XD_AUTOMATE "REQMAPQUEUE", // XD_REQMAPQUEUE "MAPQUEUE", // XD_MAPQUEUE + "REQSAY", // XD_REQSAY }; // ========================================================================= @@ -3488,6 +3491,74 @@ static void Got_MapQueuecmd(UINT8 **cp, INT32 playernum) CONS_Printf("queuemap: A map was added to the round queue (pos. %u)\n", queueposition+1); } +void Got_RequestSaycmd(UINT8 **p, INT32 playernum) +{ + SINT8 target; + UINT8 flags; + const char *dispname; + char *msg; + boolean action = false; + char *ptr; + INT32 spam_eatmsg = 0; + + UINT8 *original = *p; + + // Only the server processes this message. + if (client) + return; + + CONS_Debug(DBG_NETPLAY,"Received REQSAY cmd from Player %d (%s)\n", playernum+1, player_names[playernum]); + + target = READSINT8(*p); + flags = READUINT8(*p); + msg = (char *)*p; + SKIPSTRINGL(*p, HU_MAXMSGLEN + 1); + + if ((cv_mute.value || flags & (HU_CSAY|HU_SHOUT)) && playernum != serverplayer && !(IsPlayerAdmin(playernum))) + { + CONS_Alert(CONS_WARNING, cv_mute.value ? + M_GetText("Illegal reqsay command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"), + player_names[playernum]); + if (server) + SendKick(playernum, KICK_MSG_CON_FAIL); + return; + } + + //check for invalid characters (0x80 or above) + { + size_t i; + const size_t j = strlen(msg); + for (i = 0; i < j; i++) + { + if (msg[i] & 0x80) + { + CONS_Alert(CONS_WARNING, M_GetText("Illegal reqsay command received from %s containing invalid characters\n"), player_names[playernum]); + if (server) + SendKick(playernum, KICK_MSG_CON_FAIL); + return; + } + } + } + + // before we do anything, let's verify the guy isn't spamming, get this easier on us. + + //if (stop_spamming[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY)) + if (stop_spamming[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & (HU_CSAY|HU_SHOUT))) + { + CONS_Debug(DBG_NETPLAY,"Received REQSAY cmd too quickly from Player %d (%s), assuming as spam and blocking message.\n", playernum+1, player_names[playernum]); + stop_spamming[playernum] = 4; + spam_eatmsg = 1; + } + else + stop_spamming[playernum] = 4; // you can hold off for 4 tics, can you? + + if (spam_eatmsg) + return; // don't proceed if we were supposed to eat the message. + + SendNetXCmd(XD_SAY, original, *p - original); +} + + static void Command_Pause(void) { UINT8 buf[2]; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 94883ce92..8e9d11d9f 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -181,6 +181,7 @@ typedef enum XD_AUTOMATE, // 36 XD_REQMAPQUEUE, // 37 XD_MAPQUEUE, // 38 + XD_REQSAY, // 39 MAXNETXCMD } netxcmd_t; @@ -288,6 +289,8 @@ void D_Cheat(INT32 playernum, INT32 cheat, ...); // used for the player setup menu boolean CanChangeSkin(INT32 playernum); +void Got_RequestSaycmd(UINT8 **cp, INT32 playernum); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 5b028662d..33c824e79 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -65,12 +65,6 @@ #define HU_INPUTX 0 #define HU_INPUTY 0 -typedef enum -{ - HU_SHOUT = 1, // Shout message - HU_CSAY = 1<<1, // Middle-of-screen server message -} sayflags_t; - //------------------------------------------- // heads up font //------------------------------------------- @@ -180,7 +174,6 @@ static void Command_Sayto_f(void); static void Command_Sayteam_f(void); static void Command_CSay_f(void); static void Command_Shout(void); -static void Got_Saycmd(UINT8 **p, INT32 playernum); void HU_LoadGraphics(void) { @@ -226,7 +219,6 @@ void HU_Init(void) COM_AddCommand("sayteam", Command_Sayteam_f); COM_AddCommand("csay", Command_CSay_f); COM_AddCommand("shout", Command_Shout); - RegisterNetXCmd(XD_SAY, Got_Saycmd); // only allocate if not present, to save us a lot of headache if (missingpat == NULL) @@ -695,7 +687,7 @@ static tic_t stop_spamming[MAXPLAYERS]; * \sa DoSayCommand * \author Graue */ -static void Got_Saycmd(UINT8 **p, INT32 playernum) +void Got_Saycmd(UINT8 **p, INT32 playernum) { SINT8 target; UINT8 flags; @@ -707,57 +699,9 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) CONS_Debug(DBG_NETPLAY,"Received SAY cmd from Player %d (%s)\n", playernum+1, player_names[playernum]); - target = READSINT8(*p); - flags = READUINT8(*p); - msg = (char *)*p; - SKIPSTRINGL(*p, HU_MAXMSGLEN + 1); - - if ((cv_mute.value || flags & (HU_CSAY|HU_SHOUT)) && playernum != serverplayer && !(IsPlayerAdmin(playernum))) - { - CONS_Alert(CONS_WARNING, cv_mute.value ? - M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"), - player_names[playernum]); - if (server) - SendKick(playernum, KICK_MSG_CON_FAIL); - return; - } - - //check for invalid characters (0x80 or above) - { - size_t i; - const size_t j = strlen(msg); - for (i = 0; i < j; i++) - { - if (msg[i] & 0x80) - { - CONS_Alert(CONS_WARNING, M_GetText("Illegal say command received from %s containing invalid characters\n"), player_names[playernum]); - if (server) - SendKick(playernum, KICK_MSG_CON_FAIL); - return; - } - } - } - - // before we do anything, let's verify the guy isn't spamming, get this easier on us. - - //if (stop_spamming[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY)) - if (stop_spamming[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & (HU_CSAY|HU_SHOUT))) - { - CONS_Debug(DBG_NETPLAY,"Received SAY cmd too quickly from Player %d (%s), assuming as spam and blocking message.\n", playernum+1, player_names[playernum]); - stop_spamming[playernum] = 4; - spam_eatmsg = 1; - } - else - stop_spamming[playernum] = 4; // you can hold off for 4 tics, can you? - - // run the lua hook even if we were supposed to eat the msg, netgame consistency goes first. - if (LUA_HookPlayerMsg(playernum, target, flags, msg, spam_eatmsg)) return; - if (spam_eatmsg) - return; // don't proceed if we were supposed to eat the message. - // If it's a CSAY, just CECHO and be done with it. if (flags & HU_CSAY) { @@ -1161,7 +1105,7 @@ static void HU_sendChatMessage(void) buf[0] = target; buf[1] = ((server || IsPlayerAdmin(consoleplayer)) && cv_autoshout.value) ? HU_SHOUT : 0; // flags - SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); + SendNetXCmd(XD_REQSAY, buf, 2 + strlen(&buf[2]) + 1); } } diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 08b997bdc..ca0b265d7 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -162,6 +162,14 @@ void HU_ClearTitlecardCEcho(void); extern UINT32 hu_demotime; extern UINT32 hu_demolap; +void Got_Saycmd(UINT8 **p, INT32 playernum); + +typedef enum +{ + HU_SHOUT = 1, // Shout message + HU_CSAY = 1<<1, // Middle-of-screen server message +} sayflags_t; + #ifdef __cplusplus } // extern "C" #endif