PHP Code:
#include <amxmodx>
#include <fakemeta>
#include <okapi>
new ClientStructAddress;
new ClientStructSize;
new ForwardVoiceRecordOn;
new ForwardVoiceRecordOff;
#define GetPlayerByClientStruct(%0) ( ( %0 - ClientStructAddress ) / ClientStructSize + 1 )
forward client_voicerecord_on(id);
forward client_voicerecord_off(id);
public plugin_init()
{
new funcPointer = getSV_ParseVoiceDataPointer();
new svsPointer = getSVSPointer();
//new short = getMSG_ReadShort();
log_amx("(SV_ParseVoiceData: 0x%x, svs; 0x%x", funcPointer, svsPointer);
if( funcPointer && svsPointer /*&& short */)
{
okapi_add_hook( okapi_build_function( funcPointer, arg_void, arg_int ), "OnSV_ParseVoiceData" );
//okapi_add_hook( okapi_build_function( short, arg_int ), "OnShort", 1 );
ForwardVoiceRecordOn = CreateMultiForward( "client_voicerecord_on" , ET_IGNORE, FP_CELL );
ForwardVoiceRecordOff = CreateMultiForward( "client_voicerecord_off", ET_IGNORE, FP_CELL );
ClientStructSize = is_linux_server() ? 20212 : 20500;
ClientStructAddress = okapi_get_ptr_int( svsPointer + 4 ); // struct client_s *clients;
}
else
{
set_fail_state( "Oh, shit");
}
}
new /*s,*/ result;
/*public OnShort( info )
{
s = okapi_get_orig_return();
}*/
public OnSV_ParseVoiceData( const info )
{
static pId; pId = GetPlayerByClientStruct( info );
if( task_exists(pId) )
{
change_task(pId, 0.5);
}
else
{
ExecuteForward( ForwardVoiceRecordOn, result, pId );
set_task(0.5, "func_VoiceStopped", pId );
}
}
public func_VoiceStopped(pId)
{
ExecuteForward( ForwardVoiceRecordOff, result, pId );
}
getSV_ParseVoiceDataPointer()
{
new const SV_ParseVoiceData_Sig[] =
{
0x55,0x8B,0xDEF,0xB8,0xDEF,0xDEF,0xDEF,0xDEF,
0xE8,0xDEF,0xDEF,0xDEF,0xDEF,0x53,0x8B,0xDEF,
0xDEF,0xDEF,0xDEF,0xDEF,0x56,0x8B,0xDEF,0xDEF,0x8B
};
new pointer;
( pointer = okapi_engine_get_symbol_ptr( "SV_ParseVoiceData" ) )
||
( pointer = okapi_engine_find_sig( SV_ParseVoiceData_Sig, sizeof SV_ParseVoiceData_Sig ) );
return pointer;
}
/*getMSG_ReadShort()
{
new const SV_ParseVoiceData_Sig[] = {0xA1,0xDEF,0xDEF,0xDEF,0xDEF,0x8B,0x0D,0xDEF,0xDEF,0xDEF,0xDEF,0x8D,0x50,0x02,
0x3B,0xD1,0x7E,0x0E,0xC7,0x05,0xDEF,0xDEF,0xDEF,0xDEF,0xDEF,0xDEF,0xDEF,0xDEF,0x83,0xC8,0xFF,0xC3,0x8B,
0x0D,0xDEF,0xDEF,0xDEF,0xDEF,0x56,0x89,0x15,0xDEF,0xDEF,0xDEF,0xDEF,0x66,0x0F,0xB6,0x74,0x01,0xDEF,
0x66,0x0F,0xB6,0x04,0x01,0xC1,0xE6,0x08,0x03,0xF0,0x0F,0xBF,0xC6,0x5E,0xC3};
new pointer; ( pointer = okapi_engine_get_symbol_ptr( "MSG_ReadShort" ) ) ||
( pointer = okapi_engine_find_sig( SV_ParseVoiceData_Sig, sizeof SV_ParseVoiceData_Sig ) );
return pointer;
}*/
getSVSPointer()
{
static pointer;
if( !pointer)
{
// linux/osx
if( ( pointer = okapi_engine_get_symbol_ptr( "svs" ) ) )
{
return pointer;
}
// Windows
new const InitializeGameDLL_Signature[] =
{
0xE8,0xDEF,0xDEF,0xDEF,0xDEF,0x8B,0xDEF,0xDEF,
0xDEF,0xDEF,0xDEF,0x33,0xDEF,0x83,0xDEF,0xDEF,
0x0F,0xDEF,0xDEF,0x50
}
new funcAddress =
okapi_engine_find_sig( InitializeGameDLL_Signature, sizeof InitializeGameDLL_Signature );
if( funcAddress )
{
new bytes[ 16 ];
okapi_get_ptr_array( funcAddress, bytes, sizeof bytes );
// Try to find opcode: 8B X XXXX, where XXXX is the svs offset.
new address = okapi_engine_ptr_find_byte_at( funcAddress, 0x8B );
if( address )
{
return okapi_get_ptr_int( address + 2 ) - 8;
}
}
}
return pointer;
}
public client_voicerecord_on(id)
{
new szname[32]
get_user_name(id, szname, 31)
client_print(id, print_chat, "speak ON %s", szname)
}
public client_voicerecord_off(id)
{
new szname[32]
get_user_name(id, szname, 31)
client_print(id, print_chat, "speak OFF %s", szname)
}