/********************************************************* * Bugblatter Sound Extension - V3.3 * ********************************************************* * * * This plug-in is linux & win32 friendly. * * * * Version history * * * * NOTE: Version numbers are for the plugins package * * this plugin may not change every version. * * * * Version 3.3: * * * * - Updated to compile on Admin Mod V2.50.56 * * * * Version 3.2: * * * * - Updated for language plugin version 3.3 * * * * Version 3.1: * * * * - No Changes * * * * Version 2.6: * * * * - Copes with plugin_info firing before * * plugin_connect * * * * Version 2.5: * * - Initial Version * * * * * *********************************************************/ #pragma dynamic 4096 #include <core> #include <console> #include <string> #include <admin> #include <adminlib> #include <plugin> #include "settings" #include "clientio" #include "ip" #include "language" #include "dictionary" #include "speech" #include "connections" new g_Version[] = "3.3"; /* IMPORTANT: Increase this is your playersounds.ini contains more than 100 lines */ #define MAX_PLAYER_SOUNDS 100 /* Maximum length of a line in playersounds.ini - 3 phrases + a type + a name/wonid/ip address/acess level */ #define MAX_SOUNDS_LENGTH 300 #define DEFAULT_ENABLED 1 #define MIN_ENABLED 0 #define MAX_ENABLED 1 #define DEFAULT_REPORT 1 #define MIN_REPORT 0 #define MAX_REPORT 1 #define PSTYPE_WONID 1 #define PSTYPE_NAME 2 #define PSTYPE_IP 3 #define PSTYPE_LEVEL 4 #define PSTYPE_CLAN 5 #define PSTYPE_ANY 6 forward RegisterPlugin(); forward BBSoundEnabled(HLCommand,HLData,HLUserName,UserIndex); forward BBSoundReset(HLCommand,HLData,HLUserName,UserIndex); forward BBSoundReport(HLCommand,HLData,HLUserName,UserIndex); forward BBLogdTeamSelect(HLCommand,HLData,HLUserName,UserIndex); forward ShowConfig(Force,UserIndex); forward ReadPlayerSounds(); forward ReadSoundsLine(SoundsFile[],i,Line[]); forward StartOfRound(Timer,Repeat,HLUserName,HLParam); forward HandleConnect(Timer,Repeat,HLUserName,HLParam); forward HandleConnectOther(Timer,Repeat,HLUserName,HLParam); forward HandleDisconnect(UserIndex); forward DoHandleConnect(UserIndex,Retries); forward DoHandleConnectOther(UserIndex,Retries); new g_MSG_REPORT_TITLE[]="Bugblatter Sound configuration:|Configuration du Son Bugblatter:|Bugblatter Sound Einstellungen:"; new g_MSG_RPT_ENABLED_ON[]=" - Sound is currently enabled (bbsound_enabled)| - Le son est actuellement actif (bbsound_enabled)| - Sound ist momentan aktiviert (bbsound_enabled)"; new g_MSG_RPT_ENABLED_OFF[]=" - Sound is currently disabled (bbsound_enabled)| - Le son est actuellement desative (bbsound_enabled)| - Sound ist momentan deaktiviert (bbsound_enabled)"; /* Configuration variables */ new g_Enabled=DEFAULT_ENABLED; /* Is this plugin enabled */ new g_Report=DEFAULT_REPORT; /* Should it report */ /* State Varaibles */ new g_Registered=0; new g_PSType[MAX_PLAYER_SOUNDS]; new g_PSKey[MAX_PLAYER_SOUNDS]; new g_PSKeyString[MAX_PLAYER_SOUNDS][MAX_NAME_LENGTH]; new g_PSConnectSelf[MAX_PLAYER_SOUNDS][MAX_SOUND_LENGTH]; new g_PSConnectOther[MAX_PLAYER_SOUNDS][MAX_SOUND_LENGTH]; new g_PSDisconnectOther[MAX_PLAYER_SOUNDS][MAX_SOUND_LENGTH]; new g_PSSize=0; new g_IP[MAX_PLAYERS]; new g_JustConnected[MAX_PLAYERS]; new g_StartOfRound=1; new g_SelfTimers[MAX_PLAYERS]; new g_OtherTimers[MAX_PLAYERS]; new g_LogdDetected=0; /* True if logd is installed */ /*********************************************************/ /* Standard event handlers for adminmod */ /*********************************************************/ public plugin_init() { plugin_registerinfo("Bugblatter's Sound plugin","Provide various sound releated features",g_Version); /* Check server is configured properly */ new fOK = checkFileAccessRead(); fOK = checkVaultOK() && fOK; if (fOK == 0) { return PLUGIN_CONTINUE; } if (ReadPlayerSounds() == 0) { return PLUGIN_CONTINUE; } /* No need to abort if this one fails */ checkLanguage(); readvaultnum("bbsound_enabled",g_Enabled,DEFAULT_ENABLED,MIN_ENABLED,MAX_ENABLED); RegisterPlugin(); set_timer("StartOfRound",30,1,""); plugin_registercmd("bbsound_logdts","BBLogdTeamSelect",131072,""); exec("logd_reg 54 admin_command bbsound_logdts",0); return PLUGIN_CONTINUE; } RegisterPlugin() { /* Register commands with adminmod */ language_init(); plugin_registercmd("bbsound_speak","BBSoundSpeak",ACCESS_SAY, "bbsound_speak <message>: Speaks a message to all players."); plugin_registercmd("bbsound_enabled","BBSoundEnabled",ACCESS_CONFIG, "bbsound_enabled < ^"on^" | ^"off^" >: Enables / Disables player connection sounds."); plugin_registercmd("bbsound_report","BBSoundReport",ACCESS_CONFIG, "bbsound_report [ ^"on^" | ^"off^" ]: shows the sound config, and enables/disable report after every command"); plugin_registercmd("bbsound_reset","BBSoundReset",ACCESS_CONFIG, "bbsound_reset: resets all sound configuraiton settings to the compiled defaults"); g_Registered=1; } public plugin_connect(HLUserName, HLIP, UserIndex) { if (g_Registered ==0) { return PLUGIN_FAILURE; } PlayerConnected(UserIndex); new Data[MAX_DATA_LENGTH]; safe_convert(HLIP,Data,MAX_DATA_LENGTH); strtoip(Data,g_IP[UserIndex]); return PLUGIN_CONTINUE; } public plugin_info(HLOldName, HLNewName, UserIndex) { if (g_Registered ==0) { return PLUGIN_FAILURE; } if (IsPlayerConnected(UserIndex)==0) { return 0; } /* Prevent sounds in the first 20 seconds as it will * just be a mess */ if (g_StartOfRound == 1) { return PLUGIN_CONTINUE; } new OldName[MAX_NAME_LENGTH]; safe_convert(HLOldName, OldName, MAX_NAME_LENGTH); new NewName[MAX_NAME_LENGTH]; safe_convert(HLNewName, NewName, MAX_NAME_LENGTH); new userid = 0; new wonid=0; new team=0; new dead=0; new AuthID[MAX_AUTHID_LENGTH]; new UserName[MAX_NAME_LENGTH]; /* this fails for humans, works for bots, but we don't really care * as AuthID is only needed for bots*/ playerinfo(UserIndex, UserName, MAX_NAME_LENGTH, userid, wonid,team,dead,AuthID); if (((OldName[0] == NULL_CHAR) || isbot(AuthID)) && (NewName[0] != NULL_CHAR)) { new UserData[3]; UserData[0]=UserIndex; UserData[1]=10; UserData[2]=NULL_CHAR; if (g_LogdDetected) { g_JustConnected[UserIndex] = 1; } else { if (g_SelfTimers[UserIndex]) { kill_timer(g_SelfTimers[UserIndex]); } g_SelfTimers[UserIndex] = set_timer("HandleConnect",30,1,UserData); if (g_OtherTimers[UserIndex]) { kill_timer(g_OtherTimers[UserIndex]); } g_OtherTimers[UserIndex] = set_timer("HandleConnectOther",15,1,UserData); } } return PLUGIN_CONTINUE; } public plugin_disconnect(HLUserName, UserIndex) { if (g_Registered ==0) { return PLUGIN_FAILURE; } PlayerDisconnected(UserIndex); g_IP[UserIndex] = -1; if (g_SelfTimers[UserIndex]) { kill_timer(g_SelfTimers[UserIndex]); g_SelfTimers[UserIndex]=0; } if (g_OtherTimers[UserIndex]) { kill_timer(g_OtherTimers[UserIndex]); g_OtherTimers[UserIndex]=0; } HandleDisconnect(UserIndex); return PLUGIN_CONTINUE; } public BBLogdTeamSelect(HLCommand,HLData,HLUserName,UserIndex) { new Data[MAX_DATA_LENGTH]; safe_convert(HLData, Data, MAX_DATA_LENGTH); new i = strtonum(Data); g_LogdDetected=1; if ((i>0) && (i<=MAX_PLAYERS)) { if (g_JustConnected[i]) { g_JustConnected[i]=0; DoHandleConnect(i,10); DoHandleConnectOther(i,10); } } return PLUGIN_HANDLED; } /*********************************************************/ /* Command handlers for admin commands */ /*********************************************************/ public BBSoundSpeak(HLCommand,HLData,HLUserName,UserIndex) { new Message[MAX_DATA_LENGTH]; safe_convert(HLData,Message,MAX_DATA_LENGTH); strstripquotes(Message); preparespeech(Message); SpeakOther("",Message); return PLUGIN_HANDLED; } public BBSoundEnabled(HLCommand,HLData,HLUserName,UserIndex) { if (readHLonoff(HLData,g_Enabled,DEFAULT_ENABLED,MIN_ENABLED,MAX_ENABLED)) { writevaultnum("bbsound_enabled",g_Enabled); } return ShowConfig(0,UserIndex); } public BBSoundReset(HLCommand,HLData,HLUserName,UserIndex) { g_Enabled=DEFAULT_ENABLED; writevaultnum("bbsound_report",g_Enabled); return ShowConfig(0,UserIndex); } public BBSoundReport(HLCommand,HLData,HLUserName,UserIndex) { if (readHLonoff(HLData,g_Report,DEFAULT_REPORT,MIN_REPORT,MAX_REPORT)) { writevaultnum("bbsound_report",g_Report); ShowConfig(0,UserIndex); } else { ShowConfig(1,UserIndex); } return PLUGIN_HANDLED; } 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_Enabled) { language_say(UserIndex,g_MSG_RPT_ENABLED_ON,print_type:print_console); } else { language_say(UserIndex,g_MSG_RPT_ENABLED_OFF,print_type:print_console); } return PLUGIN_HANDLED; } /*********************************************************/ /* Sound file handling */ /*********************************************************/ ReadPlayerSounds() { g_PSSize=0; new SoundsFile[MAX_DATA_LENGTH]; if (getfilelocation(SoundsFile,"playersounds.ini")==0) { return 0; } new ReadCount = filesize(SoundsFile)+1; if (ReadCount >= MAX_PLAYER_SOUNDS) { new msg[MAX_TEXT_LENGTH]; snprintf(msg,MAX_TEXT_LENGTH,"ERROR: You have more than %i player sounds in %s",MAX_PLAYER_SOUNDS,SoundsFile); log(msg); log("You must recompile plugin_blatt_sounds with a higher value for MAX_PLAYER_SOUNDS"); return 0; } new i; new args; new Line[MAX_SOUNDS_LENGTH]; new Type[MAX_DATA_LENGTH]; new Key[MAX_DATA_LENGTH]; new ConnectSelf[MAX_SOUND_LENGTH]; new ConnectOther[MAX_SOUND_LENGTH]; new DisconnectOther[MAX_SOUND_LENGTH]; new msg[MAX_TEXT_LENGTH]; for(i=0;i<ReadCount;i++) { /* File line numbers are indexed from 1, not 0, hence the +1 */ readline(SoundsFile,i,Line); if (strlen(Line)>0) { args=strsplitx(Line,':','\',Type,MAX_DATA_LENGTH,Key,MAX_DATA_LENGTH,ConnectSelf,MAX_SOUND_LENGTH,ConnectOther,MAX_SOUND_LENGTH,DisconnectOther,MAX_SOUND_LENGTH); if (args > 3) { strtrim(Type," ^t",2); strtrim(Key," ^t",2); strtrim(ConnectSelf," ^t",2); strtrim(ConnectOther," ^t",2); strtrim(DisconnectOther," ^t",2); if (strcasecmp(Type,"wonid")==0) { g_PSType[g_PSSize] = PSTYPE_WONID; strcpy(g_PSKeyString[g_PSSize],Key,MAX_DATA_LENGTH); } else if (strcasecmp(Type,"name")==0) { g_PSType[g_PSSize] = PSTYPE_NAME; strcpy(g_PSKeyString[g_PSSize],Key,MAX_DATA_LENGTH); } else if (strcasecmp(Type,"ip")==0) { g_PSType[g_PSSize] = PSTYPE_IP; if (strtoip(Key,g_PSKey[g_PSSize])==0) { snprintf(msg,MAX_TEXT_LENGTH,"Line %i of %s contains an invalid IP address %s",i,SoundsFile,Key); configError(msg); continue; } } else if (strcasecmp(Type,"level")==0) { g_PSType[g_PSSize] = PSTYPE_LEVEL; g_PSKey[g_PSSize] = strtonum(Key); } else if (strcasecmp(Type,"clan")==0) { g_PSType[g_PSSize] = PSTYPE_CLAN; strcpy(g_PSKeyString[g_PSSize],Key,MAX_DATA_LENGTH); } else if (strcasecmp(Type,"any")==0) { g_PSType[g_PSSize] = PSTYPE_ANY; /* key is irrelevent in this case */ } else { snprintf(msg,MAX_TEXT_LENGTH,"Line %i of %s contains unknown type %s",i,SoundsFile,Type); configError(msg); continue; } preparespeech(ConnectSelf); preparespeech(ConnectOther); preparespeech(DisconnectOther); strcpy(g_PSKeyString[g_PSSize],Key,MAX_DATA_LENGTH); strcpy(g_PSConnectSelf[g_PSSize],ConnectSelf,MAX_DATA_LENGTH); strcpy(g_PSConnectOther[g_PSSize],ConnectOther,MAX_DATA_LENGTH); strcpy(g_PSDisconnectOther[g_PSSize],DisconnectOther,MAX_DATA_LENGTH); g_PSSize++; } else { snprintf(msg,MAX_TEXT_LENGTH,"Line %i of %s is not formatted correctly",i,SoundsFile); configError(msg); } } } return 1; } public StartOfRound(Timer,Repeat,HLUserName,HLParam) { g_StartOfRound=0; } public HandleConnect(Timer,Repeat,HLUserName,HLParam) { new UserData[2]; convert_string(HLParam,UserData,2); DoHandleConnect(UserData[0],UserData[1]); } DoHandleConnect(UserIndex,Retries) { new i; new userid = 0; new wonid=0; new team=0; new dead=0; new AuthID[MAX_AUTHID_LENGTH]; new UserName[MAX_NAME_LENGTH]; Retries=Retries-1; g_SelfTimers[UserIndex] = 0; if(playerinfo(UserIndex, UserName, MAX_NAME_LENGTH, userid, wonid,team,dead,AuthID)==0) { if (Retries > 0) { new UserData[3]; UserData[0]=UserIndex; UserData[1]=Retries; UserData[2]=0; g_SelfTimers[UserIndex] = set_timer("HandleConnect",5,1,UserData); } else { log("Player info failed in HandleConnect 10 times - giving up"); return 0; } } for (i=0;i<g_PSSize;i++) { switch(g_PSType[i]) { case PSTYPE_WONID: if (streq(g_PSKeyString[i],AuthID)==0) { continue; } case PSTYPE_NAME: if (streq(g_PSKeyString[i],UserName)==0) { continue; } case PSTYPE_IP: if (g_PSKey[i] != g_IP[UserIndex]) { continue; } case PSTYPE_LEVEL: if (access(g_PSKey[i],UserName) ==0) { continue; } case PSTYPE_CLAN: if (strmatch(g_PSKeyString[i],UserName,strlen(g_PSKeyString[i]))==0) { continue; } } /* If it reaches this point, no continue above fired, so the line matches */ if (strlen(g_PSConnectSelf[i]) > 0) { Speak(UserName,g_PSConnectSelf[i]); return 1; } } return 0; } public HandleConnectOther(Timer,Repeat,HLUserName,HLParam) { new UserData[2]; convert_string(HLParam,UserData,2); DoHandleConnectOther(UserData[0],UserData[1]); } DoHandleConnectOther(UserIndex,Retries) { new i; new userid = 0; new wonid=0; new team=0; new dead=0; new AuthID[MAX_AUTHID_LENGTH]; new UserName[MAX_NAME_LENGTH]; Retries=Retries-1; g_SelfTimers[UserIndex] = 0; if(playerinfo(UserIndex, UserName, MAX_NAME_LENGTH, userid, wonid,team,dead,AuthID)==0) { if (Retries > 0) { new UserData[3]; UserData[0]=UserIndex; UserData[1]=Retries; UserData[2]=0; g_SelfTimers[UserIndex] = set_timer("HandleConnectOther",5,1,UserData); } else { log("Player info failed in HandleConnectOther 10 times - giving up"); return 0; } } for (i=0;i<g_PSSize;i++) { switch(g_PSType[i]) { case PSTYPE_WONID: if (streq(g_PSKeyString[i],AuthID)==0) { continue; } case PSTYPE_NAME: if (streq(g_PSKeyString[i],UserName)==0) { continue; } case PSTYPE_IP: if (g_PSKey[i] != g_IP[UserIndex]) { continue; } case PSTYPE_LEVEL: if (access(g_PSKey[i],UserName) ==0) { continue; } case PSTYPE_CLAN: if (strmatch(g_PSKeyString[i],UserName,strlen(g_PSKeyString[i]))==0) { continue; } } /* If it reaches this point, no continue above fired, so the line matches */ if (strlen(g_PSConnectOther[i]) > 0) { SpeakOther(UserName,g_PSConnectOther[i]); return 1; } } return 0; } HandleDisconnect(UserIndex) { new i; new userid = 0; new wonid=0; new team=0; new dead=0; new AuthID[MAX_AUTHID_LENGTH]; new UserName[MAX_NAME_LENGTH]; if(playerinfo(UserIndex, UserName, MAX_NAME_LENGTH, userid, wonid,team,dead,AuthID)==0) { return 0; } for (i=0;i<g_PSSize;i++) { switch(g_PSType[i]) { case PSTYPE_WONID: { if (streq(g_PSKeyString[i],AuthID)==0) { continue; } } case PSTYPE_NAME: { if (streq(g_PSKeyString[i],UserName)==0) { continue; } } case PSTYPE_IP: { if (g_PSKey[i] != g_IP[UserIndex]) { continue; } } case PSTYPE_LEVEL: { if (access(g_PSKey[i],UserName) ==0) { continue; } } case PSTYPE_CLAN: { if (strmatch(g_PSKeyString[i],UserName,strlen(g_PSKeyString[i]))==0) { continue; } } } /* If it reaches this point, no continue above fired, so the line matches */ if ((strlen(g_PSConnectOther[i]) > 0)) { SpeakOther(UserName,g_PSDisconnectOther[i]); return 1; } } return 0; }