Compare commits

...

2 Commits

Author SHA1 Message Date
Roflmuffin
a949468db9 chore: remove unused method 2024-08-29 12:38:10 +10:00
Roflmuffin
507f868fb2 feat: add replicate convar 2024-08-29 12:35:52 +10:00
9 changed files with 156 additions and 20 deletions

View File

@@ -239,5 +239,11 @@
"windows": 2,
"linux": 0
}
},
"CNetworkGameServer_ClientList": {
"offsets": {
"windows": 78,
"linux": 80
}
}
}

View File

@@ -206,6 +206,18 @@ namespace CounterStrikeSharp.API.Core
}
}
public static void ReplicateConvar(int clientslot, string convarname, string convarvalue){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(clientslot);
ScriptContext.GlobalScriptContext.Push(convarname);
ScriptContext.GlobalScriptContext.Push(convarvalue);
ScriptContext.GlobalScriptContext.SetIdentifier(0xC8728BEC);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}
public static T DynamicHookGetReturn<T>(IntPtr hook, int datatype){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();

View File

@@ -340,4 +340,9 @@ public partial class CCSPlayerController
NativeAPI.SetClientVoiceFlags(Handle, (Byte)value);
}
}
public void ReplicateConVar(string conVar, string value)
{
NativeAPI.ReplicateConvar(Slot, conVar, value);
}
}

View File

@@ -0,0 +1,58 @@
#pragma once
#include "inetchannel.h"
#include "networkbasetypes.pb.h"
#include "playerslot.h"
#include "steam/steamclientpublic.h"
#include "utlstring.h"
class CServerSideClient : public INetworkMessageProcessingPreFilter
{
public:
virtual ~CServerSideClient() = 0;
INetChannel* GetNetChannel() const { return m_NetChannel; };
CPlayerSlot GetPlayerSlot() const { return m_nClientSlot; };
CEntityIndex GetEntityIndex() const { return m_nEntityIndex; };
CPlayerUserId GetUserID() const { return m_UserID; };
int GetSignonState() const { return m_nSignonState; }
CSteamID GetClientSteamID() const { return m_SteamID; }
const char* GetClientName() const { return m_Name; };
bool IsConnected() const { return m_nSignonState >= SIGNONSTATE_CONNECTED; };
bool IsSpawned() const { return m_nSignonState >= SIGNONSTATE_NEW; };
bool IsActive() const { return m_nSignonState == SIGNONSTATE_FULL; };
bool IsFakeClient() const { return m_bFakePlayer; };
bool IsHLTV() const { return m_bIsHLTV; }
bool IsFullyAuthenticated() { return m_bFullyAuthenticated; }
const netadr_t* GetRemoteAddress() const { return &m_NetAdr0; }
private:
[[maybe_unused]] void* m_pVT1; // INetworkMessageProcessingPreFilter
[[maybe_unused]] char pad1[0x30];
#ifdef __linux__
[[maybe_unused]] char pad2[0x10];
#endif
CUtlString m_Name; // 64 | 80
CPlayerSlot m_nClientSlot; // 72 | 88
CEntityIndex m_nEntityIndex; // 76 | 92
[[maybe_unused]] char pad3[0x8];
INetChannel* m_NetChannel; // 88 | 104
[[maybe_unused]] char pad4[0x4];
int32 m_nSignonState; // 100 | 116
[[maybe_unused]] char pad5[0x38];
bool m_bFakePlayer; // 160 | 176
[[maybe_unused]] char pad6[0x7];
CPlayerUserId m_UserID; // 168 | 184
[[maybe_unused]] char pad7[0x1];
CSteamID m_SteamID; // 171 | 187
[[maybe_unused]] char pad8[0x19];
netadr_t m_NetAdr0; // 204 | 220
[[maybe_unused]] char pad9[0x14];
netadr_t m_NetAdr1; // 236 | 252
[[maybe_unused]] char pad10[0x22];
bool m_bIsHLTV; // 282 | 298
[[maybe_unused]] char pad11[0x19];
int m_nDeltaTick; // 308 | 324
[[maybe_unused]] char pad12[0x882];
bool m_bFullyAuthenticated; // 2490 | 2506
};

View File

