Help: Making a player 'deaf'

Discuss programming in the QuakeC language.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

A1: yes, they would need to download a replacement package of some kind.
A2: yes, it would replace elements contained within the regular pak0.
A3: you would hopefully distribute such a pak within your mod's private sub directory (ie: fortress, rather than id1). The unfortunate thing here is that there are a lot of different TF mods all using the same gamedir. Also you would not redistrubte the entire pak0.pak, only the changed files (within their own pak). Users would need to explicitly download it, generally. I do want to make an extension to automagically download entire pak files ala q3, but there are too many questions and potential issues with that (also resuming downloads would be much more desirable when its using 400mb paks).
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Post by OneManClan »

Spike wrote:A1: yes, they would need to download a replacement package of some kind.
A2: yes, it would replace elements contained within the regular pak0.
Thanks Spike.

So if I understand correctly:

Step 1. Extract relevant sounds (as listed earlier this thread) from the quake/id1/pak0.pak (using Winpack) and replace them with silence.wavs.

Step 2. Save the modified pak as (eg) quake/fortress/pakfoo.pak.

Step 3. Add a test in the QuakeC which makes sure the deaf players hear the silence.wavs, and the non-deaf players (somehow) hear the 'regular' 'projectiles hitting surfaces' sounds.

Step 4. Make a directory on the server fortress/foo/pakfoo.pak.

So far so good, ie I (think)can do all those things. BUT..:
Spike wrote:A3: you would hopefully distribute such a pak within your mod's private sub directory (ie: fortress, rather than id1).
Step 5. Um....How do I get the QuakeC to tell clients to download fortress/pakfoo.pak?
Spike wrote:The unfortunate thing here is that there are a lot of different TF mods all using the same gamedir.
But if pakfoo.pak is in the quake/fortress/foo directory, it *wouldn't* replace quake/id1/pak0.pak, so players *can* play other mods (??)
Spike wrote:Also you would not redistrubte the entire pak0.pak, only the changed files (within their own pak).
Do you mean make a new pak which just has a replacement of the compete set of TE_EXPLOSION 'elements', including the .wavs which have been replaced by silence.wavs?
Spike wrote:Users would need to explicitly download it, generally.
How? Where in the quakec do I tell clients to download (and use) the new pak? My search for '.pak' in the quakec came up blank.
Spike wrote: I do want to make an extension to automagically download entire pak files ala q3, but there are too many questions and potential issues with that (also resuming downloads would be much more desirable when its using 400mb paks).
Well pak0.pak is only 14 mb. And if the new pak only contained the substituted TE_EXPLOSION 'things' it would be tiny. Ideally, it would be great if players could just automatically download the new pak, this way new players who stumble across our weekly session could just join in.

standing by,

OneManClan
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

"Um....How do I get the QuakeC to tell clients to download fortress/pakfoo.pak? "
You can't.
Well, okay, maybe you can if you're evil.
stuffcmd(foo, "download pakfoo.pak\n");
of course, that's evil, and clients ought to ignore such requests.

