2
0
mirror of https://github.com/rehlds/revoice.git synced 2024-12-25 06:05:44 +03:00

Refactoring

Added new cvar's REV_HltvCodec, REV_DefaultCodec
This commit is contained in:
s1lent 2017-07-08 02:46:03 +07:00
parent 07f5290ad9
commit b83914b030
No known key found for this signature in database
GPG Key ID: 0FE401DC73916B5C
23 changed files with 533 additions and 460 deletions

View File

@ -10,22 +10,25 @@ void _copyFile(String from, String to) {
GradleCppUtils.copyFile(project.file(from), project.file(to), false)
}
task publishPrepareFiles {
doLast {
def pubRootDir = project.file('publish/publishRoot')
if (pubRootDir.exists()) {
if (!pubRootDir.deleteDir()) {
throw new RuntimeException("Failed to delete ${pubRootDir}")
}
task publishPrepareFiles << {
def pubRootDir = project.file('publish/publishRoot')
if (pubRootDir.exists()) {
if (!pubRootDir.deleteDir()) {
throw new RuntimeException("Failed to delete ${pubRootDir}")
}
}
pubRootDir.mkdirs()
pubRootDir.mkdirs()
project.file('publish/publishRoot/revoice/bin/win32').mkdirs()
project.file('publish/publishRoot/revoice/bin/linux32').mkdirs()
project.file('publish/publishRoot/revoice/bin/win32').mkdirs()
project.file('publish/publishRoot/revoice/bin/linux32').mkdirs()
_copyFileToDir('publish/revoice_mm.dll', 'publish/publishRoot/revoice/bin/win32/')
_copyFile('publish/librevoice_mm_i386.so', 'publish/publishRoot/revoice/bin/linux32/revoice_mm_i386.so')
_copyFileToDir('publish/revoice_mm.dll', 'publish/publishRoot/revoice/bin/win32/')
_copyFile('publish/librevoice_mm_i386.so', 'publish/publishRoot/revoice/bin/linux32/revoice_mm_i386.so')
copy {
from 'revoice/dist'
into 'publish/publishRoot/revoice'
}
}

2
revoice/dist/revoice.cfg vendored Normal file
View File

@ -0,0 +1,2 @@
REV_HltvCodec opus // speex, opus
REV_DefaultCodec speex // speex, opus

View File

@ -144,7 +144,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REVOICE_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)../src/;$(ProjectDir)../public/;$(ProjectDir)../version/;$(ProjectDir)../include/;$(SolutionDir)../dep/rehlsdk/common/;$(SolutionDir)../dep/rehlsdk/dlls/;$(SolutionDir)../dep/rehlsdk/engine/;$(SolutionDir)../dep/rehlsdk/public/;$(SolutionDir)../dep/silk/include/;$(SolutionDir)../dep/opus/include/;$(SolutionDir)../dep/speex/include/;$(SolutionDir)../dep/metamod/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
</ClCompile>
@ -187,7 +187,7 @@ IF EXIST "$(ProjectDir)start_6153.bat" (CALL "$(ProjectDir)start_6153.bat")</Com
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;REVOICE_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)../src/;$(ProjectDir)../public/;$(ProjectDir)../version/;$(ProjectDir)../include/;$(SolutionDir)../dep/rehlsdk/common/;$(SolutionDir)../dep/rehlsdk/dlls/;$(SolutionDir)../dep/rehlsdk/engine/;$(SolutionDir)../dep/rehlsdk/public/;$(SolutionDir)../dep/silk/include/;$(SolutionDir)../dep/opus/include/;$(SolutionDir)../dep/speex/include/;$(SolutionDir)../dep/metamod/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
</ClCompile>

View File

@ -2,19 +2,15 @@
#include "interface.h"
class IVoiceCodec : public IBaseInterface {
class IGameClient;
class IVoiceCodec: public IBaseInterface {
protected:
virtual ~IVoiceCodec() {
}
virtual ~IVoiceCodec() {}
static const int BYTES_PER_SAMPLE = 2;
public:
// Initialize the object. The uncompressed format is always 8-bit signed mono.
virtual bool Init(int quality) = 0;
virtual void Release() = 0;
// Compress the voice data.

View File

@ -10,6 +10,11 @@ bool CSteamP2PCodec::Init(int quality)
return m_BackendCodec->Init(quality);
}
void CSteamP2PCodec::SetClient(IGameClient *client)
{
m_Client = client;
}
void CSteamP2PCodec::Release()
{
m_BackendCodec->Release();
@ -28,13 +33,13 @@ int CSteamP2PCodec::StreamDecode(const char *pCompressed, int compressedBytes, c
while (readPos < maxReadPos)
{
uint8 opcode = *(uint8*)readPos;
PayLoadType opcode = *(PayLoadType *)readPos;
readPos++;
switch (opcode)
{
// Set sampling rate
case 0xB:
case PLT_SamplingRate:
{
if (readPos + 2 > maxReadPos) {
return 0;
@ -43,12 +48,12 @@ int CSteamP2PCodec::StreamDecode(const char *pCompressed, int compressedBytes, c
break;
}
// Voice payload
case 0x04: // silk deprecated
case 0x05: // opus deprecated
case PLT_Silk: // silk deprecated
case PLT_OPUS: // opus deprecated
{
break;
}
case 0x06: // opus plc
case PLT_OPUS_PLC: // opus plc
{
if (readPos + 2 > maxReadPos) {
return 0;
@ -67,11 +72,13 @@ int CSteamP2PCodec::StreamDecode(const char *pCompressed, int compressedBytes, c
// Invalid or unknown opcode
default:
LCPrintf(true, "CSteamP2PCodec::StreamDecode() called on client(%d) with unknown voice codec opcode (%d)\n", m_Client->GetId(), opcode);
return 0;
}
}
return 0; // no voice payload in the stream
// no voice payload in the stream
return 0;
}
int CSteamP2PCodec::StreamEncode(const char *pUncompressedBytes, int nSamples, char *pCompressed, int maxCompressedBytes, bool bFinal) const
@ -82,11 +89,11 @@ int CSteamP2PCodec::StreamEncode(const char *pUncompressedBytes, int nSamples, c
return 0;
}
*(writePos++) = 0x0B; // Set sampling rate
*(writePos++) = PLT_SamplingRate; // Set sampling rate
*(uint16 *)writePos = 16000;
writePos += 2;
*(writePos++) = 0x04; // Voice payload
*(writePos++) = PLT_Silk; // Voice payload
int compressRes = m_BackendCodec->Compress(pUncompressedBytes, nSamples, writePos + 2, maxCompressedBytes - (1 + 2 + 1 + 2), bFinal);
if (compressRes == 0) {

View File

@ -3,15 +3,30 @@
#include "revoice_shared.h"
#include "IVoiceCodec.h"
class CSteamP2PCodec : public IVoiceCodec {
class CSteamP2PCodec: public IVoiceCodec {
public:
CSteamP2PCodec(IVoiceCodec *backend);
enum PayLoadType : uint8
{
PLT_Silence = 0, // Number of empty samples, which should be set to NULL.
PLT_UnknownCodec = 1,
PLT_Speex = 2,
PLT_Raw = 3,
PLT_Silk = 4,
PLT_OPUS = 5,
PLT_OPUS_PLC = 6,
PLT_Unknown = 10,
PLT_SamplingRate = 11
};
virtual bool Init(int quality);
virtual void Release();
virtual int Compress(const char *pUncompressedBytes, int nSamples, char *pCompressed, int maxCompressedBytes, bool bFinal);
virtual int Decompress(const char *pCompressed, int compressedBytes, char *pUncompressed, int maxUncompressedBytes);
virtual bool ResetState();
void SetClient(IGameClient *client);
IVoiceCodec *GetCodec() const { return m_BackendCodec; }
private:
@ -19,5 +34,6 @@ private:
int StreamEncode(const char *pUncompressedBytes, int nSamples, char *pCompressed, int maxCompressedBytes, bool bFinal) const;
private:
IGameClient *m_Client;
IVoiceCodec *m_BackendCodec;
};

View File

@ -2,8 +2,8 @@
VoiceEncoder_Silk::VoiceEncoder_Silk()
{
m_pEncoder = NULL;
m_pDecoder = NULL;
m_pEncoder = nullptr;
m_pDecoder = nullptr;
m_targetRate_bps = 25000;
m_packetLoss_perc = 0;
}
@ -12,12 +12,12 @@ VoiceEncoder_Silk::~VoiceEncoder_Silk()
{
if (m_pEncoder) {
free(m_pEncoder);
m_pEncoder = NULL;
m_pEncoder = nullptr;
}
if (m_pDecoder) {
free(m_pDecoder);
m_pDecoder = NULL;
m_pDecoder = nullptr;
}
}
@ -97,7 +97,7 @@ int VoiceEncoder_Silk::Compress(const char *pUncompressedIn, int nSamplesIn, cha
while (nSamples > 0)
{
int16* pWritePayloadSize = (int16*)pWritePos;
int16 *pWritePayloadSize = (int16 *)pWritePos;
pWritePos += sizeof(int16); //leave 2 bytes for the frame size (will be written after encoding)
int originalNBytes = (pWritePosMax - pWritePos > 0xFFFF) ? -1 : (pWritePosMax - pWritePos);
@ -111,11 +111,11 @@ int VoiceEncoder_Silk::Compress(const char *pUncompressedIn, int nSamplesIn, cha
this->m_encControl.packetSize = 20 * (inSampleRate / 1000);
this->m_encControl.packetLossPercentage = this->m_packetLoss_perc;
this->m_encControl.bitRate = (m_targetRate_bps >= 0) ? m_targetRate_bps : 0;
nSamples -= nSamplesToEncode;
int16 nBytes = originalNBytes;
int res = SKP_Silk_SDK_Encode(this->m_pEncoder, &this->m_encControl, psRead, nSamplesToEncode, (unsigned char*)pWritePos, &nBytes);
int res = SKP_Silk_SDK_Encode(this->m_pEncoder, &this->m_encControl, psRead, nSamplesToEncode, (unsigned char *)pWritePos, &nBytes);
*pWritePayloadSize = nBytes; //write frame size
pWritePos += nBytes;
@ -133,7 +133,7 @@ int VoiceEncoder_Silk::Compress(const char *pUncompressedIn, int nSamplesIn, cha
ResetState();
if (pWritePosMax > pWritePos + 2) {
uint16 * pWriteEndFlag = (uint16*)pWritePos;
uint16 *pWriteEndFlag = (uint16*)pWritePos;
pWritePos += sizeof(uint16);
*pWriteEndFlag = 0xFFFF;
}

View File

@ -2,28 +2,18 @@
size_t ENCODED_FRAME_SIZE[] = { 0x6u, 0x6u, 0xFu, 0xFu, 0x14u, 0x14u, 0x1Cu, 0x1Cu, 0x26u, 0x26u, 0x26u };
/* <d91> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:70 */
/*IBaseInterface *CreateSpeexVoiceCodec(void)
{
IFrameEncoder *pEncoder = (IFrameEncoder *)new VoiceEncoder_Speex;
return (IBaseInterface *)CreateVoiceCodec_Frame(pEncoder);
}*/
/* <fb3> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:82 */
VoiceEncoder_Speex::VoiceEncoder_Speex()
{
m_EncoderState = NULL;
m_DecoderState = NULL;
m_EncoderState = nullptr;
m_DecoderState = nullptr;
m_Quality = 0;
}
/* <e20> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:89 */
VoiceEncoder_Speex::~VoiceEncoder_Speex()
{
TermStates();
}
/* <efd> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:94 */
bool VoiceEncoder_Speex::Init(int quality, int &rawFrameSize, int &encodedFrameSize)
{
int postfilter;
@ -67,13 +57,11 @@ bool VoiceEncoder_Speex::Init(int quality, int &rawFrameSize, int &encodedFrameS
return true;
}
/* <c06> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:127 */
void VoiceEncoder_Speex::Release()
{
delete this;
}
/* <ce7> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:132 */
void VoiceEncoder_Speex::EncodeFrame(const char *pUncompressedBytes, char *pCompressed)
{
float input[160];
@ -88,7 +76,6 @@ void VoiceEncoder_Speex::EncodeFrame(const char *pUncompressedBytes, char *pComp
speex_bits_write(&m_Bits, pCompressed, ENCODED_FRAME_SIZE[m_Quality]);
}
/* <c53> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:156 */
void VoiceEncoder_Speex::DecodeFrame(const char *pCompressed, char *pDecompressedBytes)
{
float output[160];
@ -102,7 +89,6 @@ void VoiceEncoder_Speex::DecodeFrame(const char *pCompressed, char *pDecompresse
}
}
/* <c2c> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:175 */
bool VoiceEncoder_Speex::ResetState()
{
speex_encoder_ctl(m_EncoderState, SPEEX_RESET_STATE, 0);
@ -111,29 +97,25 @@ bool VoiceEncoder_Speex::ResetState()
return true;
}
/* <fd4> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:182 */
bool VoiceEncoder_Speex::InitStates()
{
speex_bits_init(&m_Bits);
m_EncoderState = speex_encoder_init(&speex_nb_mode);
m_DecoderState = speex_decoder_init(&speex_nb_mode);
return (m_EncoderState != NULL && m_DecoderState != NULL);
return (m_EncoderState != nullptr && m_DecoderState != nullptr);
}
/* <ff6> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:193 */
void VoiceEncoder_Speex::TermStates()
{
if (m_EncoderState != NULL) {
if (m_EncoderState) {
speex_encoder_destroy(m_EncoderState);
m_EncoderState = NULL;
m_EncoderState = nullptr;
}
if (m_DecoderState != NULL) {
if (m_DecoderState) {
speex_encoder_destroy(m_DecoderState);
m_DecoderState = NULL;
m_DecoderState = nullptr;
}
speex_bits_destroy(&m_Bits);
}
//EXPOSE_INTERFACE_FN(CreateSpeexVoiceCodec, VoiceEncoder_Speex, "voice_speex");

View File

@ -4,7 +4,6 @@
#include "iframeencoder.h"
#include "speex.h"
/* <61c> ../engine/voice_codecs/speex/VoiceEncoder_Speex.h:57 */
class VoiceEncoder_Speex: public IFrameEncoder {
protected:
virtual ~VoiceEncoder_Speex();
@ -12,26 +11,14 @@ protected:
public:
VoiceEncoder_Speex();
/* <6c8> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:94 */
bool Init(int quality, int &rawFrameSize, int &encodedFrameSize);
/* <6ff> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:127 */
void Release();
/* <751> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:132 */
void EncodeFrame(const char *pUncompressedBytes, char *pCompressed);
/* <723> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:156 */
void DecodeFrame(const char *pCompressed, char *pDecompressedBytes);
/* <77f> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:175 */
bool ResetState();
virtual bool Init(int quality, int &rawFrameSize, int &encodedFrameSize);
virtual void Release();
virtual void EncodeFrame(const char *pUncompressedBytes, char *pCompressed);
virtual void DecodeFrame(const char *pCompressed, char *pDecompressedBytes);
virtual bool ResetState();
protected:
/* <7a7> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:182 */
bool InitStates();
/* <7c8> ../engine/voice_codecs/speex/VoiceEncoder_Speex.cpp:193 */
void TermStates();
private:
@ -39,7 +26,4 @@ private:
void *m_EncoderState;
void *m_DecoderState;
SpeexBits m_Bits;
};
extern IVoiceCodec *CreateVoiceCodec_Frame(IFrameEncoder *pEncoder);

View File

@ -31,7 +31,8 @@
#include "precompiled.h"
static DLL_FUNCTIONS gFunctionTable = {
DLL_FUNCTIONS g_DLLFuncTable =
{
NULL, // pfnGameInit
NULL, // pfnSpawn
NULL, // pfnThink
@ -42,15 +43,12 @@ static DLL_FUNCTIONS gFunctionTable = {
NULL, // pfnSave
NULL, // pfnRestore
NULL, // pfnSetAbsBox
NULL, // pfnSaveWriteFields
NULL, // pfnSaveReadFields
NULL, // pfnSaveGlobalState
NULL, // pfnRestoreGlobalState
NULL, // pfnResetGlobalState
&mm_ClientConnect,
&ClientConnect_PreHook, // pfnClientDisconnect
NULL, // pfnClientDisconnect
NULL, // pfnClientKill
NULL, // pfnClientPutInServer
@ -58,27 +56,20 @@ static DLL_FUNCTIONS gFunctionTable = {
NULL, // pfnClientUserInfoChanged
NULL, // pfnServerActivate
NULL, // pfnServerDeactivate
NULL, // pfnPlayerPreThink
NULL, // pfnPlayerPostThink
NULL, // pfnStartFrame
NULL, // pfnParmsNewLevel
NULL, // pfnParmsChangeLevel
NULL, // pfnGetGameDescription
NULL, // pfnPlayerCustomization
NULL, // pfnSpectatorConnect
NULL, // pfnSpectatorDisconnect
NULL, // pfnSpectatorThink
NULL, // pfnSys_Error
NULL, // pfnPM_Move
NULL, // pfnPM_Init
NULL, // pfnPM_FindTextureType
NULL, // pfnSetupVisibility
NULL, // pfnUpdateClientData
NULL, // pfnAddToFullPack
@ -94,43 +85,124 @@ static DLL_FUNCTIONS gFunctionTable = {
NULL, // pfnAllowLagCompensation
};
static NEW_DLL_FUNCTIONS gNewFunctionTable = {
NULL, //pfnOnFreeEntPrivateData
NULL, //pfnGameShutdown
NULL, //pfnShouldCollide
NULL, //pfnCvarValue
&mm_CvarValue2, //pfnCvarValue2
DLL_FUNCTIONS g_DLLFuncTable_Post =
{
NULL, // pfnGameInit
NULL, // pfnSpawn
NULL, // pfnThink
NULL, // pfnUse
NULL, // pfnTouch
NULL, // pfnBlocked
NULL, // pfnKeyValue
NULL, // pfnSave
NULL, // pfnRestore
NULL, // pfnSetAbsBox
NULL, // pfnSaveWriteFields
NULL, // pfnSaveReadFields
NULL, // pfnSaveGlobalState
NULL, // pfnRestoreGlobalState
NULL, // pfnResetGlobalState
NULL, // pfnClientConnect
NULL, // pfnClientDisconnect
NULL, // pfnClientKill
NULL, // pfnClientPutInServer
NULL, // pfnClientCommand
NULL, // pfnClientUserInfoChanged
&ServerActivate_PostHook, // pfnServerActivate
NULL, // pfnServerDeactivate
NULL, // pfnPlayerPreThink
NULL, // pfnPlayerPostThink
NULL, // pfnStartFrame
NULL, // pfnParmsNewLevel
NULL, // pfnParmsChangeLevel
NULL, // pfnGetGameDescription
NULL, // pfnPlayerCustomization
NULL, // pfnSpectatorConnect
NULL, // pfnSpectatorDisconnect
NULL, // pfnSpectatorThink
NULL, // pfnSys_Error
NULL, // pfnPM_Move
NULL, // pfnPM_Init
NULL, // pfnPM_FindTextureType
NULL, // pfnSetupVisibility
NULL, // pfnUpdateClientData
NULL, // pfnAddToFullPack
NULL, // pfnCreateBaseline
NULL, // pfnRegisterEncoders
NULL, // pfnGetWeaponData
NULL, // pfnCmdStart
NULL, // pfnCmdEnd
NULL, // pfnConnectionlessPacket
NULL, // pfnGetHullBounds
NULL, // pfnCreateInstancedBaselines
NULL, // pfnInconsistentFile
NULL, // pfnAllowLagCompensation
};
NEW_DLL_FUNCTIONS g_NewDLLFuncTable =
{
NULL, //! pfnOnFreeEntPrivateData() Called right before the object's memory is freed. Calls its destructor.
NULL, //! pfnGameShutdown()
NULL, //! pfnShouldCollide()
NULL, //! pfnCvarValue()
&CvarValue2_PreHook, //! pfnCvarValue2()
};
C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
{
if(!pFunctionTable) {
if (!pFunctionTable)
{
UTIL_LogPrintf("GetEntityAPI2 called with null pFunctionTable");
return(FALSE);
return FALSE;
}
else if(*interfaceVersion != INTERFACE_VERSION) {
if (*interfaceVersion != INTERFACE_VERSION)
{
UTIL_LogPrintf("GetEntityAPI2 version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION);
//! Tell metamod what version we had, so it can figure out who is out of date.
*interfaceVersion = INTERFACE_VERSION;
return(FALSE);
return FALSE;
}
memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
return(TRUE);
memcpy(pFunctionTable, &g_DLLFuncTable, sizeof(DLL_FUNCTIONS));
return TRUE;
}
C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
{
if (!pFunctionTable)
{
ALERT(at_logged, "%s called with null pFunctionTable", __FUNCTION__);
return FALSE;
}
if (*interfaceVersion != INTERFACE_VERSION)
{
ALERT(at_logged, "%s version mismatch; requested=%d ours=%d", __FUNCTION__, *interfaceVersion, INTERFACE_VERSION);
*interfaceVersion = INTERFACE_VERSION;
return FALSE;
}
memcpy(pFunctionTable, &g_DLLFuncTable_Post, sizeof(DLL_FUNCTIONS));
return TRUE;
}
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
{
if (!pNewFunctionTable) {
if (!pNewFunctionTable)
{
UTIL_LogPrintf("GetNewDLLFunctions called with null pNewFunctionTable");
return(FALSE);
}
else if (*interfaceVersion != NEW_DLL_FUNCTIONS_VERSION) {
if (*interfaceVersion != NEW_DLL_FUNCTIONS_VERSION)
{
UTIL_LogPrintf("GetNewDLLFunctions version mismatch; requested=%d ours=%d", *interfaceVersion, NEW_DLL_FUNCTIONS_VERSION);
//! Tell metamod what version we had, so it can figure out who is out of date.
*interfaceVersion = NEW_DLL_FUNCTIONS_VERSION;
return(FALSE);
return FALSE;
}
memcpy(pNewFunctionTable, &gNewFunctionTable, sizeof(NEW_DLL_FUNCTIONS));
return(TRUE);
memcpy(pNewFunctionTable, &g_NewDLLFuncTable, sizeof(NEW_DLL_FUNCTIONS));
return TRUE;
}

View File

@ -1,24 +1,14 @@
#pragma once
/* <7e2> ../engine/voice_codecs/speex/../frame_encoder/iframeencoder.h:15 */
class IFrameEncoder {
protected:
virtual ~IFrameEncoder() {};
public:
// quality is in [0..10]
/* <855> ../engine/voice_codecs/speex/../frame_encoder/iframeencoder.h:23 */
virtual bool Init(int quality, int &rawFrameSize, int &encodedFrameSize) = 0;
/* <88c> ../engine/voice_codecs/speex/../frame_encoder/iframeencoder.h:25 */
virtual void Release() = 0;
/* <8b0> ../engine/voice_codecs/speex/../frame_encoder/iframeencoder.h:29 */
virtual void EncodeFrame(const char *pUncompressedBytes, char *pCompressed) = 0;
/* <8de> ../engine/voice_codecs/speex/../frame_encoder/iframeencoder.h:33 */
virtual void DecodeFrame(const char *pCompressed, char *pDecompressedBytes) = 0;
/* <90c> ../engine/voice_codecs/speex/../frame_encoder/iframeencoder.h:36 */
virtual bool ResetState() = 0;
};

View File

@ -42,7 +42,7 @@ static META_FUNCTIONS gMetaFunctionTable = {
NULL, // pfnGetEntityAPI HL SDK; called before game DLL
NULL, // pfnGetEntityAPI_Post META; called after game DLL
&GetEntityAPI2, // pfnGetEntityAPI2 HL SDK2; called before game DLL
NULL, // pfnGetEntityAPI2_Post META; called after game DLL
&GetEntityAPI2_Post, // pfnGetEntityAPI2_Post META; called after game DLL
&GetNewDLLFunctions, // pfnGetNewDLLFunctions HL SDK2; called before game DLL
NULL, // pfnGetNewDLLFunctions_Post META; called after game DLL
NULL, // pfnGetEngineFunctions META; called before HL engine
@ -79,7 +79,7 @@ C_DLLEXPORT int Meta_Query(char * /*ifvers */, plugin_info_t **pPlugInfo, mutil_
// Get metamod utility function table.
gpMetaUtilFuncs = pMetaUtilFuncs;
return(TRUE);
return TRUE;
}
// Metamod attaching plugin to the server.
@ -91,20 +91,20 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME /* now */, META_FUNCTIONS *pFunctionTa
{
if(!pMGlobals) {
LOG_ERROR(PLID, "Meta_Attach called with null pMGlobals");
return(FALSE);
return FALSE;
}
gpMetaGlobals = pMGlobals;
if(!pFunctionTable) {
LOG_ERROR(PLID, "Meta_Attach called with null pFunctionTable");
return(FALSE);
return FALSE;
}
memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
gpGamedllFuncs = pGamedllFuncs;
return Revoice_Load() ? (TRUE) : (FALSE);
return Revoice_Load() ? TRUE : FALSE;
}
// Metamod detaching plugin from the server.
@ -112,31 +112,6 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME /* now */, META_FUNCTIONS *pFunctionTa
// reason (given) why detaching (refresh, console unload, forced unload, etc)
C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME /* now */, PL_UNLOAD_REASON /* reason */)
{
return(TRUE);
}
bool Revoice_Load()
{
if (!Revoice_Utils_Init())
return false;
/*if (!Revoice_Cfg_LoadDefault())
return false;*/
if (!Revoice_RehldsApi_Init()) {
LCPrintf(true, "Failed to locate REHLDS API\n");
return false;
}
if (!Revoice_ReunionApi_Init())
return false;
Revoice_Init_Players();
if (!Revoice_Main_Init()) {
LCPrintf(true, "Initialization failed\n");
return false;
}
return true;
Revoice_Main_DeInit();
return TRUE;
}

View File

@ -1,129 +1,77 @@
#include "precompiled.h"
CRevoiceConfig* g_RevoiceConfig;
char g_ExecConfigCmd[MAX_PATH];
const char REVOICE_CFG_FILE[] = "revoice.cfg";
bool Revoice_Cfg_LoadDefault()
void Revoice_Exec_Config()
{
CRevoiceConfig* cfg = CRevoiceConfig::load(REVOICE_CFG_FILE);
if (!g_ExecConfigCmd[0]) {
return;
}
if (!cfg)
return false;
g_engfuncs.pfnServerCommand(g_ExecConfigCmd);
g_engfuncs.pfnServerExecute();
}
if (g_RevoiceConfig)
delete g_RevoiceConfig;
bool Revoice_Init_Config()
{
const char *pszGameDir = GET_GAME_INFO(PLID, GINFO_GAMEDIR);
const char *pszPluginDir = GET_PLUGIN_PATH(PLID);
g_RevoiceConfig = cfg;
char szRelativePath[MAX_PATH];
strncpy(szRelativePath, &pszPluginDir[strlen(pszGameDir) + 1], sizeof(szRelativePath) - 1);
szRelativePath[sizeof(szRelativePath) - 1] = '\0';
NormalizePath(szRelativePath);
char *pos = strrchr(szRelativePath, '/');
if (pos) {
*(pos + 1) = '\0';
}
snprintf(g_ExecConfigCmd, sizeof(g_ExecConfigCmd), "exec \"%s%s\"\n", szRelativePath, REVOICE_CFG_FILE);
return true;
}
CRevoiceConfig* CRevoiceConfig::load(const char* fname)
cvar_t g_cv_rev_hltv_codec = { "REV_HltvCodec", "opus", 0, 0.0f, nullptr };
cvar_t g_cv_rev_default_codec = { "REV_DefaultCodec", "speex", 0, 0.0f, nullptr };
cvar_t g_cv_rev_version = { "revoice_version", APP_VERSION, FCVAR_SERVER, 0.0f, nullptr };
cvar_t *g_pcv_rev_hltv_codec = nullptr;
cvar_t *g_pcv_rev_default_codec = nullptr;
cvar_t *g_pcv_sv_voiceenable = nullptr;
void Revoice_Init_Cvars()
{
char namebuf[MAX_PATH];
char gamedir[MAX_PATH];
g_engfuncs.pfnAddServerCommand("rev", Revoice_Cmds_Handler);
sprintf(namebuf, "./%s", fname);
g_engfuncs.pfnCvar_RegisterVariable(&g_cv_rev_version);
g_engfuncs.pfnCvar_RegisterVariable(&g_cv_rev_hltv_codec);
g_engfuncs.pfnCvar_RegisterVariable(&g_cv_rev_default_codec);
FILE *fl = fopen(namebuf, "r");
g_pcv_sv_voiceenable = g_engfuncs.pfnCVarGetPointer("sv_voiceenable");
g_pcv_rev_hltv_codec = g_engfuncs.pfnCVarGetPointer(g_cv_rev_hltv_codec.name);
g_pcv_rev_default_codec = g_engfuncs.pfnCVarGetPointer(g_cv_rev_default_codec.name);
}
if (fl == NULL)
REVCmds g_revoice_cmds[] = {
{ "version", Cmd_REV_Version }
};
void Revoice_Cmds_Handler()
{
const char *pcmd = CMD_ARGV(1);
for (auto& cmds : g_revoice_cmds)
{
g_engfuncs.pfnGetGameDir(gamedir);
sprintf(namebuf, "./%s/%s", gamedir, fname);
fl = fopen(namebuf, "r");
if (fl == NULL) {
LCPrintf(true, "Failed to load config: can't find %s in server root or gamedir\n", fname);
return NULL;
if (_stricmp(cmds.name, pcmd) == 0 && cmds.func) {
cmds.func();
}
}
char linebuf[2048];
int cline = 0;
CRevoiceConfig* cfg = createDefault();
while (fgets(linebuf, sizeof(linebuf), fl))
{
cline++;
char* l = trimbuf(linebuf);
if (l[0] == '\0' || l[0] == '#')
continue;
char* valSeparator = strchr(l, '=');
if (valSeparator == NULL) {
LCPrintf(true, "Config line parsing failed: missed '=' on line %d\n", cline);
}
*(valSeparator++) = 0;
char* param = trimbuf(l);
char* value = trimbuf(valSeparator);
if (!cfg->parseCfgParam(param, value)) {
LCPrintf(true, "Config line parsing failed: unknown parameter '%s' at line %d\n", param, cline);
}
}
if (fl)
fclose(fl);
return cfg;
}
CRevoiceConfig* CRevoiceConfig::createDefault()
void Cmd_REV_Version()
{
CRevoiceConfig* cfg = new CRevoiceConfig();
cfg->m_LogMode = rl_console | rl_logfile;
return cfg;
}
bool CRevoiceConfig::parseCfgParam(const char* param, const char* value)
{
#define REV_CFG_PARSE_INT(paramName, field, _type, minVal, maxVal) \
if (!strcasecmp(paramName, param)) { \
int i = atoi(value); \
if (i < minVal || i > maxVal) { \
LCPrintf(true, "Invalid %s value '%s'\n", param, value); \
return false; \
} \
field = (_type) i; \
return true; \
}
#define REV_CFG_PARSE_IP(paramName, field) \
if (!strcasecmp(paramName, param)) { \
field = inet_addr(value); \
return true; \
}
#define REV_CFG_PARSE_BOOL(paramName, field) \
if (!strcasecmp(paramName, param)) { \
int i = atoi(value); \
if (i < 0 || i > 1) { \
LCPrintf(true, "Invalid %s value '%s'\n", param, value); \
return false; \
} \
field = i ? true : false; \
return true; \
}
#define REV_CFG_PARSE_STR(paramName, field) \
if (!strcasecmp(paramName, param)) { \
strncpy(field, value, ARRAYSIZE(field) - 1); \
field[ARRAYSIZE(field) - 1] = 0; \
return true; \
}
REV_CFG_PARSE_INT("LoggingMode", m_LogMode, int, rl_none, (rl_console | rl_logfile));
LCPrintf(true, " Config line parsing failed: unknown parameter '%s'\n", param);
return false;
// print version
g_engfuncs.pfnServerPrint("Revoice version: " APP_VERSION "\n");
g_engfuncs.pfnServerPrint("Build date: " APP_COMMIT_TIME " " APP_COMMIT_DATE "\n");
g_engfuncs.pfnServerPrint("Build from: " APP_COMMIT_URL APP_COMMIT_SHA "\n");
}

View File

@ -2,23 +2,18 @@
#include "revoice_shared.h"
#define REVOICE_CFG_FILE "revoice.cfg"
class CRevoiceConfig {
private:
int m_LogMode;
bool parseCfgParam(const char* param, const char* value);
public:
static CRevoiceConfig* createDefault();
static CRevoiceConfig* load(const char* fname);
bool hasLogMode(revoice_log_mode m) {
return (m_LogMode & m) == m;
}
struct REVCmds {
const char *name;
void (*func)();
};
extern CRevoiceConfig* g_RevoiceConfig;
extern bool Revoice_Cfg_LoadDefault();
void Revoice_Exec_Config();
bool Revoice_Init_Config();
void Revoice_Init_Cvars();
void Revoice_Cmds_Handler();
void Cmd_REV_Version();
extern cvar_t *g_pcv_sv_voiceenable;
extern cvar_t *g_pcv_rev_hltv_codec;
extern cvar_t *g_pcv_rev_default_codec;

View File

@ -1,7 +1,5 @@
#include "precompiled.h"
cvar_t *pcv_sv_voiceenable = NULL;
void SV_DropClient_hook(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool crash, const char *msg)
{
CRevoicePlayer *plr = GetPlayerByClientPtr(cl);
@ -11,16 +9,14 @@ void SV_DropClient_hook(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool
chain->callNext(cl, crash, msg);
}
void mm_CvarValue2(const edict_t *pEnt, int requestID, const char *cvarName, const char *cvarValue)
void CvarValue2_PreHook(const edict_t *pEnt, int requestID, const char *cvarName, const char *cvarValue)
{
CRevoicePlayer *plr = GetPlayerByEdict(pEnt);
if (plr->GetRequestId() != requestID) {
RETURN_META(MRES_IGNORED);
}
const char *lastSeparator = strrchr(cvarValue, ',');
if (lastSeparator)
{
int buildNumber = atoi(lastSeparator + 1);
@ -32,7 +28,7 @@ void mm_CvarValue2(const edict_t *pEnt, int requestID, const char *cvarName, con
RETURN_META(MRES_IGNORED);
}
int TranscodeVoice(const char *srcBuf, int srcBufLen, IVoiceCodec *srcCodec, IVoiceCodec *dstCodec, char *dstBuf, int dstBufSize)
int TranscodeVoice(CRevoicePlayer *srcPlayer, const char *srcBuf, int srcBufLen, IVoiceCodec *srcCodec, IVoiceCodec *dstCodec, char *dstBuf, int dstBufSize)
{
char decodedBuf[32768];
@ -74,7 +70,7 @@ void SV_ParseVoiceData_emu(IGameClient *cl)
g_RehldsFuncs->MSG_ReadBuf(nDataLength, chReceived);
if (pcv_sv_voiceenable->value == 0.0f) {
if (g_pcv_sv_voiceenable->value == 0.0f) {
return;
}
@ -94,38 +90,38 @@ void SV_ParseVoiceData_emu(IGameClient *cl)
switch (srcPlayer->GetCodecType())
{
case vct_silk:
{
if (nDataLength > MAX_SILK_DATA_LEN || srcPlayer->GetVoiceRate() > MAX_SILK_VOICE_RATE)
return;
silkData = chReceived; silkDataLen = nDataLength;
speexData = transcodedBuf;
speexDataLen = TranscodeVoice(silkData, silkDataLen, srcPlayer->GetSilkCodec(), srcPlayer->GetSpeexCodec(), transcodedBuf, sizeof(transcodedBuf));
break;
}
case vct_opus:
{
if (nDataLength > MAX_OPUS_DATA_LEN || srcPlayer->GetVoiceRate() > MAX_OPUS_VOICE_RATE)
return;
opusData = chReceived; opusDataLen = nDataLength;
speexData = transcodedBuf;
speexDataLen = TranscodeVoice(opusData, opusDataLen, srcPlayer->GetOpusCodec(), srcPlayer->GetSpeexCodec(), transcodedBuf, sizeof(transcodedBuf));
break;
}
case vct_speex:
{
if (nDataLength > MAX_SPEEX_DATA_LEN || srcPlayer->GetVoiceRate() > MAX_SPEEX_VOICE_RATE)
return;
speexData = chReceived; speexDataLen = nDataLength;
silkData = transcodedBuf;
silkDataLen = TranscodeVoice(speexData, speexDataLen, srcPlayer->GetSpeexCodec(), srcPlayer->GetSilkCodec(), transcodedBuf, sizeof(transcodedBuf));
break;
}
default:
case vct_silk:
{
if (nDataLength > MAX_SILK_DATA_LEN || srcPlayer->GetVoiceRate() > MAX_SILK_VOICE_RATE)
return;
silkData = chReceived; silkDataLen = nDataLength;
speexData = transcodedBuf;
speexDataLen = TranscodeVoice(srcPlayer, silkData, silkDataLen, srcPlayer->GetSilkCodec(), srcPlayer->GetSpeexCodec(), transcodedBuf, sizeof(transcodedBuf));
break;
}
case vct_opus:
{
if (nDataLength > MAX_OPUS_DATA_LEN || srcPlayer->GetVoiceRate() > MAX_OPUS_VOICE_RATE)
return;
opusData = chReceived; opusDataLen = nDataLength;
speexData = transcodedBuf;
speexDataLen = TranscodeVoice(srcPlayer, opusData, opusDataLen, srcPlayer->GetOpusCodec(), srcPlayer->GetSpeexCodec(), transcodedBuf, sizeof(transcodedBuf));
break;
}
case vct_speex:
{
if (nDataLength > MAX_SPEEX_DATA_LEN || srcPlayer->GetVoiceRate() > MAX_SPEEX_VOICE_RATE)
return;
speexData = chReceived; speexDataLen = nDataLength;
silkData = transcodedBuf;
silkDataLen = TranscodeVoice(srcPlayer, speexData, speexDataLen, srcPlayer->GetSpeexCodec(), srcPlayer->GetSilkCodec(), transcodedBuf, sizeof(transcodedBuf));
break;
}
default:
return;
}
int maxclients = g_RehldsSvs->GetMaxClients();
@ -140,7 +136,8 @@ void SV_ParseVoiceData_emu(IGameClient *cl)
if (!dstClient->IsActive() && !dstClient->IsConnected() && dstPlayer != srcPlayer)
continue;
char *sendBuf; int nSendLen;
char *sendBuf;
int nSendLen;
switch (dstPlayer->GetCodecType())
{
case vct_silk:
@ -153,12 +150,12 @@ void SV_ParseVoiceData_emu(IGameClient *cl)
nSendLen = speexDataLen;
break;
default:
sendBuf = NULL;
sendBuf = nullptr;
nSendLen = 0;
break;
}
if (sendBuf == NULL || nSendLen == 0)
if (sendBuf == nullptr || nSendLen == 0)
continue;
if (dstPlayer == srcPlayer && !dstClient->GetLoopback())
@ -185,15 +182,20 @@ void Rehlds_HandleNetCommand(IRehldsHook_HandleNetCommand *chain, IGameClient *c
chain->callNext(cl, opcode);
}
qboolean mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128]) {
qboolean ClientConnect_PreHook(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128])
{
CRevoicePlayer *plr = GetPlayerByEdict(pEntity);
plr->OnConnected();
RETURN_META_VALUE(MRES_IGNORED, TRUE);
}
void ServerActivate_PostHook(edict_t *pEdictList, int edictCount, int clientMax)
{
Revoice_Exec_Config();
SET_META_RESULT(MRES_IGNORED);
}
void SV_WriteVoiceCodec_hooked(IRehldsHook_SV_WriteVoiceCodec *chain, sizebuf_t *sb)
{
IGameClient *cl = g_RehldsFuncs->GetHostClient();
@ -203,17 +205,11 @@ void SV_WriteVoiceCodec_hooked(IRehldsHook_SV_WriteVoiceCodec *chain, sizebuf_t
{
case vct_silk:
case vct_opus:
{
g_RehldsFuncs->MSG_WriteByte(sb, svc_voiceinit); // svc_voiceinit
g_RehldsFuncs->MSG_WriteString(sb, ""); // codec id
g_RehldsFuncs->MSG_WriteByte(sb, 0); // quality
break;
}
case vct_speex:
{
g_RehldsFuncs->MSG_WriteByte(sb, svc_voiceinit); // svc_voiceinit
g_RehldsFuncs->MSG_WriteString(sb, "voice_speex"); // codec id
g_RehldsFuncs->MSG_WriteByte(sb, 5); // quality
g_RehldsFuncs->MSG_WriteByte(sb, svc_voiceinit);
g_RehldsFuncs->MSG_WriteString(sb, "voice_speex"); // codec id
g_RehldsFuncs->MSG_WriteByte(sb, 5); // quality
break;
}
default:
@ -222,13 +218,55 @@ void SV_WriteVoiceCodec_hooked(IRehldsHook_SV_WriteVoiceCodec *chain, sizebuf_t
}
}
bool Revoice_Main_Init()
void Cvar_DirectSet_hooked(IRehldsHook_Cvar_DirectSet *chain, cvar_t *var, const char *value)
{
g_RehldsHookchains->SV_DropClient()->registerHook(SV_DropClient_hook, HC_PRIORITY_DEFAULT + 1);
g_RehldsHookchains->HandleNetCommand()->registerHook(Rehlds_HandleNetCommand, HC_PRIORITY_DEFAULT + 1);
g_RehldsHookchains->SV_WriteVoiceCodec()->registerHook(SV_WriteVoiceCodec_hooked, HC_PRIORITY_DEFAULT + 1);
chain->callNext(var, value);
pcv_sv_voiceenable = g_engfuncs.pfnCVarGetPointer("sv_voiceenable");
if (g_pcv_rev_hltv_codec == var
|| g_pcv_rev_default_codec == var) {
Revoice_Update_Players();
}
}
bool Revoice_Load()
{
if (!Revoice_Utils_Init())
return false;
if (!Revoice_RehldsApi_Init()) {
LCPrintf(true, "Failed to locate REHLDS API\n");
return false;
}
if (!Revoice_ReunionApi_Init())
return false;
Revoice_Init_Cvars();
Revoice_Init_Config();
Revoice_Init_Players();
if (!Revoice_Main_Init()) {
LCPrintf(true, "Initialization failed\n");
return false;
}
return true;
}
bool Revoice_Main_Init()
{
g_RehldsHookchains->SV_DropClient()->registerHook(&SV_DropClient_hook, HC_PRIORITY_DEFAULT + 1);
g_RehldsHookchains->HandleNetCommand()->registerHook(&Rehlds_HandleNetCommand, HC_PRIORITY_DEFAULT + 1);
g_RehldsHookchains->SV_WriteVoiceCodec()->registerHook(&SV_WriteVoiceCodec_hooked, HC_PRIORITY_DEFAULT + 1);
g_RehldsHookchains->Cvar_DirectSet()->registerHook(&Cvar_DirectSet_hooked, HC_PRIORITY_DEFAULT + 1);
return true;
}
void Revoice_Main_DeInit()
{
g_RehldsHookchains->SV_DropClient()->unregisterHook(&SV_DropClient_hook);
g_RehldsHookchains->HandleNetCommand()->unregisterHook(&Rehlds_HandleNetCommand);
g_RehldsHookchains->SV_WriteVoiceCodec()->unregisterHook(&SV_WriteVoiceCodec_hooked);
g_RehldsHookchains->Cvar_DirectSet()->unregisterHook(&Cvar_DirectSet_hooked);
}

View File

@ -3,7 +3,11 @@
#include "revoice_shared.h"
#include "revoice_player.h"
extern qboolean mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128]);
extern void mm_CvarValue2(const edict_t *pEnt, int requestID, const char *cvarName, const char *value);
bool Revoice_Load();
void Revoice_Main_DeInit();
bool Revoice_Main_Init();
void CvarValue2_PreHook(const edict_t *pEnt, int requestID, const char *cvarName, const char *cvarValue);
qboolean ClientConnect_PreHook(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128]);
void ServerActivate_PostHook(edict_t *pEdictList, int edictCount, int clientMax);
extern bool Revoice_Main_Init();

View File

@ -1,26 +1,38 @@
#include "precompiled.h"
const char *CRevoicePlayer::m_szCodecType[] = {
"none",
"silk",
"opus",
"speex"
};
CRevoicePlayer g_Players[MAX_PLAYERS];
CRevoicePlayer::CRevoicePlayer()
{
m_CodecType = vct_none;
m_SpeexCodec = new VoiceCodec_Frame(new VoiceEncoder_Speex());
m_SilkCodec = new CSteamP2PCodec(new VoiceEncoder_Silk());
m_OpusCodec = new CSteamP2PCodec(new VoiceEncoder_Opus());
m_SilkCodec = new CSteamP2PCodec(new VoiceEncoder_Silk());
m_OpusCodec = new CSteamP2PCodec(new VoiceEncoder_Opus());
m_SpeexCodec->Init(SPEEX_VOICE_QUALITY);
m_SilkCodec->Init(SILK_VOICE_QUALITY);
m_OpusCodec->Init(OPUS_VOICE_QUALITY);
m_SilkCodec ->Init(SILK_VOICE_QUALITY);
m_OpusCodec ->Init(OPUS_VOICE_QUALITY);
m_RehldsClient = NULL;
m_Protocol = 0;
m_HLTV = false;
m_Connected = false;
m_Client = nullptr;
}
void CRevoicePlayer::Initialize(IGameClient* cl)
void CRevoicePlayer::Initialize(IGameClient *cl)
{
m_RehldsClient = cl;
m_Client = cl;
m_SpeexCodec->SetClient(cl);
m_SilkCodec ->SetClient(cl);
m_OpusCodec ->SetClient(cl);
}
void CRevoicePlayer::OnConnected()
@ -31,8 +43,7 @@ void CRevoicePlayer::OnConnected()
return;
}
int protocol = g_ReunionApi->GetClientProtocol(m_RehldsClient->GetId());
int protocol = g_ReunionApi->GetClientProtocol(m_Client->GetId());
if (protocol != 47 && protocol != 48) {
return;
}
@ -43,19 +54,24 @@ void CRevoicePlayer::OnConnected()
m_SpeexCodec->ResetState();
// default codec
m_CodecType = vct_speex;
m_CodecType = GetCodecTypeByString(g_pcv_rev_default_codec->string);
m_VoiceRate = 0;
m_Connected = true;
m_RequestId = MAKE_REQUESTID(PLID);
m_Protocol = protocol;
if (m_Protocol == 48) {
g_engfuncs.pfnQueryClientCvarValue2(m_RehldsClient->GetEdict(), "sv_version", m_RequestId);
if (g_ReunionApi->GetClientAuthtype(m_Client->GetId()) == DP_AUTH_HLTV) {
m_CodecType = GetCodecTypeByString(g_pcv_rev_hltv_codec->string);
m_HLTV = true;
}
else if (m_Protocol == 48) {
g_engfuncs.pfnQueryClientCvarValue2(m_Client->GetEdict(), "sv_version", m_RequestId);
}
}
void CRevoicePlayer::OnDisconnected()
{
m_HLTV = false;
m_Connected = false;
m_Protocol = 0;
m_CodecType = vct_none;
@ -63,10 +79,31 @@ void CRevoicePlayer::OnDisconnected()
m_RequestId = 0;
}
void CRevoicePlayer::Update()
{
m_CodecType = GetCodecTypeByString(((m_HLTV) ?
g_pcv_rev_hltv_codec : g_pcv_rev_default_codec)->string);
m_RequestId = MAKE_REQUESTID(PLID);
if (m_Protocol == 48) {
g_engfuncs.pfnQueryClientCvarValue2(m_Client->GetEdict(), "sv_version", m_RequestId);
}
}
void Revoice_Update_Players()
{
int maxclients = g_RehldsSvs->GetMaxClients();
for (int i = 0; i < maxclients; i++) {
if (g_Players[i].IsConnected()) {
g_Players[i].Update();
}
}
}
void Revoice_Init_Players()
{
int maxclients = g_RehldsSvs->GetMaxClients();
for (int i = 0; i < maxclients; i++) {
g_Players[i].Initialize(g_RehldsSvs->GetClient(i));
}
@ -90,8 +127,8 @@ CRevoicePlayer *GetPlayerByEdict(const edict_t *ed)
void CRevoicePlayer::SetLastVoiceTime(double time)
{
UpdateVoiceRate(time - m_RehldsClient->GetLastVoiceTime());
m_RehldsClient->SetLastVoiceTime(time);
UpdateVoiceRate(time - m_Client->GetLastVoiceTime());
m_Client->SetLastVoiceTime(time);
}
void CRevoicePlayer::UpdateVoiceRate(double delta)
@ -100,20 +137,17 @@ void CRevoicePlayer::UpdateVoiceRate(double delta)
{
switch (m_CodecType)
{
case vct_silk:
m_VoiceRate -= int(delta * MAX_SILK_VOICE_RATE) + MAX_SILK_DATA_LEN;
break;
case vct_opus:
m_VoiceRate -= int(delta * MAX_OPUS_VOICE_RATE) + MAX_OPUS_DATA_LEN;
break;
case vct_speex:
m_VoiceRate -= int(delta * MAX_SPEEX_VOICE_RATE) + MAX_SPEEX_DATA_LEN;
break;
default:
break;
case vct_silk:
m_VoiceRate -= int(delta * MAX_SILK_VOICE_RATE) + MAX_SILK_DATA_LEN;
break;
case vct_opus:
m_VoiceRate -= int(delta * MAX_OPUS_VOICE_RATE) + MAX_OPUS_DATA_LEN;
break;
case vct_speex:
m_VoiceRate -= int(delta * MAX_SPEEX_VOICE_RATE) + MAX_SPEEX_DATA_LEN;
break;
default:
break;
}
if (m_VoiceRate < 0)
@ -121,7 +155,27 @@ void CRevoicePlayer::UpdateVoiceRate(double delta)
}
}
const char *CRevoicePlayer::GetCodecTypeToString()
{
return m_szCodecType[ m_CodecType ];
}
void CRevoicePlayer::IncreaseVoiceRate(int dataLength)
{
m_VoiceRate += dataLength;
}
CodecType CRevoicePlayer::GetCodecTypeByString(const char *codec)
{
#define REV_CODEC(know_codec)\
if (_stricmp(codec, #know_codec) == 0) {\
return vct_##know_codec;\
}\
REV_CODEC(opus);
REV_CODEC(silk);
REV_CODEC(speex);
#undef REV_CODEC
return vct_none;
}

View File

@ -8,40 +8,49 @@
class CRevoicePlayer {
private:
IGameClient* m_RehldsClient;
revoice_codec_type m_CodecType;
CSteamP2PCodec* m_SilkCodec;
CSteamP2PCodec* m_OpusCodec;
VoiceCodec_Frame* m_SpeexCodec;
IGameClient *m_Client;
CodecType m_CodecType;
CSteamP2PCodec *m_SilkCodec;
CSteamP2PCodec *m_OpusCodec;
VoiceCodec_Frame *m_SpeexCodec;
int m_Protocol;
int m_VoiceRate;
int m_RequestId;
bool m_Connected;
bool m_HLTV;
public:
CRevoicePlayer();
void Initialize(IGameClient* cl);
void Update();
void Initialize(IGameClient *cl);
void OnConnected();
void OnDisconnected();
void SetLastVoiceTime(double time);
void UpdateVoiceRate(double delta);
void IncreaseVoiceRate(int dataLength);
CodecType GetCodecTypeByString(const char *codec);
const char *GetCodecTypeToString();
int GetVoiceRate() const { return m_VoiceRate; }
int GetRequestId() const { return m_RequestId; }
bool IsConnected() const { return m_Connected; }
bool IsHLTV() const { return m_HLTV; }
void SetCodecType(revoice_codec_type codecType) { m_CodecType = codecType; };
revoice_codec_type GetCodecType() const { return m_CodecType; }
CSteamP2PCodec* GetSilkCodec() const { return m_SilkCodec; }
CSteamP2PCodec* GetOpusCodec() const { return m_OpusCodec; }
VoiceCodec_Frame* GetSpeexCodec() const { return m_SpeexCodec; }
IGameClient* GetClient() const { return m_RehldsClient; }
static const char *m_szCodecType[];
void SetCodecType(CodecType codecType) { m_CodecType = codecType; }
CodecType GetCodecType() const { return m_CodecType; }
CSteamP2PCodec *GetSilkCodec() const { return m_SilkCodec; }
CSteamP2PCodec *GetOpusCodec() const { return m_OpusCodec; }
VoiceCodec_Frame *GetSpeexCodec() const { return m_SpeexCodec; }
IGameClient *GetClient() const { return m_Client; }
};
extern CRevoicePlayer g_Players[MAX_PLAYERS];
extern void Revoice_Init_Players();
extern CRevoicePlayer* GetPlayerByClientPtr(IGameClient* cl);
extern CRevoicePlayer* GetPlayerByEdict(const edict_t* ed);
CRevoicePlayer *GetPlayerByClientPtr(IGameClient *cl);
CRevoicePlayer *GetPlayerByEdict(const edict_t *ed);
void Revoice_Init_Players();
void Revoice_Update_Players();

View File

@ -1,12 +1,12 @@
#include "precompiled.h"
IRehldsApi* g_RehldsApi;
const RehldsFuncs_t* g_RehldsFuncs;
IRehldsHookchains* g_RehldsHookchains;
IRehldsServerStatic* g_RehldsSvs;
IRehldsServerData* g_RehldsSv;
IRehldsApi *g_RehldsApi;
const RehldsFuncs_t *g_RehldsFuncs;
IRehldsHookchains *g_RehldsHookchains;
IRehldsServerStatic *g_RehldsSvs;
IRehldsServerData *g_RehldsSv;
bool Revoice_RehldsApi_TryInit(CSysModule* engineModule, char* failureReason)
bool Revoice_RehldsApi_TryInit(CSysModule *engineModule, char *failureReason)
{
if (!engineModule) {
LCPrintf(true, "Failed to locate engine module\n");
@ -53,16 +53,13 @@ bool Revoice_RehldsApi_Init() {
char failReason[2048];
#ifdef WIN32
CSysModule* engineModule = Sys_LoadModule("swds.dll");
CSysModule *engineModule = Sys_LoadModule("swds.dll");
if (!Revoice_RehldsApi_TryInit(engineModule, failReason)) {
engineModule = Sys_LoadModule("filesystem_stdio.dll");
if (!Revoice_RehldsApi_TryInit(engineModule, failReason)) {
LCPrintf(true, "%s", failReason);
return false;
}
LCPrintf(true, "%s", failReason);
return false;
}
#else
CSysModule* engineModule = Sys_LoadModule("engine_i486.so");
CSysModule *engineModule = Sys_LoadModule("engine_i486.so");
if (!Revoice_RehldsApi_TryInit(engineModule, failReason)) {
LCPrintf(true, "%s", failReason);
return false;

View File

@ -24,7 +24,7 @@ enum revoice_log_mode {
rl_logfile = 2,
};
enum revoice_codec_type {
enum CodecType {
vct_none,
vct_silk,
vct_opus,
@ -52,9 +52,11 @@ T clamp(T a, T min, T max) {
}
extern char* trimbuf(char *str);
extern void NormalizePath(char *path);
extern bool IsFileExists(const char *path);
extern void LCPrintf(bool critical, const char *fmt, ...);
extern uint32 crc32(const void* buf, unsigned int bufLen);
extern uint32 crc32(const void *buf, unsigned int bufLen);
extern bool Revoice_Load();
extern bool Revoice_Utils_Init();
extern void util_syserror(const char* fmt, ...);
extern void util_syserror(const char *fmt, ...);

View File

@ -1,10 +1,7 @@
#include "precompiled.h"
cvar_t cv_revoice_version = {"revoice_version", APP_VERSION_STRD, FCVAR_SERVER|FCVAR_EXTDLL, 0, NULL};
cvar_t* pcv_revoice_version;
cvar_t* pcv_mp_logecho;
char logstring[2048];
cvar_t *pcv_mp_logecho;
char g_szLogstring[2048];
void LCPrintf(bool critical, const char *fmt, ...)
{
@ -12,11 +9,11 @@ void LCPrintf(bool critical, const char *fmt, ...)
const int prefixlen = 11; //sizeof(LOG_PREFIX) - 1;
va_start(argptr, fmt);
vsnprintf(logstring + prefixlen, sizeof(logstring) - prefixlen, fmt, argptr);
vsnprintf(g_szLogstring + prefixlen, sizeof(g_szLogstring) - prefixlen, fmt, argptr);
va_end(argptr);
bool bNeedWriteInConsole = critical || (g_RevoiceConfig && g_RevoiceConfig->hasLogMode(rl_console));
bool bNeedWriteInLog = critical || (g_RevoiceConfig && g_RevoiceConfig->hasLogMode(rl_logfile));
bool bNeedWriteInConsole = critical;
bool bNeedWriteInLog = critical;
if (bNeedWriteInConsole && bNeedWriteInLog && g_RehldsSvs && g_RehldsSvs->IsLogActive())
{
@ -25,30 +22,27 @@ void LCPrintf(bool critical, const char *fmt, ...)
}
if (bNeedWriteInConsole)
SERVER_PRINT(logstring);
SERVER_PRINT(g_szLogstring);
if (bNeedWriteInLog)
ALERT(at_logged, logstring);
ALERT(at_logged, g_szLogstring);
}
bool Revoice_Utils_Init()
{
g_engfuncs.pfnCvar_RegisterVariable(&cv_revoice_version);
pcv_revoice_version = g_engfuncs.pfnCVarGetPointer(cv_revoice_version.name);
pcv_mp_logecho = g_engfuncs.pfnCVarGetPointer("mp_logecho");
strcpy(logstring, LOG_PREFIX);
strcpy(g_szLogstring, LOG_PREFIX);
return true;
}
char* trimbuf(char *str)
char *trimbuf(char *str)
{
char *ibuf = str;
int i = 0;
if (str == NULL) return NULL;
if (str == NULL)
return NULL;
for (ibuf = str; *ibuf && (byte)(*ibuf) < (byte)0x80 && isspace(*ibuf); ++ibuf)
;
@ -70,7 +64,7 @@ char* trimbuf(char *str)
return str;
}
uint32 crc32(const void* buf, unsigned int bufLen)
uint32 crc32(const void *buf, unsigned int bufLen)
{
CRC32_t hCrc;
g_engfuncs.pfnCRC32_Init(&hCrc);
@ -79,7 +73,18 @@ uint32 crc32(const void* buf, unsigned int bufLen)
return hCrc;
}
void util_syserror(const char* fmt, ...)
void NormalizePath(char *path)
{
for (char *cp = path; *cp; cp++) {
if (isupper(*cp))
*cp = tolower(*cp);
if (*cp == '\\')
*cp = '/';
}
}
void util_syserror(const char *fmt, ...)
{
va_list argptr;
char buf[4096];
@ -91,5 +96,7 @@ void util_syserror(const char* fmt, ...)
LCPrintf(true, "ERROR: %s", buf);
*(int *)0 = 0;
int *null = 0;
*null = 0;
exit(-1);
}

View File

@ -1,6 +1,5 @@
#include "precompiled.h"
/* <1f68> ../engine/voice_codecs/speex/../frame_encoder/voice_codec_frame.cpp:23 */
VoiceCodec_Frame::VoiceCodec_Frame(IFrameEncoder *pEncoder)
{
m_nEncodeBufferSamples = 0;
@ -8,72 +7,68 @@ VoiceCodec_Frame::VoiceCodec_Frame(IFrameEncoder *pEncoder)
m_pFrameEncoder = pEncoder;
}
/* <2107> ../engine/voice_codecs/speex/../frame_encoder/voice_codec_frame.cpp:30 */
VoiceCodec_Frame::~VoiceCodec_Frame()
{
if (m_pFrameEncoder != NULL) {
if (m_pFrameEncoder) {
m_pFrameEncoder->Release();
m_pFrameEncoder = NULL;
m_pFrameEncoder = nullptr;
}
}
/* <22bc> ../engine/voice_codecs/speex/../frame_encoder/voice_codec_frame.cpp:36 */
bool VoiceCodec_Frame::Init(int quality)
{
if (m_pFrameEncoder == NULL)
if (!m_pFrameEncoder)
return false;
if (m_pFrameEncoder->Init(quality, m_nRawBytes, m_nEncodedBytes)) {
m_nRawSamples = m_nRawBytes >> 1;
return true;
} else {
m_pFrameEncoder->Release();
m_pFrameEncoder = NULL;
return false;
}
m_pFrameEncoder->Release();
m_pFrameEncoder = nullptr;
return false;
}
/* <2038> ../engine/voice_codecs/speex/../frame_encoder/voice_codec_frame.cpp:54 */
void VoiceCodec_Frame::Release()
{
delete this;
}
/* <21fb> ../engine/voice_codecs/speex/../frame_encoder/voice_codec_frame.cpp:59 */
int VoiceCodec_Frame::Compress(const char *pUncompressedBytes, int nSamples, char *pCompressed, int maxCompressedBytes, bool bFinal)
{
if (m_pFrameEncoder == NULL)
if (m_pFrameEncoder == nullptr)
return 0;
const int16 *pUncompressed = (const int16*) pUncompressedBytes;
const int16 *pUncompressed = (const int16 *) pUncompressedBytes;
int nCompressedBytes = 0;
while ((nSamples + m_nEncodeBufferSamples) >= m_nRawSamples && (maxCompressedBytes - nCompressedBytes) >= m_nEncodedBytes)
{
// Get the data block out.
int16 samples[MAX_FRAMEBUFFER_SAMPLES];
memcpy(samples, m_EncodeBuffer, m_nEncodeBufferSamples*BYTES_PER_SAMPLE);
memcpy(samples, m_EncodeBuffer, m_nEncodeBufferSamples * BYTES_PER_SAMPLE);
memcpy(&samples[m_nEncodeBufferSamples], pUncompressed, (m_nRawSamples - m_nEncodeBufferSamples) * BYTES_PER_SAMPLE);
nSamples -= m_nRawSamples - m_nEncodeBufferSamples;
pUncompressed += m_nRawSamples - m_nEncodeBufferSamples;
m_nEncodeBufferSamples = 0;
// Compress it.
m_pFrameEncoder->EncodeFrame((const char*)samples, &pCompressed[nCompressedBytes]);
m_pFrameEncoder->EncodeFrame((const char *)samples, &pCompressed[nCompressedBytes]);
nCompressedBytes += m_nEncodedBytes;
}
// Store the remaining samples.
int nNewSamples = _min(nSamples, _min(m_nRawSamples-m_nEncodeBufferSamples, m_nRawSamples));
int nNewSamples = _min(nSamples, _min(m_nRawSamples - m_nEncodeBufferSamples, m_nRawSamples));
if (nNewSamples) {
memcpy(&m_EncodeBuffer[m_nEncodeBufferSamples], &pUncompressed[nSamples - nNewSamples], nNewSamples*BYTES_PER_SAMPLE);
memcpy(&m_EncodeBuffer[m_nEncodeBufferSamples], &pUncompressed[nSamples - nNewSamples], nNewSamples * BYTES_PER_SAMPLE);
m_nEncodeBufferSamples += nNewSamples;
}
// If it must get the last data, just pad with zeros..
if (bFinal && m_nEncodeBufferSamples && (maxCompressedBytes - nCompressedBytes) >= m_nEncodedBytes) {
memset(&m_EncodeBuffer[m_nEncodeBufferSamples], 0, (m_nRawSamples - m_nEncodeBufferSamples) * BYTES_PER_SAMPLE);
m_pFrameEncoder->EncodeFrame((const char*)m_EncodeBuffer, &pCompressed[nCompressedBytes]);
m_pFrameEncoder->EncodeFrame((const char *)m_EncodeBuffer, &pCompressed[nCompressedBytes]);
nCompressedBytes += m_nEncodedBytes;
m_nEncodeBufferSamples = 0;
}
@ -81,10 +76,9 @@ int VoiceCodec_Frame::Compress(const char *pUncompressedBytes, int nSamples, cha
return nCompressedBytes;
}
/* <205e> ../engine/voice_codecs/speex/../frame_encoder/voice_codec_frame.cpp:102 */
int VoiceCodec_Frame::Decompress(const char *pCompressed, int compressedBytes, char *pUncompressed, int maxUncompressedBytes)
{
if (m_pFrameEncoder == NULL || compressedBytes < m_nEncodedBytes || maxUncompressedBytes < m_nRawBytes)
if (m_pFrameEncoder == nullptr || compressedBytes < m_nEncodedBytes || maxUncompressedBytes < m_nRawBytes)
return 0;
int nDecompressedBytes = 0;
@ -104,17 +98,11 @@ int VoiceCodec_Frame::Decompress(const char *pCompressed, int compressedBytes, c
return nDecompressedBytes / BYTES_PER_SAMPLE;
}
/* <20e1> ../engine/voice_codecs/speex/../frame_encoder/voice_codec_frame.cpp:120 */
bool VoiceCodec_Frame::ResetState()
{
if (m_pFrameEncoder)
if (m_pFrameEncoder) {
return m_pFrameEncoder->ResetState();
else
return false;
}
}
/* <230a> ../engine/voice_codecs/speex/../frame_encoder/voice_codec_frame.cpp:141 */
IVoiceCodec *CreateVoiceCodec_Frame(IFrameEncoder *pEncoder)
{
return new VoiceCodec_Frame(pEncoder);
return false;
}

View File

@ -3,17 +3,19 @@
#include "IVoiceCodec.h"
#include "iframeencoder.h"
/* <19b1> ../engine/voice_codecs/speex/../frame_encoder/voice_codec_frame.cpp:18 */
class IGameClient;
class VoiceCodec_Frame: public IVoiceCodec {
public:
virtual ~VoiceCodec_Frame();
VoiceCodec_Frame(IFrameEncoder *pEncoder);
bool Init(int quality);
void Release();
int Compress(const char *pUncompressedBytes, int nSamples, char *pCompressed, int maxCompressedBytes, bool bFinal);
int Decompress(const char *pCompressed, int compressedBytes, char *pUncompressed, int maxUncompressedBytes);
bool ResetState();
virtual bool Init(int quality);
virtual void Release();
virtual int Compress(const char *pUncompressedBytes, int nSamples, char *pCompressed, int maxCompressedBytes, bool bFinal);
virtual int Decompress(const char *pCompressed, int compressedBytes, char *pUncompressed, int maxUncompressedBytes);
virtual bool ResetState();
void SetClient(IGameClient *client) { m_Client = client; }
protected:
enum { MAX_FRAMEBUFFER_SAMPLES = 1024 };
@ -26,4 +28,6 @@ protected:
int m_nRawSamples;
int m_nEncodedBytes;
}; /* size: 2072, cachelines: 33, members: 7 */
public:
IGameClient *m_Client;
};