mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
(re)implement sv_alltalk
Rebuilds SV_BroadcastVoiceData with an additional check of "sv_alltalk" cvar to disable team checking, allowing for servers to enable global voice chat
This commit is contained in:
parent
6b1d02dfea
commit
dca27475ec
@ -46,6 +46,11 @@ inline void* g_pSVC_UserMessage_VFTable = nullptr;
|
||||
//-------------------------------------------------------------------------
|
||||
inline void* g_pSVC_ServerTick_VFTable = nullptr;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// SVC_VoiceData
|
||||
//-------------------------------------------------------------------------
|
||||
inline void* g_pSVC_VoiceData_VFTable = nullptr;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Base_CmdKeyValues
|
||||
//-------------------------------------------------------------------------
|
||||
@ -197,6 +202,65 @@ public:
|
||||
nettick_t m_NetTick;
|
||||
};
|
||||
|
||||
struct SVC_VoiceData : public CNetMessage
|
||||
{
|
||||
public:
|
||||
SVC_VoiceData() = default;
|
||||
SVC_VoiceData(int senderClient, int nBytes, char* data)
|
||||
{
|
||||
void** pVFTable = reinterpret_cast<void**>(this);
|
||||
*pVFTable = g_pSVC_VoiceData_VFTable;
|
||||
|
||||
m_bReliable = false;
|
||||
m_NetChannel = nullptr;
|
||||
|
||||
m_nFromClient = senderClient;
|
||||
m_nLength = nBytes; // length in bits
|
||||
m_DataOut = data;
|
||||
|
||||
m_nGroup = 2; // must be set to 2 to avoid being copied into replay buffer
|
||||
};
|
||||
|
||||
virtual ~SVC_VoiceData() {};
|
||||
|
||||
virtual void SetNetChannel(CNetChan* netchan) { m_NetChannel = netchan; }
|
||||
virtual void SetReliable(bool state) { m_bReliable = state; };
|
||||
|
||||
virtual bool Process(void)
|
||||
{
|
||||
return CallVFunc<bool>(NetMessageVtbl::Process, this);
|
||||
};
|
||||
virtual bool ReadFromBuffer(bf_read* buffer)
|
||||
{
|
||||
return CallVFunc<bool>(NetMessageVtbl::ReadFromBuffer, this, buffer);
|
||||
}
|
||||
virtual bool WriteToBuffer(bf_write* buffer)
|
||||
{
|
||||
return CallVFunc<bool>(NetMessageVtbl::WriteToBuffer, this, buffer);
|
||||
}
|
||||
|
||||
virtual bool IsReliable(void) const { return m_bReliable; };
|
||||
|
||||
virtual int GetGroup(void) const { return m_nGroup; };
|
||||
virtual int GetType(void) const { return 14; };
|
||||
virtual const char* GetName(void) const { return "svc_VoiceData"; };
|
||||
virtual CNetChan* GetNetChannel(void) const { return m_NetChannel; };
|
||||
virtual const char* ToString(void) const
|
||||
{
|
||||
static char szBuf[4096];
|
||||
V_snprintf(szBuf, sizeof(szBuf), "%s: client %i, bytes %i", this->GetName(), m_nFromClient, ((m_nLength + 7) >> 3));
|
||||
|
||||
return szBuf;
|
||||
};
|
||||
virtual size_t GetSize(void) const { return sizeof(SVC_VoiceData); };
|
||||
|
||||
int m_nFromClient;
|
||||
int m_nLength;
|
||||
bf_read m_DataIn;
|
||||
void* m_DataOut;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Client messages:
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -249,6 +313,7 @@ class V_NetMessages : public IDetour
|
||||
LogConAdr("SVC_Print::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_Print_VFTable));
|
||||
LogConAdr("SVC_UserMessage::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_UserMessage_VFTable));
|
||||
LogConAdr("SVC_ServerTick::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_ServerTick_VFTable));
|
||||
LogConAdr("SVC_VoiceData::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_VoiceData_VFTable));
|
||||
LogConAdr("Base_CmdKeyValues::`vftable'", reinterpret_cast<uintptr_t>(g_pBase_CmdKeyValues_VFTable));
|
||||
LogFunAdr("MM_Heartbeat::ToString", MM_Heartbeat__ToString.GetPtr());
|
||||
}
|
||||
@ -264,6 +329,7 @@ class V_NetMessages : public IDetour
|
||||
g_pSVC_Print_VFTable = g_GameDll.GetVirtualMethodTable(".?AVSVC_Print@@");
|
||||
g_pSVC_UserMessage_VFTable = g_GameDll.GetVirtualMethodTable(".?AVSVC_UserMessage@@");
|
||||
g_pSVC_ServerTick_VFTable = g_GameDll.GetVirtualMethodTable(".?AVSVC_ServerTick@@");
|
||||
g_pSVC_VoiceData_VFTable = g_GameDll.GetVirtualMethodTable(".?AVSVC_VoiceData@@");
|
||||
g_pBase_CmdKeyValues_VFTable = g_GameDll.GetVirtualMethodTable(".?AVBase_CmdKeyValues@@");
|
||||
}
|
||||
virtual void Attach(void) const;
|
||||
|
@ -22,6 +22,14 @@ CClient* CClient::GetClient(int nIndex) const
|
||||
(reinterpret_cast<uintptr_t>(g_pClient) + (nIndex * sizeof(CClient))));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: gets the client's team number
|
||||
//---------------------------------------------------------------------------------
|
||||
__int64 CClient::GetTeamNum() const
|
||||
{
|
||||
return m_iTeamNum;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: gets the handle of this client
|
||||
//---------------------------------------------------------------------------------
|
||||
|
@ -62,6 +62,7 @@ class CClient : IClientMessageHandler, INetChannelHandler
|
||||
{
|
||||
public:
|
||||
CClient* GetClient(int nIndex) const;
|
||||
__int64 GetTeamNum() const;
|
||||
edict_t GetHandle(void) const;
|
||||
uint32_t GetUserID(void) const;
|
||||
uint64_t GetNucleusID(void) const;
|
||||
@ -104,7 +105,8 @@ private:
|
||||
char m_szClientName[256]; //0x0116
|
||||
char pad_0015[258]; //0x0216
|
||||
int m_nCommandTick; //0x0318
|
||||
char pad_031C[68]; //0x031C
|
||||
char pad_031C[60]; //0x031C
|
||||
__int64 m_iTeamNum; //0x0258
|
||||
KeyValues* m_ConVars; //0x0360
|
||||
char pad_0368[8]; //0x0368
|
||||
CServer* m_pServer; //0x0370
|
||||
|
@ -178,6 +178,14 @@ int CNetChan::GetSocket(void) const
|
||||
return this->m_Socket;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets a const reference to m_StreamVoice
|
||||
//-----------------------------------------------------------------------------
|
||||
const bf_write& CNetChan::GetStreamVoice(void) const
|
||||
{
|
||||
return this->m_StreamVoice;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if the reliable stream is overflowed
|
||||
// Output : true if overflowed, false otherwise
|
||||
|
@ -100,6 +100,8 @@ public:
|
||||
double GetTimeConnected(void) const;
|
||||
int GetSocket(void) const;
|
||||
|
||||
const bf_write& GetStreamVoice(void) const;
|
||||
|
||||
bool IsOverflowed(void) const;
|
||||
void Clear(bool bStopProcessing);
|
||||
|
||||
|
@ -4,6 +4,9 @@
|
||||
#include "engine/server/sv_main.h"
|
||||
#include "networksystem/pylon.h"
|
||||
#include "networksystem/bansystem.h"
|
||||
#include "engine/client/client.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "server.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if particular client is banned on the comp server
|
||||
@ -26,4 +29,59 @@ void SV_IsClientBanned(const string& svIPAddr, const uint64_t nNucleusID)
|
||||
}
|
||||
}
|
||||
|
||||
void SV_BroadcastVoiceData(CClient* cl, int nBytes, char* data)
|
||||
{
|
||||
if (!sv_voiceenable->GetBool())
|
||||
return;
|
||||
|
||||
if (g_ServerGlobalVariables->m_nMaxClients <= 0)
|
||||
return;
|
||||
|
||||
SVC_VoiceData voiceData(cl->GetUserID(), nBytes, data);
|
||||
|
||||
for (int i = 0; i < g_ServerGlobalVariables->m_nMaxClients; i++)
|
||||
{
|
||||
CClient* pClient = g_pClient->GetClient(i);
|
||||
|
||||
if (!pClient)
|
||||
continue;
|
||||
|
||||
// is this client fully connected
|
||||
if (pClient->GetSignonState() != SIGNONSTATE::SIGNONSTATE_FULL)
|
||||
continue;
|
||||
|
||||
// is this client the sender
|
||||
if (pClient == cl && !sv_voiceEcho->GetBool())
|
||||
continue;
|
||||
|
||||
// is this client on the sender's team
|
||||
if (pClient->GetTeamNum() != cl->GetTeamNum() && !sv_alltalk->GetBool())
|
||||
continue;
|
||||
|
||||
// there's also supposed to be some xplat checks here
|
||||
// but since r5r is only on PC, there's no point in implementing them here
|
||||
|
||||
CNetChan* pNetChan = pClient->GetNetChan();
|
||||
|
||||
if (!pNetChan)
|
||||
continue;
|
||||
|
||||
// if voice stream has enough space for new data
|
||||
if (pNetChan->GetStreamVoice().GetNumBitsLeft() >= 8 * nBytes + 96)
|
||||
pClient->SendNetMsg(&voiceData, false, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HSV_Main::Attach(void) const
|
||||
{
|
||||
DetourAttach(&v_SV_BroadcastVoiceData, SV_BroadcastVoiceData);
|
||||
}
|
||||
|
||||
void HSV_Main::Detach(void) const
|
||||
{
|
||||
DetourDetach(&v_SV_BroadcastVoiceData, SV_BroadcastVoiceData);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
@ -4,6 +4,8 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CClient;
|
||||
|
||||
/* ==== SV_MAIN ======================================================================================================================================================= */
|
||||
inline CMemory p_SV_InitGameDLL;
|
||||
inline auto SV_InitGameDLL = p_SV_InitGameDLL.RCast<void(*)(void)>();
|
||||
@ -17,6 +19,9 @@ inline auto SV_CreateBaseline = p_SV_CreateBaseline.RCast<bool(*)(void)>();
|
||||
inline CMemory p_CGameServer__SpawnServer;
|
||||
inline auto CGameServer__SpawnServer = p_CGameServer__SpawnServer.RCast<bool(*)(void* thisptr, const char* pszMapName, const char* pszMapGroupName)>();
|
||||
|
||||
inline CMemory p_SV_BroadcastVoiceData;
|
||||
inline auto v_SV_BroadcastVoiceData = p_SV_BroadcastVoiceData.RCast<void(__fastcall*)(CClient* cl, int nBytes, char* data)>();
|
||||
|
||||
inline bool* s_bIsDedicated = nullptr;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -46,10 +51,13 @@ class HSV_Main : public IDetour
|
||||
p_CGameServer__SpawnServer = g_GameDll.FindPatternSIMD("48 8B C4 53 55 56 57 41 54 41 55 41 57");
|
||||
// 0x140312D80 // 48 8B C4 53 55 56 57 41 54 41 55 41 57 //
|
||||
#endif
|
||||
p_SV_BroadcastVoiceData = g_GameDll.FindPatternSIMD("4C 8B DC 56 48 81 EC ? ? ? ? 80 3D ? ? ? ? ? ");
|
||||
|
||||
SV_InitGameDLL = p_SV_InitGameDLL.RCast<void(*)(void)>();
|
||||
SV_ShutdownGameDLL = p_SV_ShutdownGameDLL.RCast<void(*)(void)>();
|
||||
SV_CreateBaseline = p_SV_CreateBaseline.RCast<bool(*)(void)>();
|
||||
CGameServer__SpawnServer = p_CGameServer__SpawnServer.RCast<bool(*)(void*, const char*, const char*)>();
|
||||
v_SV_BroadcastVoiceData = p_SV_BroadcastVoiceData.RCast<void(__fastcall*)(CClient* cl, int nBytes, char* data)>();
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
@ -57,7 +65,7 @@ class HSV_Main : public IDetour
|
||||
.FindPatternSelf("40 38 3D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<bool*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
virtual void Detach(void) const;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -106,6 +106,10 @@ extern ConVar* sv_validatePersonaName;
|
||||
extern ConVar* sv_minPersonaNameLength;
|
||||
extern ConVar* sv_maxPersonaNameLength;
|
||||
|
||||
extern ConVar* sv_voiceEcho;
|
||||
extern ConVar* sv_voiceenable;
|
||||
extern ConVar* sv_alltalk;
|
||||
|
||||
//#ifdef DEDICATED
|
||||
extern ConVar* sv_rcon_debug;
|
||||
extern ConVar* sv_rcon_sendlogs;
|
||||
|
@ -101,6 +101,10 @@ ConVar* sv_validatePersonaName = nullptr;
|
||||
ConVar* sv_minPersonaNameLength = nullptr;
|
||||
ConVar* sv_maxPersonaNameLength = nullptr;
|
||||
|
||||
ConVar* sv_voiceEcho = nullptr;
|
||||
ConVar* sv_voiceenable = nullptr;
|
||||
ConVar* sv_alltalk = nullptr;
|
||||
|
||||
//#ifdef DEDICATED
|
||||
ConVar* sv_rcon_debug = nullptr;
|
||||
ConVar* sv_rcon_sendlogs = nullptr;
|
||||
@ -524,6 +528,10 @@ void ConVar::InitShipped(void)
|
||||
sv_showhitboxes = g_pCVar->FindVar("sv_showhitboxes");
|
||||
sv_forceChatToTeamOnly = g_pCVar->FindVar("sv_forceChatToTeamOnly");
|
||||
|
||||
sv_voiceenable = g_pCVar->FindVar("sv_voiceenable");
|
||||
sv_voiceEcho = g_pCVar->FindVar("sv_voiceEcho");
|
||||
sv_alltalk = g_pCVar->FindVar("sv_alltalk");
|
||||
|
||||
sv_showhitboxes->SetMin(-1); // Allow user to go over each entity manually without going out of bounds.
|
||||
sv_showhitboxes->SetMax(NUM_ENT_ENTRIES - 1);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user