/*************************************************************************** * plugin_sank_nameban.sma * Author: Luke Sankey * November 25, 2001 - Original version * February 15, 2002 - Added some debug code because of incorrect bans and * the option for exact names to ban, or just partial names to ban * November 15, 2002 - Updated file locations to be compliant with the new * directory structure. Also, updated the debug code with contact * information. * * Fuctionality of this plugin: * Bans players based on their name. If a player connects with a name that * contains one of the entries listed in the text file, then they will get * banned. If a player changes their name to one of the offending names, * they will also get banned. * * Credit is due to Vince Hague for inspiring me to write this plugin ***************************************************************************/ #include <core> #include <console> #include <string> #include <admin> #include <adminlib> // This is the name of the file to log name-ban events to new LOG_FILE[MAX_DATA_LENGTH] = "addons\adminmod\config\NameBanLog.txt"; // This is the name of the file to read the forbidden names from new TAG_FILE[MAX_DATA_LENGTH] = "addons\adminmod\config\NameBanList.txt"; // This is the maximum number of entries allowed in the name ban file #define MAX_ENTRIES 20 // Defining this value will make the plugin ban players with exact name matches //#define EXACTNAME /****************************************************************************/ /****************************************************************************/ /************** DO NOT MODIFY CONTENTS BELOW THIS LINE !!! ******************/ /************** DO NOT MODIFY CONTENTS BELOW THIS LINE !!! ******************/ /************** DO NOT MODIFY CONTENTS BELOW THIS LINE !!! ******************/ /****************************************************************************/ /****************************************************************************/ new STRING_VERSION[MAX_DATA_LENGTH] = "2.50.50"; #define INFINITE_TIMER 99999 // Holds the banned entries from the text file new BannedNames[MAX_ENTRIES][MAX_NAME_LENGTH]; // Make sure the timer matches the person new TimerLookup[MAX_PLAYERS]; /****************************************************************************/ public plugin_connect(HLUserName, HLIP, UserIndex) { new PlayerName[MAX_NAME_LENGTH]; convert_string(HLUserName, PlayerName, MAX_NAME_LENGTH); CheckName(PlayerName, UserIndex); return PLUGIN_CONTINUE; } /****************************************************************************/ public plugin_info(HLOldName, HLNewName, UserIndex) { new NewName[MAX_NAME_LENGTH]; new OldName[MAX_NAME_LENGTH]; convert_string(HLNewName, NewName, MAX_NAME_LENGTH); convert_string(HLOldName, OldName, MAX_NAME_LENGTH); // If name has not changed if (strcmp(NewName, OldName) == 0) return PLUGIN_CONTINUE; // Or if there was no previous name else if (strlen(OldName) == 0) return PLUGIN_CONTINUE; CheckName(NewName, UserIndex); return PLUGIN_CONTINUE; } /****************************************************************************/ public plugin_init() { plugin_registerinfo("Sank NameBan Plugin", "Bans users by name", STRING_VERSION); plugin_registercmd("admin_nameban", "admin_nameban", ACCESS_ALL, "admin_nameban : Prints out list of names that get banned."); parse_file(); return PLUGIN_CONTINUE; } /****************************************************************************/ public admin_nameban(HLCommand, HLData, HLUserName, UserIndex) { new i; selfmessage("NameBan entries:"); for (i = 0; i < MAX_ENTRIES; i++) { if (BannedNames[i][0] == 0) break; selfmessage(BannedNames[i]); } return PLUGIN_HANDLED; } /****************************************************************************/ public ban_timer(Timer, Repeat, HLUserName, HLParam) { new PlayerName[MAX_NAME_LENGTH]; // new ServerName[MAX_TEXT_LENGTH]; new Text[MAX_TEXT_LENGTH]; new Date[MAX_NUMBER_LENGTH]; new WONID; convert_string(HLUserName, PlayerName, MAX_NAME_LENGTH); // PlayerName will exist once the player has truly connected. // Until then, we will keep looping. if (strlen(PlayerName)) { new Index; get_userindex(PlayerName, Index); servertime(Date, MAX_NUMBER_LENGTH, "%m/%d/%y %H:%M:%S"); // First make sure the Timer and UserIndex match // Then, if the player is not immune, ban them. if (TimerLookup[Index] == Timer) { if (check_immunity(PlayerName) == 0) { ban(PlayerName, 0); // Let the players know // getstrvar("hostname", ServerName, MAX_TEXT_LENGTH); // snprintf(Text, MAX_TEXT_LENGTH, "<%s>: %s has been permanently banned from the server.", ServerName, PlayerName); // say(Text); // Let the admin know get_userWONID(PlayerName, WONID); snprintf(Text, MAX_TEXT_LENGTH, "L %s - %s<%i>", Date, PlayerName, WONID); writefile(LOG_FILE, Text); log(Text); } } else { // This is all debugging stuff for adminmod. I've never seen it, but I"ve heard // cases where this plugin would ban the wrong player. The only way this could // happen is if the timer callback function sent me the wrong name. So, in this // rare case, we will log special error messages. // The first special error message is that we almost banned the wrong person snprintf(Text, MAX_TEXT_LENGTH, "L %s - UserName and UserIndex did not match. %s:%i", Date, PlayerName, Index); writefile(LOG_FILE, Text); log(Text); // Get UserIndex of who we should've banned for (Index = 1; Index <= MAX_PLAYERS; Index++) { if (TimerLookup[Index] == Timer) break; } // Get name of who we should've banned numtostr(Index, Text); get_username(Text, PlayerName, MAX_NAME_LENGTH); snprintf(Text, MAX_TEXT_LENGTH, "L %s - I think we really wanted this banned. %s:%i", Date, PlayerName, Index); writefile(LOG_FILE, Text); log(Text); snprintf(Text, MAX_TEXT_LENGTH, "If you see this line, please please email me: sank@spu.edu Subject: Admin Mod nameban bug"); writefile(LOG_FILE, Text); log(Text); } // Stop this infinite timer kill_timer(Timer); return PLUGIN_CONTINUE; } return PLUGIN_CONTINUE; } /****************************************************************************/ CheckName(PlayerName[], UserIndex) { new Text[MAX_TEXT_LENGTH]; new i; new status = -1; for (i = 0; i < MAX_ENTRIES; i++) { #if defined EXACTNAME status = strcasecmp(PlayerName, BannedNames[i]); if (status == 0) #else status = strcasestrx(PlayerName, BannedNames[i]); if (status != -1) #endif { snprintf(Text, MAX_TEXT_LENGTH, "Setting timer to ban %s containing %s", PlayerName, BannedNames[i]); log(Text); TimerLookup[UserIndex] = set_timer("ban_timer", 3, INFINITE_TIMER); break; } } } /****************************************************************************/ parse_file() { new i; new GotLine; new iLineNum = 0; new strLineBuf[MAX_TEXT_LENGTH]; // Clear memory before using it for(i = 0; i < MAX_ENTRIES; i++) BannedNames[i][0] = 0; // File does not exist, try MOD directory (for backwards compatibility) if (!fileexists(TAG_FILE)) { strcpy(TAG_FILE, "NameBanList.txt", MAX_DATA_LENGTH); strcpy(LOG_FILE, "NameBanLog.txt", MAX_DATA_LENGTH); } i = 0; if (fileexists(TAG_FILE)) { GotLine = readfile(TAG_FILE, strLineBuf, iLineNum, MAX_TEXT_LENGTH); if (GotLine <= 0) { // See if file access is set correctly if (getvar("file_access_read") == 1) snprintf(strLineBuf, MAX_TEXT_LENGTH, "[plugin_sank_nameban] Unable to read from %s file.", TAG_FILE); else snprintf(strLineBuf, MAX_TEXT_LENGTH, "[plugin_sank_nameban] CVAR file_access_read is set incorrectly."); log(strLineBuf); return; } while (GotLine > 0) { // If there is no more room in our banned name list, then stop reading the file if (i >= MAX_ENTRIES) { log("[plugin_sank_nameban] Name list truncated. Increase MAX_ENTRIES."); printf("[plugin_sank_nameban] Stopped parsing %s file.^n", TAG_FILE); break; } // As long as the line isn't commented out, and isn't blank, then remember it. if ((strncmp(strLineBuf, "#", 1) != 0) && (strncmp(strLineBuf, "//", 2) != 0) && (strlen(strLineBuf) != 0)) { strcpy(BannedNames[i], strLineBuf, MAX_TEXT_LENGTH); i++; } // Read in the next line from the file GotLine = readfile(TAG_FILE, strLineBuf, ++iLineNum, MAX_TEXT_LENGTH); } } }