/********************************************************* * Bugblatter Name Management Extension - V3.3 * ********************************************************* * * * This plug-in is linux & win32 friendly. * * * * Version history * * * * Version 3.3: * * * * - Removed warnings compiling on Admin Mod 2.50.56 * * * * Version 3.2: * * - Updated for language plugin version 3.3 * * * * Version 3.1: * * - Added NSPlayer to default banned names * * * * Version 2.6: * * * * - Added colour and timing settings for all * * messageex class on 2.51.xx alpha builds. * * - Copes with plugin_info firing before * * plugin_connect * * * * Version 2.5: * * - Removes unrecognised characters. Kicks players * * with an empty name. * * * * Version 2.4: * * - Updated for adminmod 2.50.50 * * - Uses bbdir vault setting for file locations, then * * modfolder/addons/adminmod/config then mod folder. * * - Checks for names ini files on startup * * - Does not return PLUGIN_FAILRE during init * * - Works around bug in calling admin_command bb,,, * * from in a .cfg file saved in DOS format * * - Move prominent error messages in log * * * * Version 2.3: * * - Checks values of server.cfg vars during init * * * * Version 2.2: * * - Can now allow a limited number of name changes * * * * Version 2.1: * * - Multi lingual support added * * - Updated for adminmod 2.50.37 * * * * * * Version 2.0: * * - Plugin now works alongside cheating-death in * * optional mode. * * - Some explanation messages were being truncated * * because string buffers were too small * * * * * * Version 1.9: * * - Plugin is now bot-compatible. * * - Report can be turned on and off now * * * * * * Version 1.8: * * * * - Plugin name changed from "Anti-Player". * * - Minimum name length is now configurable. * * - Minimum letters length option added. * * - De-leet function added to attempt to make name * * legal * * - Plugin can now ban all player name changes * * - Fixed bug where last lines of badplayernames.ini/ * * newplayernames.ini were ignored. * * - Instructions to user on how to change name now * * specify using setinfo name instead of name. * * - bbname_report and bbname_reset commands added. * * Support functions moved from sma file to include * * files. * * - bbname_lanmask command and lag tasks feature added * * - checks immunity before changing names to prevent * * an admins name being changed. * * * * * * Version 1.7: * * * * - No changes * * * * Version 1.6: * * * * - Now picks names in a random order * * * * Version 1.5 - Initial Release * * * *********************************************************/ #include <core> #include <console> #include <string> #include <admin> #include <adminlib> #include <plugin> #include "settings" #include "leet" #include "clientio" #include "ip" #include "language" #include "stringx" #include "connections" new g_Version[]="3.3"; #define DEFAULT_RENAME 1 #define MIN_RENAME 0 #define MAX_RENAME 1 #define DEFAULT_CHANGES -1 #define MIN_CHANGES -1 #define MAX_CHANGES 1000 #define DEFAULT_MINLENGTH 3 #define MIN_MINLENGTH 0 #define MAX_MINLENGTH 16 #define DEFAULT_MINLETTERS 1 #define MIN_MINLETTERS 0 #define MAX_MINLETTERS 16 #define DEFAULT_LANTAGS 1 #define MIN_LANTAGS 0 #define MAX_LANTAGS 1 #define DEFAULT_AUTOCHASECAM 1 #define MIN_AUTOCHASECAM 0 #define MAX_AUTOCHASECAM 2 #define DEFAULT_REPORT 1 #define MIN_REPORT 0 #define MAX_REPORT 1 #define DEFAULT_LANTAGMASK -1 #define ERROR_RED 255 #define ERROR_GREEN 10 #define ERROR_BLUE 10 new g_MSG_NOCHANGES[]="You are not allowed to change your name mid-game on this server.|Vous n'avez pas le droit de changer votre nom au milieu du jeu sur ce serveur.|Namenswechsel ist waehrend des Spiels auf diesem Server verboten"; new g_MSG_CHANGELIMIT[]="You are only allowed to change your name %1i times mid-game on this server.|Du darfst deinen Nick auf diesem Server nur %1i mal mitten im Spiel wechseln."; new g_MSG_REPORT_TITLE[]="Bugblatter Name Management configuration:|Configuration du management de nom Bugblatter:|Bugblatter Name-Management Konfiguration:"; new g_MSG_RPT_RENAME_ON[]=" - Players with ^"bad^" names will be renamed.(bbname_rename)| - Les joueurs avec les noms ^"bad^" seront renommes.(bbname_rename)| - Spieler mit ^"boesen^" Namen werden umbenannt.(bbname_rename)"; new g_MSG_RPT_RENAME_OFF[]=" - Players with ^"bad^" names will NOT be renamed.(bbname_rename)|- Les joueurs avec les noms ^"bad^" ne seront pas renommes.(bbname_rename)| - Spieler mit ^"boesen^" Namen werden NICHT umbenannt.(bbname_rename)"; new g_MSG_RPT_CHANGE_ON[]=" - Players are allowed to change their name while connected.(bbname_changes)| - Les joueurs peuvent changer leur nom quand ils se connectent.(bbname_changes)| - Namenswechsel waehrend der Verbindung ist erlaubt.(bbname_changes)"; new g_MSG_RPT_CHANGE_OFF[]=" - Players are NOT allowed to change their name while connected.(bbname_changes)| - Les joueurs ne peuvent pas changer leur nom quand ils se connectent.(bbname_changes)| - Namenswechsel waehrend der Verbindung ist NICHT erlaubt.(bbname_changes)"; new g_MSG_RPT_CHANGE_NUM[]=" - Players are allowed to change their name %1i times while connected.(bbname_changes)| - Spieler duerfen nach dem Connect ihren Nick %1i mal wechseln. (bbname_changes)"; new g_MSG_RPT_IPSUBNET[]=" - IP address for local subnet is %1s (bbname_lantagmask)| - L'adresse IP du subnet local est %1s (bbname_lantagmask)| - IP Adresse des lokalen Subnets ist %1s (bbname_lantagmask)"; new g_MSG_RPT_LANTAG_ON[]=" - Players names are changed to include Lan Tags.(bbname_langtags)| - Les noms des joueurs sont modifies pour inclure Lan Tags.(bbname_lantags) | - Lan-Tags werden in die Namen eingefuegt.(bbname_lantags)"; new g_MSG_RPT_LANTAG_OFF[]=" - Players names are NOT changed to include Lan Tags.(bbname_lantags)| - Les noms des joueurs ne sont pas modifies pour inclure Lan Tags.(bbname_lantags)| - Lan-Tags werden NICHT in die Namen eingefuegt.(bbname_lantags)"; new g_MSG_RPT_CHASE[]=" - Automatic control of forced chase camera is set to %1i.(bbname_autochasecam)| - Le controle automatique du suivi force de la camera est regle a %1i.(bbname_autochasecam)| - Automatische Anpassung von forced-chase-camera ist auf %1i gesetzt.(bbname_autochasecam)"; new g_MSG_RPT_MINLENGTH[]=" - Minimum player name length: %1i characters.(bbname_minlength)| - Longueur minimum du nom du joueur : %1i caracteres.(bbname_minlength)| - Minimale Namenslaenge: %1i Zeichen.(bbname_minlength)"; new g_MSG_RPT_MINCONSEC[]=" - Player names must have %1i consecutive letters.(bbname_minletters)| - Les noms des joueurs doivent contenir %1i lettres consecutives.(bbname_minletters)| - Namen muessen %1i aufeinander folgende Buchstaben beinhalten.(bbname_minletters)"; new g_MSG_RPT_WARN[]="WARNING: bbname_minlettters is larger than bbname_minlength - no names are valid!|ATTENTION: bbname_minletters est plus grand que bb_name_minlength - aucun nom n'est valide!|ACHTUNG: bbname_minlettters ist groesser als bbname_minlength - alle Namen sind ungueltig!"; new g_MSG_LIST_TITLE[]="ID: User Name - Original Name - IP - Lan|ID: Nom d'utilisateur - Nom Original - IP - Lan|ID: User Name - Original Name - IP - Lan"; new g_MSG_LANWARN[]="WARNING: Players marked ^"Ln:^" may be able to see each others screens.|ATTENTION: Les joueurs qui ont ^"Ln:^" peuvent voir chacun des autres ecrans.|ACHTUNG: Mit ^"Ln:^" markierte Spieler koennten gegenseitig die Bildschirme sehen."; new g_MSG_FREELOOK_OFF[]="Free-look when dead has been disabled as some players are on a LAN|La vue libre a ete desactivee comme certaines personnes sont en LAN|Free-Look der Toten wurde deaktiviert, da manche Spieler im selben LAN sind."; new g_MSG_FREELOOK_ON[]="Free-look when dead is now enabled|La vue libre est maintenant activee|Free-Look der Toten ist jetzt aktiviert."; new g_MSG_NAMELENGTH[]="Your name must be at least %1i characters and has been changed to: %2s.|Votre nom doit contenir au moins %1i caracteres et a ete changee en: %2s|Dein Name muss mindestens %1i Zeichen enthalten und wurde geaendert auf: %2s."; new g_MSG_NAMELETTERS[]="Your name must have %1i consecutive letters, and has been changed to: %2s.|Votre nom doit avoir %1i lettres consecutives, et a ete changee en: %2s|Dein Name muss %1i aufeinander folgende Buchstaben enthalten, und wurde geaendert auf: %2s"; new g_MSG_NAMELAN_ON[]="Your name has been changed because the server believes you might be able to see another player's screen.|Votre nom a ete change car le serveur pense que vous pouvez voir les ecrans des autres joueurs.|Dein Name wurde geaendert, da der Server glaubt, Du kannst evtl. den Bildschirm eines anderen Spieler sehen."; new g_MSG_NAMELAN_OFF[]="Your name has been restored because the other player on your LAN has left.|Votre nom a ete retabli car l'autre joueur de votre LAN est parti.|Dein Name wurde wieder hergestellt, da der andere Spieler in deinem LAN gegangen ist"; new g_MSG_NAMEBANNED[]="The name %1s is not allowed on this server. You name has been changed to: %2s|Le nom %1s n'est pas autorise sur ce serveur. Votre nom a ete change en: %2s|Der Name %1s ist nicht erlaubt auf diesem Server. Dein Name wurde geaendert auf: %2s"; new g_MSG_HOWTOCHANGE[]="Type the following in this console to change your name:|Tapez ceci dans votre console pour changer votre nom:|Gib folgendes in diese Konsole ein um Deinen Namen zu aendern:"; /* Configuration variables */ new g_Rename=DEFAULT_RENAME; /* Should players be renamed? 1 = yes */ new g_Changes=DEFAULT_CHANGES; /* Should plauers be allowed to rename themselves? 1 = yes */ new g_MinLength=DEFAULT_MINLENGTH; /* Minimum allowable name length */ new g_MinLetters=DEFAULT_MINLETTERS; /* Minimum allowable sequence of consecutive letters */ new g_Report=DEFAULT_REPORT; /* Automatically show report after command? */ new g_LanTagMask=DEFAULT_LANTAGMASK; /* Network mask multiple players must match to be on same lan */ new g_LanTags = DEFAULT_LANTAGS; /* Enables / Disables updating names with lan tags */ new g_AutoChaseCam = DEFAULT_AUTOCHASECAM; /* Enabler automatic control of forcechasecam */ /* Status variables */ new g_OriginalNames[MAX_PLAYERS+1][MAX_NAME_LENGTH]; /* Names players joined with - sometimes updated though */ new g_PermitNames[MAX_PLAYERS+1][MAX_NAME_LENGTH]; /* Names players can change to - prevents feedback loops */ new g_IP[MAX_PLAYERS+1]; /* IP address of players */ new g_Lan[MAX_PLAYERS+1]; /* Lan tag number of players */ new g_LogdDetected=0; /* True if logd found on server */ new g_WaitForTeam[MAX_PLAYERS+1]; /* Indicates a player name should not change until they join a team */ new g_IgnoreNext[MAX_PLAYERS+1]; /* Indicates a player name should not change until they join a team */ new g_LanUsersPresent=0; /* Flag to indicate if lan users have been detected */ new g_RecheckTimer=0; /* Timer for checking again if playerinfo fails */ new g_Registered=0; new g_CheatingDeath=0; /* Cheating death detected */ new g_Changed[MAX_PLAYERS+1]; /* Number of name changes each player has made */ new g_Allowed[MAX_DATA_LENGTH]="ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz1234567890-=:! $%&*()_+{}[]@'#/?,.<>\|^^"; /* Name filter */ forward RegisterPlugin(); forward BBLogdWorldAction(HLCommand,HLData,HLUserName,UserIndex); forward BBLogdTeamSelect(HLCommand,HLData,HLUserName,UserIndex); forward BBDeleet(HLCommand,HLData,HLUserName,UserIndex); forward BBNameRename(HLCommand,HLData,HLUserName,UserIndex); forward BBNameChanges(HLCommand,HLData,HLUserName,UserIndex); forward BBNameMinLength(HLCommand,HLData,HLUserName,UserIndex); forward BBNameMinLetters(HLCommand,HLData,HLUserName,UserIndex); forward BBNameLanTagMask(HLCommand,HLData,HLUserName,UserIndex); forward BBNameLanTags(HLCommand,HLData,HLUserName,UserIndex); forward BBNameAutoChaseCam(HLCommand,HLData,HLUserName,UserIndex); forward BBNameReset(HLCommand,HLData,HLUserName,UserIndex); forward BBNameReport(HLCommand,HLData,HLUserName,UserIndex); forward BBNameUsers(HLCommand,HLData,HLUserName,UserIndex); forward ShowConfig(Force,UserIndex); forward ShowUsers(UserIndex); forward FreeLan(); forward LanTagAnnounce(); forward CheckNames(); forward CheckNamesAgain(); forward SetChaseCam(val); forward CheckPlayerName(OldName[],NewName[],CheckNewNames,UserIndex,DeleetName,&OnLan); forward ChoosePlayerName(Name[],UserIndex,Reason,OnLan); forward ConsiderName(OldName[],NewName[],UserIndex,Reason,OnLan); forward SetPlayerName(Name[],NewName[],UserIndex,Reason,OnLan); /*********************************************************/ /* Standard event handlers for adminmod */ /*********************************************************/ public plugin_init() { plugin_registerinfo("Bugblatter's Name Management plugin","Regulates player naming on your server",g_Version); /* Check server is configured properly */ new fOK = checkFileAccessRead(); fOK = checkAllowClientExec() && fOK; fOK = checkVaultOK() && fOK; if (fOK == 0) { return PLUGIN_CONTINUE; } /* No need to abort if this one fails */ checkLanguage(); new NamesFile[MAX_DATA_LENGTH]; if (getfilelocation(NamesFile,"badplayernames.ini")==0) { configError("Unable to find file badplayernames.ini"); return PLUGIN_CONTINUE; } if (getfilelocation(NamesFile,"newplayernames.ini")==0) { configError("Unable to find file newplayernames.ini"); return PLUGIN_CONTINUE; } readvaultnum("bbname_rename",g_Rename,DEFAULT_RENAME,MIN_RENAME,MAX_RENAME); readvaultnum("bbname_changes",g_Changes,DEFAULT_CHANGES,MIN_CHANGES,MAX_CHANGES); readvaultnum("bbname_minlength",g_MinLength,DEFAULT_MINLENGTH,MIN_MINLENGTH,MAX_MINLENGTH); readvaultnum("bbname_minlettters", g_MinLetters,DEFAULT_MINLETTERS,MIN_MINLETTERS,MAX_MINLETTERS); readvaultnum("bbname_lantags", g_LanTags,DEFAULT_LANTAGS,MIN_LANTAGS,MAX_LANTAGS); readvaultnum("bbname_autochasecam", g_AutoChaseCam,DEFAULT_AUTOCHASECAM,MIN_AUTOCHASECAM,MAX_AUTOCHASECAM); readvaultnum("bbname_report",g_Report,DEFAULT_REPORT,MIN_REPORT,MAX_REPORT); new Buffer[16]=""; get_vaultdata("bbname_lantagmask",Buffer,16); strtoip(Buffer,g_LanTagMask); /* Register with logd if its installed. If its not this will cause an error in your server logs, but will have no other detremental effects * NOTE: No access level numerically coded because its missing from include/admin.inc and I don't want to cause a name clash with future releases of include files */ plugin_registercmd("bbname_logdwa","BBLogdWorldAction",131072,""); exec("logd_reg 62 admin_command bbname_logdwa",0); plugin_registercmd("bbname_logdts","BBLogdTeamSelect",131072,""); exec("logd_reg 54 admin_command bbname_logdts",0); new cd[MAX_TEXT_LENGTH]; if (getstrvar("cdrequired",cd,MAX_TEXT_LENGTH)) { g_CheatingDeath = 1; } new i; for(i=1;i<=MAX_PLAYERS;i++) { g_IP[i]=0; g_WaitForTeam[i] = 0; g_IgnoreNext[i]= 0; } set_timer("LanTagAnnounce",300,99999); language_init(); RegisterPlugin(); return PLUGIN_CONTINUE; } RegisterPlugin() { /* Register commands with adminmod */ plugin_registercmd("bbname_rename","BBNameRename",ACCESS_CONFIG, "bbname_rename < ^"on^" | ^"off^" >: Enables automatic renaming of players with invalid names."); plugin_registercmd("bbname_changes","BBNameChanges",ACCESS_CONFIG, "bbname_changes < ^"on^" | ^"off^" | n >: Enables players to change their name specified number of times."); plugin_registercmd("bbname_minlength","BBNameMinLength",ACCESS_CONFIG, "bbname_minlength <count>: Sets the minimum permissable name length."); plugin_registercmd("bbname_minletters","BBNameMinLetters",ACCESS_CONFIG, "bbname_minletters <count>: Sets the minimum permissable length of consecutive letters."); plugin_registercmd("bbname_report","BBNameReport",ACCESS_CONFIG, "bbname_report [ ^"on^" | ^"off^" ]: shows the name management config, and enables/disable report after every command"); plugin_registercmd("bbname_reset","BBNameReset",ACCESS_CONFIG, "bbname_reset: Restores all name management settings to defaults."); plugin_registercmd("bbname_lantagmask","BBNameLanTagMask",ACCESS_CONFIG, "bbname_lantagmask <subnetmask>: Sets the subnet mask multiple players must match to be considered on the same lan."); plugin_registercmd("bbname_users","BBNameUsers",ACCESS_CONFIG, "bbname_users: Lists users connected to the server with original names, IP addresses and Lan number."); plugin_registercmd("bbname_lantags","BBNameLanTags",ACCESS_CONFIG, "bbname_lantags <^"on^" | ^"off^">: Enables / disable the use of lan tags."); plugin_registercmd("bbname_autochasecam","BBNameAutoChaseCam",ACCESS_CONFIG, "bbname_autochasecam < ^"0^" | ^"1^" | ^"2^" >: Enables automatic control of force chase cam."); g_Registered=1; } public plugin_connect(HLUserName, HLIP, UserIndex) { if (g_Registered ==0) { return PLUGIN_FAILURE; } PlayerConnected(UserIndex); new Data[MAX_DATA_LENGTH]; new i; safe_convert(HLIP,Data,MAX_DATA_LENGTH); new UserName[MAX_NAME_LENGTH]; safe_convert(HLUserName, UserName, MAX_NAME_LENGTH); strfilter(UserName,g_Allowed); if (strlen(UserName)==0) { log("Attempting to kick"); log("Attempting to kick"); log("Attempting to kick"); log("Attempting to kick"); log("Attempting to kick"); log("Attempting to kick"); log("Attempting to kick"); log("Attempting to kick"); new strIndex[10]; numtostr(UserIndex,strIndex); kick(strIndex); } /*new msg[MAX_TEXT_LENGTH]; snprintf(msg,MAX_TEXT_LENGTH,"%s connected as user %i",UserName,UserIndex); log(msg);*/ /*If Logd has been detected, don't change this players *name until they have selected a team - this ensures *messags are displayed to the player correctly */ g_WaitForTeam[UserIndex]=g_LogdDetected; g_IgnoreNext[UserIndex]=0; g_Changed[UserIndex]=0; if (strtoip(Data,g_IP[UserIndex])) { if (g_LanTagMask != 0) { for (i=1;i<=MAX_PLAYERS;i++) { if ((i != UserIndex) && (g_IP[i] !=0)) { if ((g_IP[i] & g_LanTagMask) == (g_IP[UserIndex] & g_LanTagMask)) { if (g_Lan[i] == 0) { g_Lan[i] = FreeLan(); } g_Lan[UserIndex]=g_Lan[i]; return PLUGIN_CONTINUE; } } } } } return PLUGIN_CONTINUE; } public plugin_disconnect(HLUserName, UserIndex) { if (g_Registered ==0) { return PLUGIN_FAILURE; } PlayerDisconnected(UserIndex); new UserName[MAX_NAME_LENGTH]; safe_convert(HLUserName, UserName, MAX_NAME_LENGTH); /*new msg[MAX_TEXT_LENGTH]; snprintf(msg,MAX_TEXT_LENGTH,"%s disconnected as user %i",UserName,UserIndex); log(msg);*/ g_IP[UserIndex]=0; g_Lan[UserIndex]=0; g_Changed[UserIndex]=0; g_IgnoreNext[UserIndex]= 0; set_timer("CheckNames",5,1); return PLUGIN_CONTINUE; } public plugin_info(HLOldName, HLNewName, UserIndex) { if (g_Registered ==0) { return PLUGIN_FAILURE; } if (IsPlayerConnected(UserIndex)==0) { return PLUGIN_CONTINUE; } /* Prevent a feedback loop */ if (g_IgnoreNext[UserIndex] == 1) { g_IgnoreNext[UserIndex] = 0; return PLUGIN_CONTINUE; } /* Ignore initial plugin_info call that occurs before plugin_connect, * or if the player is a bot */ if (g_IP[UserIndex] == 0) { return PLUGIN_CONTINUE; } new NewName[MAX_NAME_LENGTH]; new OldName[MAX_NAME_LENGTH]; new Timer=3; safe_convert(HLNewName, NewName, MAX_NAME_LENGTH); safe_convert(HLOldName, OldName, MAX_NAME_LENGTH); new Command[MAX_DATA_LENGTH]; new OnLan=0; if (streq(OldName,NewName)) { /* Name hasn't changed - ignore */ return PLUGIN_CONTINUE; } if (streq(g_PermitNames[UserIndex],NewName)) { return PLUGIN_CONTINUE; } if (OldName[0] == NULL_CHAR) { /* User is setting name during connection */ g_OriginalNames[UserIndex] = NewName; if (g_LogdDetected) { /*If Logd has been detected, don't change this players *name until they have selected a team - this ensures *messags are displayed to the player correctly */ g_WaitForTeam[UserIndex]=1; } else { Timer=30; /* Delay name checking on player joining so they are more likely to read the message */ } } else { /* Name change */ if ((g_Changes>-1) && (g_Changed[UserIndex]>=g_Changes)) { /* Stop C-D causing a loop */ if ((strncmp(OldName,NewName,30)==0)) { return PLUGIN_CONTINUE; } if(streq(g_OriginalNames[UserIndex],NewName)==0) { if (CheckPlayerName(OldName,OldName,1,UserIndex,0,OnLan)) { /* If current name is one of our banned names, or a name * we have given the player, allow them to change it */ g_OriginalNames[UserIndex] = NewName; } else { if (g_Changes == -1) { language_say(UserIndex,g_MSG_NOCHANGES,print_type:print_console); } else { language_sayf(UserIndex,g_MSG_CHANGELIMIT,print_type:print_console,0,0,0,0,g_Changes); } snprintf(Command, MAX_TEXT_LENGTH, "setinfo name ^"%s^"", OldName); strcpy(g_PermitNames[UserIndex],OldName,MAX_NAME_LENGTH); execclient(OldName, Command); return PLUGIN_CONTINUE; } } } } /* If new name is invalid, but old name was valid, * change back to old name, rather than to one from newplayernames.ini */ if (OldName[0] != NULL_CHAR) { new Reason=CheckPlayerName(OldName,NewName,0,UserIndex,0,OnLan); new Dummy=0; if (Reason>=5) { /* Only thing wrong with the newname is the lantag is missing */ SetPlayerName(OldName,NewName,UserIndex,Reason,OnLan); } else if (Reason>0) { if (CheckPlayerName(OldName,OldName,0,UserIndex,0,Dummy)==0) { SetPlayerName(OldName,OldName,UserIndex,Reason,OnLan); } } else { g_Changed[UserIndex]=g_Changed[UserIndex]+1; } } if (g_RecheckTimer==0) { set_timer("CheckNames",Timer,1); } return PLUGIN_CONTINUE; } /*********************************************************/ /* LogD command handlers */ /*********************************************************/ public BBLogdWorldAction(HLCommand,HLData,HLUserName,UserIndex) { g_LogdDetected =1; return PLUGIN_HANDLED; } public BBLogdTeamSelect(HLCommand,HLData,HLUserName,UserIndex) { new Data[MAX_DATA_LENGTH]; safe_convert(HLData, Data, MAX_DATA_LENGTH); new i = strtonum(Data); if ((i>0) && (i<=MAX_PLAYERS)) { if (g_WaitForTeam[i]==1) { /*new msg[MAX_TEXT_LENGTH]; snprintf(msg,MAX_TEXT_LENGTH,"Wait period has expired for user %i",i); log(msg);*/ g_WaitForTeam[i] = 0; if (g_RecheckTimer == 0) { set_timer("CheckNames",10,1); } } } return PLUGIN_HANDLED; } /*********************************************************/ /* Command handlers for admin commands */ /*********************************************************/ public BBDeleet(HLCommand,HLData,HLUserName,UserIndex) { new Data[MAX_DATA_LENGTH]; safe_convert(HLData, Data, MAX_DATA_LENGTH); deleet(Data); selfmessage(Data); } public BBNameRename(HLCommand,HLData,HLUserName,UserIndex) { if (readHLonoff(HLData,g_Rename,DEFAULT_RENAME,MIN_RENAME,MAX_RENAME)) { writevaultnum("bbname_rename",g_Rename); } CheckNames(); return ShowConfig(0,UserIndex); } public BBNameChanges(HLCommand,HLData,HLUserName,UserIndex) { if (readHLonoff(HLData,g_Changes,DEFAULT_CHANGES,MIN_CHANGES,MAX_CHANGES,-1)) { writevaultnum("bbname_changes",g_Changes); } CheckNames(); return ShowConfig(0,UserIndex); } public BBNameMinLength(HLCommand,HLData,HLUserName,UserIndex) { if (readHLnum(HLData,g_MinLength,DEFAULT_MINLENGTH,MIN_MINLENGTH,MAX_MINLENGTH)) { writevaultnum("bbname_minlength",g_MinLength); } CheckNames(); return ShowConfig(0,UserIndex); } public BBNameMinLetters(HLCommand,HLData,HLUserName,UserIndex) { if (readHLnum(HLData,g_MinLetters,DEFAULT_MINLETTERS,MIN_MINLETTERS,MAX_MINLETTERS)) { writevaultnum("bbname_minlettters",g_MinLetters); } CheckNames(); return ShowConfig(0,UserIndex); } public BBNameLanTagMask(HLCommand,HLData,HLUserName,UserIndex) { new Data[MAX_DATA_LENGTH]; new i; new j; safe_convert(HLData,Data,MAX_DATA_LENGTH); if (strtoip(Data,g_LanTagMask)) { set_vaultdata("bbname_lantagmask",Data); /* Recheck all connected players for LANness with new mask */ for (j=1;j<=MAX_PLAYERS;j++) { g_Lan[j] = 0; } for (j=1;j<=MAX_PLAYERS;j++) { if (g_IP[j] != 0) { for (i=j+1;i<=MAX_PLAYERS;i++) { if (g_IP[i] != 0) { if ((g_IP[i] & g_LanTagMask) == (g_IP[j] & g_LanTagMask)) { if (g_Lan[i] == 0) { g_Lan[i] = FreeLan(); } g_Lan[j]=g_Lan[i]; } } } } } } CheckNames(); ShowConfig(0,UserIndex); return PLUGIN_HANDLED; } public BBNameLanTags(HLCommand,HLData,HLUserName,UserIndex) { if (readHLonoff(HLData,g_LanTags,DEFAULT_LANTAGS,MIN_LANTAGS,MAX_LANTAGS)) { writevaultnum("bbname_lantags",g_LanTags); } CheckNames(); return ShowConfig(0,UserIndex); } public BBNameAutoChaseCam(HLCommand,HLData,HLUserName,UserIndex) { if (readHLnum(HLData,g_AutoChaseCam,DEFAULT_AUTOCHASECAM,MIN_AUTOCHASECAM,MAX_AUTOCHASECAM)) { writevaultnum("bbname_autochasecam",g_AutoChaseCam); } CheckNames(); return ShowConfig(0,UserIndex); } public BBNameReset(HLCommand,HLData,HLUserName,UserIndex) { g_Rename=DEFAULT_RENAME; g_Changes=DEFAULT_CHANGES; g_MinLength=DEFAULT_MINLENGTH; g_MinLetters=DEFAULT_MINLETTERS; g_LanTagMask=DEFAULT_LANTAGMASK; g_LanTags=DEFAULT_LANTAGS; g_AutoChaseCam=DEFAULT_AUTOCHASECAM; writevaultnum("bbname_rename",g_Rename); writevaultnum("bbname_changes",g_Changes); writevaultnum("bbname_minlength",g_MinLength); writevaultnum("bbname_minlettters",g_MinLetters); writevaultnum("bbname_lantags",g_LanTags); writevaultnum("bbname_autochasecam",g_AutoChaseCam); set_vaultdata("bbname_lantagmask","0.0.0.0"); CheckNames(); return ShowConfig(0,UserIndex); } public BBNameReport(HLCommand,HLData,HLUserName,UserIndex) { if (readHLonoff(HLData,g_Report,DEFAULT_REPORT,MIN_REPORT,MAX_REPORT)) { writevaultnum("bbname_report",g_Report); ShowConfig(0,UserIndex); } else { ShowConfig(1,UserIndex); } return PLUGIN_HANDLED; } public BBNameUsers(HLCommand,HLData,HLUserName,UserIndex) { return ShowUsers(UserIndex); } ShowConfig(Force,UserIndex) { if ((Force==0) && (g_Report==0)) { return PLUGIN_HANDLED; } language_say(UserIndex,g_MSG_REPORT_TITLE,print_type:print_console); if (g_Rename) { language_say(UserIndex,g_MSG_RPT_RENAME_ON,print_type:print_console); } else { language_say(UserIndex,g_MSG_RPT_RENAME_OFF,print_type:print_console); } if (g_Changes==-1) { language_say(UserIndex,g_MSG_RPT_CHANGE_ON,print_type:print_console); } else if (g_Changes==0) { language_say(UserIndex,g_MSG_RPT_CHANGE_OFF,print_type:print_console); } else { language_sayf(UserIndex,g_MSG_RPT_CHANGE_NUM,print_type:print_console,0,0,0,0,g_Changes); } new data[MAX_TEXT_LENGTH]; iptostr(g_LanTagMask,data); language_sayf(UserIndex,g_MSG_RPT_IPSUBNET,print_type:print_console,0,0,0,0,data); if (g_LanTags) { language_say(UserIndex,g_MSG_RPT_LANTAG_ON,print_type:print_console); } else { language_say(UserIndex,g_MSG_RPT_LANTAG_OFF,print_type:print_console); } language_sayf(UserIndex,g_MSG_RPT_CHASE,print_type:print_console,0,0,0,0,g_AutoChaseCam); language_sayf(UserIndex,g_MSG_RPT_MINLENGTH,print_type:print_console,0,0,0,0,g_MinLength); language_sayf(UserIndex,g_MSG_RPT_MINCONSEC,print_type:print_console,0,0,0,0,g_MinLetters); if (g_MinLetters > g_MinLength) { language_say(UserIndex,g_MSG_RPT_WARN,print_type:print_console); } return PLUGIN_HANDLED; } ShowUsers(UserIndex) { language_say(UserIndex,g_MSG_LIST_TITLE,print_type:print_console); new Name[MAX_NAME_LENGTH]; new strIP[16]; new msg[150]; new i; new ui; new ServerID; new c=maxplayercount(); for (i=1;i<=c;i++) { if (playerinfo(i,Name,MAX_NAME_LENGTH,ServerID)) { if (get_userindex(Name,ui)) { iptostr(g_IP[ui],strIP); snprintf(msg,150,"<%i> %s - %s - %s - %i",ServerID,Name,g_OriginalNames[ui],strIP,g_Lan[ui]); selfmessage(msg); } } } return PLUGIN_HANDLED; } /* Returns the lowest positive integer number that doesn't appear in g_Lan */ FreeLan() { new i; new r=1; for(i=1;i<MAX_PLAYERS;i++) { if (g_Lan[i]==r) { i=0; /* Slightly hacky, but hey */ r++; } } return r; } public LanTagAnnounce() { if (g_LanTags && g_LanUsersPresent) { language_sayall(g_MSG_LANWARN,print_type:print_chat); } } /*********************************************************/ /* Functions to perform name analysis */ /*********************************************************/ public CheckNames() { new c = maxplayercount(); new Name[MAX_NAME_LENGTH]; new dummy; new i; new OnLan; new tested=0; new AuthID[MAX_AUTHID_LENGTH]; new wonid=0; new dead=0; new team=0; if (g_RecheckTimer) { return 0; } new LanUsersPresent = 0; for(i=1;i<=c;i++) { if (playerinfo(i,Name,MAX_NAME_LENGTH,dummy,wonid,team,dead,AuthID)) { if ((g_WaitForTeam[i] == 0) && (strlen(AuthID) > 0)) { new Reason=CheckPlayerName(Name,Name,0,i,1,OnLan); if (OnLan) { LanUsersPresent = 1; } if (Reason>=5) { SetPlayerName(Name,Name,i,Reason,OnLan); } else if (Reason > 0) { ChoosePlayerName(Name,i,Reason,OnLan); } tested++; } else { tested++; } } } g_LanUsersPresent = LanUsersPresent; if (tested<playercount() || g_CheatingDeath) { if (tested<playercount()) { new msg[MAX_TEXT_LENGTH]; snprintf(msg,MAX_TEXT_LENGTH,"Bugblatter name manager: Failed to check some players names - will try again in <30 seconds",i); log(msg); } if (g_RecheckTimer == 0) { g_RecheckTimer = set_timer("CheckNamesAgain",30,1); } } if (g_AutoChaseCam) { new chase = getvar("mp_forcechasecam"); if (g_LanUsersPresent) { if (chase!=g_AutoChaseCam) { SetChaseCam(g_AutoChaseCam); } } else { if (chase!=0) { SetChaseCam(0); } } } return 0; } public CheckNamesAgain() { g_RecheckTimer = 0; CheckNames(); } SetChaseCam(val) { new cmd[MAX_TEXT_LENGTH]; snprintf(cmd,MAX_TEXT_LENGTH,"mp_forcechasecam %i",val); exec(cmd); if (val) { language_sayall(g_MSG_FREELOOK_OFF,print_type:print_pretty); } else { language_sayall(g_MSG_FREELOOK_ON,print_type:print_pretty); } } /* Returns non-zero if the Name doesn't match the test * * If CheckNewNames = 1, then it returns 1 for players * that have one of the new names. This is used to check * if manual renaming is permitted */ CheckPlayerName(OldName[],NewName[],CheckNewNames,UserIndex,DeleetName,&OnLan) { new i; new HasLanTag=0; OnLan=0; /* Admin's with immunity always have valid names */ if (check_immunity(OldName)) { return 0; } strtrim(NewName," "); new pos=0; if (g_CheatingDeath) { if (strstr(NewName,"[No C-D]")==0) { pos=8; } if (strstr(NewName,"[Old C-D]")==0) { pos=9; } } if (NewName[pos]=='L') { if ((NewName[pos+1]='1') && (NewName[pos+2]>=48) && (NewName[pos+2] <= 57) && (NewName[pos+3] == ':')) { HasLanTag=1; } else if ((NewName[pos+1]>=48) && (NewName[pos+1] <= 57) && (NewName[pos+2] == ':')) { HasLanTag=1; } } /* Test if user should have a lan tag and doesn't? */ if (g_Lan[UserIndex] > 0) { new lancount=0; for (i=0;i<=MAX_PLAYERS;i++) { if (g_Lan[i]==g_Lan[UserIndex]) { lancount++; } } if (lancount>1) { OnLan = 1; } else { g_Lan[UserIndex]=0; } } /* Filter out bad characters */ if (strfilter(NewName,g_Allowed)==0) { return 1; } /* Is name too short? */ if (strlen(NewName) < g_MinLength) { return 1; } /* Too few consecutive letters? */ if (g_MinLetters > 0) { if (strseqlen(NewName,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") < g_MinLetters) { if (DeleetName) { new LeetName[MAX_NAME_LENGTH]; strcpy(LeetName,NewName,MAX_NAME_LENGTH); deleet(LeetName); if (strseqlen(LeetName,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") < g_MinLetters) { return 2; } else { SetPlayerName(OldName,LeetName,UserIndex,2,OnLan); return 0; } } else { return 2; } } } /* On the banned names list? */ if (g_Rename) { new NamesFile[MAX_DATA_LENGTH]; new ReadCount; new TestName[MAX_NAME_LENGTH]; if (getfilelocation(NamesFile,"badplayernames.ini")) { ReadCount = filesize(NamesFile)+1; for(i=0;i<ReadCount;i++) { readfile(NamesFile,TestName,i,MAX_NAME_LENGTH); if (strcasecmp(NewName,TestName) == 0) { return 3; } } } if (CheckNewNames) { if (getfilelocation(NamesFile,"newplayernames.ini")) { ReadCount = filesize(NamesFile)+1; for(i=0;i<ReadCount;i++) { readfile(NamesFile,TestName,i,MAX_NAME_LENGTH); if (strcasecmp(NewName,TestName) == 0) { return 4; } } } } } /* Is the only thing wrong with the name a missing lan tag? */ if ((OnLan==1) && (HasLanTag==0) && (g_LanTags==1)) { return 5; } /* Is the only thing wrong with the name an extra lan tag? */ if ((HasLanTag==1) && (OnLan==0)) { return 6; } return 0; } ChoosePlayerName(Name[],UserIndex,Reason,OnLan) { new NamesFile[MAX_DATA_LENGTH]; if (getfilelocation(NamesFile,"newplayernames.ini")==0) { return 0; } new ReadCount = filesize(NamesFile); new i; new NewName[MAX_NAME_LENGTH]; /* First pick a random name from the new ones */ new count=filesize(NamesFile,fsize_unit:lines)+1; new pick=random(count); readfile(NamesFile,NewName,pick,MAX_NAME_LENGTH); if (ConsiderName(Name,NewName,UserIndex,Reason,OnLan)) { return 1; } /* If random pick is in use, then pick first free one */ for(i=0;i<ReadCount;i++) { readfile(NamesFile,NewName,i,MAX_NAME_LENGTH); if (ConsiderName(Name,NewName,UserIndex,Reason,OnLan)) { return 1; } } return 0; } ConsiderName(OldName[],NewName[],UserIndex,Reason,OnLan) { new dummy; if ((NewName[0] != '/') && (NewName[0] != NULL_CHAR)) { if (get_userindex(NewName,dummy) ==0) { /* Name is not already used */ SetPlayerName(OldName,NewName,UserIndex,Reason,OnLan); return 1; } } return 0; } SetPlayerName(Name[],NewName[],UserIndex,Reason,OnLan) { /* Name is being changed to add a lan tag */ new LanName[MAX_NAME_LENGTH]; snprintf(LanName,MAX_NAME_LENGTH,"L%i:",g_Lan[UserIndex]); if ((strstr(NewName,LanName) ==0) || (OnLan == 0) || (g_LanTags==0)) { LanName[0]=NULL_CHAR; } new LanNameLen =0; new fLoop=1; while (fLoop) { fLoop=0; if (NewName[LanNameLen]=='L') { if ((NewName[LanNameLen+1]=='1') && (NewName[LanNameLen+2]>=48) && (NewName[LanNameLen+2] <= 57) && (NewName[LanNameLen+3] == ':')) { LanNameLen=LanNameLen+4; fLoop=1; } else if ((NewName[LanNameLen+1]>=48) && (NewName[LanNameLen+1] <= 57) && (NewName[LanNameLen+2] == ':')) { LanNameLen=LanNameLen+3; fLoop=1; } } if (streqindex(NewName,"[No C-D]",LanNameLen)) { LanNameLen=LanNameLen+8; fLoop=1; } if (streqindex(NewName,"[Old C-D]",LanNameLen)) { LanNameLen=LanNameLen+9; fLoop=1; } } new i; for(i=LanNameLen;i<MAX_NAME_LENGTH;i++) { NewName[i-LanNameLen]=NewName[i]; } strcat(LanName,NewName,MAX_NAME_LENGTH); if (Reason == 1) { language_sayf(UserIndex,g_MSG_NAMELENGTH,print_type:print_pretty,15,ERROR_RED,ERROR_GREEN,ERROR_BLUE,g_MinLength,LanName); } else if (Reason == 2) { language_sayf(UserIndex,g_MSG_NAMELETTERS,print_type:print_pretty,15,ERROR_RED,ERROR_GREEN,ERROR_BLUE,g_MinLetters,LanName); } else if (Reason == 5) { language_say(UserIndex,g_MSG_NAMELAN_ON,print_type:print_pretty,15,ERROR_RED,ERROR_GREEN,ERROR_BLUE); } else if (Reason == 6) { language_say(UserIndex,g_MSG_NAMELAN_OFF,print_type:print_pretty,15,ERROR_RED,ERROR_GREEN,ERROR_BLUE); } else { language_sayf(UserIndex,g_MSG_NAMEBANNED,print_type:print_pretty,15,ERROR_RED,ERROR_GREEN,ERROR_BLUE,Name,LanName); } language_say(UserIndex,g_MSG_HOWTOCHANGE,print_type:print_chat); messageex(Name,"setinfo name <yournewname>",print_type:print_chat); if (g_CheatingDeath ==0) { g_IgnoreNext[UserIndex]=1; /* Prevent feedback loop */ } new cmd[MAX_TEXT_LENGTH]; snprintf(cmd,MAX_TEXT_LENGTH,"setinfo name ^"%s^"",LanName); safe_execclient(Name,cmd); strcpy(g_PermitNames[UserIndex],LanName,MAX_NAME_LENGTH); strcpy(g_OriginalNames[UserIndex],LanName,MAX_NAME_LENGTH); return 0; }