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:
parent
639e79e766
commit
fec9126f34
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
@ -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; }
|
||||
|
@ -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;
|
||||
|
@ -69,7 +69,6 @@ uint32 crc32(const void* buf, unsigned int bufLen) {
|
||||
return hCrc;
|
||||
}
|
||||
|
||||
|
||||
void util_syserror(const char* fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user