"But if pakfoo.pak is in the quake/fortress/foo directory, it *wouldn't* replace quake/id1/pak0.pak, so players *can* play other mods (??) "
pak files found in quake/$gamedir/*.pak override those found in quake/id1/*.pak.
Specifically, it is the contents that override, rather than the pak itself. paks are mere containers.

"How? Where in the quakec do I tell clients to download (and use) the new pak? My search for '.pak' in the quakec came up blank. "
the user would need to explicitly download it, not your qc doing it.
of course, your qc code can say 'type this into the console: download pakfoo.pak', but you don't know if they have the file serverside, so its spammy. if you order their client to download it anyway, its wasteful as hell.

"Well pak0.pak is only 14 mb. And if the new pak only contained the substituted TE_EXPLOSION 'things' it would be tiny. Ideally, it would be great if players could just automatically download the new pak, this way new players who stumble across our weekly session could just join in. "
If they're using a future client that supported pak-based content downloading instead of individual-file-based downloading, there would be no issue, at least for your mod.
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Post by OneManClan »

Spike wrote:
"Um....How do I get the QuakeC to tell clients to download fortress/pakfoo.pak? "
You can't.
Well, okay, maybe you can if you're evil.
stuffcmd(foo, "download pakfoo.pak\n");
of course, that's evil, and clients ought to ignore such requests.
I don't know what you mean by 'evil'. (Guessing) do you mean that it forces players to download it every time? Well.. I could get the QuakeC to store players IPs in a file, and make sure the pak only gets sent to those who haven't been marked as 'sent'. I could even go by player name, so it would only send the file again if the player changed their name and/or the 1st two octets of their IP.. (or something).
Spike wrote:
"But if pakfoo.pak is in the quake/fortress/foo directory, it *wouldn't* replace quake/id1/pak0.pak, so players *can* play other mods (??) "
pak files found in quake/$gamedir/*.pak override those found in quake/id1/*.pak.
Specifically, it is the contents that override, rather than the pak itself. paks are mere containers.
So all paks are read regardless of whether the game runs in fortress? If I 'force' players to download pakfoo.pak into /fortress, won't it be ignored by other mods, as it it wasn't there?
Spike wrote:
"How? Where in the quakec do I tell clients to download (and use) the new pak? My search for '.pak' in the quakec came up blank. "
the user would need to explicitly download it, not your qc doing it.
of course, your qc code can say 'type this into the console: download pakfoo.pak', but you don't know if they have the file serverside, so its spammy. if you order their client to download it anyway, its wasteful as hell.
Well the file WILL be on the server, in the fortress/ folder .. so does that mean all will be ok? (or should I put it in a new folder... I know FTE allows the QuakeC to open/read /write to the server, but IIRC it can't make a new directory on the clients comp.
Spike wrote:
"Well pak0.pak is only 14 mb. And if the new pak only contained the substituted TE_EXPLOSION 'things' it would be tiny. Ideally, it would be great if players could just automatically download the new pak, this way new players who stumble across our weekly session could just join in. "
If they're using a future client that supported pak-based content downloading instead of individual-file-based downloading, there would be no issue, at least for your mod.
But as it stands, do I need to replicate the entire pak0.pak, or does the new pakfoo.pak only need to have the sounds that have been modified?


thanks,

OneManClan
ps, Is all this pak manipulation a 'normal, acceptable procedure' or a 'foolhardy, experimental hack'?
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Post by mh »

Evil in this context means dropping a file on the player's hard disk without their knowledge or consent. Evil means potentially overwriting a file of the same name that they might already have. Evil means accessing the client's filesystem remotely from the server. Evil means opening up a potential security hole and delivery mechanism for malware (think about it - what if the server gets compromised?)

Just because you can it doesn't mean that you should. I'd support Spike's comment that clients should ignore requests like this, both as a security precaution and for good common-sense trust reasons.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Re:

Post by OneManClan »

Ok, since I'm finally uploading a new pk3, this seems to be the perfect time to continue the quest for (almost) total deafness (ie except for the sounds of a player hyper-ventilating).

IIUC a possible solution is to:

1. Make a new "weapons/r_exp3.wav" which contains 0.1 seconds of silence, and put it in the pak. This will make the client play silence, instead of automatically playing the explosion sound. However IIUC the existence of this substitute "weapons/r_exp3.wav" this might affect every other mod(!!). Unless 'AGR' became a separate -game folder, rather than be under 'fortress'.. hmm.. well, leaving that aside for now..

2. Make a new explosion sound, let's call it "weapons/r_boom.wav"

3. Find every occurrence of TE_EXPLOSION and after code such as this:

Code: Select all

WriteByte (#MSG_BROADCAST, #SVC_TEMPENTITY);
WriteByte (#MSG_BROADCAST, #TE_EXPLOSION);
WriteCoord (#MSG_BROADCAST, self.origin_x);
WriteCoord (#MSG_BROADCAST, self.origin_y);
WriteCoord (#MSG_BROADCAST, self.origin_z);

#ifdef QUAKE_WORLD
	multicast (self.origin, #MULTICAST_PHS); // Q1: What does this mean?
#endif

add:
if (player is not deaf)
sound (self, #CHAN_MISC, "weapons/r_boom.wav", 1, #ATTN_NORM);

Q2: Is this a valid concept/solution to silencing explosion sounds?
Last edited by OneManClan on Fri Mar 22, 2013 10:58 pm, edited 1 time in total.
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Re: Re:

Post by OneManClan »

Ok, I made a silent version of "weapons/r_exp3.wav" and put it in the .pk3, but you can still hear the explosions... presumably by the original r_exp3.wav which is still in the pak.

Is there something else that needs to be done?

[EDIT] I just noticed that I have a "r_exp3.wav" in C:\Quake\id1\sound\WEAPONS - ie not in a pak - is this normal?
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Help: Making a player 'deaf'

Post by frag.machine »

Okay, what I am writing here is NOT TESTED; it's just a thought exercise. But there's really no reason to not to work.

Your objective is to be able to make one or more players "deaf" for some time, while everyone else is able to hear the game sounds normally, right ?

First, it helps to understand how the sound () built in works.Every time you add something like this to you QuakeC code:

Code: Select all

sound (self, CHAN_VOICE, "doors/basetry.wav", 1, ATTN_NORM);
You're saying to the server: "for every client inside the PVS (possible visible set), send a svc_sound message, playing the "doors/basetry.wav" at full volume (1) and using normal attenuation".
Theorically, if you know the sample index, you could, using only QuakeC, send a sound to all clients directly using the WriteXXX () builtins and mimmick the sound() builtin:

Code: Select all

float SND_VOLUME = 1;
float SND_ATTENUATION = 2;
float SND_LOOP = 4;

(...)

void (entity org, float sample, float volume, float attn) mySoundReplacement =
{
local float flags;

flags = SND_VOLUME | SND_ATTENUATION;

WriteByte (MSG_ALL, 6); // 6 == svc_sound in the NetQuake protocol
WriteByte (MSG_ALL, flags);
WriteByte (MSG_ALL, volume);
WriteByte (MSG_ALL, attn);
WriteByte (MSG_ALL, sample); 
WriteCoord (MSG_ALL, org.origin_x);
WriteCoord (MSG_ALL, org.origin_y);
WriteCoord (MSG_ALL, org.origin_z);
};
A more interesting version of this function would send the messages individually (instead of using MSG_ALL):

Code: Select all

void (entity org, float sample, float volume, float attn) mySoundReplacement =
{
local float flags;
local entity cli;

flags = SND_VOLUME | SND_ATTENUATION;

cli = find (world, classname, "player");
while (cli != world)
{
  msg_entity = cli; // means "next WriteXX() calls are sending info only to this entity"
  WriteByte (MSG_ONE, 6); 
  WriteByte (MSG_ONE, flags);
  WriteByte (MSG_ONE, volume);
  WriteByte (MSG_ONE, attn);
  WriteByte (MSG_ONE, sample); 
  WriteCoord (MSG_ONE, org.origin_x);
  WriteCoord (MSG_ONE, org.origin_y);
  WriteCoord (MSG_ONE, org.origin_z);
  cli = find (cli, classname, "player");
}


};

Now you have a couple problems here with this solution:
a) *everyone* will hear the sound, regardless the player position in the map. This is different from the builtin, which has access to every player PVS and thus can determine if a client should or not receive a sound message;
b) there's no way to reliably determine the sound index in the internal precache structure. Your best chance would be to precache *all* sounds in the main () function (at world.qc), and assume the precache order to figure out the sound index.

Even with these limitations, the code above open interesting possibilities. Ignoring the PVS problem, you can change it to:
a) play different sounds to each team (just like in TF2 where the announcer says "you have taken the enemy intelligence" to a team and "the enemy has taken our intelligence" to the other at the same time). In this case the lack of PVS support is actually desirable - you want everyone to be able to hear an announcer;
b) play a sound to one player, and a different one to the rest (same reasoning as above, just checking directly the player and not the team);
c) the "deaf" effect you want: skip playing sounds to one or more players (you can pass a chain of "deaf" players as argument to the function, and the code would not send the message for them).

Hope this helps.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
leileilol
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Help: Making a player 'deaf'

Post by leileilol »

What can help is replacing those TE_EXPLOSIONs with particle() builtins with the amount set precisely to 255. This will cue the same explosion particle effect but without sound (and without dynamic light, which you could probably fake with a couple of effect flags).

Code: Select all

/*
	WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
	WriteByte (MSG_BROADCAST, TE_EXPLOSION);
	WriteCoord (MSG_BROADCAST, self.origin_x);
	WriteCoord (MSG_BROADCAST, self.origin_y);
	WriteCoord (MSG_BROADCAST, self.origin_z);
*/
	particle (self.origin, '0 0 0', 100, 255);
