#include < amxmodx >
#include < amxmisc >
#include < nvault >
#include < reapi >
#pragma semicolon 1
const Float: TASK_DELAY = 5.0; // Время после смерти, через которое живые не услышат мертвого игрока
const INACTIVITY_DAYS = 7; // Удалять неактивных игроков через 'n' дней
const SECONDS_IN_DAY = 86400; // Количество секунд в одном дне
new const VAULT_FOLDER_NAME[ ] = "voice_manager"; // Директория хранилища nvault
new const VAULT_FILE_NAME__HEARER[ ] = "voice_manager_hearer"; // Имя хранилища nvault для слушателя
new const VAULT_FILE_NAME__SPEAKER[ ] = "voice_manager_speaker"; // Имя хранилища nvault для вещателя
const START_DATE = 0;
const MAX_LENGTH__PATH = 64;
const MAX_LENGTH__AUTHID = 24;
const MAX_LENGTH__VOICE_MODE = 2;
enum _: HEARER_VOICE_MODE
{
HEARER_VOICE_MODE__ALL,
HEARER_VOICE_MODE__LIVING,
HEARER_VOICE_MODE__DEAD,
HEARER_VOICE_MODE__TEAM,
HEARER_VOICE_MODE__NOONE
}
enum _: SPEAKER_VOICE_MODE
{
SPEAKER_VOICE_MODE__ALL,
SPEAKER_VOICE_MODE__ALIVE,
SPEAKER_VOICE_MODE__DEAD,
SPEAKER_VOICE_MODE__TEAM
}
new g_iHearerVaultID;
new g_iSpeakerVaultID;
new g_iHearerVoiceMode[ MAX_PLAYERS + 1 ];
new g_iSpeakerVoiceMode[ MAX_PLAYERS + 1 ];
new bool: g_bPlayerAlive[ MAX_PLAYERS + 1 ];
new bool: g_bPlayerMuteVoice[ MAX_PLAYERS + 1 ][ MAX_PLAYERS + 1 ];
new bool: g_bPrivateVoiceMode[ MAX_PLAYERS + 1 ];
new bool: g_bPlayerPrivateVoice[ MAX_PLAYERS + 1 ][ MAX_PLAYERS + 1 ];
public plugin_natives( )
{
register_native( "native_VoiceManager_HearerVoiceMode", "native_VoiceManager_HearerVoiceMode", .style = false);
register_native( "native_VoiceManager_SpeakerVoiceMode", "native_VoiceManager_SpeakerVoiceMode", .style = false);
}
public plugin_init( )
{
register_plugin( "Voice Manager", "1.0", "Javekson" );
RegisterHookChain( RG_CBasePlayer_Spawn, "CBasePlayer_Spawn", .post = true );
RegisterHookChain( RG_CBasePlayer_Killed, "CBasePlayer_Killed", .post = true );
RegisterHookChain( RG_HandleMenu_ChooseTeam, "HandleMenu_ChooseTeam", .post = true );
RegisterHookChain( RG_CSGameRules_CanPlayerHearPlayer, "CSGameRules_CanPlayerHearPlayer", .post = false );
}
public plugin_cfg( )
{
new sVaultDir[ MAX_LENGTH__PATH ];
get_localinfo( "amxx_datadir", sVaultDir, charsmax( sVaultDir ) );
formatex( sVaultDir, charsmax( sVaultDir ), "%s/vault/%s", sVaultDir, VAULT_FOLDER_NAME );
if( !dir_exists( sVaultDir ) )
{
mkdir( sVaultDir );
}
new sHearerVaultName[ MAX_LENGTH__PATH + 32 ];
formatex( sHearerVaultName, charsmax( sHearerVaultName ), "%s/%s", VAULT_FOLDER_NAME, VAULT_FILE_NAME__HEARER );
g_iHearerVaultID = nvault_open( sHearerVaultName );
new sSpeakerVaultName[ MAX_LENGTH__PATH + 32 ];
formatex( sSpeakerVaultName, charsmax( sSpeakerVaultName ), "%s/%s", VAULT_FOLDER_NAME, VAULT_FILE_NAME__SPEAKER );
g_iSpeakerVaultID = nvault_open( sSpeakerVaultName );
nvault_prune( g_iHearerVaultID, START_DATE, get_systime( ) - SECONDS_IN_DAY * INACTIVITY_DAYS );
nvault_prune( g_iSpeakerVaultID, START_DATE, get_systime( ) - SECONDS_IN_DAY * INACTIVITY_DAYS );
}
public plugin_end( )
{
nvault_close( g_iHearerVaultID );
nvault_close( g_iSpeakerVaultID );
}
public client_putinserver( id )
{
new sAuthID[ MAX_LENGTH__AUTHID ];
get_user_authid( id, sAuthID, charsmax( sAuthID ) );
if(( g_iHearerVoiceMode[ id ] = nvault_get( g_iHearerVaultID, sAuthID ) ))
{
nvault_touch( g_iHearerVaultID, sAuthID );
}
if(( g_iSpeakerVoiceMode[ id ] = nvault_get( g_iSpeakerVaultID, sAuthID ) ))
{
nvault_touch( g_iSpeakerVaultID, sAuthID );
}
}
public client_disconnected( id )
{
remove_task( id );
g_bPlayerAlive[ id ] = false;
for( new iPlayerID = 1; iPlayerID <= MAX_PLAYERS; iPlayerID++ )
{
g_bPlayerMuteVoice[ iPlayerID ][ id ] = false;
}
arrayset( g_bPlayerMuteVoice[ id ], false , sizeof g_bPlayerMuteVoice[ ] );
for( new iPlayerID = 1; iPlayerID <= MAX_PLAYERS; iPlayerID++ )
{
g_bPlayerPrivateVoice[ iPlayerID ][ id ] = false;
}
arrayset( g_bPlayerPrivateVoice[ id ], false , sizeof g_bPlayerPrivateVoice[ ] );
func_TogglePrivateVoiceMode( id );
}
public CBasePlayer_Spawn( const id )
{
g_bPlayerAlive[ id ] = true;
}
public CBasePlayer_Killed( const id )
{
set_task_ex( TASK_DELAY, "task_AfterDeath", id, .flags = SetTask_Once );
}
public HandleMenu_ChooseTeam( const id, const MenuChooseTeam:slot )
{
g_bPlayerAlive[ id ] = bool: is_user_alive( id );
}
public task_AfterDeath( const id )
{
g_bPlayerAlive[ id ] = bool: is_user_alive( id );
}
public CSGameRules_CanPlayerHearPlayer( const iListener, const iSender )
{
if( g_bPlayerMuteVoice[ iListener ][ iSender ] )
{
SetHookChainReturn( ATYPE_BOOL, false );
return HC_SUPERCEDE;
}
if( g_bPrivateVoiceMode[ iListener ] )
{
if( !g_bPlayerPrivateVoice[ iListener ][ iSender ] )
{
SetHookChainReturn( ATYPE_BOOL, false );
return HC_SUPERCEDE;
}
}
else
{
switch( g_iHearerVoiceMode[ iListener ] )
{
case HEARER_VOICE_MODE__LIVING:
{
if( g_bPlayerAlive[ iListener ] && !g_bPlayerAlive[ iSender ] )
{
SetHookChainReturn( ATYPE_BOOL, false );
return HC_SUPERCEDE;
}
}
case HEARER_VOICE_MODE__NOONE:
{
SetHookChainReturn( ATYPE_BOOL, false );
return HC_SUPERCEDE;
}
case HEARER_VOICE_MODE__TEAM:
{
if( get_member( iListener, m_iTeam ) != get_member( iSender, m_iTeam ) )
{
SetHookChainReturn( ATYPE_BOOL, false );
return HC_SUPERCEDE;
}
}
case HEARER_VOICE_MODE__DEAD:
{
if( g_bPlayerAlive[ iSender ] )
{
SetHookChainReturn( ATYPE_BOOL, false );
return HC_SUPERCEDE;
}
}
}
}
/*==========================================================================================================*/
if( g_bPrivateVoiceMode[ iSender ] )
{
if( !g_bPlayerPrivateVoice[ iSender ][ iListener ] )
{
SetHookChainReturn( ATYPE_BOOL, false );
return HC_SUPERCEDE;
}
}
else
{
switch( g_iSpeakerVoiceMode[ iSender ] )
{
case SPEAKER_VOICE_MODE__TEAM:
{
if( get_member( iListener, m_iTeam ) != get_member( iSender, m_iTeam ) )
{
SetHookChainReturn( ATYPE_BOOL, false );
return HC_SUPERCEDE;
}
}
case SPEAKER_VOICE_MODE__ALIVE:
{
if( !g_bPlayerAlive[ iListener ] )
{
SetHookChainReturn( ATYPE_BOOL, false );
return HC_SUPERCEDE;
}
}
case SPEAKER_VOICE_MODE__DEAD:
{
if( g_bPlayerAlive[ iListener ] )
{
SetHookChainReturn( ATYPE_BOOL, false );
return HC_SUPERCEDE;
}
}
}
}
return HC_CONTINUE;
}
func_TogglePrivateVoiceMode( const id )
{
g_bPrivateVoiceMode[ id ] = false;
for( new iPlayerID = 1; iPlayerID <= MAX_PLAYERS; iPlayerID++ )
{
if( g_bPlayerPrivateVoice[ id ][ iPlayerID ] )
{
g_bPrivateVoiceMode[ id ] = true;
break;
}
}
}
public native_VoiceManager_HearerVoiceMode( iPluginID, iParamCount )
{
new id = get_param( 1 );
return g_iHearerVoiceMode[ id ];
}
public native_VoiceManager_SpeakerVoiceMode( iPluginID, iParamCount )
{
new id = get_param( 1 );
return g_iSpeakerVoiceMode[ id ];
}
public callfunc_ToggleHearerVoiceMode( const id )
{
new sAuthID[ MAX_LENGTH__AUTHID ];
get_user_authid( id, sAuthID, charsmax( sAuthID ) );
g_iHearerVoiceMode[ id ] = ++g_iHearerVoiceMode[ id ] % HEARER_VOICE_MODE;
if( g_iHearerVoiceMode[ id ] )
{
new sHearerVoiceMode[ MAX_LENGTH__VOICE_MODE ];
num_to_str( g_iHearerVoiceMode[ id ], sHearerVoiceMode, charsmax( sHearerVoiceMode ) );
nvault_set( g_iHearerVaultID, sAuthID, sHearerVoiceMode );
}
else
{
nvault_remove( g_iHearerVaultID, sAuthID );
}
}
public callfunc_ToggleSpeakerVoiceMode( const id )
{
new sAuthID[ MAX_LENGTH__AUTHID ];
get_user_authid( id, sAuthID, charsmax( sAuthID ) );
g_iSpeakerVoiceMode[ id ] = ++g_iSpeakerVoiceMode[ id ] % SPEAKER_VOICE_MODE;
if( g_iSpeakerVoiceMode[ id ] )
{
new sSpeakerVoiceMode[ MAX_LENGTH__VOICE_MODE ];
num_to_str( g_iSpeakerVoiceMode[ id ], sSpeakerVoiceMode, charsmax( sSpeakerVoiceMode ) );
nvault_set( g_iSpeakerVaultID, sAuthID, sSpeakerVoiceMode );
}
else
{
nvault_remove( g_iSpeakerVaultID, sAuthID );
}
}
public callfunc_TogglePlayerMuteVoice( id, iPlayerID )
{
g_bPlayerMuteVoice[ id ][ iPlayerID ] = !g_bPlayerMuteVoice[ id ][ iPlayerID ];
}
public callfunc_TogglePlayerPrivateVoice( id, iPlayerID )
{
g_bPlayerPrivateVoice[ id ][ iPlayerID ] = !g_bPlayerPrivateVoice[ id ][ iPlayerID ];
func_TogglePrivateVoiceMode( id );
}