Raised This Month: $ Target: $400
 0% 

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


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Author Message
joropito
AlliedModders Donor
Join Date: Mar 2009
Location: pfnAddToFullPack
Old 09-18-2010 , 17:56   [CODE] [ORPHEU] How to hook when player use +voicerecord
Reply With Quote #1

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 )
{
//

Attached Files
File Type: zip orpheu-signatures.zip (792 Bytes, 763 views)
__________________

Divide et vinces
approved plugins | steam account

I don't accept PM for support. Just ask on forums.
If you're looking for private work, PM me.

Last edited by joropito; 09-18-2010 at 20:54.
joropito is offline
Send a message via MSN to joropito
 



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 07:26.


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