diff --git a/reapi/extra/amxmodx/scripting/include/reapi_vtc.inc b/reapi/extra/amxmodx/scripting/include/reapi_vtc.inc index 98e3aae1..773d3da9 100644 --- a/reapi/extra/amxmodx/scripting/include/reapi_vtc.inc +++ b/reapi/extra/amxmodx/scripting/include/reapi_vtc.inc @@ -42,8 +42,8 @@ native bool:VTC_IsClientMuted(const index); /* * Play the audio file via the voice stream. * -* @param receiver Receiver index -* @param soundFilePath The path to the sound file +* @param receiver Receiver index (0 = play to all clients) +* @param soundFilePath The path to the sound file, relative to the game directory; must be a valid PCM WAV file (8 or 16 bit) * * @note Usage example: * VTC_PlaySound(id, "sound/ambience/Opera.wav"); @@ -52,6 +52,41 @@ native bool:VTC_IsClientMuted(const index); */ native VTC_PlaySound(const receiver, const soundFilePath[]); +/* +* Blocks the player's voice packets entirely. +* Unlike VTC_MuteClient, a blocked player is not treated as speaking: +* VTC_OnClientStartSpeak/VTC_OnClientStopSpeak are not called for this player. +* +* @param index Client index +* +* @noreturn +* +* @note Requires VoiceTranscoder API 3.1+, otherwise the native fails +*/ +native VTC_BlockClient(const index); + +/* +* Unblocks the player's voice packets. +* +* @param index Client index +* +* @noreturn +* +* @note Requires VoiceTranscoder API 3.1+, otherwise the native fails +*/ +native VTC_UnblockClient(const index); + +/* +* Checks whether the player's voice is blocked at the moment. +* +* @param index Client index +* +* @return true if client's voice is blocked, false otherwise +* +* @note Requires VoiceTranscoder API 3.1+, otherwise the native fails and returns false +*/ +native bool:VTC_IsClientBlocked(const index); + /* * Called when the player started talking. * diff --git a/reapi/include/vtc_api.h b/reapi/include/vtc_api.h index 598d925a..2e4e5267 100644 --- a/reapi/include/vtc_api.h +++ b/reapi/include/vtc_api.h @@ -2,17 +2,17 @@ #include -const char VOICETRANSCODER_VERSION[] = "2017 RC"; +const char VOICETRANSCODER_VERSION[] = "2017RC5"; const size_t VOICETRANSCODER_API_VERSION_MAJOR = 3; -const size_t VOICETRANSCODER_API_VERSION_MINOR = 0; +const size_t VOICETRANSCODER_API_VERSION_MINOR = 1; template class IEvent { public: virtual ~IEvent() {} - typedef void (*handler_t)(T_ARGS...); + typedef void (* handler_t)(T_ARGS...); virtual void operator+=(handler_t callback) = 0; virtual void operator-=(handler_t callback) = 0; @@ -22,8 +22,8 @@ class IVoiceTranscoderAPI { public: virtual ~IVoiceTranscoderAPI() {} - virtual size_t GetMajorVersion() = 0; - virtual size_t GetMinorVersion() = 0; + virtual size_t MajorVersion() = 0; + virtual size_t MinorVersion() = 0; virtual bool IsClientSpeaking(size_t clientIndex) = 0; @@ -35,4 +35,8 @@ class IVoiceTranscoderAPI { virtual bool IsClientMuted(size_t clientIndex) = 0; virtual void PlaySound(size_t receiverClientIndex, const char *soundFilePath) = 0; + + virtual void BlockClient(size_t clientIndex) = 0; + virtual void UnblockClient(size_t clientIndex) = 0; + virtual bool IsClientBlocked(size_t clientIndex) = 0; }; diff --git a/reapi/src/mods/mod_vtc_api.cpp b/reapi/src/mods/mod_vtc_api.cpp index 470555dc..39f32ca4 100644 --- a/reapi/src/mods/mod_vtc_api.cpp +++ b/reapi/src/mods/mod_vtc_api.cpp @@ -1,6 +1,7 @@ #include "precompiled.h" IVoiceTranscoderAPI *g_pVoiceTranscoderApi; +size_t g_VtcApiMinorVersion = 0; bool VTC_Api_Init() { @@ -12,8 +13,9 @@ bool VTC_Api_Init() if (!g_pVoiceTranscoderApi) return false; - size_t majorVersion = g_pVoiceTranscoderApi->GetMajorVersion(); - size_t minorVersion = g_pVoiceTranscoderApi->GetMinorVersion(); + size_t majorVersion = g_pVoiceTranscoderApi->MajorVersion(); + size_t minorVersion = g_pVoiceTranscoderApi->MinorVersion(); + g_VtcApiMinorVersion = minorVersion; if (majorVersion != VOICETRANSCODER_API_VERSION_MAJOR) { @@ -36,9 +38,9 @@ bool VTC_Api_Init() if (minorVersion < VOICETRANSCODER_API_VERSION_MINOR) { - UTIL_ServerPrint("[%s]: VTC API minor version mismatch; expected at least %d, real %d\n", Plugin_info.logtag, VOICETRANSCODER_API_VERSION_MINOR, minorVersion); - UTIL_ServerPrint("[%s]: Please update the VTC up to a minor version API >= %d\n", Plugin_info.logtag, VOICETRANSCODER_API_VERSION_MINOR); - return false; + // Not fatal: the core VTC natives keep working with API 3.0, + // only the block API (VTC_BlockClient etc.) requires minor >= 1. + UTIL_ServerPrint("[%s]: VTC API minor version %d < %d; block natives (VTC_BlockClient/VTC_UnblockClient/VTC_IsClientBlocked) are not available. Please update the VTC up to a minor version API >= %d\n", Plugin_info.logtag, minorVersion, VOICETRANSCODER_API_VERSION_MINOR, VOICETRANSCODER_API_VERSION_MINOR); } g_pVoiceTranscoderApi->OnClientStartSpeak() += OnClientStartSpeak; diff --git a/reapi/src/mods/mod_vtc_api.h b/reapi/src/mods/mod_vtc_api.h index 323288a7..a0a868cd 100644 --- a/reapi/src/mods/mod_vtc_api.h +++ b/reapi/src/mods/mod_vtc_api.h @@ -1,5 +1,6 @@ #pragma once extern IVoiceTranscoderAPI *g_pVoiceTranscoderApi; +extern size_t g_VtcApiMinorVersion; extern bool VTC_Api_Init(); diff --git a/reapi/src/natives/natives_vtc.cpp b/reapi/src/natives/natives_vtc.cpp index b53e5573..7b184790 100644 --- a/reapi/src/natives/natives_vtc.cpp +++ b/reapi/src/natives/natives_vtc.cpp @@ -77,8 +77,8 @@ cell AMX_NATIVE_CALL VTC_IsClientMuted(AMX *amx, cell *params) /* * Play the audio file via the voice stream. * -* @param receiver Receiver index -* @param soundFilePath The path to the sound file +* @param receiver Receiver index (0 = play to all clients) +* @param soundFilePath The path to the sound file, relative to the game directory; must be a valid PCM WAV file (8 or 16 bit) * * @note Usage example: * VTC_PlaySound(id, "sound/ambience/Opera.wav"); @@ -91,13 +91,96 @@ cell AMX_NATIVE_CALL VTC_PlaySound(AMX *amx, cell *params) { enum args_e { arg_count, arg_index, arg_audio_pathfile }; - CHECK_ISPLAYER(arg_index); + // 0 is a valid receiver: VTC plays the sound to all clients (broadcast) + if (unlikely(params[arg_index] < 0 || params[arg_index] > gpGlobals->maxClients)) { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: invalid receiver index %i [arg_index]", __FUNCTION__, params[arg_index]); + return FALSE; + } char pathfile[MAX_PATH]; g_pVoiceTranscoderApi->PlaySound((size_t)params[arg_index], getAmxString(amx, params[arg_audio_pathfile], pathfile)); return TRUE; } +/* +* Blocks the player's voice packets entirely. +* Unlike VTC_MuteClient, a blocked player is not treated as speaking: +* VTC_OnClientStartSpeak/VTC_OnClientStopSpeak are not called for this player. +* +* @param index Client index +* +* @noreturn +* +* @error Requires VoiceTranscoder API 3.1 (minor >= 1) +* +* native VTC_BlockClient(const index); +*/ +cell AMX_NATIVE_CALL VTC_BlockClient(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index }; + + CHECK_ISPLAYER(arg_index); + + if (g_VtcApiMinorVersion < 1) { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: requires VoiceTranscoder API 3.1 (minor >= 1)", __FUNCTION__); + return FALSE; + } + + g_pVoiceTranscoderApi->BlockClient((size_t)params[arg_index]); + return TRUE; +} + +/* +* Unblocks the player's voice packets. +* +* @param index Client index +* +* @noreturn +* +* @error Requires VoiceTranscoder API 3.1 (minor >= 1) +* +* native VTC_UnblockClient(const index); +*/ +cell AMX_NATIVE_CALL VTC_UnblockClient(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index }; + + CHECK_ISPLAYER(arg_index); + + if (g_VtcApiMinorVersion < 1) { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: requires VoiceTranscoder API 3.1 (minor >= 1)", __FUNCTION__); + return FALSE; + } + + g_pVoiceTranscoderApi->UnblockClient((size_t)params[arg_index]); + return TRUE; +} + +/* +* Checks whether the player's voice is blocked at the moment. +* +* @param index Client index +* +* @return true if client's voice is blocked, false otherwise +* +* @error Requires VoiceTranscoder API 3.1 (minor >= 1), returns false if not available +* +* native bool:VTC_IsClientBlocked(const index); +*/ +cell AMX_NATIVE_CALL VTC_IsClientBlocked(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index }; + + CHECK_ISPLAYER(arg_index); + + if (g_VtcApiMinorVersion < 1) { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: requires VoiceTranscoder API 3.1 (minor >= 1)", __FUNCTION__); + return FALSE; + } + + return (cell)g_pVoiceTranscoderApi->IsClientBlocked((size_t)params[arg_index]); +} + AMX_NATIVE_INFO VTC_Natives[] = { { "VTC_IsClientSpeaking", VTC_IsClientSpeaking }, @@ -105,6 +188,9 @@ AMX_NATIVE_INFO VTC_Natives[] = { "VTC_UnmuteClient", VTC_UnmuteClient }, { "VTC_IsClientMuted", VTC_IsClientMuted }, { "VTC_PlaySound", VTC_PlaySound }, + { "VTC_BlockClient", VTC_BlockClient }, + { "VTC_UnblockClient", VTC_UnblockClient }, + { "VTC_IsClientBlocked", VTC_IsClientBlocked }, { nullptr, nullptr } };