AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Code Snippets/Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=83)
-   -   [CODE] [ORPHEU] How to hook when player use +voicerecord (https://forums.alliedmods.net/showthread.php?t=138497)

joropito 09-18-2010 17:56

[CODE] [ORPHEU] How to hook when player use +voicerecord
 
1 Attachment(s)
I'll try to show you guys how to detect when some player use +voicerecord command.

This code will run using Orpheu and, at this time, will run only on linux because I don't have the windows signature but I can't test on windows too.
Download the file attached and install signatures in configs/orpheu/functions (only linux engine 4883)

First of all, lets talk about how messages from client will be processed by server.

Each time a client sends information to servers, it uses CL messages.
They are handled server side using SV_ExecuteClientMessage function (engine library).

This function will check which command was sent by client and then run the associated function (listed sv_clcfuncs structure)

These are the available messages with their associated engine functions:

PHP Code:

clc_bad            // no function associated
clc_nop            // no function associated
clc_move            SV_ParseMove
clc_stringcmd        SV_ParseStringCommand
clc_delta            SV_ParseDelta
clc_resourcelist        SV_ParseResourceList
clc_tmove            
// no function associated
clc_fileconsistency    SV_ParseConsistencyResponse
clc_voicedata        SV_ParseVoiceData
clc_hltv            SV_IgnoreHLTV
clc_cvarvalue        SV_ParseCvarValue
clc_cvarvalue2        SV_ParseCvarValue2 

This function has only one argument, a pointer to client_t structure.
All I know about that structure for HL1 engine is it's 20200 bytes long (for linux at least)

So, for +voicerecord command we are going to work with SV_ParseVoiceData

When the client holds +voicerecord bind, SV_ParseVoiceData repeatedly is called until it stops using it.

Here's the code to make a plugin that register 2 forwards:


client_voicerecord_on
Called from Voice_SetClientListening (from fakemeta) when sender is using +voicerecord and receiver is the lowest id connected to server.
client_voicerecord_off
Called from Voice_SetClientListening (from fakemeta) after client_voicerecord_on and sender is the same as previus forward and receiver is the highest id connected to server.
PHP Code:

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <orpheu>
#include <orpheu_memory>

#define GetPlayerByClientStruct(%0)     ( ( %0 - g_client_t_address ) / 20200 + 1 )

new g_top_client
new g_client_t_address
new g_player_voice_status32 ]

new 
g_fwdVoiceRecordOn
new g_fwdVoiceRecordOff

public plugin_init()
{
    
register_forwardFM_Voice_SetClientListening"fwd_Voice_SetClientListening" )
    
OrpheuRegisterHookOrpheuGetFunction"SV_ParseVoiceData" ), "SV_ParseVoiceData" )
    
RegisterHamHam_Spawn"player""hamPlayerSpawn" )

    
g_fwdVoiceRecordOn CreateMultiForward"client_voicerecord_on"ET_IGNOREFP_CELL )
    
g_fwdVoiceRecordOff CreateMultiForward"client_voicerecord_off"ET_IGNOREFP_CELL )

    new 
svs OrpheuMemoryGet"svs_ptr" )

    
g_client_t_address OrpheuMemoryGetAtAddresssvs 4"engineInt" )
    
arraysetg_player_voice_status032 )
    
g_top_client 0
}

public 
SV_ParseVoiceDatainfo )
{
    
// Flag user as it's using voicerecord
    
new player GetPlayerByClientStructinfo )
    
g_player_voice_statusplayer ] = 1

}

public 
hamPlayerSpawnid )
{
    
set_top_client()
    
g_player_voice_statusid ] = 0
}

public 
fwd_Voice_SetClientListeningreceiversenderbool:listen )
{
    new 
result
    
// Detect +voicerecord
    
if( receiver == && g_player_voice_statussender ] )
    {
        
ExecuteForwardg_fwdVoiceRecordOnresultsender )
    }

    
// Detect -voicerecord
    
if( receiver == g_top_client && g_player_voice_statussender ] )
    {
        
ExecuteForwardg_fwdVoiceRecordOffresultsender )
        
g_player_voice_statussender ] = 0
    
}

    return 
FMRES_IGNORED
}

public 
client_disconnectid )
{
    
set_top_client()
    
g_player_voice_statusid ] = 0
}

stock set_top_client()
{
    new 
players32 ], num

    get_players
playersnum )

    for( 
num--; num >= 0num-- )
    {
        if( 
playersnum ] > g_top_client )
          
g_top_client playersnum ]
    }


Each time SV_ParseVoiceData is called, we set a flag for the associated player.
The problem is how to know which player is using +voicerecord.
Well, we receive a pointer to the current player client_t structure.

At offset 4 of svs structure we have the pointer to the first player client_t structure and we know it's 20200 bytes long for each client, so we can do some math and get which player is using the command.

PHP Code:

svs[4] = contents at svs_ptr 4 bytes (should be readed as integer)
param1 first argument of SV_ParseVoiceData (memory address)
20200 size of client_t structure

id of player 
= ( svs[4] - param1 ) / 20200 

And here's a simple plugin that uses those new forwards:

PHP Code:

#include <amxmodx>
#include <fakemeta>

forward client_voicerecord_onid )
forward client_voicerecord_offid )

public 
client_voicerecord_onid )
{
        
client_print(idprint_center"you're talking!!")
}

public 
client_voicerecord_offid )
{
//



Arkshine 09-18-2010 18:49

Re: [CODE] [ORPHEU] How to hook when player use +voicerecord
 
Hehe, nice. :)

As suggestion about the package, try to keep the directory structure. /configs/etc. And you could provide the plugin in the package too.

ot_207 09-18-2010 18:51

Re: [CODE] [ORPHEU] How to hook when player use +voicerecord
 
Omg, you killed Kenny, you bastards!
Very nice job joro!

joropito 09-18-2010 19:03

Re: [CODE] [ORPHEU] How to hook when player use +voicerecord
 
I would like to update this to work on windows.

All I need is:

- someone who can tell me this offsets for windows
- someone can test it on windows :)

Arkshine 09-18-2010 19:12

Re: [CODE] [ORPHEU] How to hook when player use +voicerecord
 
0xAB34F ; you are lazy, I find it in less 10 seconds. :p Also, it would be nice to make signatures of bytes, but I can understand it's boring as hell.

jnnq. 09-18-2010 20:40

Re: [CODE] [ORPHEU] How to hook when player use +voicerecord
 
nice work!

Owyn 09-19-2010 05:17

Re: [CODE] [ORPHEU] How to hook when player use +voicerecord
 
Quote:

These are the available messages with their associated engine functions:
how can i catch those messages? the clc_ ones

Arkshine 09-19-2010 05:19

Re: [CODE] [ORPHEU] How to hook when player use +voicerecord
 
Quote:

These are the available messages with their associated engine functions:

Owyn 09-19-2010 05:22

Re: [CODE] [ORPHEU] How to hook when player use +voicerecord
 
if you don't know you don't have to write some random stuff back just to answer something

Arkshine 09-19-2010 05:34

Re: [CODE] [ORPHEU] How to hook when player use +voicerecord
 
Look the first post and hook the function related to the message... :roll:


All times are GMT -4. The time now is 11:06.

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