ok hier di Fehlermeldung:
plugin_sank_sounds.sma(49) Fatal [100]: cannot read from file: "..\include\sound.inc"
Und hier der sma Inhalt:
/***************************************************************************
* plugin_sank_sounds.sma
* Author: Luke Sankey
* Date: March 21, 2001 - Original hard-coded version
* Date: July 2, 2001 - Rewrote to be text file configurable
* Last Updated: July 8, 2001
*
* This plugin will read from a text file keyword/wav file combinations
* and when a player says one of the keywords, it will trigger HL to play
* that wav file to all players. It allows reloading of the file without
* restarting the current level, as well as adding keyword/wav combinations
* from the console during gameplay. If it finds it can't read the file, it
* will automagically set file_access_read to 1 and then set it back to 0
* when it's done.
*
* My most deepest thanks goes to William Bateman (aka HunteR)
*
http://thepit.shacknet.nu
*
huntercc@hotmail.com
* For he was the one who got me motivated once again to write this plugin
* since I don't run a server anymore. And besides that, he helped write
* parts of it.
*
* For technical assistance with this plugin, please see the README.TXT file
* that was bundled in the zip file. When that fails (and it will, because
* I'm the one who wrote it) then please see the adminmod forums at
*
http://www.adminmod.org If they still fail you, email Bill Bateman.
* As a very last final resort, email me:
sank@spu.edu
*
* I hope you enjoy this new functionality on the old plugin_sank_sounds!
*
* Luke Sankey
*
sank@spu.edu
***************************************************************************/
// Functions included in this plugin
// admin_sound_add "<keyword>;<dir\wav>"
// admin_sound_help
// admin_sound_off
// admin_sound_on
// admin_sound_reload [filename]
// admin_sound_remove "<keyword>;[dir\wav]"
// admin_sound_write <filename>
#include <core>
#include <console>
#include <string>
#include <admin>
#include <adminlib>
#include <sound>
#include <dead>
#define ACCESS_SOUND 512+64 // Access level for advanced sound commands.
new FILENAME[MAX_DATA_LENGTH] = "SND-LIST.CFG"; // Name of file to parse.
#define MAX_KEYWORDS 40 // Maximum number of keywords
#define MAX_RANDOM 10 // Maximum number of wavs per keyword
#define TOK_LENGTH 40 // Maximum length of keyword and wav file strings
#define NUM_PER_LINE 4 // Number of words per line from admin_sound_help
//#define DEBUG 1
/****************************************************************************/
/****************************************************************************/
/************** 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.e";
/****************************************************************************/
/* Holds the number telling how many sounds a player has played */
new SndCount[MAX_PLAYERS] = {0,...};
/* The number at which a player will get warned for playing too many sounds */
new SND_WARN = 0;
/* The number at which a player will get kicked for playing too many sounds */
new SND_KICK = 0;
/* The wav to play when a person joins the game */
new SND_JOIN[TOK_LENGTH] = "";
/* The wav to play when a person exits the game */
new SND_EXIT[TOK_LENGTH] = "";
/****************************************************************************/
/****************************************************************************/
/* First column is the indentifier of the Word-Wav Combination */
/* Second column is the token identifier */
/* Third column is the token (string) */
/* Empty tokens are delimited by empty strings */
/****************************************************************************/
/*
[0] [TOK_LENGTH*0] ["crap"]
[0] [TOK_LENGTH*1] ["misc/awwcrap.wav"]
[0] [TOK_LENGTH*2] ["misc/awwcrap2.wav"]
[0] [TOK_LENGTH*3] [""]
[1] [TOK_LENGTH*0] ["woohoo"]
[1] [TOK_LENGTH*1] ["misc/woohoo.wav"]
[1] [TOK_LENGTH*2] [""]
[2] [TOK_LENGTH*0] ["ha ha"]
[2] [TOK_LENGTH*1] ["misc/haha.wav"]
[2] [TOK_LENGTH*2] [""]
[3] [TOK_LENGTH*0] ["doh"]
[3] [TOK_LENGTH*1] ["misc/doh.wav"]
[3] [TOK_LENGTH*2] ["misc/doh2.wav"]
[3] [TOK_LENGTH*3] ["misc/doh3.wav"]
[3] [TOK_LENGTH*4] ["misc/doh4.wav"]
[3] [TOK_LENGTH*5] [""]
[4] [TOK_LENGTH*0] [""]
...
*/
new WordWavCombo[MAX_KEYWORDS][TOK_LENGTH*(MAX_RANDOM+1)];
/****************************************************************************/
new LastSoundTime = 0; // Used for very limited spam protection
new bSoundsEnabled = 1; // Used for admin_sound_on and admin_sound_off
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
public plugin_init()
{
plugin_registerinfo("Sank Sounds Plugin", "Responds to certain chat messages by playing a sound.", STRING_VERSION);
plugin_registercmd("say", "HandleSay", ACCESS_ALL);
plugin_registercmd("admin_sound_add", "admin_sound_add", ACCESS_SOUND, "admin_sound_add ^"<keyword>;<dir\wav>^" : Adds a word/wav combo for the duration of the level.");
plugin_registercmd("admin_sound_help", "admin_sound_help", ACCESS_ALL, "admin_sound_help: Lists all sounds associated with say command");
plugin_registercmd("admin_sound_off", "admin_sound_off", ACCESS_SOUND, "admin_sound_off: Turns off sounds.");
plugin_registercmd("admin_sound_on", "admin_sound_on", ACCESS_SOUND, "admin_sound_on: Turns on sounds.");
plugin_registercmd("admin_sound_reload", "admin_sound_reload", ACCESS_SOUND, "admin_sound_reload: Re-parses sound list config file.");
plugin_registercmd("admin_sound_remove", "admin_sound_remove", ACCESS_SOUND, "admin_sound_remove ^"<keyword>;[dir\wav]^" : Removes a word/wav combo for the duration of the level.");
plugin_registercmd("admin_sound_write", "admin_sound_write", ACCESS_SOUND, "admin_sound_write: Writes current sound configuration to file.");
#if defined (DEBUG)
plugin_registercmd("admin_sound_debug", "print_matrix", ACCESS_SOUND, "admin_sound_debug");
#endif
parse_sound_file(FILENAME);
return PLUGIN_CONTINUE;
}
public plugin_connect(HLUserName, HLIP, UserIndex)
{
playsoundall(SND_JOIN);
if (UserIndex >= 1 && UserIndex <= MAX_PLAYERS)
SndCount[UserIndex] = 0;
return PLUGIN_CONTINUE;
}
public plugin_disconnect(HLUserName, UserIndex)
{
if (UserIndex >= 1 && UserIndex <= MAX_PLAYERS)
SndCount[UserIndex] = 0;
playsoundall(SND_EXIT); /* moeglicher Bot-Crash */
return PLUGIN_CONTINUE;
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
// Adds a Word/Wav combo to the list. If it is a valid line in the config
// file, then it is a valid parameter here. The only difference is you can
// only specify one .wav file at a time with this command.
//
// Usage: admin_sound_add "<keyword>;<dir\wav>"
// Usage: admin_sound_add "<setting>;<value>"
//////////////////////////////////////////////////////////////////////////////
public admin_sound_add(HLCommand, HLData, HLUserName, UserIndex)
{
new Data[MAX_DATA_LENGTH];
new User[MAX_NAME_LENGTH];
new Word[TOK_LENGTH];
new Wav[TOK_LENGTH];
new Text[MAX_TEXT_LENGTH];
new i;
new j;
convert_string(HLData, Data, MAX_DATA_LENGTH);
convert_string(HLUserName, User, MAX_NAME_LENGTH);
// Parse command line
strsplit(Data, ";", Word, TOK_LENGTH, Wav, TOK_LENGTH);
// Remove whitespace
strtrim(Word, " ^t");
strtrim(Wav, " ^t");
if(strlen(Data) == 0 || strlen(Wav) == 0)
{
selfmessage("Invalid format.");
selfmessage("USAGE: admin_sound_add ^"<keyword>;<dir\wav>^"");
return PLUGIN_HANDLED;
}
// First look for special parameters
if (!strcasecmp(Data, "SND_KICK"))
SND_KICK = strtonum(Wav);
else if (!strcasecmp(Data, "SND_WARN"))
SND_WARN = strtonum(Wav);
else if (!strcasecmp(Data, "SND_JOIN"))
strcpy(SND_JOIN, Wav, TOK_LENGTH);
else if (!strcasecmp(Data, "SND_EXIT"))
strcpy(SND_EXIT, Wav, TOK_LENGTH);
// Loop once for each keyword
for(i=0; i<MAX_KEYWORDS; i++)
{
// If an empty string, then break this loop
if(strlen(WordWavCombo
) == 0)
break;
// If we find a match, then add on the new wav data
if(strncmp(Word, WordWavCombo, TOK_LENGTH) == 0)
{
// See if the wav already exists
for(j=1; j<=MAX_RANDOM; j++)
{
// If an empty string, then break this loop
if (strlen(WordWavCombo[TOK_LENGTH*j]) == 0)
break;
// See if this is the same as the new wav
if(strncmp(Wav, WordWavCombo[TOK_LENGTH*j], TOK_LENGTH) == 0)
{
snprintf(Text, MAX_TEXT_LENGTH, "%s; %s already exists.", Word, Wav);
selfmessage(Text);
return PLUGIN_HANDLED;
}
}
// If we reached the end, then there is no room
if(j == MAX_RANDOM)
selfmessage("No room for new wav. Increase MAX_RANDOM.");
else
{
// Word exists, but Wav is new to the list, so add entry
strcpy(WordWavCombo[TOK_LENGTH*j], Wav, TOK_LENGTH);
snprintf(Text, MAX_TEXT_LENGTH, "%s successfully added to %s", Wav, Word);
selfmessage(Text);
}
return PLUGIN_HANDLED;
}
}
// If we reached the end, then there is no room
if(i == MAX_KEYWORDS)
selfmessage("No room for new Word/Wav combo. Increase MAX_KEYWORDS");
else
{
// Word/Wav combo is new to the list, so make a new entry
strcpy(WordWavCombo[TOK_LENGTH*0], Word, TOK_LENGTH);
strcpy(WordWavCombo[TOK_LENGTH*1], Wav, TOK_LENGTH);
snprintf(Text, MAX_TEXT_LENGTH, "%s; %s successfully added.", Word, Wav);
selfmessage(Text);
}
return PLUGIN_HANDLED;
}
//////////////////////////////////////////////////////////////////////////////
// Instead of using admin_help, which uses static data, admin_sound_help
// always lists the most up-to-date information because the Word/Wav list can
// change the middle of gameplay. admin_sound_help lists all admin_sound
// commands and keywords to the user.
//
// Usage: admin_sound_help
//////////////////////////////////////////////////////////////////////////////
public admin_sound_help(HLCommand,HLData,HLUserName,UserIndex)
{
new User[MAX_NAME_LENGTH];
new Text[MAX_TEXT_LENGTH] = "";
new i = 0;
convert_string(HLUserName,User,MAX_NAME_LENGTH);
selfmessage("admin_sound_help: Shows this text.");
selfmessage("admin_sound_on: Turns on playing of wav files with this plugin.");
selfmessage("admin_sound_off: Turns off playing of wav files with this plugin.");
selfmessage("admin_sound_reload [filename] : Reloads config file. Filename is optional.");
selfmessage("admin_sound_add ^"<keyword>;<dir\wav>^" : Adds a Word/Wav combo to the sound list. Must use quotes");
selfmessage("admin_sound_remove ^"<keyword>;[dir\wav]^" : Removes a Word/Wav combo from the list. Must use quotes");
selfmessage("say <keyword>: Plays a sound. Keywords are listed below:");
// Loop once for each keyword
for(i=0; i<MAX_KEYWORDS; i++)
{
// If an invalid string, then break this loop
if( (strlen(WordWavCombo) == 0) || (strlen(WordWavCombo) > TOK_LENGTH) )
break;
strcat(Text, WordWavCombo, MAX_TEXT_LENGTH);
strcat(Text, " ^t ^t", MAX_TEXT_LENGTH);
if(i % NUM_PER_LINE == NUM_PER_LINE - 1)
{
// We got NUM_PER_LINE on this line,
// so print it and start on the next line
selfmessage(Text);
Text[0] = 0;
}
}
if(strlen(Text) != 0)
selfmessage(Text);
return PLUGIN_HANDLED;
}
//////////////////////////////////////////////////////////////////////////////
// Turns off the playing of the wav files for this plugin only.
//
// Usage: admin_sound_off
//////////////////////////////////////////////////////////////////////////////
public admin_sound_off(HLCommand, HLData, HLUserName, UserIndex)
{
bSoundsEnabled = 0;
say("Sank Sounds Plugin has been disabled!");
playsoundall("misc\awwcrap.wav"); /* moeglicher Bot-Crash */
return PLUGIN_HANDLED;
}
//////////////////////////////////////////////////////////////////////////////
// Turns on the playing of the wav files for this plugin only.
//
// Usage: admin_sound_on
//////////////////////////////////////////////////////////////////////////////
public admin_sound_on(HLCommand, HLData, HLUserName, UserIndex)
{
bSoundsEnabled = 1;
say("Sank Sounds Plugin has been enabled!");
playsoundall("misc\woohoo.wav"); /* moeglicher Bot-Crash */
return PLUGIN_HANDLED;
}
//////////////////////////////////////////////////////////////////////////////
// Reloads the Word/Wav combos from filename.
//
// Usage: admin_sound_reload [filename]
//////////////////////////////////////////////////////////////////////////////
public admin_sound_reload(HLCommand, HLData, HLUserName, UserIndex)
{
new parsefile[MAX_DATA_LENGTH];
convert_string(HLData, parsefile, MAX_DATA_LENGTH);
// Initialize WordWavCombo[][][] array
new i;
for(i = 0; i < MAX_KEYWORDS; i++)
WordWavCombo[i][0] = 0;
parse_sound_file(parsefile);
return PLUGIN_HANDLED;
}
//////////////////////////////////////////////////////////////////////////////
// Removes a Word/Wav combo from the list. You must specify a keyword, but it
// is not necessary to specify a wav if you want to remove all wavs associated
// with that keyword. Surrounding quotes are required.
//
// Usage: admin_sound_remove "<keyword>;[wav]"
//////////////////////////////////////////////////////////////////////////////
public admin_sound_remove(HLCommand, HLData, HLUserName, UserIndex)
{
new Data[MAX_DATA_LENGTH];
new User[MAX_NAME_LENGTH];
new Word[TOK_LENGTH];
new Wav[TOK_LENGTH];
new Text[MAX_TEXT_LENGTH];
new iCurWord;
new jCurWav;
convert_string(HLData, Data, MAX_DATA_LENGTH);
convert_string(HLUserName, User, MAX_NAME_LENGTH);
// Parse command line
strsplit(Data, ";", Word, TOK_LENGTH, Wav, TOK_LENGTH);
// Remove whitespace
strtrim(Word, " ^t");
strtrim(Wav, " ^t");
if(strlen(Data) == 0)
{
selfmessage("Invalid format.");
selfmessage("USAGE: admin_sound_remove ^"<keyword>;[dir\wav]^"");
return PLUGIN_HANDLED;
}
// Loop once for each keyword
for(iCurWord=0; iCurWord<MAX_KEYWORDS; iCurWord++)
{
// If an empty string, then break this loop, we're at the end
if(strlen(WordWavCombo[iCurWord]) == 0)
break;
// Look for a Word match
if(strncmp(Word, WordWavCombo[iCurWord], TOK_LENGTH) == 0)
{
// If no wav was specified, then remove the whole word's entry
if(strlen(Wav) == 0)
{
// Keep looping i, copying the next into the current
for(; iCurWord<MAX_KEYWORDS; iCurWord++)
{
// If we're about to copy a string that doesn't exist,
// then just erase the last string instead of copying.
if (iCurWord >= MAX_KEYWORDS-1)
{
// Delete the last word string
WordWavCombo[iCurWord][0] = 0;
// We reached the end
snprintf(Text, MAX_TEXT_LENGTH, "%s successfully removed.", Word);
selfmessage(Text);
return PLUGIN_HANDLED;
}
else
{
// Copy the next string over the current string
for(jCurWav=0; jCurWav<TOK_LENGTH*(MAX_RANDOM+1); jCurWav++)
WordWavCombo[iCurWord][jCurWav] = WordWavCombo[iCurWord+1][jCurWav];
}
}
}
else
{
// Just remove the one wav, if it exists
for(jCurWav=1; jCurWav<=MAX_RANDOM; jCurWav++)
{
// If an empty string, then break this loop, we're at the end
if (strlen(WordWavCombo[iCurWord][TOK_LENGTH*jCurWav]) == 0)
break;
// Look for a Wav match
if(strncmp(Wav, WordWavCombo[iCurWord][TOK_LENGTH*jCurWav], TOK_LENGTH) == 0)
{
for(; jCurWav<=MAX_RANDOM; jCurWav++)
{
// If this is the only wav entry, then remove the entry altogether
if ( (jCurWav == 1) && (strlen(WordWavCombo[iCurWord][TOK_LENGTH*(jCurWav+1)]) == 0) )
{
// Keep looping i, copying the next into the current
for(; iCurWord<MAX_KEYWORDS; iCurWord++)
{
// If we're about to copy a string that doesn't exist,
// then just erase the last string instead of copying.
if (iCurWord >= MAX_KEYWORDS-1)
{
// Delete the last word string
WordWavCombo[iCurWord][0] = 0;
// We reached the end
snprintf(Text, MAX_TEXT_LENGTH, "%s successfully removed.", Word);
selfmessage(Text);
return PLUGIN_HANDLED;
}
else
{
// Copy the next string over the current string
for(jCurWav=0; jCurWav<TOK_LENGTH*(MAX_RANDOM+1); jCurWav++)
WordWavCombo[iCurWord][jCurWav] = WordWavCombo[iCurWord+1][jCurWav];
}
}
}
// If we're about to copy a string that doesn't exist,
// then just erase the last string instead of copying.
if(jCurWav >= MAX_RANDOM)
{
// Delete the last wav string
WordWavCombo[iCurWord][TOK_LENGTH*jCurWav] = 0;
// We reached the end
snprintf(Text, MAX_TEXT_LENGTH, "%s successfully removed from %s.", Wav, Word);
selfmessage(Text);
return PLUGIN_HANDLED;
}
else
{
// Copy the next string over the current string
strcpy(WordWavCombo[iCurWord][TOK_LENGTH*jCurWav], WordWavCombo[iCurWord][TOK_LENGTH*(jCurWav+1)], TOK_LENGTH);
}
}
}
}
// We reached the end for this word, and the wav didn't exist
snprintf(Text, MAX_TEXT_LENGTH, "%s not found.", Wav);
selfmessage(Text);
return PLUGIN_HANDLED;
}
}
}
// We reached the end, and the word didn't exist
snprintf(Text, MAX_TEXT_LENGTH, "%s not found.", Word);
selfmessage(Text);
return PLUGIN_HANDLED;
}
//////////////////////////////////////////////////////////////////////////////
// Saves the current configuration of Word/Wav combos to filename for possible
// reloading at a later time. You cannot overwrite the default file.
//
// Usage: admin_sound_write <filename>
//////////////////////////////////////////////////////////////////////////////
public admin_sound_write(HLCommand, HLData, HLUserName, UserIndex)
{
new savefile[MAX_DATA_LENGTH];
new User[MAX_NAME_LENGTH];
new Text[MAX_TEXT_LENGTH];
new TimeStamp[MAX_TEXT_LENGTH];
new bSuccess = 1;
new i;
new j;
convert_string(HLData, savefile, MAX_DATA_LENGTH);
convert_string(HLUserName, User, MAX_NAME_LENGTH);
servertime(TimeStamp, MAX_NUMBER_LENGTH, "%H:%M %B %d, %Y");
// If the filename is NULL, then that's bad.
if (strlen(savefile) == 0)
{
selfmessage("Sound Plugin >> You must specify a filename.");
return PLUGIN_HANDLED;
}
// If the filename is the same as the default FILENAME, then that's bad.
if (strcasecmp(savefile, FILENAME) == 0)
{
selfmessage("Sound Plugin >> Illegal write to default sound config file.");
selfmessage("Sound Plugin >> Specify a different filename.");
return PLUGIN_HANDLED;
}
/************ File should have the following format: **************
# TimeStamp: 07:15 January 15, 2001
# File created by: [SPU]Crazy_Chevy
# Important parameters:
SND_KICK; 30
SND_WARN; 17
SND_JOIN;
SND_EXIT; misc\comeagain.wav
# Word/Wav combinations:
crap; misc\awwcrap.wav;misc\awwcrap2.wav
woohoo; misc\woohoo.wav
ha ha; misc\haha.wav
doh; misc\doh.wav;misc\doh2.wav;misc\doh3.wav
******************************************************************/
// See if we have file_access_write
if (!resetfile(savefile))
{
snprintf(Text, MAX_TEXT_LENGTH, "Sound Plugin >> Cannot write to %s", savefile);
selfmessage(Text);
selfmessage("Sound Plugin >> Make sure file_access_write is set to 1.");
return PLUGIN_HANDLED;
}
// We now assume that we can write to the file, so here we go!
snprintf(Text, MAX_TEXT_LENGTH, "# TimeStamp:^t^t%s", TimeStamp);
writefile(savefile, Text);
snprintf(Text, MAX_TEXT_LENGTH, "# File created by:^t%s", User);
writefile(savefile, Text);
writefile(savefile, ""); // blank line
writefile(savefile, "# Important parameters:");
snprintf(Text, MAX_TEXT_LENGTH, "SND_KICK;^t%d", SND_KICK);
writefile(savefile, Text);
snprintf(Text, MAX_TEXT_LENGTH, "SND_WARN;^t%d", SND_WARN);
writefile(savefile, Text);
snprintf(Text, MAX_TEXT_LENGTH, "SND_JOIN;^t%s", SND_JOIN);
writefile(savefile, Text);
snprintf(Text, MAX_TEXT_LENGTH, "SND_EXIT;^t%s", SND_EXIT);
writefile(savefile, Text);
writefile(savefile, ""); // blank line
writefile(savefile, "# Word/Wav combinations:");
for (i = 0; i < MAX_KEYWORDS && bSuccess; i++)
{
// See if we reached the end
if (strlen(WordWavCombo[i]) == 0)
break;
// I guess not, so format up a string to write
// First, add the keyword
snprintf(Text, MAX_TEXT_LENGTH, "%s;^t", WordWavCombo[i]);
// Then add all the wavs
for (j = 0; j < MAX_RANDOM && strlen(WordWavCombo[i][TOK_LENGTH*j]); j++)
snprintf(Text, MAX_TEXT_LENGTH, "%s%s;", Text, WordWavCombo[i][TOK_LENGTH*j]);
// Now write the formatted string to the file
bSuccess = writefile(savefile, Text);
// And loop for the next wav
}
snprintf(Text, MAX_TEXT_LENGTH, "Sound Plugin >> Configuration successfully written to %s.", savefile);
selfmessage(Text);
return PLUGIN_HANDLED;
}
//////////////////////////////////////////////////////////////////////////////
// This function exists in order to call parse_sound_file from a timer, which
// becomes necessary when file_access_read is set to 0.
//////////////////////////////////////////////////////////////////////////////
public parse_file_timer(Timer, Repeat, HLUser, HLParam)
{
new param[MAX_TEXT_LENGTH];
convert_string(HLParam, param, MAX_TEXT_LENGTH);
parse_sound_file(param);
return PLUGIN_HANDLED;
}
//////////////////////////////////////////////////////////////////////////////
// Parses the sound file specified by loadfile. If loadfile is empty, then
// it parses the default FILENAME.
//
// Returns 0 if parsing was successful
// Returns 1 if parsing failed
// Returns -1 otherwise
//
// Usage: admin_sound_reload <filename>
//////////////////////////////////////////////////////////////////////////////
parse_sound_file(loadfile[] = "")
{
new bGotLine;
new iLineNum = 0;
new strLineBuf[MAX_TEXT_LENGTH];
new WadOstrings[MAX_RANDOM*TOK_LENGTH]; // same as [MAX_RANDOM][TOK_LENGTH]
new ListIndex = 0;
new Text[MAX_TEXT_LENGTH];
/************ File should have the following format: **************
# Set the necessary variables
SND_KICK; 20
SND_WARN; 17
SND_EXIT; misc\comeagain.wav
# Now give the sound list
crap; misc\awwcrap.wav;misc\awwcrap2.wav
woohoo; misc\woohoo.wav
ha ha; misc\haha.wav
doh; misc\doh.wav;misc\doh2.wav;misc\doh3.wav
******************************************************************/
if (strlen(loadfile) == 0)
strcpy(loadfile, FILENAME, MAX_TEXT_LENGTH);
if (fileexists(loadfile) > 0)
{
new i;
bGotLine = readfile(loadfile, strLineBuf, iLineNum, MAX_TEXT_LENGTH);
if (!bGotLine)
{
// If file access is already set correctly...
if (getvar("file_access_read") == 1)
{
snprintf(Text, MAX_TEXT_LENGTH, "Sound Plugin >> Unable to read from %s file.", loadfile);
selfmessage(Text);
// If we set the file access last time, then set it back
get_serverinfo("SNDSetAccess", Text, MAX_TEXT_LENGTH);
if(strncmp(Text, "1", MAX_TEXT_LENGTH) == 0)
exec("file_access_read 0");
set_serverinfo("SNDSetAccess", "0");
return 1;
}
// else set it correctly and try again
exec("file_access_read 1");
// flag ourselves to set it back later
set_serverinfo("SNDSetAccess", "1");
set_timer("parse_file_timer", 1, 0, loadfile);
return -1;
}
// Initialize WordWavCombo[][][] array before using it
for(i = 0; i < MAX_KEYWORDS; i++)
WordWavCombo[i][0] = 0;
while (bGotLine)
{
if (ListIndex >= MAX_KEYWORDS)
{
log("Sound Plugin >> Sound list truncated. Increase MAX_KEYWORDS.");
printf("Sound Plugin >> Stopped parsing %s file.^n", loadfile);
break;
}
// As long as the line isn't commented out, and isn't blank, then process it.
if ((strncmp(strLineBuf, "#", 1) != 0) && (strncmp(strLineBuf, "//", 2) != 0) && (strlen(strLineBuf) != 0))
{
// Take up to MAX_RANDOM wav files for each keyword, each separated by a ';'
// Right now we fill the big WadOstrings[] with the information from the file.
for(i=0; i<=MAX_RANDOM; i++)
{
strsep(strLineBuf, ";", WadOstrings[TOK_LENGTH*i], TOK_LENGTH, strLineBuf, MAX_TEXT_LENGTH);
}
// If we finished MAX_RANDOM times, and strRest still has contents
// then we should have a bigger MAX_RANDOM
if(strlen(strLineBuf) != 0)
{
log("Sound Plugin >> Sound list partially truncated. Increase MAX_RANDOM.");
printf("Sound Plugin >> Continuing to parse %s file.^n", loadfile);
}
// Now remove any spaces or tabs from around the strings -- clean them up
for(i=0; i<MAX_RANDOM; i++)
{
strtrim(WadOstrings[TOK_LENGTH*i], " ^t");
}
// First look for special parameters
if (!strcasecmp(WadOstrings, "SND_KICK"))
SND_KICK = strtonum(WadOstrings[TOK_LENGTH*1]);
else if (!strcasecmp(WadOstrings, "SND_WARN"))
SND_WARN = strtonum(WadOstrings[TOK_LENGTH*1]);
else if (!strcasecmp(WadOstrings, "SND_JOIN"))
strcpy(SND_JOIN, WadOstrings[TOK_LENGTH*1], TOK_LENGTH);
else if (!strcasecmp(WadOstrings, "SND_EXIT"))
strcpy(SND_EXIT, WadOstrings[TOK_LENGTH*1], TOK_LENGTH);
// If it wasn't one of those essential parameters, then it should be
// a Keyword/Wav combo, so we'll treat it as such by copying it from our
// temporary structure into our global structure, WordWavCombo[][][]
else
{
// Now we must transfer the contents of WadOstrings[] to
// our global data structure, WordWavCombo[Index][]
// with a really tricky "string copy"
for(i=0; i<MAX_RANDOM*TOK_LENGTH; i++)
{
WordWavCombo[ListIndex][i] = WadOstrings[i];
}
ListIndex++;
}
}
// Initialize variables for next time by clearing all the
// strings in the WadOstrings[]
for(i = 0; i < MAX_RANDOM; i++)
{
WadOstrings[i*TOK_LENGTH] = 0;
}
// Read in the next line from the file
bGotLine = readfile(loadfile, strLineBuf, ++iLineNum, MAX_TEXT_LENGTH);
// This is pretty gay hacking, but here goes. The readfile API function here
// has a static buffer that is 100 chars long in AM version 2.50.e and previous.
// A line longer than 100 chars in length looks like 2 lines to us in the script,
// with the first 'line' being the first 100 chars and the second 'line' being
// the rest of the line (given it is shorter than 100 as well). So in order to
// fix this, we have to read in two lines, but only if the first has filled the
// first 100 chars completely. Then we add the second string to the end of the
// first and we get what we should've gotten the first time we did readline().
// In AM versions later than 2.50.e, this should be removed, because I'm told
// the static buffer will be increased to 200, which is the MAX_TEXT_LENGTH for
// us anyway.
if (strlen(strLineBuf) == 99)
{
bGotLine = readfile(loadfile, Text, ++iLineNum, MAX_TEXT_LENGTH);
strcat(strLineBuf, Text, MAX_TEXT_LENGTH);
}
}
// Now we have all of the data from the text file in our data structures.
// Next we do some error checking, some setup, and we're done parsing!
// Do some error checking on the user-input numbers
// If SND_KICK is zero, then sounds quota is disabled.
if (SND_KICK <= 0)
{
SND_KICK = 0; // in case it was negative
log("Sound quota disabled.");
}
// If SND_WARN is zero, then we can't have warning every
// time a keyword is said, so we default to 3 less than max
else if (SND_WARN <= 0)
{
if (SND_KICK > 3)
SND_WARN = SND_KICK - 3;
else
SND_WARN = SND_KICK - 1;
log("Sound Plugin >> SND_WARN cannot be set to zero.");
log(" >> SND_WARN set to default value.");
}
// And finally, if they want to warn after a person has been
// kicked, that's silly, so we'll fix it.
else if (SND_KICK < SND_WARN)
{
if (SND_KICK > 3)
SND_WARN = SND_KICK - 3;
else
SND_WARN = SND_KICK - 1;
log("Sound Plugin >> SND_WARN cannot be higher than SND_KICK.");
log(" >> SND_WARN set to default value.");
}
// Log some info for the nosey admin
snprintf(Text, MAX_TEXT_LENGTH, "Sound quota set to %i", SND_KICK);
log(Text);
#if defined (DEBUG)
print_matrix();
printf("Sound Plugin >> Done parsing %s file.^n", loadfile);
#endif
}
else // file exists returned false, meaning the file didn't exist
{
snprintf(Text, MAX_TEXT_LENGTH, "Sound Plugin >> Cannot find %s file.", loadfile);
selfmessage(Text);
return 1;
}
// If we set the file access last time, then set it back
get_serverinfo("SNDSetAccess", Text, MAX_TEXT_LENGTH);
if(strncmp(Text, "1", MAX_TEXT_LENGTH) == 0)
{
exec("file_access_read 0");
set_serverinfo("SNDSetAccess", "0");
}
snprintf(Text, MAX_TEXT_LENGTH, "Sound Plugin >> %s successfully loaded.", loadfile);
selfmessage(Text);
return 0;
}
#if defined (DEBUG)
//////////////////////////////////////////////////////////////////////////////
// Prints out word wav combo matrix for debugging purposes. Kinda cool, even
// if you're not really debugging.
//
// Usage: admin_sound_debug
// Usage: admin_sound_reload <filename>
//////////////////////////////////////////////////////////////////////////////
public print_matrix()
{
printf("SND_WARN: %d^n", SND_WARN);
printf("SND_KICK: %d^n", SND_KICK);
printf("SND_JOIN: %s^n", SND_JOIN);
printf("SND_EXIT: %s^n", SND_EXIT);
new i;
new j;
// Print out the matrix of sound data, so we got what we think we did
for(i=0; i<MAX_KEYWORDS; i++)
{
if (strlen(WordWavCombo[i]) != 0)
{
printf("^n");
for(j=0; j<MAX_RANDOM+1; j++)
{
if (strlen(WordWavCombo[i][j*TOK_LENGTH]) != 0)
printf("[%d] [%d] ^"%s^"^n", i, j, WordWavCombo[i][j*TOK_LENGTH]);
}
}
}
return PLUGIN_HANDLED;
}
#endif
//////////////////////////////////////////////////////////////////////////////
// Returns 0 if the user is allowed to say things
// Returns 1 and kicks the user if the quota has been exceeded.
//////////////////////////////////////////////////////////////////////////////
QuotaCheck(User[], UserIndex)
{
// If the sound limitation is disabled, then return happily.
if (SND_KICK == 0)
return 0;
new Text[MAX_TEXT_LENGTH];
new HowManyLeft = SND_KICK - SndCount[UserIndex];
if (check_immunity(User) == 0)
{
if (SndCount[UserIndex] >= SND_KICK)
{
//playsoundall("misc\comeagain.wav"); // moved to the plugin_disconnect function
message(User, "You were warned, but did not quit playing sounds");
snprintf(Text, MAX_TEXT_LENGTH, "Kicked %s for saying too much", User);
say(Text);
kick(User);
return 1;
}
else if (SndCount[UserIndex] >= SND_WARN)
{
messageex(User, "You have almost used up your sound quota. Stop.", print_center);
messageex(User, "You have almost used up your sound quota. Stop.", print_console);
snprintf(Text, MAX_TEXT_LENGTH, "You have %d left before you get kicked.", HowManyLeft);
messageex(User, Text, print_center);
messageex(User, Text, print_console);
}
// Increment their playsound count
SndCount[UserIndex] = SndCount[UserIndex] + 1;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////
// Everything a person says goes through here, and we determine if we want to
// play a sound or not.
//
// Usage: say <something>
//////////////////////////////////////////////////////////////////////////////
public HandleSay(HLCommand, HLData, HLUserName, UserIndex)
{
// If sounds are not enabled, then skip this whole thing
if (!bSoundsEnabled)
return PLUGIN_CONTINUE;
new i;
new Speech[MAX_DATA_LENGTH];
new User[MAX_NAME_LENGTH];
new Text[MAX_TEXT_LENGTH];
new ListIndex = -1;
convert_string(HLData, Speech, MAX_DATA_LENGTH);
convert_string(HLUserName, User, MAX_NAME_LENGTH);
strstripquotes(Speech);
if (systemtime() == LastSoundTime)
{
// Only one sound per second, please
LastSoundTime = systemtime();
return PLUGIN_CONTINUE;
}
// Check to see if what the player said is a trigger for a sound
for (i=0; i<MAX_KEYWORDS; i++)
{
if (!strcasecmp(Speech, WordWavCombo[i]))
{
ListIndex = i;
}
}
// If what the player said is a sound trigger, then handle it.
if (ListIndex != -1)
{
if (!QuotaCheck(User, UserIndex))
{
new rand = random(MAX_RANDOM);
new timeout = 25;
new playFile[TOK_LENGTH];
// This for loop runs around until it finds a real file to play
for(rand = random(MAX_RANDOM); strlen(playFile) == 0; rand = random(MAX_RANDOM))
{
strcpy(playFile, WordWavCombo[ListIndex][(rand+1)*TOK_LENGTH], TOK_LENGTH);
// If for some reason we never find a file
// then exit this infinite loop
if (!timeout--)
{
printf("Could not find wav to play for %s^n", playFile);
return PLUGIN_CONTINUE;
}
}
snprintf(Text, MAX_TEXT_LENGTH, "%s : %s", User, Speech);
say(Text);
if (am_i_dead(User)) {
/* say("seit wann koennen Tote reden?"); */
playsounddead(playFile);
} else {
playsoundall(playFile);
}
LastSoundTime = systemtime();
return PLUGIN_HANDLED;
}
}
return PLUGIN_CONTINUE;
}