2
0
mirror of https://github.com/rehlds/revoice.git synced 2025-01-14 15:47:58 +03:00

Added voice rate limiter

This commit is contained in:
asmodai 2015-12-15 00:50:47 +03:00
parent 639e79e766
commit fec9126f34
6 changed files with 86 additions and 30 deletions

View File

@ -32,7 +32,7 @@ int CSteamP2PCodec::StreamDecode(const char *pCompressed, int compressedBytes, c
readPos += 2;
break;
case 0x04: //Voice payoad
case 0x04: //Voice payload
{
if (readPos + 2 > maxReadPos) {
return 0;

View File

@ -5,7 +5,7 @@ cvar_t* pcv_sv_voiceenable = NULL;
void Rehlds_ClientConnected_Hook(IRehldsHook_ClientConnected* chain, IGameClient* cl) {
int protocol = g_ReunionApi->GetClientProtocol(cl->GetId());
if (protocol >= 47 && protocol <= 48) {
if (protocol == 47 || protocol == 48) {
CRevoicePlayer* plr = GetPlayerByClientPtr(cl);
plr->OnConnected(protocol);
@ -21,7 +21,7 @@ void Rehlds_ClientConnected_Hook(IRehldsHook_ClientConnected* chain, IGameClient
void SV_DropClient_hook(IRehldsHook_SV_DropClient* chain, IGameClient* cl, bool crash, const char* msg) {
CRevoicePlayer* plr = GetPlayerByClientPtr(cl);
plr->OnDisconected();
plr->OnDisconnected();
chain->callNext(cl, crash, msg);
}
@ -54,7 +54,6 @@ int TranscodeVoice(const char* srcBuf, int srcBufLen, IVoiceCodec* srcCodec, IVo
return 0;
}
int compressedSize = dstCodec->Compress(decodedBuf, numDecodedSamples, dstBuf, dstBufSize, false);
if (compressedSize <= 0) {
return 0;
@ -77,25 +76,23 @@ int TranscodeVoice(const char* srcBuf, int srcBufLen, IVoiceCodec* srcCodec, IVo
}
void SV_ParseVoiceData_emu(IGameClient* cl) {
if (pcv_sv_voiceenable->value == 0.0f)
if (pcv_sv_voiceenable->value == 0.0f) {
return;
}
char chReceived[4096];
unsigned int nDataLength = g_RehldsFuncs->MSG_ReadShort();
if (nDataLength > sizeof(chReceived))
{
if (nDataLength > sizeof(chReceived)) {
g_RehldsFuncs->DropClient(cl, FALSE, "Invalid voice data\n");
return;
}
g_RehldsFuncs->MSG_ReadBuf(nDataLength, chReceived);
//cl->m_lastvoicetime = g_RehldsSv->GetTime();
CRevoicePlayer* srcPlayer = GetPlayerByClientPtr(cl);
if (srcPlayer->GetCodecType() == vct_none) {
return;
}
srcPlayer->SetLastVoiceTime(g_RehldsSv->GetTime());
srcPlayer->IncreaseVoiceRate(nDataLength);
char transcodedBuf[4096];
char* speexData; int speexDataLen;
@ -104,6 +101,9 @@ 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));
@ -111,6 +111,9 @@ void SV_ParseVoiceData_emu(IGameClient* cl) {
}
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));
@ -120,14 +123,16 @@ void SV_ParseVoiceData_emu(IGameClient* cl) {
return;
}
for (int i = 0; i < g_RehldsSvs->GetMaxClients(); i++) {
int maxclients = g_RehldsSvs->GetMaxClients();
for (int i = 0; i < maxclients; i++) {
CRevoicePlayer* dstPlayer = &g_Players[i];
IGameClient* dstClient = dstPlayer->GetClient();
if (!((1 << (i & 0x1F)) & cl->GetVoiceStream(i >> 5)) && i != cl->GetId())
if (!((1 << i) & cl->GetVoiceStream(0)) && dstPlayer != srcPlayer)
continue;
if (!dstClient->IsActive() && !dstClient->IsConnected() && i != cl->GetId())
if (!dstClient->IsActive() && !dstClient->IsConnected() && dstPlayer != srcPlayer)
continue;
char* sendBuf; int nSendLen;
@ -146,17 +151,15 @@ void SV_ParseVoiceData_emu(IGameClient* cl) {
break;
}
if (sendBuf == NULL || nSendLen == 0) {
if (sendBuf == NULL || nSendLen == 0)
continue;
}
if (i == cl->GetId() && !dstClient->GetLoopback())
if (dstPlayer == srcPlayer && !dstClient->GetLoopback())
nSendLen = 0;
sizebuf_t* dstDatagram = dstClient->GetDatagram();
if (dstDatagram->cursize + nSendLen + 6 < dstDatagram->maxsize)
{
g_RehldsFuncs->MSG_WriteByte(dstDatagram, 53); //svc_voicedata
if (dstDatagram->cursize + nSendLen + 6 < dstDatagram->maxsize) {
g_RehldsFuncs->MSG_WriteByte(dstDatagram, svc_voicedata); //svc_voicedata
g_RehldsFuncs->MSG_WriteByte(dstDatagram, cl->GetId());
g_RehldsFuncs->MSG_WriteShort(dstDatagram, nSendLen);
g_RehldsFuncs->MSG_WriteBuf(dstDatagram, nSendLen, sendBuf);
@ -187,13 +190,13 @@ void SV_WriteVoiceCodec_hooked(IRehldsHook_SV_WriteVoiceCodec* chain, sizebuf_t*
switch (plr->GetCodecType()) {
case vct_silk:
g_RehldsFuncs->MSG_WriteByte(sb, 52); //svc_voiceinit
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, 52); //svc_voiceinit
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
break;

View File

@ -8,8 +8,8 @@ CRevoicePlayer::CRevoicePlayer() {
m_SpeexCodec = new VoiceCodec_Frame(new VoiceEncoder_Speex());
m_SilkCodec = new CSteamP2PCodec(new VoiceEncoder_Silk());
m_SpeexCodec->Init(5);
m_SilkCodec->Init(5);
m_SpeexCodec->Init(SPEEX_VOICE_QUALITY);
m_SilkCodec->Init(SILK_VOICE_QUALITY);
m_RehldsClient = NULL;
m_Protocol = 0;
@ -28,11 +28,13 @@ void CRevoicePlayer::InitVoice(revoice_codec_type codecType) {
void CRevoicePlayer::OnConnected(int protocol) {
m_Protocol = protocol;
m_CodecType = vct_none;
m_VoiceRate = 0;
}
void CRevoicePlayer::OnDisconected() {
void CRevoicePlayer::OnDisconnected() {
m_Protocol = 0;
m_CodecType = vct_none;
m_VoiceRate = 0;
}
void Revoice_Init_Players() {
@ -54,4 +56,43 @@ CRevoicePlayer* GetPlayerByEdict(const edict_t* ed) {
}
return &g_Players[clientId];
}
void CRevoicePlayer::SetLastVoiceTime(double time)
{
UpdateVoiceRate(time - m_RehldsClient->GetLastVoiceTime());
m_RehldsClient->SetLastVoiceTime(time);
}
void CRevoicePlayer::UpdateVoiceRate(double delta)
{
if (m_VoiceRate)
{
switch (m_CodecType)
{
case vct_silk:
m_VoiceRate -= int(delta * MAX_SILK_VOICE_RATE) + MAX_SILK_DATA_LEN;
break;
case vct_speex:
m_VoiceRate -= int(delta * MAX_SPEEX_VOICE_RATE) + MAX_SPEEX_DATA_LEN;
break;
default:
;
}
if (m_VoiceRate < 0)
m_VoiceRate = 0;
}
}
void CRevoicePlayer::IncreaseVoiceRate(int dataLength)
{
m_VoiceRate += dataLength;
}
int CRevoicePlayer::GetVoiceRate()
{
return m_VoiceRate;
}

View File

@ -14,13 +14,18 @@ private:
CSteamP2PCodec* m_SilkCodec;
VoiceCodec_Frame* m_SpeexCodec;
int m_Protocol;
int m_VoiceRate;
public:
CRevoicePlayer();
void Initialize(IGameClient* cl);
void OnConnected(int protocol);
void OnDisconected();
void OnDisconnected();
void InitVoice(revoice_codec_type codecType);
void SetLastVoiceTime(double time);
void UpdateVoiceRate(double delta);
void IncreaseVoiceRate(int dataLength);
int GetVoiceRate();
int GetProtocol() const { return m_Protocol; }
revoice_codec_type GetCodecType() const { return m_CodecType; }

View File

@ -3,13 +3,16 @@
#include "rehlds_api.h"
#define MAX_PLAYERS 32
#define MAX_STEAMIDSALTLEN 64
#define LOG_PREFIX "[REVOICE]: "
#define HLDS_APPID 10
#define HLDS_APPVERSION "1.1.2.7/Stdio"
#define MAX_SILK_DATA_LEN 650
#define MAX_SPEEX_DATA_LEN 228
#define MAX_SILK_VOICE_RATE 3800
#define MAX_SPEEX_VOICE_RATE 2014
#define SILK_VOICE_QUALITY 5
#define SPEEX_VOICE_QUALITY 5
enum revoice_log_mode {
rl_none = 0,
@ -23,6 +26,11 @@ enum revoice_codec_type {
vct_speex,
};
enum svc_messages {
svc_voiceinit = 52,
svc_voicedata = 53
};
template <typename T>
T _min(T a, T b) {
return (a < b) ? a : b;

View File

@ -69,7 +69,6 @@ uint32 crc32(const void* buf, unsigned int bufLen) {
return hCrc;
}
void util_syserror(const char* fmt, ...)
{
va_list argptr;