mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Engine: add new netmsg 'SVC_SetClassVar'
Netmessage SVC_SetClassVar allows the server to change class settings securely on the client. This was implemented due to popular demand, and previous approaches using a combination of ClientCommands (Cbuf and NET_StringCmd) were deemed insecure and unreliable.
This commit is contained in:
parent
3b1622af95
commit
b11d7e3c9b
@ -4,6 +4,8 @@ inline bool(*v_SetupGamemode)(const char* pszPlayList);
|
|||||||
|
|
||||||
/* ==== CONCOMMANDCALLBACK ============================================================================================================================================== */
|
/* ==== CONCOMMANDCALLBACK ============================================================================================================================================== */
|
||||||
inline void(*v__Cmd_Exec_f)(const CCommand& args);
|
inline void(*v__Cmd_Exec_f)(const CCommand& args);
|
||||||
|
inline bool(*v__setClassVarServer_f)(const CCommand& args);
|
||||||
|
inline bool(*v__setClassVarClient_f)(const CCommand& args);
|
||||||
#ifndef DEDICATED
|
#ifndef DEDICATED
|
||||||
inline void(*v__UIScript_Reset_f)();
|
inline void(*v__UIScript_Reset_f)();
|
||||||
#endif // !DEDICATED
|
#endif // !DEDICATED
|
||||||
@ -41,6 +43,8 @@ class VCallback : public IDetour
|
|||||||
{
|
{
|
||||||
LogFunAdr("SetupGamemode", v_SetupGamemode);
|
LogFunAdr("SetupGamemode", v_SetupGamemode);
|
||||||
LogFunAdr("Cmd_Exec_f", v__Cmd_Exec_f);
|
LogFunAdr("Cmd_Exec_f", v__Cmd_Exec_f);
|
||||||
|
LogFunAdr("SetClassVarServer_f", v__setClassVarServer_f);
|
||||||
|
LogFunAdr("SetClassVarClient_f", v__setClassVarClient_f);
|
||||||
#ifndef DEDICATED
|
#ifndef DEDICATED
|
||||||
LogFunAdr("UIScript_Reset_f", v__UIScript_Reset_f);
|
LogFunAdr("UIScript_Reset_f", v__UIScript_Reset_f);
|
||||||
#endif // !DEDICATED
|
#endif // !DEDICATED
|
||||||
@ -49,6 +53,8 @@ class VCallback : public IDetour
|
|||||||
{
|
{
|
||||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B D9 48 C7 C0 ?? ?? ?? ??").GetPtr(v_SetupGamemode);
|
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B D9 48 C7 C0 ?? ?? ?? ??").GetPtr(v_SetupGamemode);
|
||||||
g_GameDll.FindPatternSIMD("40 55 53 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9").GetPtr(v__Cmd_Exec_f);
|
g_GameDll.FindPatternSIMD("40 55 53 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9").GetPtr(v__Cmd_Exec_f);
|
||||||
|
g_GameDll.FindPatternSIMD("41 56 48 83 EC ?? 8B 05 ?? ?? ?? ?? 4C 8B F1 FF C0").GetPtr(v__setClassVarServer_f);
|
||||||
|
g_GameDll.FindPatternSIMD("4C 8B DC 57 48 81 EC ?? ?? ?? ?? 8B 05").GetPtr(v__setClassVarClient_f);
|
||||||
#ifndef DEDICATED
|
#ifndef DEDICATED
|
||||||
g_GameDll.FindPatternSIMD("40 55 41 54 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 45 33 E4 48 8D 0D").GetPtr(v__UIScript_Reset_f);
|
g_GameDll.FindPatternSIMD("40 55 41 54 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 45 33 E4 48 8D 0D").GetPtr(v__UIScript_Reset_f);
|
||||||
#endif // !DEDICATED
|
#endif // !DEDICATED
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "tier1/cvar.h"
|
#include "tier1/cvar.h"
|
||||||
#include "engine/net.h"
|
#include "engine/net.h"
|
||||||
#include "common/netmessages.h"
|
#include "common/netmessages.h"
|
||||||
|
#include "common/callback.h"
|
||||||
#include "game/shared/usermessages.h"
|
#include "game/shared/usermessages.h"
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -64,6 +65,37 @@ bool SVC_UserMessage::ProcessImpl()
|
|||||||
return SVC_UserMessage_Process(this); // Need to return original.
|
return SVC_UserMessage_Process(this); // Need to return original.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Net message to change class settings vars on the client
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool SVC_SetClassVar::ReadFromBuffer(bf_read* buffer)
|
||||||
|
{
|
||||||
|
const bool set = buffer->ReadString(m_szSetting, sizeof(m_szSetting));
|
||||||
|
const bool var = buffer->ReadString(m_szVariable, sizeof(m_szVariable));
|
||||||
|
|
||||||
|
return set && var;
|
||||||
|
}
|
||||||
|
bool SVC_SetClassVar::WriteToBuffer(bf_write* buffer)
|
||||||
|
{
|
||||||
|
const bool set = buffer->WriteString(m_szSetting);
|
||||||
|
const bool var = buffer->WriteString(m_szVariable);
|
||||||
|
|
||||||
|
return set && var;
|
||||||
|
}
|
||||||
|
bool SVC_SetClassVar::Process(void)
|
||||||
|
{
|
||||||
|
const char* pArgs[3] = {
|
||||||
|
"_setClassVarClient",
|
||||||
|
m_szSetting,
|
||||||
|
m_szVariable
|
||||||
|
};
|
||||||
|
|
||||||
|
CCommand command((int)V_ARRAYSIZE(pArgs), pArgs, cmd_source_t::kCommandSrcCode);
|
||||||
|
v__setClassVarClient_f(command);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Below functions are hooked as playlist overrides can be abused from the client.
|
// Below functions are hooked as playlist overrides can be abused from the client.
|
||||||
// The client could basically manage the server's playlists. Only allow read/write
|
// The client could basically manage the server's playlists. Only allow read/write
|
||||||
@ -122,7 +154,7 @@ bool Base_CmdKeyValues::WriteToBufferImpl(Base_CmdKeyValues* thisptr, bf_write*
|
|||||||
// determine whether or not the message should be copied into the replay buffer,
|
// determine whether or not the message should be copied into the replay buffer,
|
||||||
// regardless of the 'CNetMessage::m_Group' type.
|
// regardless of the 'CNetMessage::m_Group' type.
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
bool ShouldReplayMessage(const CNetMessage* msg)
|
bool ShouldReplayMessage(const CNetMessage* msg) // todo(amos): rename to 'CanReplayMessage'
|
||||||
{
|
{
|
||||||
switch (msg->GetType())
|
switch (msg->GetType())
|
||||||
{
|
{
|
||||||
|
@ -162,6 +162,15 @@ enum NetMessageType
|
|||||||
clc_AntiCheat = 63,
|
clc_AntiCheat = 63,
|
||||||
clc_AntiCheatChallenge = 64,
|
clc_AntiCheatChallenge = 64,
|
||||||
clc_GamepadMsg = 65,
|
clc_GamepadMsg = 65,
|
||||||
|
|
||||||
|
// NOTE: if you make new netmessages, the order should be as follows:
|
||||||
|
// - NET (messages shared between server & client).
|
||||||
|
// - SVC (messages originating from the server).
|
||||||
|
// - CLC (messages originating from the client.
|
||||||
|
// Reorder message indices to retain consistency here.
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// From here on, SDK netmessages are enumerated.
|
||||||
|
svc_SetClassVar = 66,
|
||||||
};
|
};
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@ -176,10 +185,16 @@ enum NetMessageGroup
|
|||||||
class CNetMessage : public INetMessage
|
class CNetMessage : public INetMessage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual void SetNetChannel(CNetChan* netchan) { m_NetChannel = netchan; }
|
||||||
|
virtual void SetReliable(bool state) { m_bReliable = state; }
|
||||||
|
virtual bool IsReliable(void) const { return m_bReliable; }
|
||||||
|
virtual int GetGroup(void) const { return m_nGroup; }
|
||||||
|
virtual CNetChan* GetNetChannel(void) const { return m_NetChannel; }
|
||||||
|
|
||||||
int m_nGroup;
|
int m_nGroup;
|
||||||
bool m_bReliable;
|
bool m_bReliable;
|
||||||
CNetChan* m_NetChannel;
|
CNetChan* m_NetChannel;
|
||||||
INetMessageHandler* m_pMessageHandler;
|
INetChannelHandler* m_pMessageHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -445,6 +460,43 @@ private:
|
|||||||
bf_write m_DataOut;
|
bf_write m_DataOut;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SVC_SetClassVar : public CNetMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SVC_SetClassVar() = default;
|
||||||
|
SVC_SetClassVar(const char* setting, const char* var)
|
||||||
|
{
|
||||||
|
V_strncpy(m_szSetting, setting, sizeof(m_szSetting));
|
||||||
|
V_strncpy(m_szVariable, var, sizeof(m_szVariable));
|
||||||
|
|
||||||
|
m_szSetting[sizeof(m_szSetting) - 1] = '\0';
|
||||||
|
m_szVariable[sizeof(m_szVariable) - 1] = '\0';
|
||||||
|
|
||||||
|
m_nGroup = 2; // must be set to 2 to avoid being copied into replay buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool ReadFromBuffer(bf_read* buffer);
|
||||||
|
virtual bool WriteToBuffer(bf_write* buffer);
|
||||||
|
|
||||||
|
virtual bool Process(void);
|
||||||
|
|
||||||
|
virtual int GetType(void) const { return svc_SetClassVar; };
|
||||||
|
virtual const char* GetName(void) const { return "svc_SetClassVar"; };
|
||||||
|
|
||||||
|
virtual const char* ToString(void) const
|
||||||
|
{
|
||||||
|
static char szBuf[4096];
|
||||||
|
V_snprintf(szBuf, sizeof(szBuf), "%s: setting \"%s\", variable \"%s\"", this->GetName(), m_szSetting, m_szVariable);
|
||||||
|
|
||||||
|
return szBuf;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual size_t GetSize(void) const { return sizeof(SVC_SetClassVar); }
|
||||||
|
|
||||||
|
char m_szSetting[128];
|
||||||
|
char m_szVariable[128];
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Client messages:
|
// Client messages:
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -509,6 +509,7 @@ void CClientState::Reconnect()
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
void CClientState::RegisterNetMsgs(CNetChan* chan)
|
void CClientState::RegisterNetMsgs(CNetChan* chan)
|
||||||
{
|
{
|
||||||
|
REGISTER_SVC_MSG(SetClassSettingsVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VClientState::Detour(const bool bAttach) const
|
void VClientState::Detour(const bool bAttach) const
|
||||||
|
Loading…
x
Reference in New Issue
Block a user