@@ -24,6 +24,8 @@
#include "core/managers/server_manager.h"
#include "core/managers/voice_manager.h"
#include "core/managers/usermessage_manager.h"
#include "serversideclient.h"
#include "utlvector.h"
#include <public/game/server/iplayerinfo.h>
#include <public/entity2/entitysystem.h>
@@ -32,6 +34,14 @@
namespace counterstrikesharp {
CUtlVector<CServerSideClient*>* GetClientList()
{
if (!globals::networkGameServer) return nullptr;
static int offset = globals::gameConfig->GetOffset("CNetworkGameServer_ClientList");
return (CUtlVector<CServerSideClient*>*)(&globals::networkGameServer[offset]);
}
namespace modules {
std::vector<std::unique_ptr<CModule>> moduleList{};
CModule* engine = nullptr;
@@ -53,6 +63,7 @@ IUniformRandomStream* randomStream = nullptr;
IEngineTrace* engineTrace = nullptr;
IEngineSound* engineSound = nullptr;
IEngineServiceMgr* engineServiceManager = nullptr;
INetworkGameServer* networkGameServer = nullptr;
INetworkMessages* networkMessages = nullptr;
INetworkStringTableContainer* netStringTables = nullptr;
CGlobalVars* globalVars = nullptr;

View File

@@ -41,6 +41,7 @@ class CounterStrikeSharpMMPlugin;
class CGameEntitySystem;
class IGameEventListener2;
class CSchemaSystem;
class INetworkGameServer;
namespace counterstrikesharp {
class EntityListener;
@@ -81,6 +82,7 @@ extern IFileSystem* fileSystem;
extern IServerGameDLL* serverGameDll;
extern IServerGameClients* serverGameClients;
extern INetworkServerService* networkServerService;
extern INetworkGameServer* networkGameServer;
extern CSchemaSystem* schemaSystem;
extern IServerTools* serverTools;
extern IPhysics* physics;

View File

@@ -165,6 +165,7 @@ bool CounterStrikeSharpMMPlugin::Load(PluginId id, ISmmAPI* ismm, char* error, s
void CounterStrikeSharpMMPlugin::Hook_StartupServer(const GameSessionConfiguration_t& config, ISource2WorldSession*, const char*)
{
globals::networkGameServer = globals::networkServerService->GetIGameServer();
globals::entitySystem = interfaces::pGameResourceServiceServer->GetGameEntitySystem();
globals::entitySystem->AddListenerEntity(&globals::entityManager.entityListener);
globals::timerSystem.OnStartupServer();

View File

@@ -15,13 +15,19 @@
*/
#include <eiface.h>
#include <inetchannel.h>
#include <networksystem/inetworkmessages.h>
#include <networksystem/inetworkserializer.h>
#include "scripting/autonative.h"
#include "scripting/callback_manager.h"
#include "core/log.h"
#include "core/managers/con_command_manager.h"
#include "core/managers/player_manager.h"
#include "scripting/autonative.h"
#include "scripting/callback_manager.h"
#include "scripting/script_engine.h"
#include "core/log.h"
#include "serversideclient.h"
#include "utlvector.h"
#include <networkbasetypes.pb.h>
namespace counterstrikesharp {
@@ -33,8 +39,7 @@ static void AddCommand(ScriptContext& script_context)
auto flags = script_context.GetArgument<int>(3);
auto callback = script_context.GetArgument<CallbackT>(4);
CSSHARP_CORE_TRACE("Adding command {}, {}, {}, {}, {}", name, description, server_only, flags,
(void*)callback);
CSSHARP_CORE_TRACE("Adding command {}, {}, {}, {}, {}", name, description, server_only, flags, (void*)callback);
globals::conCommandManager.AddValveCommand(name, description, server_only, flags);
globals::conCommandManager.AddCommandListener(name, callback, HookMode::Pre);
@@ -55,8 +60,7 @@ static void AddCommandListener(ScriptContext& script_context)
auto callback = script_context.GetArgument<CallbackT>(1);
auto post = script_context.GetArgument<bool>(2);
globals::conCommandManager.AddCommandListener(name, callback,
post ? HookMode::Post : HookMode::Pre);
globals::conCommandManager.AddCommandListener(name, callback, post ? HookMode::Post : HookMode::Pre);
}
static void RemoveCommandListener(ScriptContext& script_context)
@@ -65,15 +69,15 @@ static void RemoveCommandListener(ScriptContext& script_context)
auto callback = script_context.GetArgument<CallbackT>(1);
auto post = script_context.GetArgument<bool>(2);
globals::conCommandManager.RemoveCommandListener(name, callback,
post ? HookMode::Post : HookMode::Pre);
globals::conCommandManager.RemoveCommandListener(name, callback, post ? HookMode::Post : HookMode::Pre);
}
static int CommandGetArgCount(ScriptContext& script_context)
{
auto command = script_context.GetArgument<CCommand*>(0);
if (!command) {
if (!command)
{
script_context.ThrowNativeError("Invalid command.");
return -1;
}
@@ -85,7 +89,8 @@ static const char* CommandGetArgString(ScriptContext& script_context)
{
auto command = script_context.GetArgument<CCommand*>(0);
if (!command) {
if (!command)
{
script_context.ThrowNativeError("Invalid command.");
return nullptr;
}
@@ -97,7 +102,8 @@ static const char* CommandGetCommandString(ScriptContext& script_context)
{
auto* command = script_context.GetArgument<CCommand*>(0);
if (!command) {
if (!command)
{
script_context.ThrowNativeError("Invalid command.");
return nullptr;
}
@@ -110,7 +116,8 @@ static const char* CommandGetArgByIndex(ScriptContext& script_context)
auto* command = script_context.GetArgument<CCommand*>(0);
auto index = script_context.GetArgument<int>(1);
if (!command) {
if (!command)
{
script_context.ThrowNativeError("Invalid command.");
return nullptr;
}
@@ -142,8 +149,7 @@ static void IssueClientCommandFromServer(ScriptContext& script_context)
args.Tokenize(pszCommand);
auto handle = globals::cvars->FindCommand(args.Arg(0));
if (!handle.IsValid())
return;
if (!handle.IsValid()) return;
CCommandContext context(CommandTarget_t::CT_NO_TARGET, CPlayerSlot(slot));
@@ -172,7 +178,8 @@ ConVar* FindConVar(ScriptContext& script_context)
auto name = script_context.GetArgument<const char*>(0);
auto hCvarHandle = globals::cvars->FindConVar(name, true);
if (!hCvarHandle.IsValid()) {
if (!hCvarHandle.IsValid())
{
return nullptr;
}
@@ -184,13 +191,46 @@ void SetConVarStringValue(ScriptContext& script_context)
auto pCvar = script_context.GetArgument<ConVar*>(0);
auto value = script_context.GetArgument<const char*>(1);
if (!pCvar) {
if (!pCvar)
{
script_context.ThrowNativeError("Invalid cvar.");
}
pCvar->values = reinterpret_cast<CVValue_t**>((char*)value);
}
extern CUtlVector<CServerSideClient*>* GetClientList();
void ReplicateConVar(ScriptContext& script_context)
{
auto slot = script_context.GetArgument<int>(0);
auto name = script_context.GetArgument<const char*>(1);
auto value = script_context.GetArgument<const char*>(2);
INetworkMessageInternal* pNetMsg = globals::networkMessages->FindNetworkMessagePartial("SetConVar");
auto data = pNetMsg->AllocateMessage()->ToPB<CNETMsg_SetConVar>();
CMsg_CVars_CVar* cvarMsg = data->mutable_convars()->add_cvars();
cvarMsg->set_name(name);
cvarMsg->set_value(value);
if (!GetClientList())
{
script_context.ThrowNativeError("Error retrieving client list.");
return;
}
auto client = GetClientList()->Element(slot);
if (!client)
{
script_context.ThrowNativeError("Invalid client.");
return;
}
client->GetNetChannel()->SendNetMessage(data, BUF_RELIABLE);
delete data;
}
REGISTER_NATIVES(commands, {
ScriptEngine::RegisterNativeHandler("ADD_COMMAND", AddCommand);
ScriptEngine::RegisterNativeHandler("REMOVE_COMMAND", RemoveCommand);
@@ -207,9 +247,9 @@ REGISTER_NATIVES(commands, {
ScriptEngine::RegisterNativeHandler("SET_CONVAR_STRING_VALUE", SetConVarStringValue);
ScriptEngine::RegisterNativeHandler("ISSUE_CLIENT_COMMAND", IssueClientCommand);
ScriptEngine::RegisterNativeHandler("ISSUE_CLIENT_COMMAND_FROM_SERVER",
IssueClientCommandFromServer);
ScriptEngine::RegisterNativeHandler("ISSUE_CLIENT_COMMAND_FROM_SERVER", IssueClientCommandFromServer);
ScriptEngine::RegisterNativeHandler("GET_CLIENT_CONVAR_VALUE", GetClientConVarValue);
ScriptEngine::RegisterNativeHandler("SET_FAKE_CLIENT_CONVAR_VALUE", SetFakeClientConVarValue);
ScriptEngine::RegisterNativeHandler("REPLICATE_CONVAR", ReplicateConVar);
})
} // namespace counterstrikesharp

View File

@@ -12,4 +12,5 @@ ISSUE_CLIENT_COMMAND_FROM_SERVER: slot:int,command:string -> void
FIND_CONVAR: name:string -> pointer
SET_CONVAR_STRING_VALUE: convar:pointer,value:string -> void
GET_CLIENT_CONVAR_VALUE: clientIndex:int,convarName:string -> string
SET_FAKE_CLIENT_CONVAR_VALUE: clientIndex:int,convarName:string,convarValue:string -> void
SET_FAKE_CLIENT_CONVAR_VALUE: clientIndex:int,convarName:string,convarValue:string -> void
REPLICATE_CONVAR: clientSlot:int,convarName:string,convarValue:string -> void