i should not be here
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Help: Making a player 'deaf'

Post by Spike »

except he's making a QW mod. not all clients support the particle builtin, and even if they do there's no guarentee that they can cope with the 1024-particles quirk. I really have no idea which qw clients actually support that.
writebytes are evil. Also QW uses a slightly different format, and has nasty protocol limits.
as his mod is already dependant upon fteqwsv, he can just use the dimension_send&self.dimension_see filter for greater control over the sound+multicast+etc builtins so should have no need for writebytes.
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Re: Help: Making a player 'deaf'

Post by OneManClan »

Thanks for the suggestions guys.

As Spike says, I'm already using:
Spike wrote:dimension_send&self.dimension_see filter for greater control over the sound+multicast+etc builtins so should have no need for writebytes.
The substitution of r_exp3.wav with a silent version finally worked!. The problem was that I used "sound/weapons/r_exp3.wav" which is wrong because Spike says calls to 'sound' automatically add 'sound' to the path. Also I had mistakenly called the folder 'sounds', but lets not get into that. :oops:

So it's all working VERY well, including the substitution of an underwater version so explosions under water finally sound realistic. :) The only issue left is that (and I just tested it to confirm) this DOES break compatibility with other fortress mods (no explosions!) So the options are:

1. Use another method (eg frag.machine, leileilol)
2. Put the mod in a completely separate directory (not sure how to do this..)
3. Some special/secret/Guruesque setting to make the client only use resources in the agr.pk3 if it the client is connected to the AGR server.


