From ff05cf7ceb252e22eb34a8c2545cec45be0e3204 Mon Sep 17 00:00:00 2001
From: Daniel Simoes <slicer@rq3.com>
Date: Sat, 11 May 2002 16:22:38 +0000
Subject: [PATCH] Added a Repeat Flood Protection to Radio

---
 reaction/game/g_local.h    | 15 ++++++++++++++
 reaction/game/g_main.c     | 12 ++++++++++++
 reaction/game/g_teamplay.c | 40 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+)

diff --git a/reaction/game/g_local.h b/reaction/game/g_local.h
index 1b3ef940..dba9dd42 100644
--- a/reaction/game/g_local.h
+++ b/reaction/game/g_local.h
@@ -5,6 +5,9 @@
 //-----------------------------------------------------------------------------
 //
 // $Log$
+// Revision 1.79  2002/05/11 16:22:38  slicer
+// Added a Repeat Flood Protection to Radio
+//
 // Revision 1.78  2002/05/10 04:06:27  jbravo
 // Added Ignore
 //
@@ -576,6 +579,13 @@ struct gclient_s {
 	int			team_wounds_before;
 	int			ff_warning;
 	int			team_kills;
+
+	//Slicer Flood protect:
+	
+	float	rd_mute;		//Time to be muted
+	int		rd_lastRadio;	//Code of the last radio used
+	int		rd_repCount;	//Counter for the number of repeated radio msgs
+	float	rd_repTime;		//The time for the last repeated radio msg
 };
 
 // JBravo: for model loading
@@ -1170,6 +1180,11 @@ extern vmCvar_t g_RQ3_IniFile;
 extern vmCvar_t g_RQ3_ValidIniFile;
 extern vmCvar_t g_RQ3_NextMapID;
 
+//Slicer: Radio flood protect
+extern vmCvar_t		g_RQ3_radioRepeat;
+extern vmCvar_t		g_RQ3_radioRepeatTime;
+extern vmCvar_t		g_RQ3_radioBan;
+
 void	trap_Printf( const char *fmt );
 void	trap_Error( const char *fmt );
 int		trap_Milliseconds( void );
diff --git a/reaction/game/g_main.c b/reaction/game/g_main.c
index 00a2017a..08c43b5d 100644
--- a/reaction/game/g_main.c
+++ b/reaction/game/g_main.c
@@ -5,6 +5,9 @@
 //-----------------------------------------------------------------------------
 //
 // $Log$
+// Revision 1.56  2002/05/11 16:22:38  slicer
+// Added a Repeat Flood Protection to Radio
+//
 // Revision 1.55  2002/05/09 20:58:30  jbravo
 // New Obit system and a warning cleanup in zcam
 //
@@ -250,6 +253,11 @@ vmCvar_t	g_RQ3_IniFile;
 vmCvar_t	g_RQ3_ValidIniFile;
 vmCvar_t	g_RQ3_NextMapID;
 
+//Slicer Radio radio flood protect
+vmCvar_t		g_RQ3_radioRepeat;
+vmCvar_t		g_RQ3_radioRepeatTime;
+vmCvar_t		g_RQ3_radioBan;
+
  
 #ifdef MISSIONPACK
 vmCvar_t	g_obeliskHealth;
@@ -357,6 +365,10 @@ static cvarTable_t		gameCvarTable[] = {
 	{ &g_rankings, "g_rankings", "0", 0, 0, qfalse},
 	//Slicer: Matchmode
 	{ &g_RQ3_matchmode, "g_RQ3_matchmode", "0", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH, 0, qfalse  },
+	//Slicer: radio protect
+	{ &g_RQ3_radioRepeat, "g_RQ3_radioRepeat", "2", 0 , 0, qfalse  },
+	{ &g_RQ3_radioRepeatTime, "g_RQ3_radioRepeat", "1", 0 , 0, qfalse  },
+	{ &g_RQ3_radioBan, "g_RQ3_radioBan", "10", 0 , 0, qfalse  },
 	//Blaze: Reaction stuff
 	// Elder: these are explicit values set every time the game initializes
 	{ &g_RQ3_ejectBlood, "g_RQ3_ejectBlood", "0", CVAR_ARCHIVE | CVAR_NORESTART,0, qfalse},
diff --git a/reaction/game/g_teamplay.c b/reaction/game/g_teamplay.c
index d7c1707e..85856613 100644
--- a/reaction/game/g_teamplay.c
+++ b/reaction/game/g_teamplay.c
@@ -5,6 +5,9 @@
 //-----------------------------------------------------------------------------
 //
 // $Log$
+// Revision 1.87  2002/05/11 16:22:38  slicer
+// Added a Repeat Flood Protection to Radio
+//
 // Revision 1.86  2002/05/11 14:22:06  makro
 // Func_statics now reset at the beginning of each round
 //
@@ -1198,6 +1201,38 @@ radio_msg_t female_radio_msgs[] = {
 	{ "click", 6 },
 	{ "END", 0 }, // end of list delimiter
 };
+//Slicer Adding Flood Protection Functions
+qboolean CheckForRepeat (gentity_t *ent, int radioCode) {
+	int lastRadioCode;
+	//If he's muted..
+  if (ent->client->rd_mute) {
+      if (ent->client->rd_mute > level.time) // Still muted..
+		return qfalse;
+      else
+		ent->client->rd_mute = 0; // No longer muted..
+   }
+  lastRadioCode = ent->client->rd_lastRadio;
+
+  if (lastRadioCode == radioCode) { //He's trying to repeat it..
+	  if ((level.time - ent->client->rd_repTime ) < g_RQ3_radioRepeatTime.integer*1000) {
+		  if (++ent->client->rd_repCount >= g_RQ3_radioRepeat.integer) { //Busted
+			 if (ent->client->rd_repCount == g_RQ3_radioRepeat.integer) {
+				 trap_SendServerCommand(ent-g_entities, va("print \"Radio Repeat Flood Detected, you are silenced for %i secs\n\"",
+			      (int) g_RQ3_radioBan.integer));
+				 ent->client->rd_mute = level.time + g_RQ3_radioBan.integer*1000;
+			 }
+	      return qfalse;
+		  }
+	  }
+	  else
+		  ent->client->rd_repCount = 0;
+
+	  ent->client->rd_repTime = level.time;
+  }
+  ent->client->rd_lastRadio = radioCode;
+  ent->client->rd_repTime = level.time;
+  return qtrue;
+}
 
 void RQ3_Cmd_Radio_f(gentity_t *ent)
 {
@@ -1225,6 +1260,9 @@ void RQ3_Cmd_Radio_f(gentity_t *ent)
 
 	while (Q_stricmp(radio_msgs[x].msg, "END")) {
 		if (!Q_stricmp(radio_msgs[x].msg, msg)) {
+			//Slicer Checking for repeat flood
+			if(!CheckForRepeat(ent,x))
+				return;
 			if (!Q_stricmp(radio_msgs[x].msg, "enemyd")) {
 				kills = ent->client->killStreak;
 				ent->client->killStreak = 0;
@@ -1256,6 +1294,8 @@ void RQ3_Cmd_Radio_f(gentity_t *ent)
 							ent->client->radioGender));
 				}
 			}
+			//Slicer lets return to stop the while if found..
+			return;
 		}
 		x++;
 	}