AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   FM_PrecacheSound forwards only 4 sound precaches (https://forums.alliedmods.net/showthread.php?t=93538)

Silencer123 05-30-2009 10:25

FM_PrecacheSound forwards only 4 sound precaches
 
I tried to make a simple sound replacement plugin, but a method called by reigster_forward looking for FM_PrecacheSound is only called four times. Always for the same four sounds. First, have some code:
Code:
#include <amxmodx> #include <fakemeta> new const REPLACEMENTFILE[] = "addons/amxmodx/configs/sr.cfg"; const MAXENTRIES = 512; const MAXPATHLENGTH = 127; new const VERSION[]=  "1.0"; new i; new column1[MAXENTRIES][MAXPATHLENGTH+1]; new column2[MAXENTRIES][MAXPATHLENGTH+1]; public plugin_precache() {     register_forward(FM_PrecacheSound, "sr_do_debug", 0);     register_plugin("Sound replacement", VERSION, "Silencer")     if(file_exists(REPLACEMENTFILE)) {         new len = file_size(REPLACEMENTFILE, 1); // Amount of lines in file         if(len > MAXENTRIES)             len = MAXENTRIES;         new txtlen;         const arrays=2*MAXPATHLENGTH+1;         new line[arrays+1];         new skipline;         new hack[MAXPATHLENGTH+6+1]         for(i = 0; i < len-skipline; i++) {             read_file(REPLACEMENTFILE, i+skipline, line, arrays, txtlen);             log_amx("[SR] Debug: Read line %i.", i+skipline+1);             if(contain(line, "//") == 0) { // skip comments                 i--;                 skipline++;                 log_amx("[SR] Debug: Skipping comment in line %i.", i+skipline+1);             } else {                 parse(line, column1[i], MAXPATHLENGTH+1, column2[i], MAXPATHLENGTH+1);                 log_amx("[SR] Debug: Parsed ^"%s^" and ^"%s^".", column1[i], column2[i]);                 if(column1[i][MAXPATHLENGTH] != 0) {                     column1[i][MAXPATHLENGTH] = 0;                     log_amx("[SR] Warning: Origin sound file path in line %i of sound replacement file is longer than %i chars! Not using.", i+skipline+1, MAXPATHLENGTH);                     i--;                     skipline++;                 } else if(column2[i][MAXPATHLENGTH] != 0) {                     column2[i][MAXPATHLENGTH] = 0;                     log_amx("[SR] Warning: Target sound file path in line %i of sound replacement file is longer than %i chars! Not using.", i+skipline+1, MAXPATHLENGTH);                     i--;                     skipline++;                 } else {                     format(hack, 6, "sound/");                     add(hack, MAXPATHLENGTH+6, column1[i], 0);                     if(!file_exists(hack)) { // file_exists starts searching in modfolder                         log_amx("[SR] Warning: Origin sound file path in line %i of sound replacement file not found! Not using.", i+skipline+1, MAXPATHLENGTH);                         i--;                         skipline++;                     } else {                         format(hack, 6, "sound/");                         add(hack, MAXPATHLENGTH+6, column2[i], 0);                         if(!file_exists(hack)) { // file_exists starts searching in modfolder                             log_amx("[SR] Warning: Target sound file path in line %i of sound replacement file not found! Not using.", i+skipline+1, MAXPATHLENGTH);                             i--;                             skipline++;                         }                     }                 }             }         }         if(i > 0) {             log_amx("[SR] Debug: Replacing %i sounds...", i);             register_forward(FM_PrecacheSound, "sr_do", 0);         } else {             log_amx("[SR] Error: Zero sounds replaced.");             set_fail_state("Nothing to replace");         }     } else {         log_amx("[SR] Error: Sound replacement file ^"%s^" not found.", REPLACEMENTFILE);         set_fail_state("File not found");     } } public sr_do(const PATH[]) { // PATH is the original sound file path     log_amx("[SR] Debug: ^"sr_do^" called!");     for(new j = 0; j < i; j++) {         log_amx("[SR] Debug: Checking if ^"%s^" equals ^"%s^"", PATH, column1[j]);         if(equali(PATH, column1[j])) {             log_amx("[SR] Debug: Yes! CALLING FORWARD_RETURN!");             forward_return(FMV_STRING, column2[j]);             return FMRES_SUPERCEDE;         }         log_amx("[SR] Debug: No.");     }     return FMRES_IGNORED; } public sr_do_debug(const PATH[]) {     log_amx("[SR] Debug: ^"sr_do_debug^" called! PATH = ^"%s^"", PATH);     return FMRES_IGNORED; }
Now, see the console output after loading any map:
Code:

// blabla

L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Read line 1.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Skipping comment in line 1.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Read line 2.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Skipping comment in line 2.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Read line 3.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Skipping comment in line 3.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Read line 4.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Skipping comment in line 4.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Read line 5.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Skipping comment in line 5.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Read line 6.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Skipping comment in line 6.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Read line 7.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Skipping comment in line 7.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Read line 8.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Skipping comment in line 8.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Read line 9.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Skipping comment in line 9.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Read line 10.
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Parsed "weapons/sniper_zoom.wav" and "weapons/explode3.wav".
L 05/30/2009 - 15:54:19: [sr.amxx] [SR] Debug: Replacing 1 sounds...

// blabla

L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: "sr_do_debug" called! PATH = "player/pl_wade1.wav"
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: "sr_do" called!
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: Checking if "player/pl_wade1.wav" equals "weapons/sniper_zoom.wav"
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: No.
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: "sr_do_debug" called! PATH = "player/pl_wade2.wav"
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: "sr_do" called!
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: Checking if "player/pl_wade2.wav" equals "weapons/sniper_zoom.wav"
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: No.
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: "sr_do_debug" called! PATH = "player/pl_wade3.wav"
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: "sr_do" called!
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: Checking if "player/pl_wade3.wav" equals "weapons/sniper_zoom.wav"
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: No.
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: "sr_do_debug" called! PATH = "player/pl_wade4.wav"
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: "sr_do" called!
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: Checking if "player/pl_wade4.wav" equals "weapons/sniper_zoom.wav"
L 05/30/2009 - 15:54:21: [sr.amxx] [SR] Debug: No.

// blabla

As you can see, I already debugged a lot.
In the end, sr_do is only called for those four pl_wade#.wav-sounds.

I added the method sr_do_debug to check whether I lost time
by the the code block which parses the sound replacement file,
but the whole thing seems to be as linear as it is supposed to be. (Thank god)

Any clue what the problem might be?

This is the sr.cfg that is used:
Code:

// -- AMXX Sound replacement file --
// One line, one sound replacement:
// First comes the path to the sound to replace.
// Then comes a space.
// Then comes the path to the new sound file.
// Don't wrap quotes around the paths. Example:
// ambience/squeeks1.wav my_great_server_with_custom_sounds/my_squeeks1_custom.wav
// Please keep the file paths short. Don't make long file names and deep folder structures.
// The above would be a horrid example of doing that.
weapons/sniper_zoom.wav weapons/explode3.wav


joaquimandrade 05-30-2009 11:03

Re: FM_PrecacheSound forwards only 4 sound precaches
 
The good news is that the problem is really not your code. I tested it as it is just changed the config file entry to a sound that I have in my computer and I got lots of debug. (Not only those four sounds)

The bad news is that I don't know what's the problem.

__

Apart of your problem, but it won't hurt:

Don't use read_file to parse a file. read_file reads, everytime it's called, the file from its beginning. Basically you are reading n + (n - 1) + (n - 2) + 1 lines instead of n.

And this
PHP Code:

contain(line"//") == 0


should be
PHP Code:

equal(line"//",2



Silencer123 05-30-2009 11:45

Re: FM_PrecacheSound forwards only 4 sound precaches
 
Thanks for taking the time to test this, and for doing it this fast.


About using equal instead, okay, was not aware of the third parameter.
But it seems to now return false all the time.

About read_file: What else to use? (And how?)
In C++ you'd use a file handle, and close it when you are done reading
everything. As far as I know this option exists in sourcemod. Didn't ever
see it in AMXX.

I now removed the check for if the file exists, since if the file is in a *.gcf,
it won't be found even if there.

I tried running this plugin on Sven Co-op 4 and 3. My first suspicion was
SC 4.0's new sound engine being at fault, but the good ol' 3.0 from 2004
or so output the same.

Now testing this on Half-Life straight.

[...]

Better, but still not perfect. It now parses billions of sounds and it finds the sound to replace, okay.
However, the replacement seems to have failed. Still hearing the original
sound. And more strangely, every time a sound is heard, the forward is
called again and again for the heard sounds. Only thing I can think of why
it does this is to check if the sound was precached because Valve was too
stupid to make a variable with arrays to act as a list for precached sounds.

Arkshine 05-30-2009 11:52

Re: FM_PrecacheSound forwards only 4 sound precaches
 
About the read, fopen, fclose, fgets etc. exist. See in file.inc

joaquimandrade 05-30-2009 11:58

Re: FM_PrecacheSound forwards only 4 sound precaches
 
Quote:

Originally Posted by Silencer123 (Post 838084)
Thanks for taking the time to test this, and for doing it this fast.


About using equal instead, okay, was not aware of the third parameter.
But it seems to now return false all the time.

About read_file: What else to use? (And how?)
In C++ you'd use a file handle, and close it when you are done reading
everything. As far as I know this option exists in sourcemod. Didn't ever
see it in AMXX.

I now removed the check for if the file exists, since if the file is in a *.gcf,
it won't be found even if there.

I tried running this plugin on Sven Co-op 4 and 3. My first suspicion was
SC 4.0's new sound engine being at fault, but the good ol' 3.0 from 2004
or so output the same.

Now testing this on Half-Life straight.

[...]

It "works". It parses billions of sounds and it finds the sound to replace.
However, the replacement seems to have failed. Still hearing the original
sound. And more strangely, every time a sound is heard, the forward is
called again and again for the heard sounds. Only thing I can think of why
it does this is to check if the sound was precached because Valve was too
stupid to make a variable with arrays to act as a list for precached sounds.

For me, the best way is using fgets. The only less good thing on it is that it also retrieves the newline character so you have to ignore it.

Silencer123 05-30-2009 12:07

Re: FM_PrecacheSound forwards only 4 sound precaches
 
Thanks. Still, the main problem remains.
Seems it can only replace some sounds.
E.g. something happend to crowbar-hits-wall-sound,
but the sound of a crossbowbolt being shot
cannot be changed.

Also, the only change I can manage is that it says SV_StartSound: sound xyz not precached.
Whereas xyz would still be the original sound.
So I'd have to hook up SV_StartSound.
Is this possible? I'm finding nothing comparable anywhere.

Also, I have to unregister the forward at an appropriate point.

EDIT: I am so completely unsure if I am using forward_return correctly here.
Can I just return the parameters one after another like this?
Code:
public sr_es(ent, iChannel, const szSample[], Float:fVolume, Float:fAttenuation, iFlags, iPitch) {     for(new j = 0; j < i; j++) {         if(equali(szSample, column1[j])) {             forward_return(FMV_CELL, ent);             forward_return(FMV_CELL, iChannel);             forward_return(FMV_STRING, column2[j]);             forward_return(FMV_FLOAT, fVolume)             forward_return(FMV_FLOAT, fAttenuation)             forward_return(FMV_CELL, iFlags)             forward_return(FMV_CELL, iPitch)             return FMRES_SUPERCEDE;         }     }     return FMRES_IGNORED; }

Silencer123 05-30-2009 13:41

Re: FM_PrecacheSound forwards only 4 sound precaches
 
And what the heck is up with this?
Code:

FM_BuildSoundMsg,        // void )    (ent, iChannel, const szSample[], Float:fVolume, Float:fAttenuation, iFlags, iPitch, iMsg_Dest, iMsg_Type, const Float:fOrigin[3], ent)
Variable "ent" is in it twice!? Is this a typo or is it a second entity id?


All times are GMT -4. The time now is 13:55.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.