What's involved in moving the whole thing to quake/agr? Would that mean that none of the resources in /fortress would be available?
ratbert
Posts: 37
Joined: Thu Nov 19, 2009 3:47 pm

Re: Help: Making a player 'deaf'

Post by ratbert »

OMC keep things simple

1) Keep mod based on using the same fortress folder structure setup. Making players download ton new things from a different setup is going to annoy people.

2) Make your new sounds and/or models unique names so they do not conflict with existing customtf mod (or other tf mods for that matter) that it currently uses.
Your only adding a few new things to your customtf agr mod anyhow. Having to download whole pak or pk3 files for simple mod changes in this current age is
Dumb (just my two cents). Maybe a good idea back in 1996 when things were way different. As you know with my coop mod many custom things I added I usually
added "rat" to start of the model or sound to give a unique name.

3) Is your player base using only modern quakeworld clients using FTE or EZQUAKE?

4) With these various changes you are trying implement will they make your player base happy or annoyed?
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Help: Making a player 'deaf'

Post by Baker »

Seems super complicated for such modest goal.

I'd cheat and use a script and solve in 5 seconds.
alias make_deaf "set saved_volume $volume; volume 0; echo my ears are ringing ...." // Save original setting
alias i_can_hear_again "set volume $saved_volume" // Restore original setting
type make_deaf in console and do stuff and then type i_can_hear_again in console and do stuff. Stuffcmd the above aliases AND "i_can_hear_again" (to save volume level) when player connects to server. Stuffcmd "make_deaf" after attack. Stuffcmd "i_can_hear_again" to client after effect should wear off and if player dies.

Spike will say the above is wrong from a design standpoint, that if a player exits the server while deaf it won't restore his volume to normal (it's true). And he's right both a design and technical standpoint, but in practice the above isn't all that "bad".

But the above is easier than 25 QuakeC modifications and 50 extra sounds. Oh yeah ... your dream of the "deaf sound" won't happen, but you'll get maybe 95% of what you without hassling the players and with only a small amount of sacrifice.

One opinion ... probably wrong too! But hey, you've only been trying to do this for only 2 years and 2 months now ...
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
leileilol
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Help: Making a player 'deaf'

Post by leileilol »

He wants hyperventilation sounds. Alias abuse won't help that.
i should not be here
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Help: Making a player 'deaf'

Post by Spike »

regarding the volume cvar (or rather any cvar in general), if the server changes the setting to its non-default setting, fte clients will restore the original value automatically when the map changes/player disconnects/server restores the setting to its default.
ezquake will not. which means ezquake users will likely get annoyed if they disconnect while the effect is in force. If its a short-term effect, you can probably get away with it. if it stays like that for the rest of the game then you probably cannot. on the plus side, quakeworld clients tend to not save configs by default, so it should be restorable by just quitting and starting it up again.

I have to ask though, is the aim to make the player unable to hear anything (including the someone-just-said-something-beep), or will you want to still be able to hear a select sounds (alternatives, announcements, etc)?

hacks are evil nasty things, but they're often the simplest/fastest/best/only way to do things. just make sure you understand and accept the consequences.
Post Reply