#include // Limits you to a maximum of 10 bits of text in any 60s period #define TIME_LIMIT 60000 #define MAX_TEXT 10 // Comment out the following lines to customise the code #define PROTECT_TEXT // Filter text #define PROTECT_PMS // Filter PMs #define PROTECT_CMD // Filter Commands #define IGNORE_ADMINS // Let admins talk as much as they like #define WARN_PLAYER // Send the player a flood exceeded message #if defined WARN_PLAYER // Color for warning message to be displayed in (red) #define WARN_COLOR 0xFF0000AA // UNCOMMENT ONE OF THE FOLLOWING // OR WRITE YOUR OWN MESSAGE // Message to be displayed to the player - without time //#define WARN_MESSAGE "*** Flood limit exceeded, please try again in a moment" // Message to be displayed to the player - with time #define WARN_MESSAGE "*** Flood limit exceeded, please try again in %d seconds" #endif /* ================================================================================ Edit ABOVE this line! And where marked below for flitered commands ================================================================================ */ #if !defined PROTECT_TEXT && !defined PROTECT_PMS && !defined PROTECT_CMD #error "You must filter somthing! - Make sure a PROTECT_XXX is uncommented." #endif public OnFilterScriptInit() { print("\n---------------------------------------"); print("| Flood protection filterscript |"); print("| (c) SA:MP team - 2007 |"); print("---------------------------------------\n"); return 1; } #if defined PROTECT_TEXT // Check for floods on standard text public OnPlayerText(playerid, text[]) { // Call one function to reduce globals and combine flooding checks if (!CheckFlooding(playerid)) return 1; return 0; #pragma unused text } #endif #if defined PROTECT_PMS // Check for floods on private messages public OnPlayerPrivmsg(playerid, recieverid, text[]) { if (!CheckFlooding(playerid)) return 1; return 0; #pragma unused recieverid, text } #endif #if defined PROTECT_CMD // Check for floods on specific commands public OnPlayerCommandText(playerid, cmdtext[]) { /* ================================================================================ Edit BELOW this line! Put command names you want flood protected here ================================================================================ */ static sFilteredCommands[][] = { "/me", "/say", "/announce" }; /* ================================================================================ Edit ABOVE this line! ================================================================================ */ // More processing required so save time here #if defined IGNORE_ADMINS if (IsPlayerAdmin(playerid)) return 0; #endif // Loop through text based commands for (new i = 0; i < sizeof (sFilteredCommands); i++) { // If we have this command in the list if (!strcmp(cmdtext, sFilteredCommands[i])) { // Faster than two strlens new len = strlen(sFilteredCommands[i]); // Check command, e.g. /me not /meths if (cmdtext[len] == '\0' || cmdtext[len] == ' ') { // Mark as command processed if (CheckFlooding(playerid)) return 1; // Break out break; } } } return 0; #pragma unused cmdtext } #endif #define CEIL_DIV(%1,%2) (((%1) + (%2) - 1) / (%2)) #if !defined WARN_COLOR #define WARN_COLOR 0xFF0000AA #endif #if !defined WARN_MESSAGE #define WARN_MESSAGE "*** Flood limit exceeded, please try again in %d seconds" #endif #if !defined TIME_LIMIT #define TIME_LIMIT 60000 #endif #if !defined MAX_TEXT #define MAX_TEXT 10 #endif CheckFlooding(playerid) { // Holds the times of the last MAX_TEXT messages static sTextTimes[MAX_PLAYERS][MAX_TEXT]; // Holds the current stack pointer for new messages static sTextIndex[MAX_PLAYERS]; #if defined IGNORE_ADMINS // If admins aren't flood protected break out if (IsPlayerAdmin(playerid)) return 0; #endif // Works on Linux and Windows now new tickCount = GetTickCount(); // Get the current point in the flood time array new index = sTextIndex[playerid]; // Check this is less than the flood cutoff (normally MAX_TEXT before) if (sTextTimes[playerid][index] <= (tickCount - TIME_LIMIT)) { // Save the new time sTextTimes[playerid][index] = tickCount; // Increment to the next messages time index++; // Wrap around index %= MAX_TEXT; // Save this value statically sTextIndex[playerid] = index; // Mark as OK return 0; } #if defined WARN_PLAYER new str[128]; // More than enough normally // Calculate the time remaining in seconds format(str, sizeof (str), WARN_MESSAGE, CEIL_DIV(TIME_LIMIT - (tickCount - sTextTimes[playerid][index]), 1000)); // Send the client their warning SendClientMessage(playerid, WARN_COLOR, str); #endif // Mark as bad return 1; }