chore: cleanup cpp & add clang format linting (#862)

This commit is contained in:
Michael Wilson
2025-05-12 15:46:13 +10:00
committed by GitHub
parent f50fb783bb
commit 6511a0098a
54 changed files with 2621 additions and 2486 deletions

View File

@@ -38,7 +38,7 @@ BraceWrapping:
SplitEmptyNamespace: true SplitEmptyNamespace: true
PointerAlignment: Left PointerAlignment: Left
SortIncludes: CaseSensitive SortIncludes: Never
IncludeBlocks: Regroup IncludeBlocks: Regroup
IncludeCategories: IncludeCategories:
# External headers in <> with extension or / # External headers in <> with extension or /

View File

@@ -1,11 +1,18 @@
{ {
"name": "SteamRT Sniper SDK", "name": "SteamRT Sniper SDK",
"image": "registry.gitlab.steamos.cloud/steamrt/sniper/sdk:latest", "image": "registry.gitlab.steamos.cloud/steamrt/sniper/sdk:latest",
"customizations": { "updateContentCommand": "git submodule update --init --recursive",
"customizations": {
"vscode": { "vscode": {
"extensions": [ "extensions": [
"ms-vscode.cpptools" "ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"GitHub.copilot",
"jeff-hykin.better-cpp-syntax"
] ]
} }
},
"features": {
"ghcr.io/devcontainers/features/dotnet": "8.0"
} }
} }

25
.github/workflows/lint-code.yaml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Code format checks
on:
pull_request:
paths:
- '.github/workflows/**'
- 'src/**'
- '.clang-format'
push:
paths:
- '.github/workflows/**'
- 'src/**'
- '.clang-format'
jobs:
lint:
name: Lint code with clang-format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jidicula/clang-format-action@4726374d1aa3c6aecf132e5197e498979588ebc8
with:
clang-format-version: '20'
check-path: 'src'
exclude-regex: '(sdk|\.proto)'

View File

@@ -1,41 +1,41 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
#include "UserMessage.h" #include "UserMessage.h"
#include "networksystem/inetworkserializer.h" #include "networksystem/inetworkserializer.h"
using namespace google; using namespace google;
namespace counterstrikesharp { namespace counterstrikesharp {
int UserMessage::GetMessageID() { return msgSerializable->GetNetMessageInfo()->m_MessageId; } int UserMessage::GetMessageID() { return msgSerializable->GetNetMessageInfo()->m_MessageId; }
std::string UserMessage::GetMessageName() { return msgSerializable->GetUnscopedName(); } std::string UserMessage::GetMessageName() { return msgSerializable->GetUnscopedName(); }
bool UserMessage::HasField(std::string fieldName) bool UserMessage::HasField(std::string fieldName)
{ {
const google::protobuf::Descriptor* descriptor = msg->GetDescriptor(); const google::protobuf::Descriptor* descriptor = msg->GetDescriptor();
const google::protobuf::FieldDescriptor* field = descriptor->FindFieldByName(fieldName); const google::protobuf::FieldDescriptor* field = descriptor->FindFieldByName(fieldName);
if (field == nullptr || (field->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED)) if (field == nullptr || (field->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED))
{ {
return false; return false;
} }
return this->msg->GetReflection()->HasField(*this->msg, field); return this->msg->GetReflection()->HasField(*this->msg, field);
} }
const CNetMessagePB<google::protobuf::Message>* UserMessage::GetProtobufMessage() { return msg; } const CNetMessagePB<google::protobuf::Message>* UserMessage::GetProtobufMessage() { return msg; }
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -28,8 +28,7 @@ class CGameResourceService
public: public:
CGameEntitySystem* GetGameEntitySystem() CGameEntitySystem* GetGameEntitySystem()
{ {
return *reinterpret_cast<CGameEntitySystem**>( return *reinterpret_cast<CGameEntitySystem**>((uintptr_t)(this) +
(uintptr_t)(this) + counterstrikesharp::globals::gameConfig->GetOffset("GameEntitySystem"));
counterstrikesharp::globals::gameConfig->GetOffset("GameEntitySystem"));
} }
}; };

View File

@@ -26,11 +26,10 @@
#include "tier0/memdbgon.h" #include "tier0/memdbgon.h"
namespace counterstrikesharp { namespace counterstrikesharp {
void interfaces::Initialize() { void interfaces::Initialize()
pGameResourceServiceServer = (CGameResourceService*)modules::engine->FindInterface( {
GAMERESOURCESERVICESERVER_INTERFACE_VERSION); pGameResourceServiceServer = (CGameResourceService*)modules::engine->FindInterface(GAMERESOURCESERVICESERVER_INTERFACE_VERSION);
g_pCVar = (ICvar*)modules::tier0->FindInterface(CVAR_INTERFACE_VERSION); g_pCVar = (ICvar*)modules::tier0->FindInterface(CVAR_INTERFACE_VERSION);
g_pSource2GameEntities = (ISource2GameEntities*)modules::server->FindInterface( g_pSource2GameEntities = (ISource2GameEntities*)modules::server->FindInterface(SOURCE2GAMEENTITIES_INTERFACE_VERSION);
SOURCE2GAMEENTITIES_INTERFACE_VERSION);
} }
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -25,6 +25,6 @@ namespace counterstrikesharp {
namespace interfaces { namespace interfaces {
void Initialize(); void Initialize();
inline CGameResourceService *pGameResourceServiceServer = nullptr; inline CGameResourceService* pGameResourceServiceServer = nullptr;
} // namespace interfaces } // namespace interfaces
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -33,8 +33,10 @@
using SchemaKeyValueMap_t = CUtlMap<uint32_t, SchemaKey>; using SchemaKeyValueMap_t = CUtlMap<uint32_t, SchemaKey>;
using SchemaTableMap_t = CUtlMap<uint32_t, SchemaKeyValueMap_t*>; using SchemaTableMap_t = CUtlMap<uint32_t, SchemaKeyValueMap_t*>;
bool IsFieldNetworked(SchemaClassFieldData_t& field) { bool IsFieldNetworked(SchemaClassFieldData_t& field)
for (int i = 0; i < field.m_nStaticMetadataCount; i++) { {
for (int i = 0; i < field.m_nStaticMetadataCount; i++)
{
static auto networkEnabled = hash_32_fnv1a_const("MNetworkEnable"); static auto networkEnabled = hash_32_fnv1a_const("MNetworkEnable");
if (networkEnabled == hash_32_fnv1a_const(field.m_pStaticMetadata[i].m_pszName)) return true; if (networkEnabled == hash_32_fnv1a_const(field.m_pStaticMetadata[i].m_pszName)) return true;
} }
@@ -42,16 +44,16 @@ bool IsFieldNetworked(SchemaClassFieldData_t& field) {
return false; return false;
} }
static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap, static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap, const char* className, uint32_t classKey)
const char* className, {
uint32_t classKey) {
CSchemaSystemTypeScope* pType = counterstrikesharp::globals::schemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT); CSchemaSystemTypeScope* pType = counterstrikesharp::globals::schemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
if (!pType) return false; if (!pType) return false;
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className).Get(); SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className).Get();
if (!pClassInfo) { if (!pClassInfo)
{
SchemaKeyValueMap_t* map = new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t)); SchemaKeyValueMap_t* map = new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t));
tableMap->Insert(classKey, map); tableMap->Insert(classKey, map);
@@ -66,31 +68,34 @@ static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap,
keyValueMap->EnsureCapacity(fieldsSize); keyValueMap->EnsureCapacity(fieldsSize);
tableMap->Insert(classKey, keyValueMap); tableMap->Insert(classKey, keyValueMap);
for (int i = 0; i < fieldsSize; ++i) { for (int i = 0; i < fieldsSize; ++i)
{
SchemaClassFieldData_t& field = pFields[i]; SchemaClassFieldData_t& field = pFields[i];
keyValueMap->Insert(hash_32_fnv1a_const(field.m_pszName), keyValueMap->Insert(hash_32_fnv1a_const(field.m_pszName), { field.m_nSingleInheritanceOffset, IsFieldNetworked(field) });
{field.m_nSingleInheritanceOffset, IsFieldNetworked(field)});
} }
return true; return true;
} }
int16_t schema::FindChainOffset(const char* className) { int16_t schema::FindChainOffset(const char* className)
CSchemaSystemTypeScope* pType = {
counterstrikesharp::globals::schemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT); CSchemaSystemTypeScope* pType = counterstrikesharp::globals::schemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
if (!pType) return false; if (!pType) return false;
auto* pClassInfo = pType->FindDeclaredClass(className).Get(); auto* pClassInfo = pType->FindDeclaredClass(className).Get();
do { do
{
SchemaClassFieldData_t* pFields = pClassInfo->m_pFields; SchemaClassFieldData_t* pFields = pClassInfo->m_pFields;
short fieldsSize = pClassInfo->m_nFieldCount; short fieldsSize = pClassInfo->m_nFieldCount;
for (int i = 0; i < fieldsSize; ++i) { for (int i = 0; i < fieldsSize; ++i)
{
SchemaClassFieldData_t& field = pFields[i]; SchemaClassFieldData_t& field = pFields[i];
if (V_strcmp(field.m_pszName, "__m_pChainEntity") == 0) { if (V_strcmp(field.m_pszName, "__m_pChainEntity") == 0)
{
return field.m_nSingleInheritanceOffset; return field.m_nSingleInheritanceOffset;
} }
} }
@@ -99,29 +104,29 @@ int16_t schema::FindChainOffset(const char* className) {
return 0; return 0;
} }
SchemaKey schema::GetOffset(const char* className, SchemaKey schema::GetOffset(const char* className, uint32_t classKey, const char* memberName, uint32_t memberKey)
uint32_t classKey, {
const char* memberName,
uint32_t memberKey) {
static SchemaTableMap_t schemaTableMap(0, 0, DefLessFunc(uint32_t)); static SchemaTableMap_t schemaTableMap(0, 0, DefLessFunc(uint32_t));
int16_t tableMapIndex = schemaTableMap.Find(classKey); int16_t tableMapIndex = schemaTableMap.Find(classKey);
if (!schemaTableMap.IsValidIndex(tableMapIndex)) { if (!schemaTableMap.IsValidIndex(tableMapIndex))
if (InitSchemaFieldsForClass(&schemaTableMap, className, classKey)) {
return GetOffset(className, classKey, memberName, memberKey); if (InitSchemaFieldsForClass(&schemaTableMap, className, classKey)) return GetOffset(className, classKey, memberName, memberKey);
return {0, 0}; return { 0, 0 };
} }
SchemaKeyValueMap_t* tableMap = schemaTableMap[tableMapIndex]; SchemaKeyValueMap_t* tableMap = schemaTableMap[tableMapIndex];
int16_t memberIndex = tableMap->Find(memberKey); int16_t memberIndex = tableMap->Find(memberKey);
if (!tableMap->IsValidIndex(memberIndex)) { if (!tableMap->IsValidIndex(memberIndex))
return {0, 0}; {
return { 0, 0 };
} }
return tableMap->Element(memberIndex); return tableMap->Element(memberIndex);
} }
void SetStateChanged(Z_CBaseEntity* pEntity, int offset) { void SetStateChanged(Z_CBaseEntity* pEntity, int offset)
{
// addresses::StateChanged(pEntity->m_NetworkTransmitComponent(), pEntity, offset, -1, -1); // addresses::StateChanged(pEntity->m_NetworkTransmitComponent(), pEntity, offset, -1, -1);
auto vars = counterstrikesharp::globals::getGlobalVars(); auto vars = counterstrikesharp::globals::getGlobalVars();

View File

@@ -30,29 +30,28 @@
#undef schema #undef schema
struct SchemaKey { struct SchemaKey
{
int32_t offset; int32_t offset;
bool networked; bool networked;
}; };
class Z_CBaseEntity; class Z_CBaseEntity;
void SetStateChanged(Z_CBaseEntity *pEntity, int offset); void SetStateChanged(Z_CBaseEntity* pEntity, int offset);
inline uint32_t val_32_const = 0x811c9dc5; inline uint32_t val_32_const = 0x811c9dc5;
inline uint32_t prime_32_const = 0x1000193; inline uint32_t prime_32_const = 0x1000193;
inline uint64_t val_64_const = 0xcbf29ce484222325; inline uint64_t val_64_const = 0xcbf29ce484222325;
inline uint64_t prime_64_const = 0x100000001b3; inline uint64_t prime_64_const = 0x100000001b3;
inline uint32_t hash_32_fnv1a_const(const char *str, const uint32_t value = val_32_const) noexcept { inline uint32_t hash_32_fnv1a_const(const char* str, const uint32_t value = val_32_const) noexcept
return (str[0] == '\0') {
? value return (str[0] == '\0') ? value : hash_32_fnv1a_const(&str[1], (value ^ uint32_t(str[0])) * prime_32_const);
: hash_32_fnv1a_const(&str[1], (value ^ uint32_t(str[0])) * prime_32_const);
} }
inline uint64_t hash_64_fnv1a_const(const char *str, const uint64_t value = val_64_const) noexcept { inline uint64_t hash_64_fnv1a_const(const char* str, const uint64_t value = val_64_const) noexcept
return (str[0] == '\0') {
? value return (str[0] == '\0') ? value : hash_64_fnv1a_const(&str[1], (value ^ uint64_t(str[0])) * prime_64_const);
: hash_64_fnv1a_const(&str[1], (value ^ uint64_t(str[0])) * prime_64_const);
} }
namespace schema { namespace schema {
@@ -95,6 +94,6 @@ static std::vector<std::string> CS2BadList = {
"m_nMusicID", "m_nMusicID",
}; };
int16_t FindChainOffset(const char *className); int16_t FindChainOffset(const char* className);
SchemaKey GetOffset(const char *className, uint32_t classKey, const char *memberName, uint32_t memberKey); SchemaKey GetOffset(const char* className, uint32_t classKey, const char* memberName, uint32_t memberKey);
} // namespace schema } // namespace schema

View File

@@ -52,30 +52,30 @@ std::map<dyno::Hook*, ValveFunction*> g_HookMap;
// ============================================================================ // ============================================================================
int GetDynCallConvention(Convention_t eConv) int GetDynCallConvention(Convention_t eConv)
{ {
switch (eConv) { switch (eConv)
case CONV_CUSTOM: {
return -1; case CONV_CUSTOM:
case CONV_CDECL: return -1;
return DC_CALL_C_DEFAULT; case CONV_CDECL:
case CONV_THISCALL: return DC_CALL_C_DEFAULT;
case CONV_THISCALL:
#ifdef _WIN32 #ifdef _WIN32
return DC_CALL_C_X86_WIN32_THIS_MS; return DC_CALL_C_X86_WIN32_THIS_MS;
#else #else
return DC_CALL_C_X86_WIN32_THIS_GNU; return DC_CALL_C_X86_WIN32_THIS_GNU;
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
case CONV_STDCALL: case CONV_STDCALL:
return DC_CALL_C_X86_WIN32_STD; return DC_CALL_C_X86_WIN32_STD;
case CONV_FASTCALL: case CONV_FASTCALL:
return DC_CALL_C_X86_WIN32_FAST_MS; return DC_CALL_C_X86_WIN32_FAST_MS;
#endif #endif
} }
return -1; return -1;
} }
ValveFunction::ValveFunction(void* ulAddr, Convention_t callingConvention, ValveFunction::ValveFunction(void* ulAddr, Convention_t callingConvention, std::vector<DataType_t> args, DataType_t returnType)
std::vector<DataType_t> args, DataType_t returnType)
: m_ulAddr(ulAddr) : m_ulAddr(ulAddr)
{ {
m_Args = args; m_Args = args;
@@ -87,8 +87,7 @@ ValveFunction::ValveFunction(void* ulAddr, Convention_t callingConvention,
m_iCallingConvention = GetDynCallConvention(m_eCallingConvention); m_iCallingConvention = GetDynCallConvention(m_eCallingConvention);
} }
ValveFunction::ValveFunction(void* ulAddr, Convention_t callingConvention, DataType_t* args, ValveFunction::ValveFunction(void* ulAddr, Convention_t callingConvention, DataType_t* args, int argCount, DataType_t returnType)
int argCount, DataType_t returnType)
: m_ulAddr(ulAddr) : m_ulAddr(ulAddr)
{ {
@@ -101,13 +100,9 @@ ValveFunction::ValveFunction(void* ulAddr, Convention_t callingConvention, DataT
ValveFunction::~ValveFunction() {} ValveFunction::~ValveFunction() {}
bool ValveFunction::IsCallable() bool ValveFunction::IsCallable() { return (m_eCallingConvention != CONV_CUSTOM) && (m_iCallingConvention != -1); }
{
return (m_eCallingConvention != CONV_CUSTOM) && (m_iCallingConvention != -1);
}
template <class ReturnType, class Function> template <class ReturnType, class Function> ReturnType CallHelper(Function func, DCCallVM* vm, void* addr)
ReturnType CallHelper(Function func, DCCallVM* vm, void* addr)
{ {
ReturnType result; ReturnType result;
result = (ReturnType)func(vm, (void*)addr); result = (ReturnType)func(vm, (void*)addr);
@@ -118,119 +113,120 @@ void CallHelperVoid(DCCallVM* vm, void* addr) { dcCallVoid(vm, (void*)addr); }
void ValveFunction::Call(ScriptContext& script_context, int offset) void ValveFunction::Call(ScriptContext& script_context, int offset)
{ {
if (!IsCallable()) if (!IsCallable()) return;
return;
dcReset(g_pCallVM); dcReset(g_pCallVM);
dcMode(g_pCallVM, m_iCallingConvention); dcMode(g_pCallVM, m_iCallingConvention);
for (size_t i = 0; i < m_Args.size(); i++) { for (size_t i = 0; i < m_Args.size(); i++)
{
int contextIndex = i + offset; int contextIndex = i + offset;
switch (m_Args[i]) { switch (m_Args[i])
case DATA_TYPE_BOOL: {
dcArgBool(g_pCallVM, script_context.GetArgument<bool>(contextIndex)); case DATA_TYPE_BOOL:
break; dcArgBool(g_pCallVM, script_context.GetArgument<bool>(contextIndex));
case DATA_TYPE_CHAR: break;
dcArgChar(g_pCallVM, script_context.GetArgument<char>(contextIndex)); case DATA_TYPE_CHAR:
break; dcArgChar(g_pCallVM, script_context.GetArgument<char>(contextIndex));
case DATA_TYPE_UCHAR: break;
dcArgChar(g_pCallVM, script_context.GetArgument<unsigned char>(contextIndex)); case DATA_TYPE_UCHAR:
break; dcArgChar(g_pCallVM, script_context.GetArgument<unsigned char>(contextIndex));
case DATA_TYPE_SHORT: break;
dcArgShort(g_pCallVM, script_context.GetArgument<short>(contextIndex)); case DATA_TYPE_SHORT:
break; dcArgShort(g_pCallVM, script_context.GetArgument<short>(contextIndex));
case DATA_TYPE_USHORT: break;
dcArgShort(g_pCallVM, script_context.GetArgument<unsigned short>(contextIndex)); case DATA_TYPE_USHORT:
break; dcArgShort(g_pCallVM, script_context.GetArgument<unsigned short>(contextIndex));
case DATA_TYPE_INT: break;
dcArgInt(g_pCallVM, script_context.GetArgument<int>(contextIndex)); case DATA_TYPE_INT:
break; dcArgInt(g_pCallVM, script_context.GetArgument<int>(contextIndex));
case DATA_TYPE_UINT: break;
dcArgInt(g_pCallVM, script_context.GetArgument<unsigned int>(contextIndex)); case DATA_TYPE_UINT:
break; dcArgInt(g_pCallVM, script_context.GetArgument<unsigned int>(contextIndex));
case DATA_TYPE_LONG: break;
dcArgLong(g_pCallVM, script_context.GetArgument<long>(contextIndex)); case DATA_TYPE_LONG:
break; dcArgLong(g_pCallVM, script_context.GetArgument<long>(contextIndex));
case DATA_TYPE_ULONG: break;
dcArgLong(g_pCallVM, script_context.GetArgument<unsigned long>(contextIndex)); case DATA_TYPE_ULONG:
break; dcArgLong(g_pCallVM, script_context.GetArgument<unsigned long>(contextIndex));
case DATA_TYPE_LONG_LONG: break;
dcArgLongLong(g_pCallVM, script_context.GetArgument<long long>(contextIndex)); case DATA_TYPE_LONG_LONG:
break; dcArgLongLong(g_pCallVM, script_context.GetArgument<long long>(contextIndex));
case DATA_TYPE_ULONG_LONG: break;
dcArgLongLong(g_pCallVM, script_context.GetArgument<unsigned long long>(contextIndex)); case DATA_TYPE_ULONG_LONG:
break; dcArgLongLong(g_pCallVM, script_context.GetArgument<unsigned long long>(contextIndex));
case DATA_TYPE_FLOAT: break;
dcArgFloat(g_pCallVM, script_context.GetArgument<float>(contextIndex)); case DATA_TYPE_FLOAT:
break; dcArgFloat(g_pCallVM, script_context.GetArgument<float>(contextIndex));
case DATA_TYPE_DOUBLE: break;
dcArgDouble(g_pCallVM, script_context.GetArgument<double>(contextIndex)); case DATA_TYPE_DOUBLE:
break; dcArgDouble(g_pCallVM, script_context.GetArgument<double>(contextIndex));
case DATA_TYPE_POINTER: break;
dcArgPointer(g_pCallVM, script_context.GetArgument<void*>(contextIndex)); case DATA_TYPE_POINTER:
break; dcArgPointer(g_pCallVM, script_context.GetArgument<void*>(contextIndex));
case DATA_TYPE_STRING: break;
dcArgPointer(g_pCallVM, (void*)script_context.GetArgument<const char*>(contextIndex)); case DATA_TYPE_STRING:
break; dcArgPointer(g_pCallVM, (void*)script_context.GetArgument<const char*>(contextIndex));
default: break;
assert(!"Unknown function parameter type!"); default:
break; assert(!"Unknown function parameter type!");
break;
} }
} }
switch (m_eReturnType) { switch (m_eReturnType)
case DATA_TYPE_VOID: {
CallHelperVoid(g_pCallVM, m_ulAddr); case DATA_TYPE_VOID:
break; CallHelperVoid(g_pCallVM, m_ulAddr);
case DATA_TYPE_BOOL: break;
script_context.SetResult(CallHelper<bool>(dcCallBool, g_pCallVM, m_ulAddr)); case DATA_TYPE_BOOL:
break; script_context.SetResult(CallHelper<bool>(dcCallBool, g_pCallVM, m_ulAddr));
case DATA_TYPE_CHAR: break;
script_context.SetResult(CallHelper<char>(dcCallChar, g_pCallVM, m_ulAddr)); case DATA_TYPE_CHAR:
break; script_context.SetResult(CallHelper<char>(dcCallChar, g_pCallVM, m_ulAddr));
case DATA_TYPE_UCHAR: break;
script_context.SetResult(CallHelper<unsigned char>(dcCallChar, g_pCallVM, m_ulAddr)); case DATA_TYPE_UCHAR:
break; script_context.SetResult(CallHelper<unsigned char>(dcCallChar, g_pCallVM, m_ulAddr));
case DATA_TYPE_SHORT: break;
script_context.SetResult(CallHelper<short>(dcCallShort, g_pCallVM, m_ulAddr)); case DATA_TYPE_SHORT:
break; script_context.SetResult(CallHelper<short>(dcCallShort, g_pCallVM, m_ulAddr));
case DATA_TYPE_USHORT: break;
script_context.SetResult(CallHelper<unsigned short>(dcCallShort, g_pCallVM, m_ulAddr)); case DATA_TYPE_USHORT:
break; script_context.SetResult(CallHelper<unsigned short>(dcCallShort, g_pCallVM, m_ulAddr));
case DATA_TYPE_INT: break;
script_context.SetResult(CallHelper<int>(dcCallInt, g_pCallVM, m_ulAddr)); case DATA_TYPE_INT:
break; script_context.SetResult(CallHelper<int>(dcCallInt, g_pCallVM, m_ulAddr));
case DATA_TYPE_UINT: break;
script_context.SetResult(CallHelper<unsigned int>(dcCallInt, g_pCallVM, m_ulAddr)); case DATA_TYPE_UINT:
break; script_context.SetResult(CallHelper<unsigned int>(dcCallInt, g_pCallVM, m_ulAddr));
case DATA_TYPE_LONG: break;
script_context.SetResult(CallHelper<long>(dcCallLong, g_pCallVM, m_ulAddr)); case DATA_TYPE_LONG:
break; script_context.SetResult(CallHelper<long>(dcCallLong, g_pCallVM, m_ulAddr));
case DATA_TYPE_ULONG: break;
script_context.SetResult(CallHelper<unsigned long>(dcCallLong, g_pCallVM, m_ulAddr)); case DATA_TYPE_ULONG:
break; script_context.SetResult(CallHelper<unsigned long>(dcCallLong, g_pCallVM, m_ulAddr));
case DATA_TYPE_LONG_LONG: break;
script_context.SetResult(CallHelper<long long>(dcCallLongLong, g_pCallVM, m_ulAddr)); case DATA_TYPE_LONG_LONG:
break; script_context.SetResult(CallHelper<long long>(dcCallLongLong, g_pCallVM, m_ulAddr));
case DATA_TYPE_ULONG_LONG: break;
script_context.SetResult( case DATA_TYPE_ULONG_LONG:
CallHelper<unsigned long long>(dcCallLongLong, g_pCallVM, m_ulAddr)); script_context.SetResult(CallHelper<unsigned long long>(dcCallLongLong, g_pCallVM, m_ulAddr));
break; break;
case DATA_TYPE_FLOAT: case DATA_TYPE_FLOAT:
script_context.SetResult(CallHelper<float>(dcCallFloat, g_pCallVM, m_ulAddr)); script_context.SetResult(CallHelper<float>(dcCallFloat, g_pCallVM, m_ulAddr));
break; break;
case DATA_TYPE_DOUBLE: case DATA_TYPE_DOUBLE:
script_context.SetResult(CallHelper<double>(dcCallDouble, g_pCallVM, m_ulAddr)); script_context.SetResult(CallHelper<double>(dcCallDouble, g_pCallVM, m_ulAddr));
break; break;
case DATA_TYPE_POINTER: case DATA_TYPE_POINTER:
script_context.SetResult(CallHelper<void*>(dcCallPointer, g_pCallVM, m_ulAddr)); script_context.SetResult(CallHelper<void*>(dcCallPointer, g_pCallVM, m_ulAddr));
break; break;
case DATA_TYPE_STRING: case DATA_TYPE_STRING:
script_context.SetResult(CallHelper<const char*>(dcCallPointer, g_pCallVM, m_ulAddr)); script_context.SetResult(CallHelper<const char*>(dcCallPointer, g_pCallVM, m_ulAddr));
break; break;
default: default:
assert(!"Unknown function return type!"); assert(!"Unknown function return type!");
break; break;
} }
} }
@@ -240,23 +236,24 @@ dyno::ReturnAction HookHandler(dyno::HookType hookType, dyno::Hook& hook)
auto callback = hookType == dyno::HookType::Pre ? vf->m_precallback : vf->m_postcallback; auto callback = hookType == dyno::HookType::Pre ? vf->m_precallback : vf->m_postcallback;
if (callback == nullptr) { if (callback == nullptr)
{
return dyno::ReturnAction::Ignored; return dyno::ReturnAction::Ignored;
} }
callback->Reset(); callback->Reset();
callback->ScriptContext().Push(&hook); callback->ScriptContext().Push(&hook);
for (auto fnMethodToCall : callback->GetFunctions()) { for (auto fnMethodToCall : callback->GetFunctions())
if (!fnMethodToCall) {
continue; if (!fnMethodToCall) continue;
fnMethodToCall(&callback->ScriptContextStruct()); fnMethodToCall(&callback->ScriptContextStruct());
auto result = callback->ScriptContext().GetResult<HookResult>(); auto result = callback->ScriptContext().GetResult<HookResult>();
CSSHARP_CORE_TRACE("Received hook callback result of {}, hook mode {}", result, CSSHARP_CORE_TRACE("Received hook callback result of {}, hook mode {}", result, (int)hookType);
(int)hookType);
if (result >= HookResult::Handled) { if (result >= HookResult::Handled)
{
return dyno::ReturnAction::Supercede; return dyno::ReturnAction::Supercede;
} }
} }
@@ -269,7 +266,8 @@ std::vector<dyno::DataObject> ConvertArgsToDynoHook(const std::vector<DataType_t
std::vector<dyno::DataObject> converted; std::vector<dyno::DataObject> converted;
converted.reserve(dataTypes.size()); converted.reserve(dataTypes.size());
for (DataType_t dt : dataTypes) { for (DataType_t dt : dataTypes)
{
converted.push_back(dyno::DataObject(static_cast<dyno::DataType>(dt))); converted.push_back(dyno::DataObject(static_cast<dyno::DataType>(dt)));
} }
@@ -290,19 +288,25 @@ void ValveFunction::AddHook(CallbackT callable, bool post)
hook->addCallback(dyno::HookType::Post, (dyno::HookHandler*)&HookHandler); hook->addCallback(dyno::HookType::Post, (dyno::HookHandler*)&HookHandler);
hook->addCallback(dyno::HookType::Pre, (dyno::HookHandler*)&HookHandler); hook->addCallback(dyno::HookType::Pre, (dyno::HookHandler*)&HookHandler);
if (post) { if (post)
if (m_postcallback == nullptr) { {
if (m_postcallback == nullptr)
{
m_postcallback = globals::callbackManager.CreateCallback(""); m_postcallback = globals::callbackManager.CreateCallback("");
} }
m_postcallback->AddListener(callable); m_postcallback->AddListener(callable);
} else { }
if (m_precallback == nullptr) { else
{
if (m_precallback == nullptr)
{
m_precallback = globals::callbackManager.CreateCallback(""); m_precallback = globals::callbackManager.CreateCallback("");
} }
m_precallback->AddListener(callable); m_precallback->AddListener(callable);
} }
} }
void ValveFunction::RemoveHook(CallbackT callable, bool post) { void ValveFunction::RemoveHook(CallbackT callable, bool post)
{
dyno::HookManager& manager = dyno::HookManager::Get(); dyno::HookManager& manager = dyno::HookManager::Get();
dyno::Hook* hook = manager.hook((void*)m_ulAddr, [this] { dyno::Hook* hook = manager.hook((void*)m_ulAddr, [this] {
#ifdef _WIN32 #ifdef _WIN32
@@ -313,12 +317,17 @@ void ValveFunction::RemoveHook(CallbackT callable, bool post) {
}); });
g_HookMap[hook] = this; g_HookMap[hook] = this;
if (post) { if (post)
if (m_postcallback != nullptr) { {
if (m_postcallback != nullptr)
{
m_postcallback->RemoveListener(callable); m_postcallback->RemoveListener(callable);
} }
} else { }
if (m_precallback != nullptr) { else
{
if (m_precallback != nullptr)
{
m_precallback->RemoveListener(callable); m_precallback->RemoveListener(callable);
} }
} }

View File

@@ -40,7 +40,8 @@ class Hook;
namespace counterstrikesharp { namespace counterstrikesharp {
enum DataType_t { enum DataType_t
{
DATA_TYPE_VOID, DATA_TYPE_VOID,
DATA_TYPE_BOOL, DATA_TYPE_BOOL,
DATA_TYPE_CHAR, DATA_TYPE_CHAR,
@@ -60,7 +61,8 @@ enum DataType_t {
DATA_TYPE_VARIANT DATA_TYPE_VARIANT
}; };
enum Protection_t { enum Protection_t
{
PROTECTION_NONE, PROTECTION_NONE,
PROTECTION_READ, PROTECTION_READ,
PROTECTION_READ_WRITE, PROTECTION_READ_WRITE,
@@ -69,19 +71,20 @@ enum Protection_t {
PROTECTION_EXECUTE_READ_WRITE PROTECTION_EXECUTE_READ_WRITE
}; };
enum Convention_t { CONV_CUSTOM, CONV_CDECL, CONV_THISCALL, CONV_STDCALL, CONV_FASTCALL }; enum Convention_t
{
CONV_CUSTOM,
CONV_CDECL,
CONV_THISCALL,
CONV_STDCALL,
CONV_FASTCALL
};
class ValveFunction { class ValveFunction
public: {
ValveFunction(void* ulAddr, public:
Convention_t callingConvention, ValveFunction(void* ulAddr, Convention_t callingConvention, std::vector<DataType_t> args, DataType_t returnType);
std::vector<DataType_t> args, ValveFunction(void* ulAddr, Convention_t callingConvention, DataType_t* args, int argCount, DataType_t returnType);
DataType_t returnType);
ValveFunction(void* ulAddr,
Convention_t callingConvention,
DataType_t* args,
int argCount,
DataType_t returnType);
~ValveFunction(); ~ValveFunction();
@@ -110,4 +113,4 @@ public:
ScriptCallback* m_postcallback = nullptr; ScriptCallback* m_postcallback = nullptr;
}; };
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -36,7 +36,8 @@ bool InitGameSystems()
// bytes so we skip those // bytes so we skip those
uint8* ptr = (uint8*)counterstrikesharp::globals::gameConfig->ResolveSignature("IGameSystem_InitAllSystems_pFirst") + 3; uint8* ptr = (uint8*)counterstrikesharp::globals::gameConfig->ResolveSignature("IGameSystem_InitAllSystems_pFirst") + 3;
if (!ptr) { if (!ptr)
{
CSSHARP_CORE_ERROR("Failed to InitGameSystems, see warnings above."); CSSHARP_CORE_ERROR("Failed to InitGameSystems, see warnings above.");
return false; return false;
} }
@@ -63,4 +64,4 @@ GS_EVENT_MEMBER(CGameSystem, BuildGameSessionManifest)
CSSHARP_CORE_INFO("CGameSystem::BuildGameSessionManifest"); CSSHARP_CORE_INFO("CGameSystem::BuildGameSessionManifest");
counterstrikesharp::globals::serverManager.OnPrecacheResources(pResourceManifest); counterstrikesharp::globals::serverManager.OnPrecacheResources(pResourceManifest);
} }

View File

@@ -37,11 +37,10 @@ class CGameSystem : public CBaseGameSystem
void SetGameSystemGlobalPtrs(void* pValue) override void SetGameSystemGlobalPtrs(void* pValue) override
{ {
if (sm_Factory) if (sm_Factory) sm_Factory->SetGlobalPtr(pValue);
sm_Factory->SetGlobalPtr(pValue);
} }
bool DoesGameSystemReallocate() override { return sm_Factory->ShouldAutoAdd(); } bool DoesGameSystemReallocate() override { return sm_Factory->ShouldAutoAdd(); }
static IGameSystemFactory* sm_Factory; static IGameSystemFactory* sm_Factory;
}; };

View File

@@ -1,6 +1,5 @@
#pragma once #pragma once
#include "core/globals.h" #include "core/globals.h"
#include "core/memory_module.h" #include "core/memory_module.h"
#include <KeyValues.h> #include <KeyValues.h>

View File

@@ -32,34 +32,37 @@
#pragma once #pragma once
namespace counterstrikesharp { namespace counterstrikesharp {
class GlobalClass { class GlobalClass
public: {
public:
virtual ~GlobalClass() = default; virtual ~GlobalClass() = default;
GlobalClass() { GlobalClass()
{
m_pGlobalClassNext = GlobalClass::head; m_pGlobalClassNext = GlobalClass::head;
GlobalClass::head = this; GlobalClass::head = this;
} }
public: public:
virtual void OnStartup() {} virtual void OnStartup() {}
virtual void OnShutdown() {} virtual void OnShutdown() {}
virtual void OnAllInitialized() {} virtual void OnAllInitialized() {}
virtual void OnGameLoopInitialized() {} virtual void OnGameLoopInitialized() {}
virtual void OnAllInitialized_Post() {} virtual void OnAllInitialized_Post() {}
virtual void OnLevelChange(const char *mapName) {} virtual void OnLevelChange(const char* mapName) {}
virtual void OnLevelEnd() {} virtual void OnLevelEnd() {}
public: public:
GlobalClass *m_pGlobalClassNext; GlobalClass* m_pGlobalClassNext;
static GlobalClass *head; static GlobalClass* head;
}; };
} // namespace counterstrikesharp } // namespace counterstrikesharp
#define CALL_GLOBAL_LISTENER(func) \ #define CALL_GLOBAL_LISTENER(func) \
GlobalClass *pBase = GlobalClass::head; \ GlobalClass* pBase = GlobalClass::head; \
pBase = GlobalClass::head; \ pBase = GlobalClass::head; \
while (pBase) { \ while (pBase) \
{ \
pBase->func; \ pBase->func; \
pBase = pBase->m_pGlobalClassNext; \ pBase = pBase->m_pGlobalClassNext; \
} }

View File

@@ -1,4 +1,3 @@
// clang-format off
#include "mm_plugin.h" #include "mm_plugin.h"
#include "core/globals.h" #include "core/globals.h"
#include "core/managers/player_manager.h" #include "core/managers/player_manager.h"
@@ -28,7 +27,6 @@
#include <public/entity2/entitysystem.h> #include <public/entity2/entitysystem.h>
#include <funchook.h> #include <funchook.h>
// clang-format on
namespace counterstrikesharp { namespace counterstrikesharp {
@@ -142,7 +140,8 @@ void DetourGameEventManagerInit(IGameEventManager2* pGameEventManager)
} }
int source_hook_pluginid = 0; int source_hook_pluginid = 0;
CGlobalVars* getGlobalVars() { CGlobalVars* getGlobalVars()
{
INetworkGameServer* server = networkServerService->GetIGameServer(); INetworkGameServer* server = networkServerService->GetIGameServer();
if (!server) return nullptr; if (!server) return nullptr;
return networkServerService->GetIGameServer()->GetGlobals(); return networkServerService->GetIGameServer()->GetGlobals();

View File

@@ -7,7 +7,8 @@
namespace counterstrikesharp { namespace counterstrikesharp {
std::shared_ptr<spdlog::logger> Log::m_core_logger; std::shared_ptr<spdlog::logger> Log::m_core_logger;
void Log::Init() { void Log::Init()
{
std::vector<spdlog::sink_ptr> log_sinks; std::vector<spdlog::sink_ptr> log_sinks;
auto color_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>(); auto color_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
#if _WIN32 #if _WIN32
@@ -17,8 +18,7 @@ void Log::Init() {
#endif #endif
log_sinks.emplace_back(color_sink); log_sinks.emplace_back(color_sink);
log_sinks.emplace_back( log_sinks.emplace_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>("counterstrikesharp.log", true));
std::make_shared<spdlog::sinks::basic_file_sink_mt>("counterstrikesharp.log", true));
log_sinks[0]->set_pattern("%^[%T.%e] %n: %v%$"); log_sinks[0]->set_pattern("%^[%T.%e] %n: %v%$");
log_sinks[1]->set_pattern("[%T.%e] [%l] %n: %v"); log_sinks[1]->set_pattern("[%T.%e] [%l] %n: %v");
@@ -31,8 +31,9 @@ void Log::Init() {
spdlog::cfg::load_env_levels(); spdlog::cfg::load_env_levels();
} }
void Log::Close() { void Log::Close()
{
spdlog::drop("CSSharp"); spdlog::drop("CSSharp");
m_core_logger = nullptr; m_core_logger = nullptr;
} }
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -6,21 +6,22 @@
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
namespace counterstrikesharp { namespace counterstrikesharp {
class Log { class Log
public: {
public:
static void Init(); static void Init();
static void Close(); static void Close();
static std::shared_ptr<spdlog::logger> &GetCoreLogger() { return m_core_logger; } static std::shared_ptr<spdlog::logger>& GetCoreLogger() { return m_core_logger; }
private: private:
static std::shared_ptr<spdlog::logger> m_core_logger; static std::shared_ptr<spdlog::logger> m_core_logger;
}; };
} // namespace counterstrikesharp } // namespace counterstrikesharp
#define CSSHARP_CORE_TRACE(...) ::counterstrikesharp::Log::GetCoreLogger()->trace(__VA_ARGS__) #define CSSHARP_CORE_TRACE(...) ::counterstrikesharp::Log::GetCoreLogger()->trace(__VA_ARGS__)
#define CSSHARP_CORE_DEBUG(...) ::counterstrikesharp::Log::GetCoreLogger()->debug(__VA_ARGS__) #define CSSHARP_CORE_DEBUG(...) ::counterstrikesharp::Log::GetCoreLogger()->debug(__VA_ARGS__)
#define CSSHARP_CORE_INFO(...) ::counterstrikesharp::Log::GetCoreLogger()->info(__VA_ARGS__) #define CSSHARP_CORE_INFO(...) ::counterstrikesharp::Log::GetCoreLogger()->info(__VA_ARGS__)
#define CSSHARP_CORE_WARN(...) ::counterstrikesharp::Log::GetCoreLogger()->warn(__VA_ARGS__) #define CSSHARP_CORE_WARN(...) ::counterstrikesharp::Log::GetCoreLogger()->warn(__VA_ARGS__)
#define CSSHARP_CORE_ERROR(...) ::counterstrikesharp::Log::GetCoreLogger()->error(__VA_ARGS__) #define CSSHARP_CORE_ERROR(...) ::counterstrikesharp::Log::GetCoreLogger()->error(__VA_ARGS__)
#define CSSHARP_CORE_CRITICAL(...) ::counterstrikesharp::Log::GetCoreLogger()->critical(__VA_ARGS__) #define CSSHARP_CORE_CRITICAL(...) ::counterstrikesharp::Log::GetCoreLogger()->critical(__VA_ARGS__)

View File

@@ -1,127 +1,127 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
#include "core/managers/chat_manager.h" #include "core/managers/chat_manager.h"
#include <funchook.h> #include <funchook.h>
#include <igameevents.h> #include <igameevents.h>
#include <public/eiface.h> #include <public/eiface.h>
#include "characterset.h" #include "characterset.h"
#include "core/coreconfig.h" #include "core/coreconfig.h"
#include "core/gameconfig.h" #include "core/gameconfig.h"
#include "core/log.h" #include "core/log.h"
#include "core/managers/con_command_manager.h" #include "core/managers/con_command_manager.h"
#include "core/memory.h" #include "core/memory.h"
#include "core/memory_module.h" #include "core/memory_module.h"
#include "scripting/callback_manager.h" #include "scripting/callback_manager.h"
namespace counterstrikesharp { namespace counterstrikesharp {
ChatManager::ChatManager() {} ChatManager::ChatManager() {}
ChatManager::~ChatManager() {} ChatManager::~ChatManager() {}
void ChatManager::OnAllInitialized() void ChatManager::OnAllInitialized()
{ {
m_pHostSay = reinterpret_cast<HostSay>(modules::server->FindSignature(globals::gameConfig->GetSignature("Host_Say"))); m_pHostSay = reinterpret_cast<HostSay>(modules::server->FindSignature(globals::gameConfig->GetSignature("Host_Say")));
if (m_pHostSay == nullptr) if (m_pHostSay == nullptr)
{ {
CSSHARP_CORE_ERROR("Failed to find signature for \'Host_Say\'"); CSSHARP_CORE_ERROR("Failed to find signature for \'Host_Say\'");
return; return;
} }
auto m_hook = funchook_create(); auto m_hook = funchook_create();
funchook_prepare(m_hook, (void**)&m_pHostSay, (void*)&DetourHostSay); funchook_prepare(m_hook, (void**)&m_pHostSay, (void*)&DetourHostSay);
funchook_install(m_hook, 0); funchook_install(m_hook, 0);
} }
void ChatManager::OnShutdown() {} void ChatManager::OnShutdown() {}
void DetourHostSay(CEntityInstance* pController, CCommand& args, bool teamonly, int unk1, const char* unk2) void DetourHostSay(CEntityInstance* pController, CCommand& args, bool teamonly, int unk1, const char* unk2)
{ {
if (pController) if (pController)
{ {
auto pEvent = globals::gameEventManager->CreateEvent("player_chat", true); auto pEvent = globals::gameEventManager->CreateEvent("player_chat", true);
if (pEvent) if (pEvent)
{ {
pEvent->SetBool("teamonly", teamonly); pEvent->SetBool("teamonly", teamonly);
pEvent->SetInt("userid", pController->GetEntityIndex().Get() - 1); pEvent->SetInt("userid", pController->GetEntityIndex().Get() - 1);
pEvent->SetString("text", args[1]); pEvent->SetString("text", args[1]);
globals::gameEventManager->FireEvent(pEvent, true); globals::gameEventManager->FireEvent(pEvent, true);
} }
} }
std::string prefix; std::string prefix;
bool bSilent = globals::coreConfig->IsSilentChatTrigger(args[1], prefix); bool bSilent = globals::coreConfig->IsSilentChatTrigger(args[1], prefix);
bool bCommand = globals::coreConfig->IsPublicChatTrigger(args[1], prefix) || bSilent; bool bCommand = globals::coreConfig->IsPublicChatTrigger(args[1], prefix) || bSilent;
if (!bSilent) if (!bSilent)
{ {
m_pHostSay(pController, args, teamonly, unk1, unk2); m_pHostSay(pController, args, teamonly, unk1, unk2);
} }
if (bCommand) if (bCommand)
{ {
char* pszMessage = (char*)(args.ArgS() + prefix.length() + 1); char* pszMessage = (char*)(args.ArgS() + prefix.length() + 1);
// Trailing slashes are only removed if Host_Say has been called. // Trailing slashes are only removed if Host_Say has been called.
if (bSilent) pszMessage[V_strlen(pszMessage) - 1] = 0; if (bSilent) pszMessage[V_strlen(pszMessage) - 1] = 0;
CCommand args; CCommand args;
args.Tokenize(pszMessage); args.Tokenize(pszMessage);
auto prefixedPhrase = std::string("css_") + args.Arg(0); auto prefixedPhrase = std::string("css_") + args.Arg(0);
auto bValidWithPrefix = globals::conCommandManager.IsValidValveCommand(prefixedPhrase.c_str()); auto bValidWithPrefix = globals::conCommandManager.IsValidValveCommand(prefixedPhrase.c_str());
if (bValidWithPrefix) if (bValidWithPrefix)
{ {
// Re-tokenize with a `css_` prefix if we have found that its a valid command. // Re-tokenize with a `css_` prefix if we have found that its a valid command.
args.Tokenize(("css_" + std::string(pszMessage)).c_str()); args.Tokenize(("css_" + std::string(pszMessage)).c_str());
} }
globals::chatManager.OnSayCommandPost(pController, args); globals::chatManager.OnSayCommandPost(pController, args);
} }
} }
bool ChatManager::OnSayCommandPre(CEntityInstance* pController, CCommand& command) { return false; } bool ChatManager::OnSayCommandPre(CEntityInstance* pController, CCommand& command) { return false; }
void ChatManager::OnSayCommandPost(CEntityInstance* pController, CCommand& command) void ChatManager::OnSayCommandPost(CEntityInstance* pController, CCommand& command)
{ {
auto commandStr = command.Arg(0); auto commandStr = command.Arg(0);
return InternalDispatch(pController, commandStr, command); return InternalDispatch(pController, commandStr, command);
} }
void ChatManager::InternalDispatch(CEntityInstance* pPlayerController, const char* szTriggerPhase, CCommand& fullCommand) void ChatManager::InternalDispatch(CEntityInstance* pPlayerController, const char* szTriggerPhase, CCommand& fullCommand)
{ {
if (pPlayerController == nullptr) if (pPlayerController == nullptr)
{ {
globals::conCommandManager.ExecuteCommandCallbacks(fullCommand.Arg(0), globals::conCommandManager.ExecuteCommandCallbacks(fullCommand.Arg(0),
CCommandContext(CommandTarget_t::CT_NO_TARGET, CPlayerSlot(-1)), fullCommand, CCommandContext(CommandTarget_t::CT_NO_TARGET, CPlayerSlot(-1)), fullCommand,
HookMode::Pre, CommandCallingContext::Chat); HookMode::Pre, CommandCallingContext::Chat);
return; return;
} }
auto index = pPlayerController->GetEntityIndex().Get(); auto index = pPlayerController->GetEntityIndex().Get();
auto slot = CPlayerSlot(index - 1); auto slot = CPlayerSlot(index - 1);
globals::conCommandManager.ExecuteCommandCallbacks(fullCommand.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, slot), globals::conCommandManager.ExecuteCommandCallbacks(fullCommand.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, slot),
fullCommand, HookMode::Pre, CommandCallingContext::Chat); fullCommand, HookMode::Pre, CommandCallingContext::Chat);
} }
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -1,68 +1,68 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
#pragma once #pragma once
#include <map> #include <map>
#include <vector> #include <vector>
#include "core/global_listener.h" #include "core/global_listener.h"
#include "core/globals.h" #include "core/globals.h"
#include "scripting/script_engine.h" #include "scripting/script_engine.h"
namespace counterstrikesharp { namespace counterstrikesharp {
class ScriptCallback; class ScriptCallback;
typedef void (*HostSay)(CEntityInstance*, CCommand&, bool, int, const char*); typedef void (*HostSay)(CEntityInstance*, CCommand&, bool, int, const char*);
class ChatCommandInfo class ChatCommandInfo
{ {
friend class ChatManager; friend class ChatManager;
public: public:
ChatCommandInfo() {} ChatCommandInfo() {}
public: public:
ScriptCallback* GetCallback() { return callback_pre; } ScriptCallback* GetCallback() { return callback_pre; }
private: private:
std::string command; std::string command;
ScriptCallback* callback_pre; ScriptCallback* callback_pre;
ScriptCallback* callback_post; ScriptCallback* callback_post;
}; };
class ChatManager : public GlobalClass class ChatManager : public GlobalClass
{ {
public: public:
ChatManager(); ChatManager();
~ChatManager(); ~ChatManager();
void OnAllInitialized() override; void OnAllInitialized() override;
void OnShutdown() override; void OnShutdown() override;
bool OnSayCommandPre(CEntityInstance* pController, CCommand& args); bool OnSayCommandPre(CEntityInstance* pController, CCommand& args);
void OnSayCommandPost(CEntityInstance* pController, CCommand& args); void OnSayCommandPost(CEntityInstance* pController, CCommand& args);
private: private:
void InternalDispatch(CEntityInstance* pPlayerController, const char* szTriggerPhrase, CCommand& pFullCommand); void InternalDispatch(CEntityInstance* pPlayerController, const char* szTriggerPhrase, CCommand& pFullCommand);
std::vector<ChatCommandInfo*> m_cmd_list; std::vector<ChatCommandInfo*> m_cmd_list;
std::map<std::string, ChatCommandInfo*> m_cmd_lookup; std::map<std::string, ChatCommandInfo*> m_cmd_lookup;
}; };
static void DetourHostSay(CEntityInstance* pController, CCommand& args, bool teamonly, int unk1, const char* unk2); static void DetourHostSay(CEntityInstance* pController, CCommand& args, bool teamonly, int unk1, const char* unk2);
static HostSay m_pHostSay = nullptr; static HostSay m_pHostSay = nullptr;
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -1,18 +1,18 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
#include "core/managers/entity_manager.h" #include "core/managers/entity_manager.h"
#include "core/gameconfig.h" #include "core/gameconfig.h"
@@ -25,18 +25,28 @@
#include <public/eiface.h> #include <public/eiface.h>
#include "scripting/callback_manager.h" #include "scripting/callback_manager.h"
SH_DECL_HOOK7_void(ISource2GameEntities, CheckTransmit, SH_NOATTRIB, 0, CCheckTransmitInfo**, int, CBitVec<16384>&, const Entity2Networkable_t**, const uint16*, int, bool); SH_DECL_HOOK7_void(ISource2GameEntities,
CheckTransmit,
SH_NOATTRIB,
0,
CCheckTransmitInfo**,
int,
CBitVec<16384>&,
const Entity2Networkable_t**,
const uint16*,
int,
bool);
namespace counterstrikesharp { namespace counterstrikesharp {
EntityManager::EntityManager() EntityManager::EntityManager() { m_profile_name = "EntityManager"; }
{
m_profile_name = "EntityManager";
}
EntityManager::~EntityManager() {} EntityManager::~EntityManager() {}
CCheckTransmitInfoList::CCheckTransmitInfoList(CCheckTransmitInfo** pInfoInfoList, int nInfoCount) : infoList(pInfoInfoList), infoCount(nInfoCount) {} CCheckTransmitInfoList::CCheckTransmitInfoList(CCheckTransmitInfo** pInfoInfoList, int nInfoCount)
: infoList(pInfoInfoList), infoCount(nInfoCount)
{
}
void EntityManager::OnAllInitialized() void EntityManager::OnAllInitialized()
{ {
@@ -46,13 +56,13 @@ void EntityManager::OnAllInitialized()
on_entity_spawned_callback = globals::callbackManager.CreateCallback("OnEntitySpawned"); on_entity_spawned_callback = globals::callbackManager.CreateCallback("OnEntitySpawned");
on_entity_created_callback = globals::callbackManager.CreateCallback("OnEntityCreated"); on_entity_created_callback = globals::callbackManager.CreateCallback("OnEntityCreated");
on_entity_deleted_callback = globals::callbackManager.CreateCallback("OnEntityDeleted"); on_entity_deleted_callback = globals::callbackManager.CreateCallback("OnEntityDeleted");
on_entity_parent_changed_callback = on_entity_parent_changed_callback = globals::callbackManager.CreateCallback("OnEntityParentChanged");
globals::callbackManager.CreateCallback("OnEntityParentChanged");
m_pFireOutputInternal = reinterpret_cast<FireOutputInternal>(modules::server->FindSignature( m_pFireOutputInternal = reinterpret_cast<FireOutputInternal>(
globals::gameConfig->GetSignature("CEntityIOOutput_FireOutputInternal"))); modules::server->FindSignature(globals::gameConfig->GetSignature("CEntityIOOutput_FireOutputInternal")));
if (m_pFireOutputInternal == nullptr) { if (m_pFireOutputInternal == nullptr)
{
CSSHARP_CORE_CRITICAL("Failed to find signature for \'CEntityIOOutput_FireOutputInternal\'"); CSSHARP_CORE_CRITICAL("Failed to find signature for \'CEntityIOOutput_FireOutputInternal\'");
return; return;
} }
@@ -73,7 +83,7 @@ void EntityManager::OnAllInitialized()
CSSHARP_CORE_CRITICAL("Failed to find signature for \'CEntitySystem_AddEntityIOEvent\'"); CSSHARP_CORE_CRITICAL("Failed to find signature for \'CEntitySystem_AddEntityIOEvent\'");
} }
CBaseEntity_EmitSoundFilter = decltype(CBaseEntity_EmitSoundFilter) ( CBaseEntity_EmitSoundFilter = decltype(CBaseEntity_EmitSoundFilter)(
modules::server->FindSignature(globals::gameConfig->GetSignature("CBaseEntity_EmitSoundFilter"))); modules::server->FindSignature(globals::gameConfig->GetSignature("CBaseEntity_EmitSoundFilter")));
if (!CBaseEntity_EmitSoundFilter) if (!CBaseEntity_EmitSoundFilter)
@@ -104,7 +114,8 @@ void CEntityListener::OnEntitySpawned(CEntityInstance* pEntity)
{ {
auto callback = globals::entityManager.on_entity_spawned_callback; auto callback = globals::entityManager.on_entity_spawned_callback;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->ScriptContext().Push(pEntity); callback->ScriptContext().Push(pEntity);
callback->Execute(); callback->Execute();
@@ -114,7 +125,8 @@ void CEntityListener::OnEntityCreated(CEntityInstance* pEntity)
{ {
auto callback = globals::entityManager.on_entity_created_callback; auto callback = globals::entityManager.on_entity_created_callback;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->ScriptContext().Push(pEntity); callback->ScriptContext().Push(pEntity);
callback->Execute(); callback->Execute();
@@ -124,7 +136,8 @@ void CEntityListener::OnEntityDeleted(CEntityInstance* pEntity)
{ {
auto callback = globals::entityManager.on_entity_deleted_callback; auto callback = globals::entityManager.on_entity_deleted_callback;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->ScriptContext().Push(pEntity); callback->ScriptContext().Push(pEntity);
callback->Execute(); callback->Execute();
@@ -134,7 +147,8 @@ void CEntityListener::OnEntityParentChanged(CEntityInstance* pEntity, CEntityIns
{ {
auto callback = globals::entityManager.on_entity_parent_changed_callback; auto callback = globals::entityManager.on_entity_parent_changed_callback;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->ScriptContext().Push(pEntity); callback->ScriptContext().Push(pEntity);
callback->ScriptContext().Push(pNewParent); callback->ScriptContext().Push(pNewParent);
@@ -142,49 +156,58 @@ void CEntityListener::OnEntityParentChanged(CEntityInstance* pEntity, CEntityIns
} }
} }
void EntityManager::HookEntityOutput(const char* szClassname, const char* szOutput, void EntityManager::HookEntityOutput(const char* szClassname, const char* szOutput, CallbackT fnCallback, HookMode mode)
CallbackT fnCallback, HookMode mode)
{ {
auto outputKey = OutputKey_t(szClassname, szOutput); auto outputKey = OutputKey_t(szClassname, szOutput);
CallbackPair* pCallbackPair; CallbackPair* pCallbackPair;
auto search = m_pHookMap.find(outputKey); auto search = m_pHookMap.find(outputKey);
if (search == m_pHookMap.end()) { if (search == m_pHookMap.end())
{
m_pHookMap[outputKey] = new CallbackPair(); m_pHookMap[outputKey] = new CallbackPair();
pCallbackPair = m_pHookMap[outputKey]; pCallbackPair = m_pHookMap[outputKey];
} else }
else
pCallbackPair = search->second; pCallbackPair = search->second;
auto* pCallback = mode == HookMode::Pre ? pCallbackPair->pre : pCallbackPair->post; auto* pCallback = mode == HookMode::Pre ? pCallbackPair->pre : pCallbackPair->post;
pCallback->AddListener(fnCallback); pCallback->AddListener(fnCallback);
} }
void EntityManager::UnhookEntityOutput(const char* szClassname, const char* szOutput, void EntityManager::UnhookEntityOutput(const char* szClassname, const char* szOutput, CallbackT fnCallback, HookMode mode)
CallbackT fnCallback, HookMode mode)
{ {
auto outputKey = OutputKey_t(szClassname, szOutput); auto outputKey = OutputKey_t(szClassname, szOutput);
auto search = m_pHookMap.find(outputKey); auto search = m_pHookMap.find(outputKey);
if (search != m_pHookMap.end()) { if (search != m_pHookMap.end())
{
auto* pCallbackPair = search->second; auto* pCallbackPair = search->second;
auto* pCallback = mode == Pre ? pCallbackPair->pre : pCallbackPair->post; auto* pCallback = mode == Pre ? pCallbackPair->pre : pCallbackPair->post;
pCallback->RemoveListener(fnCallback); pCallback->RemoveListener(fnCallback);
if (!pCallbackPair->HasCallbacks()) { if (!pCallbackPair->HasCallbacks())
{
m_pHookMap.erase(outputKey); m_pHookMap.erase(outputKey);
} }
} }
} }
void EntityManager::CheckTransmit(CCheckTransmitInfo** pInfoInfoList, int nInfoCount, CBitVec<16384>& unionTransmitEdicts, const Entity2Networkable_t** pNetworkables, const uint16* pEntityIndicies, int nEntityIndices, bool bEnablePVSBits) void EntityManager::CheckTransmit(CCheckTransmitInfo** pInfoInfoList,
int nInfoCount,
CBitVec<16384>& unionTransmitEdicts,
const Entity2Networkable_t** pNetworkables,
const uint16* pEntityIndicies,
int nEntityIndices,
bool bEnablePVSBits)
{ {
VPROF_BUDGET(m_profile_name.c_str(), "CS# CheckTransmit"); VPROF_BUDGET(m_profile_name.c_str(), "CS# CheckTransmit");
auto callback = globals::entityManager.check_transmit; auto callback = globals::entityManager.check_transmit;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
CCheckTransmitInfoList* infoList = new CCheckTransmitInfoList(pInfoInfoList, nInfoCount); CCheckTransmitInfoList* infoList = new CCheckTransmitInfoList(pInfoInfoList, nInfoCount);
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
@@ -195,39 +218,43 @@ void EntityManager::CheckTransmit(CCheckTransmitInfo** pInfoInfoList, int nInfoC
} }
} }
void DetourFireOutputInternal(CEntityIOOutput* const pThis, CEntityInstance* pActivator, void DetourFireOutputInternal(
CEntityInstance* pCaller, const CVariant* const value, float flDelay) CEntityIOOutput* const pThis, CEntityInstance* pActivator, CEntityInstance* pCaller, const CVariant* const value, float flDelay)
{ {
std::vector vecSearchKeys{OutputKey_t("*", pThis->m_pDesc->m_pName), std::vector vecSearchKeys{ OutputKey_t("*", pThis->m_pDesc->m_pName), OutputKey_t("*", "*") };
OutputKey_t("*", "*")};
if (pCaller) { if (pCaller)
{
vecSearchKeys.push_back(OutputKey_t(pCaller->GetClassname(), pThis->m_pDesc->m_pName)); vecSearchKeys.push_back(OutputKey_t(pCaller->GetClassname(), pThis->m_pDesc->m_pName));
OutputKey_t(pCaller->GetClassname(), "*"); OutputKey_t(pCaller->GetClassname(), "*");
} }
std::vector<CallbackPair*> vecCallbackPairs; std::vector<CallbackPair*> vecCallbackPairs;
if (pCaller) { if (pCaller)
CSSHARP_CORE_TRACE("[EntityManager][FireOutputHook] - {}, {}", pThis->m_pDesc->m_pName, {
pCaller->GetClassname()); CSSHARP_CORE_TRACE("[EntityManager][FireOutputHook] - {}, {}", pThis->m_pDesc->m_pName, pCaller->GetClassname());
auto& hookMap = globals::entityManager.m_pHookMap; auto& hookMap = globals::entityManager.m_pHookMap;
for (auto& searchKey : vecSearchKeys) { for (auto& searchKey : vecSearchKeys)
{
auto search = hookMap.find(searchKey); auto search = hookMap.find(searchKey);
if (search != hookMap.end()) { if (search != hookMap.end())
{
vecCallbackPairs.push_back(search->second); vecCallbackPairs.push_back(search->second);
} }
} }
} else }
CSSHARP_CORE_TRACE("[EntityManager][FireOutputHook] - {}, unknown caller", else
pThis->m_pDesc->m_pName); CSSHARP_CORE_TRACE("[EntityManager][FireOutputHook] - {}, unknown caller", pThis->m_pDesc->m_pName);
HookResult result = HookResult::Continue; HookResult result = HookResult::Continue;
for (auto pCallbackPair : vecCallbackPairs) { for (auto pCallbackPair : vecCallbackPairs)
if (pCallbackPair->pre->GetFunctionCount()) { {
if (pCallbackPair->pre->GetFunctionCount())
{
pCallbackPair->pre->ScriptContext().Reset(); pCallbackPair->pre->ScriptContext().Reset();
pCallbackPair->pre->ScriptContext().Push(pThis); pCallbackPair->pre->ScriptContext().Push(pThis);
pCallbackPair->pre->ScriptContext().Push(pThis->m_pDesc->m_pName); pCallbackPair->pre->ScriptContext().Push(pThis->m_pDesc->m_pName);
@@ -236,32 +263,37 @@ void DetourFireOutputInternal(CEntityIOOutput* const pThis, CEntityInstance* pAc
pCallbackPair->pre->ScriptContext().Push(value); pCallbackPair->pre->ScriptContext().Push(value);
pCallbackPair->pre->ScriptContext().Push(flDelay); pCallbackPair->pre->ScriptContext().Push(flDelay);
for (auto fnMethodToCall : pCallbackPair->pre->GetFunctions()) { for (auto fnMethodToCall : pCallbackPair->pre->GetFunctions())
if (!fnMethodToCall) {
continue; if (!fnMethodToCall) continue;
fnMethodToCall(&pCallbackPair->pre->ScriptContextStruct()); fnMethodToCall(&pCallbackPair->pre->ScriptContextStruct());
auto thisResult = pCallbackPair->pre->ScriptContext().GetResult<HookResult>(); auto thisResult = pCallbackPair->pre->ScriptContext().GetResult<HookResult>();
if (thisResult >= HookResult::Stop) { if (thisResult >= HookResult::Stop)
{
return; return;
} }
if (thisResult > result) { if (thisResult > result)
{
result = thisResult; result = thisResult;
} }
} }
} }
} }
if (result >= HookResult::Handled) { if (result >= HookResult::Handled)
{
return; return;
} }
m_pFireOutputInternal(pThis, pActivator, pCaller, value, flDelay); m_pFireOutputInternal(pThis, pActivator, pCaller, value, flDelay);
for (auto pCallbackPair : vecCallbackPairs) { for (auto pCallbackPair : vecCallbackPairs)
if (pCallbackPair->post->GetFunctionCount()) { {
if (pCallbackPair->post->GetFunctionCount())
{
pCallbackPair->post->ScriptContext().Reset(); pCallbackPair->post->ScriptContext().Reset();
pCallbackPair->post->ScriptContext().Push(pThis); pCallbackPair->post->ScriptContext().Push(pThis);
pCallbackPair->post->ScriptContext().Push(pThis->m_pDesc->m_pName); pCallbackPair->post->ScriptContext().Push(pThis->m_pDesc->m_pName);
@@ -276,8 +308,10 @@ void DetourFireOutputInternal(CEntityIOOutput* const pThis, CEntityInstance* pAc
SndOpEventGuid_t EntityEmitSoundFilter(IRecipientFilter& filter, uint32 ent, const char* pszSound, float flVolume, float flPitch) SndOpEventGuid_t EntityEmitSoundFilter(IRecipientFilter& filter, uint32 ent, const char* pszSound, float flVolume, float flPitch)
{ {
if (!CBaseEntity_EmitSoundFilter) { if (!CBaseEntity_EmitSoundFilter)
CSSHARP_CORE_ERROR("[EntityManager][EmitSoundFilter] - Failed to emit a sound. Signature for \'CBaseEntity_EmitSoundFilter\' is not found. The latest update may have broken it."); {
CSSHARP_CORE_ERROR("[EntityManager][EmitSoundFilter] - Failed to emit a sound. Signature for \'CBaseEntity_EmitSoundFilter\' is "
"not found. The latest update may have broken it.");
return SndOpEventGuid_t{}; return SndOpEventGuid_t{};
} }

View File

@@ -1,18 +1,18 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
#pragma once #pragma once
@@ -34,24 +34,29 @@ class ScriptCallback;
typedef std::pair<std::string, std::string> OutputKey_t; typedef std::pair<std::string, std::string> OutputKey_t;
class CEntityListener : public IEntityListener { class CEntityListener : public IEntityListener
void OnEntitySpawned(CEntityInstance *pEntity) override; {
void OnEntityCreated(CEntityInstance *pEntity) override; void OnEntitySpawned(CEntityInstance* pEntity) override;
void OnEntityDeleted(CEntityInstance *pEntity) override; void OnEntityCreated(CEntityInstance* pEntity) override;
void OnEntityParentChanged(CEntityInstance *pEntity, CEntityInstance *pNewParent) override; void OnEntityDeleted(CEntityInstance* pEntity) override;
void OnEntityParentChanged(CEntityInstance* pEntity, CEntityInstance* pNewParent) override;
}; };
class CCheckTransmitInfoList { class CCheckTransmitInfoList
public: {
public:
CCheckTransmitInfoList(CCheckTransmitInfo** pInfoInfoList, int nInfoCount); CCheckTransmitInfoList(CCheckTransmitInfo** pInfoInfoList, int nInfoCount);
private:
private:
CCheckTransmitInfo** infoList; CCheckTransmitInfo** infoList;
int infoCount; int infoCount;
}; };
class EntityManager : public GlobalClass { class EntityManager : public GlobalClass
{
friend CEntityListener; friend CEntityListener;
public:
public:
EntityManager(); EntityManager();
~EntityManager(); ~EntityManager();
void OnAllInitialized() override; void OnAllInitialized() override;
@@ -60,19 +65,25 @@ public:
void UnhookEntityOutput(const char* szClassname, const char* szOutput, CallbackT fnCallback, HookMode mode); void UnhookEntityOutput(const char* szClassname, const char* szOutput, CallbackT fnCallback, HookMode mode);
CEntityListener entityListener; CEntityListener entityListener;
std::map<OutputKey_t, CallbackPair*> m_pHookMap; std::map<OutputKey_t, CallbackPair*> m_pHookMap;
private:
void CheckTransmit(CCheckTransmitInfo** pInfoInfoList, int nInfoCount, CBitVec<16384>& unionTransmitEdicts, const Entity2Networkable_t** pNetworkables, const uint16* pEntityIndicies, int nEntityIndices, bool bEnablePVSBits);
ScriptCallback *on_entity_spawned_callback; private:
ScriptCallback *on_entity_created_callback; void CheckTransmit(CCheckTransmitInfo** pInfoInfoList,
ScriptCallback *on_entity_deleted_callback; int nInfoCount,
ScriptCallback *on_entity_parent_changed_callback; CBitVec<16384>& unionTransmitEdicts,
ScriptCallback *check_transmit; const Entity2Networkable_t** pNetworkables,
const uint16* pEntityIndicies,
int nEntityIndices,
bool bEnablePVSBits);
ScriptCallback* on_entity_spawned_callback;
ScriptCallback* on_entity_created_callback;
ScriptCallback* on_entity_deleted_callback;
ScriptCallback* on_entity_parent_changed_callback;
ScriptCallback* check_transmit;
std::string m_profile_name; std::string m_profile_name;
}; };
enum EntityIOTargetType_t enum EntityIOTargetType_t
{ {
ENTITY_IO_TARGET_INVALID = 0xFFFFFFFF, ENTITY_IO_TARGET_INVALID = 0xFFFFFFFF,
@@ -118,16 +129,16 @@ class CEntityIOOutput
EntityIOOutputDesc_t* m_pDesc; EntityIOOutputDesc_t* m_pDesc;
}; };
typedef void (*FireOutputInternal)(CEntityIOOutput* const, CEntityInstance*, CEntityInstance*, typedef void (*FireOutputInternal)(CEntityIOOutput* const, CEntityInstance*, CEntityInstance*, const CVariant* const, float);
const CVariant* const, float);
static void DetourFireOutputInternal(CEntityIOOutput* const pThis, CEntityInstance* pActivator, static void DetourFireOutputInternal(
CEntityInstance* pCaller, const CVariant* const value, float flDelay); CEntityIOOutput* const pThis, CEntityInstance* pActivator, CEntityInstance* pCaller, const CVariant* const value, float flDelay);
static FireOutputInternal m_pFireOutputInternal = nullptr; static FireOutputInternal m_pFireOutputInternal = nullptr;
// Do it in here because i didn't found a good place to do this // Do it in here because i didn't found a good place to do this
inline void (*CEntityInstance_AcceptInput)(CEntityInstance* pThis, const char* pInputName, CEntityInstance* pActivator, CEntityInstance* pCaller, variant_t* value, int nOutputID); inline void (*CEntityInstance_AcceptInput)(
CEntityInstance* pThis, const char* pInputName, CEntityInstance* pActivator, CEntityInstance* pCaller, variant_t* value, int nOutputID);
inline void (*CEntitySystem_AddEntityIOEvent)(CEntitySystem* pEntitySystem, inline void (*CEntitySystem_AddEntityIOEvent)(CEntitySystem* pEntitySystem,
CEntityInstance* pTarget, CEntityInstance* pTarget,
@@ -142,66 +153,53 @@ typedef uint32 SoundEventGuid_t;
enum gender_t : uint8 enum gender_t : uint8
{ {
GENDER_NONE = 0x0, GENDER_NONE = 0x0,
GENDER_MALE = 0x1, GENDER_MALE = 0x1,
GENDER_FEMALE = 0x2, GENDER_FEMALE = 0x2,
GENDER_NAMVET = 0x3, GENDER_NAMVET = 0x3,
GENDER_TEENGIRL = 0x4, GENDER_TEENGIRL = 0x4,
GENDER_BIKER = 0x5, GENDER_BIKER = 0x5,
GENDER_MANAGER = 0x6, GENDER_MANAGER = 0x6,
GENDER_GAMBLER = 0x7, GENDER_GAMBLER = 0x7,
GENDER_PRODUCER = 0x8, GENDER_PRODUCER = 0x8,
GENDER_COACH = 0x9, GENDER_COACH = 0x9,
GENDER_MECHANIC = 0xA, GENDER_MECHANIC = 0xA,
GENDER_CEDA = 0xB, GENDER_CEDA = 0xB,
GENDER_CRAWLER = 0xC, GENDER_CRAWLER = 0xC,
GENDER_UNDISTRACTABLE = 0xD, GENDER_UNDISTRACTABLE = 0xD,
GENDER_FALLEN = 0xE, GENDER_FALLEN = 0xE,
GENDER_RIOT_CONTROL = 0xF, GENDER_RIOT_CONTROL = 0xF,
GENDER_CLOWN = 0x10, GENDER_CLOWN = 0x10,
GENDER_JIMMY = 0x11, GENDER_JIMMY = 0x11,
GENDER_HOSPITAL_PATIENT = 0x12, GENDER_HOSPITAL_PATIENT = 0x12,
GENDER_BRIDE = 0x13, GENDER_BRIDE = 0x13,
GENDER_LAST = 0x14, GENDER_LAST = 0x14,
}; };
struct EmitSound_t struct EmitSound_t
{ {
EmitSound_t() : EmitSound_t()
m_nChannel(0), : m_nChannel(0), m_pSoundName(0), m_flVolume(VOL_NORM), m_SoundLevel(SNDLVL_NONE), m_nFlags(0), m_nPitch(PITCH_NORM), m_pOrigin(0),
m_pSoundName(0), m_flSoundTime(0.0f), m_pflSoundDuration(0), m_bEmitCloseCaption(true), m_bWarnOnMissingCloseCaption(false),
m_flVolume(VOL_NORM), m_bWarnOnDirectWaveReference(false), m_nSpeakerEntity(-1), m_UtlVecSoundOrigin(), m_nForceGuid(0), m_SpeakerGender(GENDER_NONE)
m_SoundLevel(SNDLVL_NONE), {
m_nFlags(0), }
m_nPitch(PITCH_NORM), int m_nChannel;
m_pOrigin(0), const char* m_pSoundName;
m_flSoundTime(0.0f), float m_flVolume;
m_pflSoundDuration(0), soundlevel_t m_SoundLevel;
m_bEmitCloseCaption(true), int m_nFlags;
m_bWarnOnMissingCloseCaption(false), int m_nPitch;
m_bWarnOnDirectWaveReference(false), const Vector* m_pOrigin;
m_nSpeakerEntity(-1), float m_flSoundTime;
m_UtlVecSoundOrigin(), float* m_pflSoundDuration;
m_nForceGuid(0), bool m_bEmitCloseCaption;
m_SpeakerGender(GENDER_NONE) bool m_bWarnOnMissingCloseCaption;
{ bool m_bWarnOnDirectWaveReference;
} CEntityIndex m_nSpeakerEntity;
int m_nChannel; CUtlVector<Vector, CUtlMemory<Vector, int>> m_UtlVecSoundOrigin;
const char* m_pSoundName; SoundEventGuid_t m_nForceGuid;
float m_flVolume; gender_t m_SpeakerGender;
soundlevel_t m_SoundLevel;
int m_nFlags;
int m_nPitch;
const Vector* m_pOrigin;
float m_flSoundTime;
float* m_pflSoundDuration;
bool m_bEmitCloseCaption;
bool m_bWarnOnMissingCloseCaption;
bool m_bWarnOnDirectWaveReference;
CEntityIndex m_nSpeakerEntity;
CUtlVector<Vector, CUtlMemory<Vector, int> > m_UtlVecSoundOrigin;
SoundEventGuid_t m_nForceGuid;
gender_t m_SpeakerGender;
}; };
struct SndOpEventGuid_t struct SndOpEventGuid_t
@@ -212,5 +210,6 @@ struct SndOpEventGuid_t
inline SndOpEventGuid_t(FASTCALL* CBaseEntity_EmitSoundFilter)(IRecipientFilter& filter, CEntityIndex ent, const EmitSound_t& params); inline SndOpEventGuid_t(FASTCALL* CBaseEntity_EmitSoundFilter)(IRecipientFilter& filter, CEntityIndex ent, const EmitSound_t& params);
SndOpEventGuid_t EntityEmitSoundFilter(IRecipientFilter& filter, uint32 ent, const char* pszSound, float flVolume = 1.0f, float flPitch = 1.0f); SndOpEventGuid_t
} // namespace counterstrikesharp EntityEmitSoundFilter(IRecipientFilter& filter, uint32 ent, const char* pszSound, float flVolume = 1.0f, float flPitch = 1.0f);
} // namespace counterstrikesharp

View File

@@ -44,19 +44,15 @@
#include <iplayerinfo.h> #include <iplayerinfo.h>
// extern CEntitySystem *g_pEntitySystem; // extern CEntitySystem *g_pEntitySystem;
SH_DECL_HOOK4_void(IServerGameClients, ClientActive, SH_NOATTRIB, 0, CPlayerSlot, bool, const char*, SH_DECL_HOOK4_void(IServerGameClients, ClientActive, SH_NOATTRIB, 0, CPlayerSlot, bool, const char*, uint64);
uint64); SH_DECL_HOOK5_void(
SH_DECL_HOOK5_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, CPlayerSlot, IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, CPlayerSlot, ENetworkDisconnectionReason, const char*, uint64, const char*);
ENetworkDisconnectionReason, const char*, uint64, const char*);
SH_DECL_HOOK1_void(IServerGameClients, ClientVoice, SH_NOATTRIB, 0, CPlayerSlot); SH_DECL_HOOK1_void(IServerGameClients, ClientVoice, SH_NOATTRIB, 0, CPlayerSlot);
SH_DECL_HOOK4_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, CPlayerSlot, char const*, SH_DECL_HOOK4_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, CPlayerSlot, char const*, int, uint64);
int, uint64);
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, CPlayerSlot); SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, CPlayerSlot);
SH_DECL_HOOK6_void(IServerGameClients, OnClientConnected, SH_NOATTRIB, 0, CPlayerSlot, const char*, SH_DECL_HOOK6_void(IServerGameClients, OnClientConnected, SH_NOATTRIB, 0, CPlayerSlot, const char*, uint64, const char*, const char*, bool);
uint64, const char*, const char*, bool); SH_DECL_HOOK6(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, CPlayerSlot, const char*, uint64, const char*, bool, CBufferString*);
SH_DECL_HOOK6(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, CPlayerSlot, const char*,
uint64, const char*, bool, CBufferString*);
SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, CPlayerSlot, const CCommand&); SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, CPlayerSlot, const CCommand&);
@@ -66,48 +62,39 @@ void PlayerManager::OnStartup() {}
void PlayerManager::OnAllInitialized() void PlayerManager::OnAllInitialized()
{ {
SH_ADD_HOOK(IServerGameClients, ClientConnect, globals::serverGameClients, SH_ADD_HOOK(IServerGameClients, ClientConnect, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientConnect), false);
SH_MEMBER(this, &PlayerManager::OnClientConnect), false); SH_ADD_HOOK(IServerGameClients, ClientConnect, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientConnect_Post), true);
SH_ADD_HOOK(IServerGameClients, ClientConnect, globals::serverGameClients, SH_ADD_HOOK(IServerGameClients, ClientPutInServer, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientPutInServer),
SH_MEMBER(this, &PlayerManager::OnClientConnect_Post), true); true);
SH_ADD_HOOK(IServerGameClients, ClientPutInServer, globals::serverGameClients, SH_ADD_HOOK(IServerGameClients, ClientDisconnect, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientDisconnect),
SH_MEMBER(this, &PlayerManager::OnClientPutInServer), true); false);
SH_ADD_HOOK(IServerGameClients, ClientDisconnect, globals::serverGameClients, SH_ADD_HOOK(IServerGameClients, ClientDisconnect, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientDisconnect_Post),
SH_MEMBER(this, &PlayerManager::OnClientDisconnect), false); true);
SH_ADD_HOOK(IServerGameClients, ClientDisconnect, globals::serverGameClients, SH_ADD_HOOK(IServerGameClients, ClientCommand, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientCommand), false);
SH_MEMBER(this, &PlayerManager::OnClientDisconnect_Post), true); SH_ADD_HOOK(IServerGameClients, ClientVoice, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientVoice), true);
SH_ADD_HOOK(IServerGameClients, ClientCommand, globals::serverGameClients,
SH_MEMBER(this, &PlayerManager::OnClientCommand), false);
SH_ADD_HOOK(IServerGameClients, ClientVoice, globals::serverGameClients,
SH_MEMBER(this, &PlayerManager::OnClientVoice), true);
m_on_client_connect_callback = globals::callbackManager.CreateCallback("OnClientConnect"); m_on_client_connect_callback = globals::callbackManager.CreateCallback("OnClientConnect");
m_on_client_connected_callback = globals::callbackManager.CreateCallback("OnClientConnected"); m_on_client_connected_callback = globals::callbackManager.CreateCallback("OnClientConnected");
m_on_client_put_in_server_callback = m_on_client_put_in_server_callback = globals::callbackManager.CreateCallback("OnClientPutInServer");
globals::callbackManager.CreateCallback("OnClientPutInServer");
m_on_client_disconnect_callback = globals::callbackManager.CreateCallback("OnClientDisconnect"); m_on_client_disconnect_callback = globals::callbackManager.CreateCallback("OnClientDisconnect");
m_on_client_disconnect_post_callback = m_on_client_disconnect_post_callback = globals::callbackManager.CreateCallback("OnClientDisconnectPost");
globals::callbackManager.CreateCallback("OnClientDisconnectPost");
m_on_client_voice_callback = globals::callbackManager.CreateCallback("OnClientVoice"); m_on_client_voice_callback = globals::callbackManager.CreateCallback("OnClientVoice");
m_on_client_authorized_callback = globals::callbackManager.CreateCallback("OnClientAuthorized"); m_on_client_authorized_callback = globals::callbackManager.CreateCallback("OnClientAuthorized");
} }
void PlayerManager::OnShutdown() void PlayerManager::OnShutdown()
{ {
SH_REMOVE_HOOK(IServerGameClients, ClientConnect, globals::serverGameClients, SH_REMOVE_HOOK(IServerGameClients, ClientConnect, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientConnect), false);
SH_MEMBER(this, &PlayerManager::OnClientConnect), false); SH_REMOVE_HOOK(IServerGameClients, ClientConnect, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientConnect_Post),
SH_REMOVE_HOOK(IServerGameClients, ClientConnect, globals::serverGameClients, true);
SH_MEMBER(this, &PlayerManager::OnClientConnect_Post), true); SH_REMOVE_HOOK(IServerGameClients, ClientPutInServer, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientPutInServer),
SH_REMOVE_HOOK(IServerGameClients, ClientPutInServer, globals::serverGameClients, true);
SH_MEMBER(this, &PlayerManager::OnClientPutInServer), true); SH_REMOVE_HOOK(IServerGameClients, ClientDisconnect, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientDisconnect),
SH_REMOVE_HOOK(IServerGameClients, ClientDisconnect, globals::serverGameClients, false);
SH_MEMBER(this, &PlayerManager::OnClientDisconnect), false);
SH_REMOVE_HOOK(IServerGameClients, ClientDisconnect, globals::serverGameClients, SH_REMOVE_HOOK(IServerGameClients, ClientDisconnect, globals::serverGameClients,
SH_MEMBER(this, &PlayerManager::OnClientDisconnect_Post), true); SH_MEMBER(this, &PlayerManager::OnClientDisconnect_Post), true);
SH_REMOVE_HOOK(IServerGameClients, ClientCommand, globals::serverGameClients, SH_REMOVE_HOOK(IServerGameClients, ClientCommand, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientCommand), false);
SH_MEMBER(this, &PlayerManager::OnClientCommand), false); SH_REMOVE_HOOK(IServerGameClients, ClientVoice, globals::serverGameClients, SH_MEMBER(this, &PlayerManager::OnClientVoice), true);
SH_REMOVE_HOOK(IServerGameClients, ClientVoice, globals::serverGameClients,
SH_MEMBER(this, &PlayerManager::OnClientVoice), true);
globals::callbackManager.ReleaseCallback(m_on_client_connect_callback); globals::callbackManager.ReleaseCallback(m_on_client_connect_callback);
globals::callbackManager.ReleaseCallback(m_on_client_connected_callback); globals::callbackManager.ReleaseCallback(m_on_client_connected_callback);
@@ -118,21 +105,18 @@ void PlayerManager::OnShutdown()
globals::callbackManager.ReleaseCallback(m_on_client_voice_callback); globals::callbackManager.ReleaseCallback(m_on_client_voice_callback);
} }
bool PlayerManager::OnClientConnect(CPlayerSlot slot, const char* pszName, uint64 xuid, bool PlayerManager::OnClientConnect(
const char* pszNetworkID, bool unk1, CPlayerSlot slot, const char* pszName, uint64 xuid, const char* pszNetworkID, bool unk1, CBufferString* pRejectReason)
CBufferString* pRejectReason)
{ {
CSSHARP_CORE_TRACE("[PlayerManager][OnClientConnect] - {}, {}, {}", slot.Get(), pszName, CSSHARP_CORE_TRACE("[PlayerManager][OnClientConnect] - {}, {}, {}", slot.Get(), pszName, pszNetworkID);
pszNetworkID);
int client = slot.Get(); int client = slot.Get();
CPlayer* pPlayer = &m_players[client]; CPlayer* pPlayer = &m_players[client];
if (pPlayer->IsConnected()) { if (pPlayer->IsConnected())
OnClientDisconnect(slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, pszName, {
xuid, pszNetworkID); OnClientDisconnect(slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, pszName, xuid, pszNetworkID);
OnClientDisconnect_Post(slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, OnClientDisconnect_Post(slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, pszName, xuid, pszNetworkID);
pszName, xuid, pszNetworkID);
} }
pPlayer->Initialize(pszName, pszNetworkID, slot); pPlayer->Initialize(pszName, pszNetworkID, slot);
@@ -143,7 +127,8 @@ bool PlayerManager::OnClientConnect(CPlayerSlot slot, const char* pszName, uint6
m_on_client_connect_callback->ScriptContext().Push(pszNetworkID); m_on_client_connect_callback->ScriptContext().Push(pszNetworkID);
m_on_client_connect_callback->Execute(); m_on_client_connect_callback->Execute();
if (m_on_client_connect_callback->GetFunctionCount() > 0) { if (m_on_client_connect_callback->GetFunctionCount() > 0)
{
// auto cancel = m_on_client_connect_callback->ScriptContext().GetArgument<bool>(0); // auto cancel = m_on_client_connect_callback->ScriptContext().GetArgument<bool>(0);
// auto cancelReason = // auto cancelReason =
// m_on_client_connect_callback->ScriptContext().GetArgument<const char *>(1); // m_on_client_connect_callback->ScriptContext().GetArgument<const char *>(1);
@@ -167,47 +152,47 @@ bool PlayerManager::OnClientConnect(CPlayerSlot slot, const char* pszName, uint6
return true; return true;
} }
bool PlayerManager::OnClientConnect_Post(CPlayerSlot slot, const char* pszName, uint64 xuid, bool PlayerManager::OnClientConnect_Post(
const char* pszNetworkID, bool unk1, CPlayerSlot slot, const char* pszName, uint64 xuid, const char* pszNetworkID, bool unk1, CBufferString* pRejectReason)
CBufferString* pRejectReason)
{ {
CSSHARP_CORE_TRACE("[PlayerManager][OnClientConnect_Post] - {}, {}, {}", slot.Get(), pszName, CSSHARP_CORE_TRACE("[PlayerManager][OnClientConnect_Post] - {}, {}, {}", slot.Get(), pszName, pszNetworkID);
pszNetworkID);
int client = slot.Get(); int client = slot.Get();
bool orig_value = META_RESULT_ORIG_RET(bool); bool orig_value = META_RESULT_ORIG_RET(bool);
CPlayer* pPlayer = &m_players[client]; CPlayer* pPlayer = &m_players[client];
if (orig_value) { if (orig_value)
{
m_on_client_connected_callback->ScriptContext().Reset(); m_on_client_connected_callback->ScriptContext().Reset();
m_on_client_connected_callback->ScriptContext().Push(pPlayer->m_slot.Get()); m_on_client_connected_callback->ScriptContext().Push(pPlayer->m_slot.Get());
m_on_client_connected_callback->Execute(); m_on_client_connected_callback->Execute();
if (!pPlayer->IsFakeClient() && m_is_listen_server && if (!pPlayer->IsFakeClient() && m_is_listen_server && strncmp(pszNetworkID, "127.0.0.1", 9) == 0)
strncmp(pszNetworkID, "127.0.0.1", 9) == 0) { {
m_listen_client = client; m_listen_client = client;
} }
} else { }
else
{
InvalidatePlayer(pPlayer); InvalidatePlayer(pPlayer);
} }
return true; return true;
} }
void PlayerManager::OnClientPutInServer(CPlayerSlot slot, char const* pszName, int type, void PlayerManager::OnClientPutInServer(CPlayerSlot slot, char const* pszName, int type, uint64 xuid)
uint64 xuid)
{ {
CSSHARP_CORE_TRACE("[PlayerManager][OnClientPutInServer] - {}, {}, {}", slot.Get(), pszName, CSSHARP_CORE_TRACE("[PlayerManager][OnClientPutInServer] - {}, {}, {}", slot.Get(), pszName, type);
type);
int client = slot.Get(); int client = slot.Get();
CPlayer* pPlayer = &m_players[client]; CPlayer* pPlayer = &m_players[client];
if (!pPlayer->IsConnected()) { if (!pPlayer->IsConnected())
{
pPlayer->m_is_fake_client = true; pPlayer->m_is_fake_client = true;
if (!OnClientConnect(slot, pszName, 0, "127.0.0.1", false, if (!OnClientConnect(slot, pszName, 0, "127.0.0.1", false, new CBufferStringGrowable<255>()))
new CBufferStringGrowable<255>())) { {
/* :TODO: kick the bot if it's rejected */ /* :TODO: kick the bot if it's rejected */
return; return;
} }
@@ -233,39 +218,39 @@ void PlayerManager::OnClientPutInServer(CPlayerSlot slot, char const* pszName, i
m_on_client_put_in_server_callback->Execute(); m_on_client_put_in_server_callback->Execute();
} }
void PlayerManager::OnClientDisconnect(CPlayerSlot slot, ENetworkDisconnectionReason reason, void PlayerManager::OnClientDisconnect(
const char* pszName, uint64 xuid, const char* pszNetworkID) CPlayerSlot slot, ENetworkDisconnectionReason reason, const char* pszName, uint64 xuid, const char* pszNetworkID)
{ {
CSSHARP_CORE_TRACE("[PlayerManager][OnClientDisconnect] - {}, {}, {}", slot.Get(), pszName, CSSHARP_CORE_TRACE("[PlayerManager][OnClientDisconnect] - {}, {}, {}", slot.Get(), pszName, pszNetworkID);
pszNetworkID);
int client = slot.Get(); int client = slot.Get();
CPlayer* pPlayer = &m_players[client]; CPlayer* pPlayer = &m_players[client];
if (pPlayer->IsConnected()) { if (pPlayer->IsConnected())
{
m_on_client_disconnect_callback->ScriptContext().Reset(); m_on_client_disconnect_callback->ScriptContext().Reset();
m_on_client_disconnect_callback->ScriptContext().Push(pPlayer->m_slot.Get()); m_on_client_disconnect_callback->ScriptContext().Push(pPlayer->m_slot.Get());
m_on_client_disconnect_callback->ScriptContext().Push(reason); m_on_client_disconnect_callback->ScriptContext().Push(reason);
m_on_client_disconnect_callback->Execute(); m_on_client_disconnect_callback->Execute();
} }
if (pPlayer->WasCountedAsInGame()) { if (pPlayer->WasCountedAsInGame())
{
m_player_count--; m_player_count--;
} }
// globals::entityListener.HandleEntityDeleted(pPlayer->GetBaseEntity(), client); // globals::entityListener.HandleEntityDeleted(pPlayer->GetBaseEntity(), client);
} }
void PlayerManager::OnClientDisconnect_Post(CPlayerSlot slot, ENetworkDisconnectionReason reason, void PlayerManager::OnClientDisconnect_Post(
const char* pszName, uint64 xuid, CPlayerSlot slot, ENetworkDisconnectionReason reason, const char* pszName, uint64 xuid, const char* pszNetworkID) const
const char* pszNetworkID) const
{ {
CSSHARP_CORE_TRACE("[PlayerManager][OnClientDisconnect_Post] - {}, {}, {}", slot.Get(), pszName, CSSHARP_CORE_TRACE("[PlayerManager][OnClientDisconnect_Post] - {}, {}, {}", slot.Get(), pszName, pszNetworkID);
pszNetworkID);
int client = slot.Get(); int client = slot.Get();
CPlayer* pPlayer = &m_players[client]; CPlayer* pPlayer = &m_players[client];
if (!pPlayer->IsConnected()) { if (!pPlayer->IsConnected())
{
/* We don't care, prevent a double call */ /* We don't care, prevent a double call */
return; return;
} }
@@ -291,14 +276,14 @@ void PlayerManager::OnLevelEnd()
{ {
CSSHARP_CORE_TRACE("[PlayerManager][OnLevelEnd]"); CSSHARP_CORE_TRACE("[PlayerManager][OnLevelEnd]");
for (int i = 0; i <= MaxClients(); i++) { for (int i = 0; i <= MaxClients(); i++)
if (m_players[i].IsConnected()) { {
OnClientDisconnect(m_players[i].m_slot, if (m_players[i].IsConnected())
ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, {
m_players[i].GetName(), 0, m_players[i].GetIpAddress()); OnClientDisconnect(m_players[i].m_slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, m_players[i].GetName(), 0,
OnClientDisconnect_Post(m_players[i].m_slot, m_players[i].GetIpAddress());
ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, OnClientDisconnect_Post(m_players[i].m_slot, ENetworkDisconnectionReason::NETWORK_DISCONNECT_INVALID, m_players[i].GetName(), 0,
m_players[i].GetName(), 0, m_players[i].GetIpAddress()); m_players[i].GetIpAddress());
} }
} }
m_player_count = 0; m_player_count = 0;
@@ -306,17 +291,17 @@ void PlayerManager::OnLevelEnd()
void PlayerManager::OnClientCommand(CPlayerSlot slot, const CCommand& args) const void PlayerManager::OnClientCommand(CPlayerSlot slot, const CCommand& args) const
{ {
CSSHARP_CORE_TRACE("[PlayerManager][OnClientCommand] - {}, {}, {}", slot.Get(), args.Arg(0), CSSHARP_CORE_TRACE("[PlayerManager][OnClientCommand] - {}, {}, {}", slot.Get(), args.Arg(0), (void*)&args);
(void*)&args);
const char* cmd = args.Arg(0); const char* cmd = args.Arg(0);
globals::voiceManager.OnClientCommand(slot, args); globals::voiceManager.OnClientCommand(slot, args);
auto result = globals::conCommandManager.ExecuteCommandCallbacks( auto result = globals::conCommandManager.ExecuteCommandCallbacks(cmd, CCommandContext(CommandTarget_t::CT_NO_TARGET, slot), args,
cmd, CCommandContext(CommandTarget_t::CT_NO_TARGET, slot), args, HookMode::Pre, CommandCallingContext::Console); HookMode::Pre, CommandCallingContext::Console);
if (result >= HookResult::Handled) { if (result >= HookResult::Handled)
{
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
} }
@@ -329,7 +314,8 @@ int PlayerManager::MaxClients() const { return globals::getGlobalVars()->maxClie
CPlayer* PlayerManager::GetPlayerBySlot(int client) const CPlayer* PlayerManager::GetPlayerBySlot(int client) const
{ {
if (client > MaxClients() || client < 0) { if (client > MaxClients() || client < 0)
{
return nullptr; return nullptr;
} }
@@ -378,8 +364,7 @@ CPlayer* PlayerManager::GetPlayerBySlot(int client) const
void PlayerManager::InvalidatePlayer(CPlayer* pPlayer) const void PlayerManager::InvalidatePlayer(CPlayer* pPlayer) const
{ {
auto userid = globals::engine->GetPlayerUserId(pPlayer->m_slot); auto userid = globals::engine->GetPlayerUserId(pPlayer->m_slot);
if (userid.Get() != -1) if (userid.Get() != -1) m_user_id_lookup[userid.Get()] = 0;
m_user_id_lookup[userid.Get()] = 0;
pPlayer->Disconnect(); pPlayer->Disconnect();
} }
@@ -406,7 +391,8 @@ bool CPlayer::IsAuthorized() const { return m_is_authorized; }
bool CPlayer::IsAuthStringValidated() const bool CPlayer::IsAuthStringValidated() const
{ {
if (!IsFakeClient()) { if (!IsFakeClient())
{
return globals::engine->IsClientFullyAuthenticated(m_slot); return globals::engine->IsClientFullyAuthenticated(m_slot);
} }
return false; return false;
@@ -416,12 +402,14 @@ void CPlayer::Authorize() { m_is_authorized = true; }
void CPlayer::PrintToConsole(const char* message) const void CPlayer::PrintToConsole(const char* message) const
{ {
if (m_is_connected == false || m_is_fake_client == true) { if (m_is_connected == false || m_is_fake_client == true)
{
return; return;
} }
INetChannelInfo* pNetChan = globals::engine->GetPlayerNetInfo(m_slot); INetChannelInfo* pNetChan = globals::engine->GetPlayerNetInfo(m_slot);
if (pNetChan == nullptr) { if (pNetChan == nullptr)
{
return; return;
} }
@@ -457,18 +445,21 @@ PlayerManager::PlayerManager()
void PlayerManager::RunAuthChecks() void PlayerManager::RunAuthChecks()
{ {
if (globals::timerSystem.GetTickedTime() - m_last_auth_check_time < 0.5F) { if (globals::timerSystem.GetTickedTime() - m_last_auth_check_time < 0.5F)
{
return; return;
} }
m_last_auth_check_time = globals::timerSystem.GetTickedTime(); m_last_auth_check_time = globals::timerSystem.GetTickedTime();
for (int i = 0; i <= MaxClients(); i++) { for (int i = 0; i <= MaxClients(); i++)
if (m_players[i].IsConnected()) { {
if (m_players[i].IsAuthorized() || m_players[i].IsFakeClient()) if (m_players[i].IsConnected())
continue; {
if (m_players[i].IsAuthorized() || m_players[i].IsFakeClient()) continue;
if (globals::engine->IsClientFullyAuthenticated(i)) { if (globals::engine->IsClientFullyAuthenticated(i))
{
m_players[i].Authorize(); m_players[i].Authorize();
m_players[i].SetSteamId(globals::engine->GetClientSteamID(i)); m_players[i].SetSteamId(globals::engine->GetClientSteamID(i));
OnAuthorized(&m_players[i]); OnAuthorized(&m_players[i]);
@@ -479,8 +470,7 @@ void PlayerManager::RunAuthChecks()
void PlayerManager::OnAuthorized(CPlayer* player) const void PlayerManager::OnAuthorized(CPlayer* player) const
{ {
CSSHARP_CORE_TRACE("[PlayerManager][OnAuthorized] - {} {}", player->GetName(), CSSHARP_CORE_TRACE("[PlayerManager][OnAuthorized] - {} {}", player->GetName(), player->GetSteamId()->ConvertToUint64());
player->GetSteamId()->ConvertToUint64());
m_on_client_authorized_callback->ScriptContext().Reset(); m_on_client_authorized_callback->ScriptContext().Reset();
m_on_client_authorized_callback->ScriptContext().Push(player->m_slot.Get()); m_on_client_authorized_callback->ScriptContext().Push(player->m_slot.Get());
@@ -492,7 +482,8 @@ bool CPlayer::WasCountedAsInGame() const { return m_is_in_game; }
int CPlayer::GetUserId() int CPlayer::GetUserId()
{ {
if (m_user_id == -1) { if (m_user_id == -1)
{
m_user_id = globals::engine->GetPlayerUserId(m_slot).Get(); m_user_id = globals::engine->GetPlayerUserId(m_slot).Get();
} }
@@ -523,10 +514,7 @@ int CPlayer::GetFrags() const { return m_info->GetFragCount(); }
int CPlayer::GetDeaths() const { return m_info->GetDeathCount(); } int CPlayer::GetDeaths() const { return m_info->GetDeathCount(); }
const char* CPlayer::GetKeyValue(const char* key) const const char* CPlayer::GetKeyValue(const char* key) const { return globals::engine->GetClientConVarValue(m_slot, key); }
{
return globals::engine->GetClientConVarValue(m_slot, key);
}
Vector CPlayer::GetMaxSize() const { return m_info->GetPlayerMaxs(); } Vector CPlayer::GetMaxSize() const { return m_info->GetPlayerMaxs(); }
@@ -542,17 +530,15 @@ int CPlayer::GetUserId() const { return m_user_id; }
float CPlayer::GetTimeConnected() const float CPlayer::GetTimeConnected() const
{ {
if (!IsConnected() || IsFakeClient()) { if (!IsConnected() || IsFakeClient())
{
return 0; return 0;
} }
return GetNetInfo()->GetTimeConnected(); return GetNetInfo()->GetTimeConnected();
} }
void CPlayer::SetListen(CPlayerSlot slot, ListenOverride listen) void CPlayer::SetListen(CPlayerSlot slot, ListenOverride listen) { m_listenMap[slot.Get()] = listen; }
{
m_listenMap[slot.Get()] = listen;
}
void CPlayer::SetVoiceFlags(VoiceFlag_t flags) { m_voiceFlag = flags; } void CPlayer::SetVoiceFlags(VoiceFlag_t flags) { m_voiceFlag = flags; }
@@ -562,7 +548,8 @@ ListenOverride CPlayer::GetListen(CPlayerSlot slot) const { return m_listenMap[s
void CPlayer::Connect() void CPlayer::Connect()
{ {
if (m_is_in_game) { if (m_is_in_game)
{
return; return;
} }
@@ -590,7 +577,8 @@ Vector CPlayer::GetAbsOrigin() const { return m_info->GetAbsOrigin(); }
bool CPlayer::IsAlive() const bool CPlayer::IsAlive() const
{ {
if (!IsInGame()) { if (!IsInGame())
{
return false; return false;
} }
@@ -599,4 +587,4 @@ bool CPlayer::IsAlive() const
const CSteamID* CPlayer::GetSteamId() { return m_steamId; } const CSteamID* CPlayer::GetSteamId() { return m_steamId; }
void CPlayer::SetSteamId(const CSteamID* steam_id) { m_steamId = steam_id; } void CPlayer::SetSteamId(const CSteamID* steam_id) { m_steamId = steam_id; }
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -143,15 +143,15 @@ class PlayerManager : public GlobalClass
PlayerManager(); PlayerManager();
void OnStartup() override; void OnStartup() override;
void OnAllInitialized() override; void OnAllInitialized() override;
bool OnClientConnect(CPlayerSlot slot, const char* pszName, uint64 xuid, bool
const char* pszNetworkID, bool unk1, CBufferString* pRejectReason); OnClientConnect(CPlayerSlot slot, const char* pszName, uint64 xuid, const char* pszNetworkID, bool unk1, CBufferString* pRejectReason);
bool OnClientConnect_Post(CPlayerSlot slot, const char* pszName, uint64 xuid, bool OnClientConnect_Post(
const char* pszNetworkID, bool unk1, CBufferString* pRejectReason); CPlayerSlot slot, const char* pszName, uint64 xuid, const char* pszNetworkID, bool unk1, CBufferString* pRejectReason);
void OnClientPutInServer(CPlayerSlot slot, char const* pszName, int type, uint64 xuid); void OnClientPutInServer(CPlayerSlot slot, char const* pszName, int type, uint64 xuid);
void OnClientDisconnect(CPlayerSlot slot, ENetworkDisconnectionReason reason, void
const char* pszName, uint64 xuid, const char* pszNetworkID); OnClientDisconnect(CPlayerSlot slot, ENetworkDisconnectionReason reason, const char* pszName, uint64 xuid, const char* pszNetworkID);
void OnClientDisconnect_Post(CPlayerSlot slot, ENetworkDisconnectionReason reason, void OnClientDisconnect_Post(
const char* pszName, uint64 xuid, const char* pszNetworkID) const; CPlayerSlot slot, ENetworkDisconnectionReason reason, const char* pszName, uint64 xuid, const char* pszNetworkID) const;
void OnClientVoice(CPlayerSlot slot) const; void OnClientVoice(CPlayerSlot slot) const;
void OnAuthorized(CPlayer* player) const; void OnAuthorized(CPlayer* player) const;
void OnServerActivate(edict_t* pEdictList, int edictCount, int clientMax) const; void OnServerActivate(edict_t* pEdictList, int edictCount, int clientMax) const;
@@ -188,4 +188,4 @@ class PlayerManager : public GlobalClass
ScriptCallback* m_on_client_authorized_callback; ScriptCallback* m_on_client_authorized_callback;
}; };
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -1,18 +1,18 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
#include "core/managers/server_manager.h" #include "core/managers/server_manager.h"
@@ -36,21 +36,17 @@ ServerManager::ServerManager() = default;
ServerManager::~ServerManager() = default; ServerManager::~ServerManager() = default;
void ServerManager::OnAllInitialized() { void ServerManager::OnAllInitialized()
SH_ADD_HOOK(ISource2Server, ServerHibernationUpdate, globals::server, {
SH_MEMBER(this, &ServerManager::ServerHibernationUpdate), true); SH_ADD_HOOK(ISource2Server, ServerHibernationUpdate, globals::server, SH_MEMBER(this, &ServerManager::ServerHibernationUpdate), true);
SH_ADD_HOOK(ISource2Server, GameServerSteamAPIActivated, globals::server, SH_ADD_HOOK(ISource2Server, GameServerSteamAPIActivated, globals::server, SH_MEMBER(this, &ServerManager::GameServerSteamAPIActivated),
SH_MEMBER(this, &ServerManager::GameServerSteamAPIActivated), true); true);
SH_ADD_HOOK(ISource2Server, GameServerSteamAPIDeactivated, globals::server, SH_ADD_HOOK(ISource2Server, GameServerSteamAPIDeactivated, globals::server,
SH_MEMBER(this, &ServerManager::GameServerSteamAPIDeactivated), true); SH_MEMBER(this, &ServerManager::GameServerSteamAPIDeactivated), true);
SH_ADD_HOOK(ISource2Server, OnHostNameChanged, globals::server, SH_ADD_HOOK(ISource2Server, OnHostNameChanged, globals::server, SH_MEMBER(this, &ServerManager::OnHostNameChanged), true);
SH_MEMBER(this, &ServerManager::OnHostNameChanged), true); SH_ADD_HOOK(ISource2Server, PreFatalShutdown, globals::server, SH_MEMBER(this, &ServerManager::PreFatalShutdown), true);
SH_ADD_HOOK(ISource2Server, PreFatalShutdown, globals::server, SH_ADD_HOOK(ISource2Server, UpdateWhenNotInGame, globals::server, SH_MEMBER(this, &ServerManager::UpdateWhenNotInGame), true);
SH_MEMBER(this, &ServerManager::PreFatalShutdown), true); SH_ADD_HOOK(ISource2Server, PreWorldUpdate, globals::server, SH_MEMBER(this, &ServerManager::PreWorldUpdate), true);
SH_ADD_HOOK(ISource2Server, UpdateWhenNotInGame, globals::server,
SH_MEMBER(this, &ServerManager::UpdateWhenNotInGame), true);
SH_ADD_HOOK(ISource2Server, PreWorldUpdate, globals::server,
SH_MEMBER(this, &ServerManager::PreWorldUpdate), true);
on_server_hibernation_update_callback = globals::callbackManager.CreateCallback("OnServerHibernationUpdate"); on_server_hibernation_update_callback = globals::callbackManager.CreateCallback("OnServerHibernationUpdate");
on_server_steam_api_activated_callback = globals::callbackManager.CreateCallback("OnGameServerSteamAPIActivated"); on_server_steam_api_activated_callback = globals::callbackManager.CreateCallback("OnGameServerSteamAPIActivated");
@@ -63,21 +59,18 @@ void ServerManager::OnAllInitialized() {
on_server_precache_resources = globals::callbackManager.CreateCallback("OnServerPrecacheResources"); on_server_precache_resources = globals::callbackManager.CreateCallback("OnServerPrecacheResources");
} }
void ServerManager::OnShutdown() { void ServerManager::OnShutdown()
SH_REMOVE_HOOK(ISource2Server, ServerHibernationUpdate, globals::server, {
SH_MEMBER(this, &ServerManager::ServerHibernationUpdate), true); SH_REMOVE_HOOK(ISource2Server, ServerHibernationUpdate, globals::server, SH_MEMBER(this, &ServerManager::ServerHibernationUpdate),
true);
SH_REMOVE_HOOK(ISource2Server, GameServerSteamAPIActivated, globals::server, SH_REMOVE_HOOK(ISource2Server, GameServerSteamAPIActivated, globals::server,
SH_MEMBER(this, &ServerManager::GameServerSteamAPIActivated), true); SH_MEMBER(this, &ServerManager::GameServerSteamAPIActivated), true);
SH_REMOVE_HOOK(ISource2Server, GameServerSteamAPIDeactivated, globals::server, SH_REMOVE_HOOK(ISource2Server, GameServerSteamAPIDeactivated, globals::server,
SH_MEMBER(this, &ServerManager::GameServerSteamAPIDeactivated), true); SH_MEMBER(this, &ServerManager::GameServerSteamAPIDeactivated), true);
SH_REMOVE_HOOK(ISource2Server, OnHostNameChanged, globals::server, SH_REMOVE_HOOK(ISource2Server, OnHostNameChanged, globals::server, SH_MEMBER(this, &ServerManager::OnHostNameChanged), true);
SH_MEMBER(this, &ServerManager::OnHostNameChanged), true); SH_REMOVE_HOOK(ISource2Server, PreFatalShutdown, globals::server, SH_MEMBER(this, &ServerManager::PreFatalShutdown), true);
SH_REMOVE_HOOK(ISource2Server, PreFatalShutdown, globals::server, SH_REMOVE_HOOK(ISource2Server, UpdateWhenNotInGame, globals::server, SH_MEMBER(this, &ServerManager::UpdateWhenNotInGame), true);
SH_MEMBER(this, &ServerManager::PreFatalShutdown), true); SH_REMOVE_HOOK(ISource2Server, PreWorldUpdate, globals::server, SH_MEMBER(this, &ServerManager::PreWorldUpdate), true);
SH_REMOVE_HOOK(ISource2Server, UpdateWhenNotInGame, globals::server,
SH_MEMBER(this, &ServerManager::UpdateWhenNotInGame), true);
SH_REMOVE_HOOK(ISource2Server, PreWorldUpdate, globals::server,
SH_MEMBER(this, &ServerManager::PreWorldUpdate), true);
globals::callbackManager.ReleaseCallback(on_server_hibernation_update_callback); globals::callbackManager.ReleaseCallback(on_server_hibernation_update_callback);
globals::callbackManager.ReleaseCallback(on_server_steam_api_activated_callback); globals::callbackManager.ReleaseCallback(on_server_steam_api_activated_callback);
@@ -86,19 +79,13 @@ void ServerManager::OnShutdown() {
globals::callbackManager.ReleaseCallback(on_server_pre_fatal_shutdown); globals::callbackManager.ReleaseCallback(on_server_pre_fatal_shutdown);
globals::callbackManager.ReleaseCallback(on_server_update_when_not_in_game); globals::callbackManager.ReleaseCallback(on_server_update_when_not_in_game);
globals::callbackManager.ReleaseCallback(on_server_pre_world_update); globals::callbackManager.ReleaseCallback(on_server_pre_world_update);
globals::callbackManager.ReleaseCallback(on_server_precache_resources); globals::callbackManager.ReleaseCallback(on_server_precache_resources);
} }
void* ServerManager::GetEconItemSystem() void* ServerManager::GetEconItemSystem() { return globals::server->GetEconItemSystem(); }
{
return globals::server->GetEconItemSystem();
}
bool ServerManager::IsPaused() bool ServerManager::IsPaused() { return globals::server->IsPaused(); }
{
return globals::server->IsPaused();
}
void ServerManager::ServerHibernationUpdate(bool bHibernating) void ServerManager::ServerHibernationUpdate(bool bHibernating)
{ {
@@ -106,7 +93,8 @@ void ServerManager::ServerHibernationUpdate(bool bHibernating)
auto callback = globals::serverManager.on_server_hibernation_update_callback; auto callback = globals::serverManager.on_server_hibernation_update_callback;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->ScriptContext().Push(bHibernating); callback->ScriptContext().Push(bHibernating);
callback->Execute(); callback->Execute();
@@ -119,7 +107,8 @@ void ServerManager::GameServerSteamAPIActivated()
auto callback = globals::serverManager.on_server_steam_api_activated_callback; auto callback = globals::serverManager.on_server_steam_api_activated_callback;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->Execute(); callback->Execute();
} }
@@ -131,19 +120,21 @@ void ServerManager::GameServerSteamAPIDeactivated()
auto callback = globals::serverManager.on_server_steam_api_deactivated_callback; auto callback = globals::serverManager.on_server_steam_api_deactivated_callback;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->Execute(); callback->Execute();
} }
} }
void ServerManager::OnHostNameChanged(const char *pHostname) void ServerManager::OnHostNameChanged(const char* pHostname)
{ {
CSSHARP_CORE_TRACE("Server hostname changed {0}", pHostname); CSSHARP_CORE_TRACE("Server hostname changed {0}", pHostname);
auto callback = globals::serverManager.on_server_hostname_changed_callback; auto callback = globals::serverManager.on_server_hostname_changed_callback;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->ScriptContext().Push(pHostname); callback->ScriptContext().Push(pHostname);
callback->Execute(); callback->Execute();
@@ -156,7 +147,8 @@ void ServerManager::PreFatalShutdown()
auto callback = globals::serverManager.on_server_pre_fatal_shutdown; auto callback = globals::serverManager.on_server_pre_fatal_shutdown;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->Execute(); callback->Execute();
} }
@@ -168,7 +160,8 @@ void ServerManager::UpdateWhenNotInGame(float flFrameTime)
auto callback = globals::serverManager.on_server_update_when_not_in_game; auto callback = globals::serverManager.on_server_update_when_not_in_game;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->ScriptContext().Push(flFrameTime); callback->ScriptContext().Push(flFrameTime);
callback->Execute(); callback->Execute();
@@ -181,18 +174,20 @@ void ServerManager::PreWorldUpdate(bool bSimulating)
auto size = m_nextWorldUpdateTasks.try_dequeue_bulk(out_list.begin(), 1024); auto size = m_nextWorldUpdateTasks.try_dequeue_bulk(out_list.begin(), 1024);
if (size > 0) { if (size > 0)
CSSHARP_CORE_TRACE("Executing queued tasks of size: {0} at time {1}", size, {
globals::getGlobalVars()->curtime); CSSHARP_CORE_TRACE("Executing queued tasks of size: {0} at time {1}", size, globals::getGlobalVars()->curtime);
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++)
{
out_list[i](); out_list[i]();
} }
} }
auto callback = globals::serverManager.on_server_pre_world_update; auto callback = globals::serverManager.on_server_pre_world_update;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->ScriptContext().Push(bSimulating); callback->ScriptContext().Push(bSimulating);
callback->Execute(); callback->Execute();
@@ -208,11 +203,12 @@ void ServerManager::OnPrecacheResources(IEntityResourceManifest* pResourceManife
{ {
CSSHARP_CORE_TRACE("Precache resources"); CSSHARP_CORE_TRACE("Precache resources");
auto callback = globals::serverManager.on_server_precache_resources; auto callback = globals::serverManager.on_server_precache_resources;
if (callback && callback->GetFunctionCount()) { if (callback && callback->GetFunctionCount())
{
callback->ScriptContext().Reset(); callback->ScriptContext().Reset();
callback->ScriptContext().Push(pResourceManifest); callback->ScriptContext().Push(pResourceManifest);
callback->Execute(); callback->Execute();
} }
} }
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -1,18 +1,18 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
#pragma once #pragma once
@@ -26,8 +26,9 @@
namespace counterstrikesharp { namespace counterstrikesharp {
class ScriptCallback; class ScriptCallback;
class ServerManager : public GlobalClass { class ServerManager : public GlobalClass
public: {
public:
ServerManager(); ServerManager();
~ServerManager(); ~ServerManager();
void OnAllInitialized() override; void OnAllInitialized() override;
@@ -37,27 +38,26 @@ public:
void AddTaskForNextWorldUpdate(std::function<void()>&& task); void AddTaskForNextWorldUpdate(std::function<void()>&& task);
void OnPrecacheResources(IEntityResourceManifest* pResourceManifest); void OnPrecacheResources(IEntityResourceManifest* pResourceManifest);
private: private:
void ServerHibernationUpdate(bool bHibernating); void ServerHibernationUpdate(bool bHibernating);
void GameServerSteamAPIActivated(); void GameServerSteamAPIActivated();
void GameServerSteamAPIDeactivated(); void GameServerSteamAPIDeactivated();
void OnHostNameChanged(const char *pHostname); void OnHostNameChanged(const char* pHostname);
void PreFatalShutdown(); void PreFatalShutdown();
void UpdateWhenNotInGame(float flFrameTime); void UpdateWhenNotInGame(float flFrameTime);
void PreWorldUpdate(bool bSimulating); void PreWorldUpdate(bool bSimulating);
ScriptCallback* on_server_hibernation_update_callback;
ScriptCallback* on_server_steam_api_activated_callback;
ScriptCallback* on_server_steam_api_deactivated_callback;
ScriptCallback* on_server_hostname_changed_callback;
ScriptCallback* on_server_pre_fatal_shutdown;
ScriptCallback* on_server_update_when_not_in_game;
ScriptCallback* on_server_pre_world_update;
ScriptCallback *on_server_hibernation_update_callback; ScriptCallback* on_server_precache_resources;
ScriptCallback *on_server_steam_api_activated_callback;
ScriptCallback *on_server_steam_api_deactivated_callback;
ScriptCallback *on_server_hostname_changed_callback;
ScriptCallback *on_server_pre_fatal_shutdown;
ScriptCallback *on_server_update_when_not_in_game;
ScriptCallback *on_server_pre_world_update;
ScriptCallback *on_server_precache_resources;
moodycamel::ConcurrentQueue<std::function<void()>> m_nextWorldUpdateTasks; moodycamel::ConcurrentQueue<std::function<void()>> m_nextWorldUpdateTasks;
}; };
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -32,7 +32,8 @@ class VoiceManager : public GlobalClass
void OnShutdown() override; void OnShutdown() override;
bool SetClientListening(CPlayerSlot iReceiver, CPlayerSlot iSender, bool bListen); bool SetClientListening(CPlayerSlot iReceiver, CPlayerSlot iSender, bool bListen);
void OnClientCommand(CPlayerSlot slot, const CCommand& args); void OnClientCommand(CPlayerSlot slot, const CCommand& args);
private: private:
}; };
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -22,9 +22,11 @@
#include "gameconfig.h" #include "gameconfig.h"
#include "memory_module.h" #include "memory_module.h"
void* FindSignature(const char* moduleName, const char* bytesStr) { void* FindSignature(const char* moduleName, const char* bytesStr)
{
auto module = counterstrikesharp::modules::GetModuleByName(moduleName); auto module = counterstrikesharp::modules::GetModuleByName(moduleName);
if (module == nullptr) { if (module == nullptr)
{
return nullptr; return nullptr;
} }

View File

@@ -1,15 +1,15 @@
#pragma once #pragma once
#ifdef _WIN32 #ifdef _WIN32
#define ROOTBIN "/bin/win64/" #define ROOTBIN "/bin/win64/"
#define GAMEBIN "/csgo/bin/win64/" #define GAMEBIN "/csgo/bin/win64/"
#define MODULE_PREFIX "" #define MODULE_PREFIX ""
#define MODULE_EXT ".dll" #define MODULE_EXT ".dll"
#else #else
#define ROOTBIN "/bin/linuxsteamrt64/" #define ROOTBIN "/bin/linuxsteamrt64/"
#define GAMEBIN "/csgo/bin/linuxsteamrt64/" #define GAMEBIN "/csgo/bin/linuxsteamrt64/"
#define MODULE_PREFIX "lib" #define MODULE_PREFIX "lib"
#define MODULE_EXT ".so" #define MODULE_EXT ".so"
#endif #endif
void* FindSignature(const char* moduleName, const char* bytesStr); void* FindSignature(const char* moduleName, const char* bytesStr);

View File

@@ -63,8 +63,7 @@ void Initialize()
moduleList.emplace_back(std::move(mod)); moduleList.emplace_back(std::move(mod));
} }
#else #else
dl_iterate_phdr( dl_iterate_phdr([](struct dl_phdr_info* info, size_t, void*) {
[](struct dl_phdr_info* info, size_t, void*) {
std::string name = info->dlpi_name; std::string name = info->dlpi_name;
if (name.rfind(MODULE_EXT) != name.length() - strlen(MODULE_EXT)) return 0; if (name.rfind(MODULE_EXT) != name.length() - strlen(MODULE_EXT)) return 0;
@@ -80,8 +79,7 @@ void Initialize()
moduleList.emplace_back(std::move(mod)); moduleList.emplace_back(std::move(mod));
return 0; return 0;
}, }, nullptr);
nullptr);
#endif #endif
} }

View File

@@ -77,8 +77,8 @@ class CModule
std::uintptr_t m_baseAddress{}; std::uintptr_t m_baseAddress{};
std::unordered_map<std::string, std::uintptr_t> _symbols{}; std::unordered_map<std::string, std::uintptr_t> _symbols{};
std::unordered_map<std::string, std::uintptr_t> _interfaces{}; std::unordered_map<std::string, std::uintptr_t> _interfaces{};
using fnCreateInterface = void*(*)(const char*); using fnCreateInterface = void* (*)(const char*);
fnCreateInterface m_fnCreateInterface {}; fnCreateInterface m_fnCreateInterface{};
#ifdef _WIN32 #ifdef _WIN32
void DumpSymbols(); void DumpSymbols();
@@ -86,7 +86,8 @@ class CModule
void DumpSymbols(ElfW(Dyn) * dyn); void DumpSymbols(ElfW(Dyn) * dyn);
#endif #endif
std::optional<std::vector<std::uint8_t>> GetOriginalBytes(const std::vector<std::uint8_t>& disk_data, std::uintptr_t rva, std::size_t size); std::optional<std::vector<std::uint8_t>>
GetOriginalBytes(const std::vector<std::uint8_t>& disk_data, std::uintptr_t rva, std::size_t size);
void* FindSignature(const std::vector<int16_t>& sigBytes); void* FindSignature(const std::vector<int16_t>& sigBytes);
}; };

View File

@@ -1,84 +1,84 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
#include "irecipientfilter.h" #include "irecipientfilter.h"
class CSingleRecipientFilter : public IRecipientFilter class CSingleRecipientFilter : public IRecipientFilter
{ {
public: public:
CSingleRecipientFilter(CPlayerSlot iRecipient, NetChannelBufType_t nBufType = BUF_RELIABLE, bool bInitMessage = false) CSingleRecipientFilter(CPlayerSlot iRecipient, NetChannelBufType_t nBufType = BUF_RELIABLE, bool bInitMessage = false)
: m_iRecipient(iRecipient), m_nBufType(nBufType), m_bInitMessage(bInitMessage) : m_iRecipient(iRecipient), m_nBufType(nBufType), m_bInitMessage(bInitMessage)
{ {
} }
~CSingleRecipientFilter() override {} ~CSingleRecipientFilter() override {}
NetChannelBufType_t GetNetworkBufType(void) const override { return m_nBufType; } NetChannelBufType_t GetNetworkBufType(void) const override { return m_nBufType; }
bool IsInitMessage(void) const override { return m_bInitMessage; } bool IsInitMessage(void) const override { return m_bInitMessage; }
int GetRecipientCount(void) const override { return 1; } int GetRecipientCount(void) const override { return 1; }
CPlayerSlot GetRecipientIndex(int slot) const override { return m_iRecipient; } CPlayerSlot GetRecipientIndex(int slot) const override { return m_iRecipient; }
private: private:
CPlayerSlot m_iRecipient; CPlayerSlot m_iRecipient;
NetChannelBufType_t m_nBufType; NetChannelBufType_t m_nBufType;
bool m_bInitMessage; bool m_bInitMessage;
}; };
class CRecipientFilter : public IRecipientFilter class CRecipientFilter : public IRecipientFilter
{ {
public: public:
CRecipientFilter() CRecipientFilter()
{ {
m_nBufType = BUF_RELIABLE; m_nBufType = BUF_RELIABLE;
m_bInitMessage = false; m_bInitMessage = false;
} }
~CRecipientFilter() override {} ~CRecipientFilter() override {}
NetChannelBufType_t GetNetworkBufType(void) const override { return m_nBufType; } NetChannelBufType_t GetNetworkBufType(void) const override { return m_nBufType; }
bool IsInitMessage(void) const override { return m_bInitMessage; } bool IsInitMessage(void) const override { return m_bInitMessage; }
int GetRecipientCount(void) const override { return m_Recipients.Count(); } int GetRecipientCount(void) const override { return m_Recipients.Count(); }
CPlayerSlot GetRecipientIndex(int slot) const override CPlayerSlot GetRecipientIndex(int slot) const override
{ {
if (slot < 0 || slot >= GetRecipientCount()) return CPlayerSlot(-1); if (slot < 0 || slot >= GetRecipientCount()) return CPlayerSlot(-1);
return m_Recipients[slot]; return m_Recipients[slot];
} }
void AddRecipient(CPlayerSlot slot) void AddRecipient(CPlayerSlot slot)
{ {
if (m_Recipients.Find(slot) != m_Recipients.InvalidIndex()) return; if (m_Recipients.Find(slot) != m_Recipients.InvalidIndex()) return;
m_Recipients.AddToTail(slot); m_Recipients.AddToTail(slot);
} }
void AddRecipientsFromMask(uint64 mask) void AddRecipientsFromMask(uint64 mask)
{ {
for (int i = 0; i < 64; ++i) for (int i = 0; i < 64; ++i)
{ {
if (mask & (uint64)1 << i) if (mask & (uint64)1 << i)
{ {
AddRecipient(CPlayerSlot(i)); AddRecipient(CPlayerSlot(i));
} }
} }
} }
private: private:
NetChannelBufType_t m_nBufType; NetChannelBufType_t m_nBufType;
bool m_bInitMessage; bool m_bInitMessage;
CUtlVectorFixed<CPlayerSlot, 64> m_Recipients; CUtlVectorFixed<CPlayerSlot, 64> m_Recipients;
}; };

View File

@@ -1,45 +1,47 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
#include "tick_scheduler.h" #include "tick_scheduler.h"
namespace counterstrikesharp { namespace counterstrikesharp {
void TickScheduler::schedule(int tick, std::function<void()> callback) void TickScheduler::schedule(int tick, std::function<void()> callback)
{ {
std::lock_guard<std::mutex> lock(taskMutex); std::lock_guard<std::mutex> lock(taskMutex);
scheduledTasks.push(std::make_pair(tick, callback)); scheduledTasks.push(std::make_pair(tick, callback));
} }
std::vector<std::function<void()>> TickScheduler::getCallbacks(int currentTick) std::vector<std::function<void()>> TickScheduler::getCallbacks(int currentTick)
{ {
std::vector<std::function<void()>> callbacksToRun; std::vector<std::function<void()>> callbacksToRun;
std::lock_guard<std::mutex> lock(taskMutex); std::lock_guard<std::mutex> lock(taskMutex);
if (scheduledTasks.empty()) { if (scheduledTasks.empty())
return callbacksToRun; {
} return callbacksToRun;
}
// Process tasks due for the current tick
while (!scheduledTasks.empty() && scheduledTasks.top().first <= currentTick) { // Process tasks due for the current tick
callbacksToRun.push_back(scheduledTasks.top().second); while (!scheduledTasks.empty() && scheduledTasks.top().first <= currentTick)
scheduledTasks.pop(); {
} callbacksToRun.push_back(scheduledTasks.top().second);
scheduledTasks.pop();
return callbacksToRun; }
}
} // namespace counterstrikesharp return callbacksToRun;
}
} // namespace counterstrikesharp

View File

@@ -1,44 +1,42 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
#include <functional> #include <functional>
#include <queue> #include <queue>
#include <mutex> #include <mutex>
#include <condition_variable> #include <condition_variable>
namespace counterstrikesharp { namespace counterstrikesharp {
class TickScheduler class TickScheduler
{ {
public: public:
struct TaskComparator struct TaskComparator
{ {
bool operator()(const std::pair<int, std::function<void()>>& a, bool operator()(const std::pair<int, std::function<void()>>& a, const std::pair<int, std::function<void()>>& b) const
const std::pair<int, std::function<void()>>& b) const {
{ return a.first > b.first;
return a.first > b.first; }
} };
};
void schedule(int tick, std::function<void()> callback);
void schedule(int tick, std::function<void()> callback); std::vector<std::function<void()>> getCallbacks(int currentTick);
std::vector<std::function<void()>> getCallbacks(int currentTick);
private: private:
std::priority_queue<std::pair<int, std::function<void()>>, std::priority_queue<std::pair<int, std::function<void()>>, std::vector<std::pair<int, std::function<void()>>>, TaskComparator>
std::vector<std::pair<int, std::function<void()>>>, scheduledTasks;
TaskComparator> std::mutex taskMutex;
scheduledTasks; };
std::mutex taskMutex; } // namespace counterstrikesharp
};
} // namespace counterstrikesharp

View File

@@ -41,30 +41,32 @@ class TimerSystem;
class ScriptCallback; class ScriptCallback;
namespace timers { namespace timers {
#define TIMER_FLAG_REPEAT (1 << 0) /**< Timer will repeat until stopped */ #define TIMER_FLAG_REPEAT (1 << 0) /**< Timer will repeat until stopped */
#define TIMER_FLAG_NO_MAPCHANGE (1 << 1) /**< Timer will not carry over mapchanges */ #define TIMER_FLAG_NO_MAPCHANGE (1 << 1) /**< Timer will not carry over mapchanges */
class Timer { class Timer
{
friend class TimerSystem; friend class TimerSystem;
public: public:
Timer(float interval, float exec_time, CallbackT callback, int flags); Timer(float interval, float exec_time, CallbackT callback, int flags);
~Timer(); ~Timer();
float m_interval; float m_interval;
ScriptCallback *m_callback; ScriptCallback* m_callback;
int m_flags; int m_flags;
float m_exec_time; float m_exec_time;
bool m_in_exec; bool m_in_exec;
bool m_kill_me; bool m_kill_me;
}; };
} // namespace timers } // namespace timers
class ScriptCallback; class ScriptCallback;
class TimerSystem : public GlobalClass { class TimerSystem : public GlobalClass
public: {
public:
TimerSystem(); TimerSystem();
void OnAllInitialized() override; void OnAllInitialized() override;
void OnShutdown() override; void OnShutdown() override;
@@ -74,19 +76,18 @@ public:
double CalculateNextThink(double last_think_time, float interval); double CalculateNextThink(double last_think_time, float interval);
void RunFrame(); void RunFrame();
void RemoveMapChangeTimers(); void RemoveMapChangeTimers();
timers::Timer *CreateTimer(float interval, CallbackT callback, int flags); timers::Timer* CreateTimer(float interval, CallbackT callback, int flags);
void KillTimer(timers::Timer *timer); void KillTimer(timers::Timer* timer);
double GetTickedTime(); double GetTickedTime();
private: private:
bool m_has_map_ticked = false; bool m_has_map_ticked = false;
bool m_has_map_simulated = false; bool m_has_map_simulated = false;
float m_last_ticked_time = 0.0f; float m_last_ticked_time = 0.0f;
ScriptCallback *m_on_tick_callback_ = nullptr; ScriptCallback* m_on_tick_callback_ = nullptr;
ScriptCallback *on_map_end_callback = nullptr; ScriptCallback* on_map_end_callback = nullptr;
std::vector<timers::Timer *> m_once_off_timers; std::vector<timers::Timer*> m_once_off_timers;
std::vector<timers::Timer *> m_repeat_timers; std::vector<timers::Timer*> m_repeat_timers;
}; };
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -10,8 +10,10 @@ namespace utils {
static std::string gameDirectory; static std::string gameDirectory;
inline std::string GameDirectory() { inline std::string GameDirectory()
if (gameDirectory.empty()) { {
if (gameDirectory.empty())
{
CBufferStringGrowable<255> gamePath; CBufferStringGrowable<255> gamePath;
globals::engine->GetGameDir(gamePath); globals::engine->GetGameDir(gamePath);
gameDirectory = std::string(gamePath.Get()); gameDirectory = std::string(gamePath.Get());
@@ -25,5 +27,5 @@ inline std::string PluginsDirectory() { return GameDirectory() + "/addons/counte
inline std::string ConfigsDirectory() { return GameDirectory() + "/addons/counterstrikesharp/configs"; } inline std::string ConfigsDirectory() { return GameDirectory() + "/addons/counterstrikesharp/configs"; }
inline std::string GamedataDirectory() { return GameDirectory() + "/addons/counterstrikesharp/gamedata"; } inline std::string GamedataDirectory() { return GameDirectory() + "/addons/counterstrikesharp/gamedata"; }
} // namespace utils } // namespace utils
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -17,7 +17,6 @@
#ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ #ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_
#define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ #define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_
// clang-format off
#include <ISmmPlugin.h> #include <ISmmPlugin.h>
#include <functional> #include <functional>
#include <iserver.h> #include <iserver.h>
@@ -27,7 +26,6 @@
#include <vector> #include <vector>
#include "entitysystem.h" #include "entitysystem.h"
#include "concurrentqueue.h" #include "concurrentqueue.h"
// clang-format on
namespace counterstrikesharp { namespace counterstrikesharp {
class ScriptCallback; class ScriptCallback;
@@ -74,9 +72,7 @@ static ScriptCallback* on_activate_callback;
static ScriptCallback* on_metamod_all_plugins_loaded_callback; static ScriptCallback* on_metamod_all_plugins_loaded_callback;
extern CounterStrikeSharpMMPlugin gPlugin; extern CounterStrikeSharpMMPlugin gPlugin;
#endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ #endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_
} }
PLUGIN_GLOBALVARS(); PLUGIN_GLOBALVARS();

File diff suppressed because it is too large Load Diff

View File

@@ -20,29 +20,31 @@
#include "core/globals.h" #include "core/globals.h"
#include "scripting/script_engine.h" #include "scripting/script_engine.h"
#define REGISTER_NATIVE(name, func) \ #define REGISTER_NATIVE(name, func) counterstrikesharp::ScriptEngine::RegisterNativeHandler(#name, func);
counterstrikesharp::ScriptEngine::RegisterNativeHandler(#name, func);
#define REGISTER_NATIVES(name, method) \ #define REGISTER_NATIVES(name, method) \
class Natives##name : public counterstrikesharp::GlobalClass { \ class Natives##name : public counterstrikesharp::GlobalClass \
public: \ { \
void OnAllInitialized() override method \ public: \
}; \ void OnAllInitialized() override method \
\ }; \
\
Natives##name g_natives_##name; Natives##name g_natives_##name;
#define CREATE_GETTER_FUNCTION(object_name, parameter_type, parameter_name, from_type, getter) \ #define CREATE_GETTER_FUNCTION(object_name, parameter_type, parameter_name, from_type, getter) \
static parameter_type object_name##Get##parameter_name(ScriptContext &script_context) { \ static parameter_type object_name##Get##parameter_name(ScriptContext& script_context) \
{ \
auto obj = script_context.GetArgument<from_type>(0); \ auto obj = script_context.GetArgument<from_type>(0); \
return getter; \ return getter; \
} }
#define CREATE_STATIC_GETTER_FUNCTION(parameter_name, parameter_type, getter) \ #define CREATE_STATIC_GETTER_FUNCTION(parameter_name, parameter_type, getter) \
static parameter_type Get##parameter_name(ScriptContext &script_context) { return getter; } static parameter_type Get##parameter_name(ScriptContext& script_context) { return getter; }
#define CREATE_SETTER_FUNCTION(type_name, get_type, name, from_type, setter) \ #define CREATE_SETTER_FUNCTION(type_name, get_type, name, from_type, setter) \
static void type_name##Set##name(ScriptContext &script_context) { \ static void type_name##Set##name(ScriptContext& script_context) \
{ \
auto obj = script_context.GetArgument<from_type>(0); \ auto obj = script_context.GetArgument<from_type>(0); \
auto value = script_context.GetArgument<get_type>(1); \ auto value = script_context.GetArgument<get_type>(1); \
setter; \ setter; \
} }

View File

@@ -26,13 +26,13 @@
#include <Windows.h> #include <Windows.h>
#include <direct.h> #include <direct.h>
#define STR(s) L##s #define STR(s) L##s
#define CH(c) L##c #define CH(c) L##c
#define DIR_SEPARATOR L'\\' #define DIR_SEPARATOR L'\\'
#else #else
#define STR(s) s #define STR(s) s
#define CH(c) c #define CH(c) c
#define DIR_SEPARATOR '/' #define DIR_SEPARATOR '/'
#include <dlfcn.h> #include <dlfcn.h>
@@ -99,8 +99,7 @@ bool load_hostfxr()
std::string base_dir = counterstrikesharp::utils::GetRootDirectory(); std::string base_dir = counterstrikesharp::utils::GetRootDirectory();
namespace css = counterstrikesharp; namespace css = counterstrikesharp;
#if _WIN32 #if _WIN32
std::wstring buffer = std::wstring buffer = std::wstring(css::widen(base_dir) + L"\\dotnet\\host\\fxr\\8.0.3\\hostfxr.dll");
std::wstring(css::widen(base_dir) + L"\\dotnet\\host\\fxr\\8.0.3\\hostfxr.dll");
CSSHARP_CORE_INFO("Loading hostfxr from {0}", css::narrow(buffer).c_str()); CSSHARP_CORE_INFO("Loading hostfxr from {0}", css::narrow(buffer).c_str());
#else #else
std::string buffer = std::string(base_dir + "/dotnet/host/fxr/8.0.3/libhostfxr.so"); std::string buffer = std::string(base_dir + "/dotnet/host/fxr/8.0.3/libhostfxr.so");
@@ -109,21 +108,21 @@ bool load_hostfxr()
// Load hostfxr and get desired exports // Load hostfxr and get desired exports
void* lib = load_library(buffer.c_str()); void* lib = load_library(buffer.c_str());
init_fptr = (hostfxr_initialize_for_runtime_config_fn)get_export( init_fptr = (hostfxr_initialize_for_runtime_config_fn)get_export(lib, "hostfxr_initialize_for_runtime_config");
lib, "hostfxr_initialize_for_runtime_config"); if (init_fptr == nullptr)
if (init_fptr == nullptr) { {
CSSHARP_CORE_CRITICAL( CSSHARP_CORE_CRITICAL("unable to get export function: \"hostfxr_initialize_for_runtime_config\"");
"unable to get export function: \"hostfxr_initialize_for_runtime_config\"");
return false; return false;
} }
get_delegate_fptr = get_delegate_fptr = (hostfxr_get_runtime_delegate_fn)get_export(lib, "hostfxr_get_runtime_delegate");
(hostfxr_get_runtime_delegate_fn)get_export(lib, "hostfxr_get_runtime_delegate"); if (!get_delegate_fptr)
if (!get_delegate_fptr) { {
CSSHARP_CORE_CRITICAL("unable to get export function: \"hostfxr_get_runtime_delegate\""); CSSHARP_CORE_CRITICAL("unable to get export function: \"hostfxr_get_runtime_delegate\"");
return false; return false;
} }
close_fptr = (hostfxr_close_fn)get_export(lib, "hostfxr_close"); close_fptr = (hostfxr_close_fn)get_export(lib, "hostfxr_close");
if (!close_fptr) { if (!close_fptr)
{
CSSHARP_CORE_CRITICAL("unable to get export function: \"hostfxr_close\""); CSSHARP_CORE_CRITICAL("unable to get export function: \"hostfxr_close\"");
return false; return false;
} }
@@ -139,16 +138,17 @@ load_assembly_and_get_function_pointer_fn get_dotnet_load_assembly(const char_t*
// Load .NET Core // Load .NET Core
void* load_assembly_and_get_function_pointer = nullptr; void* load_assembly_and_get_function_pointer = nullptr;
int rc = init_fptr(config_path, nullptr, &cxt); int rc = init_fptr(config_path, nullptr, &cxt);
if (rc != 0 || cxt == nullptr) { if (rc != 0 || cxt == nullptr)
{
CSSHARP_CORE_CRITICAL("Init failed: {0:x}", rc); CSSHARP_CORE_CRITICAL("Init failed: {0:x}", rc);
close_fptr(cxt); close_fptr(cxt);
return nullptr; return nullptr;
} }
// Get the load assembly function pointer // Get the load assembly function pointer
rc = get_delegate_fptr(cxt, hdt_load_assembly_and_get_function_pointer, rc = get_delegate_fptr(cxt, hdt_load_assembly_and_get_function_pointer, &load_assembly_and_get_function_pointer);
&load_assembly_and_get_function_pointer); if (rc != 0 || load_assembly_and_get_function_pointer == nullptr)
if (rc != 0 || load_assembly_and_get_function_pointer == nullptr) { {
CSSHARP_CORE_ERROR("Get delegate failed: {0:x}", rc); CSSHARP_CORE_ERROR("Get delegate failed: {0:x}", rc);
} }
@@ -168,54 +168,51 @@ bool CDotNetManager::Initialize()
CSSHARP_CORE_INFO("Loading .NET runtime..."); CSSHARP_CORE_INFO("Loading .NET runtime...");
if (!load_hostfxr()) { if (!load_hostfxr())
{
CSSHARP_CORE_ERROR("Failed to initialize .NET runtime."); CSSHARP_CORE_ERROR("Failed to initialize .NET runtime.");
return false; return false;
} }
CSSHARP_CORE_INFO(".NET Runtime Initialised."); CSSHARP_CORE_INFO(".NET Runtime Initialised.");
namespace css = counterstrikesharp; namespace css = counterstrikesharp;
#if _WIN32 #if _WIN32
const auto wide_str = const auto wide_str = std::wstring(css::widen(base_dir) + L"\\api\\CounterStrikeSharp.API.runtimeconfig.json");
std::wstring(css::widen(base_dir) + L"\\api\\CounterStrikeSharp.API.runtimeconfig.json"); CSSHARP_CORE_INFO("Loading CSS API, Runtime config: {}", counterstrikesharp::narrow(wide_str).c_str());
CSSHARP_CORE_INFO("Loading CSS API, Runtime config: {}",
counterstrikesharp::narrow(wide_str).c_str());
#else #else
std::string wide_str = std::string wide_str = std::string((base_dir + "/api/CounterStrikeSharp.API.runtimeconfig.json").c_str());
std::string((base_dir + "/api/CounterStrikeSharp.API.runtimeconfig.json").c_str());
CSSHARP_CORE_INFO("Loading CSS API, Runtime Config: {}", wide_str); CSSHARP_CORE_INFO("Loading CSS API, Runtime Config: {}", wide_str);
#endif #endif
const auto load_assembly_and_get_function_pointer = get_dotnet_load_assembly(wide_str.c_str()); const auto load_assembly_and_get_function_pointer = get_dotnet_load_assembly(wide_str.c_str());
if (load_assembly_and_get_function_pointer == nullptr) { if (load_assembly_and_get_function_pointer == nullptr)
{
CSSHARP_CORE_ERROR("Failed to load CSS API."); CSSHARP_CORE_ERROR("Failed to load CSS API.");
return false; return false;
} }
#if _WIN32 #if _WIN32
const auto dotnetlib_path = const auto dotnetlib_path = std::wstring(css::widen(base_dir) + L"\\api\\CounterStrikeSharp.API.dll");
std::wstring(css::widen(base_dir) + L"\\api\\CounterStrikeSharp.API.dll");
CSSHARP_CORE_INFO("CSS API DLL: {}", counterstrikesharp::narrow(dotnetlib_path)); CSSHARP_CORE_INFO("CSS API DLL: {}", counterstrikesharp::narrow(dotnetlib_path));
#else #else
const std::string dotnetlib_path = const std::string dotnetlib_path = std::string((base_dir + "/api/CounterStrikeSharp.API.dll").c_str());
std::string((base_dir + "/api/CounterStrikeSharp.API.dll").c_str());
#endif #endif
const auto dotnet_type = STR("CounterStrikeSharp.API.Bootstrap, CounterStrikeSharp.API"); const auto dotnet_type = STR("CounterStrikeSharp.API.Bootstrap, CounterStrikeSharp.API");
// Namespace, assembly name // Namespace, assembly name
typedef int(CORECLR_DELEGATE_CALLTYPE * custom_entry_point_fn)(); typedef int(CORECLR_DELEGATE_CALLTYPE * custom_entry_point_fn)();
custom_entry_point_fn entry_point = nullptr; custom_entry_point_fn entry_point = nullptr;
const int rc = load_assembly_and_get_function_pointer( const int rc = load_assembly_and_get_function_pointer(dotnetlib_path.c_str(), dotnet_type, STR("Run"), UNMANAGEDCALLERSONLY_METHOD,
dotnetlib_path.c_str(), dotnet_type, STR("Run"), UNMANAGEDCALLERSONLY_METHOD, nullptr, reinterpret_cast<void**>(&entry_point));
nullptr, reinterpret_cast<void**>(&entry_point)); if (entry_point == nullptr)
if (entry_point == nullptr) { {
CSSHARP_CORE_ERROR("Trying to get entry point \"Bootstrap::Run\" but failed."); CSSHARP_CORE_ERROR("Trying to get entry point \"Bootstrap::Run\" but failed.");
return false; return false;
} }
assert(rc == 0 && entry_point != nullptr && assert(rc == 0 && entry_point != nullptr && "Failure: load_assembly_and_get_function_pointer()");
"Failure: load_assembly_and_get_function_pointer()");
if (const int invoke_result_code = entry_point(); invoke_result_code == 0) { if (const int invoke_result_code = entry_point(); invoke_result_code == 0)
{
CSSHARP_CORE_ERROR("Bootstrap::Run return failure."); CSSHARP_CORE_ERROR("Bootstrap::Run return failure.");
return false; return false;
} }

View File

@@ -21,29 +21,30 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
class PluginContext { class PluginContext
{
friend class CDotNetManager; friend class CDotNetManager;
public: public:
PluginContext(std::string dll_path) PluginContext(std::string dll_path) : m_dll_path(dll_path) {}
: m_dll_path(dll_path) {}
private: private:
std::string m_dll_path; std::string m_dll_path;
}; };
class CDotNetManager { class CDotNetManager
{
friend class PluginContext; friend class PluginContext;
public: public:
CDotNetManager(); CDotNetManager();
~CDotNetManager(); ~CDotNetManager();
bool Initialize(); bool Initialize();
void UnloadPlugin(PluginContext *context); void UnloadPlugin(PluginContext* context);
void Shutdown(); void Shutdown();
PluginContext *FindContext(std::string path); PluginContext* FindContext(std::string path);
private: private:
std::vector<std::shared_ptr<PluginContext>> m_app_domains; std::vector<std::shared_ptr<PluginContext>> m_app_domains;
}; };

View File

@@ -20,15 +20,17 @@
namespace counterstrikesharp { namespace counterstrikesharp {
static bool AddListener(ScriptContext &script_context) { static bool AddListener(ScriptContext& script_context)
auto name = script_context.GetArgument<const char *>(0); {
auto name = script_context.GetArgument<const char*>(0);
auto callback = script_context.GetArgument<CallbackT>(1); auto callback = script_context.GetArgument<CallbackT>(1);
return globals::callbackManager.TryAddFunction(name, callback); return globals::callbackManager.TryAddFunction(name, callback);
} }
static bool RemoveListener(ScriptContext &script_context) { static bool RemoveListener(ScriptContext& script_context)
auto name = script_context.GetArgument<const char *>(0); {
auto name = script_context.GetArgument<const char*>(0);
auto callback = script_context.GetArgument<CallbackT>(1); auto callback = script_context.GetArgument<CallbackT>(1);
return globals::callbackManager.TryRemoveFunction(name, callback); return globals::callbackManager.TryRemoveFunction(name, callback);
@@ -38,4 +40,4 @@ REGISTER_NATIVES(callbacks, {
ScriptEngine::RegisterNativeHandler("ADD_LISTENER", AddListener); ScriptEngine::RegisterNativeHandler("ADD_LISTENER", AddListener);
ScriptEngine::RegisterNativeHandler("REMOVE_LISTENER", RemoveListener); ScriptEngine::RegisterNativeHandler("REMOVE_LISTENER", RemoveListener);
}) })
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -1,283 +1,288 @@
/* /*
* This file is part of CounterStrikeSharp. * This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify * CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* CounterStrikeSharp is distributed in the hope that it will be useful, * CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
// clang-format off #include "mm_plugin.h"
#include "mm_plugin.h" #include "core/timer_system.h"
#include "core/timer_system.h" #include "scripting/autonative.h"
#include "scripting/autonative.h" #include "scripting/script_engine.h"
#include "scripting/script_engine.h" #include "core/function.h"
#include "core/function.h" #include "pch.h"
#include "pch.h" #include "dynohook/core.h"
#include "dynohook/core.h" #include "dynohook/manager.h"
#include "dynohook/manager.h"
namespace counterstrikesharp {
// clang-format on
void DHookGetReturn(ScriptContext& script_context)
namespace counterstrikesharp { {
auto hook = script_context.GetArgument<dyno::Hook*>(0);
void DHookGetReturn(ScriptContext& script_context) auto dataType = script_context.GetArgument<DataType_t>(1);
{ if (hook == nullptr)
auto hook = script_context.GetArgument<dyno::Hook*>(0); {
auto dataType = script_context.GetArgument<DataType_t>(1); script_context.ThrowNativeError("Invalid hook");
if (hook == nullptr) { }
script_context.ThrowNativeError("Invalid hook");
} switch (dataType)
{
switch (dataType) { case DATA_TYPE_BOOL:
case DATA_TYPE_BOOL: script_context.SetResult(hook->getReturnValue<bool>());
script_context.SetResult(hook->getReturnValue<bool>()); break;
break; case DATA_TYPE_CHAR:
case DATA_TYPE_CHAR: script_context.SetResult(hook->getReturnValue<char>());
script_context.SetResult(hook->getReturnValue<char>()); break;
break; case DATA_TYPE_UCHAR:
case DATA_TYPE_UCHAR: script_context.SetResult(hook->getReturnValue<unsigned char>());
script_context.SetResult(hook->getReturnValue<unsigned char>()); break;
break; case DATA_TYPE_SHORT:
case DATA_TYPE_SHORT: script_context.SetResult(hook->getReturnValue<short>());
script_context.SetResult(hook->getReturnValue<short>()); break;
break; case DATA_TYPE_USHORT:
case DATA_TYPE_USHORT: script_context.SetResult(hook->getReturnValue<unsigned short>());
script_context.SetResult(hook->getReturnValue<unsigned short>()); break;
break; case DATA_TYPE_INT:
case DATA_TYPE_INT: script_context.SetResult(hook->getReturnValue<int>());
script_context.SetResult(hook->getReturnValue<int>()); break;
break; case DATA_TYPE_UINT:
case DATA_TYPE_UINT: script_context.SetResult(hook->getReturnValue<unsigned int>());
script_context.SetResult(hook->getReturnValue<unsigned int>()); break;
break; case DATA_TYPE_LONG:
case DATA_TYPE_LONG: script_context.SetResult(hook->getReturnValue<long>());
script_context.SetResult(hook->getReturnValue<long>()); break;
break; case DATA_TYPE_ULONG:
case DATA_TYPE_ULONG: script_context.SetResult(hook->getReturnValue<unsigned long>());
script_context.SetResult(hook->getReturnValue<unsigned long>()); break;
break; case DATA_TYPE_LONG_LONG:
case DATA_TYPE_LONG_LONG: script_context.SetResult(hook->getReturnValue<long long>());
script_context.SetResult(hook->getReturnValue<long long>()); break;
break; case DATA_TYPE_ULONG_LONG:
case DATA_TYPE_ULONG_LONG: script_context.SetResult(hook->getReturnValue<unsigned long long>());
script_context.SetResult(hook->getReturnValue<unsigned long long>()); break;
break; case DATA_TYPE_FLOAT:
case DATA_TYPE_FLOAT: script_context.SetResult(hook->getReturnValue<float>());
script_context.SetResult(hook->getReturnValue<float>()); break;
break; case DATA_TYPE_DOUBLE:
case DATA_TYPE_DOUBLE: script_context.SetResult(hook->getReturnValue<double>());
script_context.SetResult(hook->getReturnValue<double>()); break;
break; case DATA_TYPE_POINTER:
case DATA_TYPE_POINTER: script_context.SetResult(hook->getReturnValue<void*>());
script_context.SetResult(hook->getReturnValue<void*>()); break;
break; case DATA_TYPE_STRING:
case DATA_TYPE_STRING: script_context.SetResult(hook->getReturnValue<const char*>());
script_context.SetResult(hook->getReturnValue<const char*>()); break;
break; default:
default: assert(!"Unknown function parameter type!");
assert(!"Unknown function parameter type!"); break;
break; }
} }
}
void DHookSetReturn(ScriptContext& script_context)
void DHookSetReturn(ScriptContext& script_context) {
{ auto hook = script_context.GetArgument<dyno::Hook*>(0);
auto hook = script_context.GetArgument<dyno::Hook*>(0); auto dataType = script_context.GetArgument<DataType_t>(1);
auto dataType = script_context.GetArgument<DataType_t>(1); if (hook == nullptr)
if (hook == nullptr) { {
script_context.ThrowNativeError("Invalid hook"); script_context.ThrowNativeError("Invalid hook");
} }
auto valueIndex = 2; auto valueIndex = 2;
switch (dataType) { switch (dataType)
case DATA_TYPE_BOOL: {
hook->setReturnValue(script_context.GetArgument<bool>(valueIndex)); case DATA_TYPE_BOOL:
break; hook->setReturnValue(script_context.GetArgument<bool>(valueIndex));
case DATA_TYPE_CHAR: break;
hook->setReturnValue(script_context.GetArgument<char>(valueIndex)); case DATA_TYPE_CHAR:
break; hook->setReturnValue(script_context.GetArgument<char>(valueIndex));
case DATA_TYPE_UCHAR: break;
hook->setReturnValue(script_context.GetArgument<unsigned char>(valueIndex)); case DATA_TYPE_UCHAR:
break; hook->setReturnValue(script_context.GetArgument<unsigned char>(valueIndex));
case DATA_TYPE_SHORT: break;
hook->setReturnValue(script_context.GetArgument<short>(valueIndex)); case DATA_TYPE_SHORT:
break; hook->setReturnValue(script_context.GetArgument<short>(valueIndex));
case DATA_TYPE_USHORT: break;
hook->setReturnValue(script_context.GetArgument<unsigned short>(valueIndex)); case DATA_TYPE_USHORT:
break; hook->setReturnValue(script_context.GetArgument<unsigned short>(valueIndex));
case DATA_TYPE_INT: break;
hook->setReturnValue(script_context.GetArgument<int>(valueIndex)); case DATA_TYPE_INT:
break; hook->setReturnValue(script_context.GetArgument<int>(valueIndex));
case DATA_TYPE_UINT: break;
hook->setReturnValue(script_context.GetArgument<unsigned int>(valueIndex)); case DATA_TYPE_UINT:
break; hook->setReturnValue(script_context.GetArgument<unsigned int>(valueIndex));
case DATA_TYPE_LONG: break;
hook->setReturnValue(script_context.GetArgument<long>(valueIndex)); case DATA_TYPE_LONG:
break; hook->setReturnValue(script_context.GetArgument<long>(valueIndex));
case DATA_TYPE_ULONG: break;
hook->setReturnValue(script_context.GetArgument<unsigned long>(valueIndex)); case DATA_TYPE_ULONG:
break; hook->setReturnValue(script_context.GetArgument<unsigned long>(valueIndex));
case DATA_TYPE_LONG_LONG: break;
hook->setReturnValue(script_context.GetArgument<long long>(valueIndex)); case DATA_TYPE_LONG_LONG:
break; hook->setReturnValue(script_context.GetArgument<long long>(valueIndex));
case DATA_TYPE_ULONG_LONG: break;
hook->setReturnValue(script_context.GetArgument<unsigned long long>(valueIndex)); case DATA_TYPE_ULONG_LONG:
break; hook->setReturnValue(script_context.GetArgument<unsigned long long>(valueIndex));
case DATA_TYPE_FLOAT: break;
hook->setReturnValue(script_context.GetArgument<float>(valueIndex)); case DATA_TYPE_FLOAT:
break; hook->setReturnValue(script_context.GetArgument<float>(valueIndex));
case DATA_TYPE_DOUBLE: break;
hook->setReturnValue(script_context.GetArgument<double>(valueIndex)); case DATA_TYPE_DOUBLE:
break; hook->setReturnValue(script_context.GetArgument<double>(valueIndex));
case DATA_TYPE_POINTER: break;
hook->setReturnValue(script_context.GetArgument<void*>(valueIndex)); case DATA_TYPE_POINTER:
break; hook->setReturnValue(script_context.GetArgument<void*>(valueIndex));
case DATA_TYPE_STRING: break;
hook->setReturnValue(script_context.GetArgument<const char*>(valueIndex)); case DATA_TYPE_STRING:
break; hook->setReturnValue(script_context.GetArgument<const char*>(valueIndex));
default: break;
assert(!"Unknown function parameter type!"); default:
break; assert(!"Unknown function parameter type!");
} break;
} }
}
void DHookGetParam(ScriptContext& script_context)
{ void DHookGetParam(ScriptContext& script_context)
auto hook = script_context.GetArgument<dyno::Hook*>(0); {
auto dataType = script_context.GetArgument<DataType_t>(1); auto hook = script_context.GetArgument<dyno::Hook*>(0);
auto paramIndex = script_context.GetArgument<int>(2); auto dataType = script_context.GetArgument<DataType_t>(1);
if (hook == nullptr) { auto paramIndex = script_context.GetArgument<int>(2);
script_context.ThrowNativeError("Invalid hook"); if (hook == nullptr)
} {
script_context.ThrowNativeError("Invalid hook");
switch (dataType) { }
case DATA_TYPE_BOOL:
script_context.SetResult(hook->getArgument<bool>(paramIndex)); switch (dataType)
break; {
case DATA_TYPE_CHAR: case DATA_TYPE_BOOL:
script_context.SetResult(hook->getArgument<char>(paramIndex)); script_context.SetResult(hook->getArgument<bool>(paramIndex));
break; break;
case DATA_TYPE_UCHAR: case DATA_TYPE_CHAR:
script_context.SetResult(hook->getArgument<unsigned char>(paramIndex)); script_context.SetResult(hook->getArgument<char>(paramIndex));
break; break;
case DATA_TYPE_SHORT: case DATA_TYPE_UCHAR:
script_context.SetResult(hook->getArgument<short>(paramIndex)); script_context.SetResult(hook->getArgument<unsigned char>(paramIndex));
break; break;
case DATA_TYPE_USHORT: case DATA_TYPE_SHORT:
script_context.SetResult(hook->getArgument<unsigned short>(paramIndex)); script_context.SetResult(hook->getArgument<short>(paramIndex));
break; break;
case DATA_TYPE_INT: case DATA_TYPE_USHORT:
script_context.SetResult(hook->getArgument<int>(paramIndex)); script_context.SetResult(hook->getArgument<unsigned short>(paramIndex));
break; break;
case DATA_TYPE_UINT: case DATA_TYPE_INT:
script_context.SetResult(hook->getArgument<unsigned int>(paramIndex)); script_context.SetResult(hook->getArgument<int>(paramIndex));
break; break;
case DATA_TYPE_LONG: case DATA_TYPE_UINT:
script_context.SetResult(hook->getArgument<long>(paramIndex)); script_context.SetResult(hook->getArgument<unsigned int>(paramIndex));
break; break;
case DATA_TYPE_ULONG: case DATA_TYPE_LONG:
script_context.SetResult(hook->getArgument<unsigned long>(paramIndex)); script_context.SetResult(hook->getArgument<long>(paramIndex));
break; break;
case DATA_TYPE_LONG_LONG: case DATA_TYPE_ULONG:
script_context.SetResult(hook->getArgument<long long>(paramIndex)); script_context.SetResult(hook->getArgument<unsigned long>(paramIndex));
break; break;
case DATA_TYPE_ULONG_LONG: case DATA_TYPE_LONG_LONG:
script_context.SetResult(hook->getArgument<unsigned long long>(paramIndex)); script_context.SetResult(hook->getArgument<long long>(paramIndex));
break; break;
case DATA_TYPE_FLOAT: case DATA_TYPE_ULONG_LONG:
script_context.SetResult(hook->getArgument<float>(paramIndex)); script_context.SetResult(hook->getArgument<unsigned long long>(paramIndex));
break; break;
case DATA_TYPE_DOUBLE: case DATA_TYPE_FLOAT:
script_context.SetResult(hook->getArgument<double>(paramIndex)); script_context.SetResult(hook->getArgument<float>(paramIndex));
break; break;
case DATA_TYPE_POINTER: case DATA_TYPE_DOUBLE:
script_context.SetResult(hook->getArgument<void*>(paramIndex)); script_context.SetResult(hook->getArgument<double>(paramIndex));
break; break;
case DATA_TYPE_STRING: case DATA_TYPE_POINTER:
script_context.SetResult(hook->getArgument<const char*>(paramIndex)); script_context.SetResult(hook->getArgument<void*>(paramIndex));
break; break;
default: case DATA_TYPE_STRING:
assert(!"Unknown function parameter type!"); script_context.SetResult(hook->getArgument<const char*>(paramIndex));
break; break;
} default:
} assert(!"Unknown function parameter type!");
break;
void DHookSetParam(ScriptContext& script_context) }
{ }
auto hook = script_context.GetArgument<dyno::Hook*>(0);
auto dataType = script_context.GetArgument<DataType_t>(1); void DHookSetParam(ScriptContext& script_context)
auto paramIndex = script_context.GetArgument<int>(2); {
if (hook == nullptr) { auto hook = script_context.GetArgument<dyno::Hook*>(0);
script_context.ThrowNativeError("Invalid hook"); auto dataType = script_context.GetArgument<DataType_t>(1);
} auto paramIndex = script_context.GetArgument<int>(2);
if (hook == nullptr)
auto valueIndex = 3; {
script_context.ThrowNativeError("Invalid hook");
switch (dataType) { }
case DATA_TYPE_BOOL:
hook->setArgument(paramIndex, script_context.GetArgument<bool>(valueIndex)); auto valueIndex = 3;
break;
case DATA_TYPE_CHAR: switch (dataType)
hook->setArgument(paramIndex, script_context.GetArgument<char>(valueIndex)); {
break; case DATA_TYPE_BOOL:
case DATA_TYPE_UCHAR: hook->setArgument(paramIndex, script_context.GetArgument<bool>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<unsigned char>(valueIndex)); break;
break; case DATA_TYPE_CHAR:
case DATA_TYPE_SHORT: hook->setArgument(paramIndex, script_context.GetArgument<char>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<short>(valueIndex)); break;
break; case DATA_TYPE_UCHAR:
case DATA_TYPE_USHORT: hook->setArgument(paramIndex, script_context.GetArgument<unsigned char>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<unsigned short>(valueIndex)); break;
break; case DATA_TYPE_SHORT:
case DATA_TYPE_INT: hook->setArgument(paramIndex, script_context.GetArgument<short>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<int>(valueIndex)); break;
break; case DATA_TYPE_USHORT:
case DATA_TYPE_UINT: hook->setArgument(paramIndex, script_context.GetArgument<unsigned short>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<unsigned int>(valueIndex)); break;
break; case DATA_TYPE_INT:
case DATA_TYPE_LONG: hook->setArgument(paramIndex, script_context.GetArgument<int>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<long>(valueIndex)); break;
break; case DATA_TYPE_UINT:
case DATA_TYPE_ULONG: hook->setArgument(paramIndex, script_context.GetArgument<unsigned int>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<unsigned long>(valueIndex)); break;
break; case DATA_TYPE_LONG:
case DATA_TYPE_LONG_LONG: hook->setArgument(paramIndex, script_context.GetArgument<long>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<long long>(valueIndex)); break;
break; case DATA_TYPE_ULONG:
case DATA_TYPE_ULONG_LONG: hook->setArgument(paramIndex, script_context.GetArgument<unsigned long>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<unsigned long long>(valueIndex)); break;
break; case DATA_TYPE_LONG_LONG:
case DATA_TYPE_FLOAT: hook->setArgument(paramIndex, script_context.GetArgument<long long>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<float>(valueIndex)); break;
break; case DATA_TYPE_ULONG_LONG:
case DATA_TYPE_DOUBLE: hook->setArgument(paramIndex, script_context.GetArgument<unsigned long long>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<double>(valueIndex)); break;
break; case DATA_TYPE_FLOAT:
case DATA_TYPE_POINTER: hook->setArgument(paramIndex, script_context.GetArgument<float>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<void*>(valueIndex)); break;
break; case DATA_TYPE_DOUBLE:
case DATA_TYPE_STRING: hook->setArgument(paramIndex, script_context.GetArgument<double>(valueIndex));
hook->setArgument(paramIndex, script_context.GetArgument<const char*>(valueIndex)); break;
break; case DATA_TYPE_POINTER:
default: hook->setArgument(paramIndex, script_context.GetArgument<void*>(valueIndex));
assert(!"Unknown function parameter type!"); break;
break; case DATA_TYPE_STRING:
} hook->setArgument(paramIndex, script_context.GetArgument<const char*>(valueIndex));
} break;
default:
REGISTER_NATIVES(dynamichooks, { assert(!"Unknown function parameter type!");
ScriptEngine::RegisterNativeHandler("DYNAMIC_HOOK_GET_RETURN", DHookGetReturn); break;
ScriptEngine::RegisterNativeHandler("DYNAMIC_HOOK_SET_RETURN", DHookSetReturn); }
ScriptEngine::RegisterNativeHandler("DYNAMIC_HOOK_GET_PARAM", DHookGetParam); }
ScriptEngine::RegisterNativeHandler("DYNAMIC_HOOK_SET_PARAM", DHookSetParam);
}) REGISTER_NATIVES(dynamichooks, {
} // namespace counterstrikesharp ScriptEngine::RegisterNativeHandler("DYNAMIC_HOOK_GET_RETURN", DHookGetReturn);
ScriptEngine::RegisterNativeHandler("DYNAMIC_HOOK_SET_RETURN", DHookSetReturn);
ScriptEngine::RegisterNativeHandler("DYNAMIC_HOOK_GET_PARAM", DHookGetParam);
ScriptEngine::RegisterNativeHandler("DYNAMIC_HOOK_SET_PARAM", DHookSetParam);
})
} // namespace counterstrikesharp

View File

@@ -20,7 +20,6 @@
#include <filesystem.h> #include <filesystem.h>
#include <public/worldsize.h> #include <public/worldsize.h>
// clang-format off
#include "mm_plugin.h" #include "mm_plugin.h"
#include "core/timer_system.h" #include "core/timer_system.h"
#include "core/utils.h" #include "core/utils.h"
@@ -32,7 +31,6 @@
#include "core/managers/player_manager.h" #include "core/managers/player_manager.h"
#include "core/managers/server_manager.h" #include "core/managers/server_manager.h"
#include "core/tick_scheduler.h" #include "core/tick_scheduler.h"
// clang-format on
#if _WIN32 #if _WIN32
#undef GetCurrentTime #undef GetCurrentTime

View File

@@ -20,44 +20,49 @@
#include "scripting/autonative.h" #include "scripting/autonative.h"
#include "igameevents.h" #include "igameevents.h"
namespace counterstrikesharp { namespace counterstrikesharp {
std::vector<IGameEvent *> managed_game_events; std::vector<IGameEvent*> managed_game_events;
static void HookEvent(ScriptContext &script_context) { static void HookEvent(ScriptContext& script_context)
const char *name = script_context.GetArgument<const char *>(0); {
const char* name = script_context.GetArgument<const char*>(0);
auto callback = script_context.GetArgument<CallbackT>(1); auto callback = script_context.GetArgument<CallbackT>(1);
auto post = script_context.GetArgument<bool>(2); auto post = script_context.GetArgument<bool>(2);
globals::eventManager.HookEvent(name, callback, post); globals::eventManager.HookEvent(name, callback, post);
} }
static void UnhookEvent(ScriptContext &script_context) { static void UnhookEvent(ScriptContext& script_context)
const char *name = script_context.GetArgument<const char *>(0); {
const char* name = script_context.GetArgument<const char*>(0);
auto callback = script_context.GetArgument<CallbackT>(1); auto callback = script_context.GetArgument<CallbackT>(1);
auto post = script_context.GetArgument<bool>(2); auto post = script_context.GetArgument<bool>(2);
globals::eventManager.UnhookEvent(name, callback, post); globals::eventManager.UnhookEvent(name, callback, post);
} }
static IGameEvent *CreateEvent(ScriptContext &script_context) { static IGameEvent* CreateEvent(ScriptContext& script_context)
auto name = script_context.GetArgument<const char *>(0); {
auto name = script_context.GetArgument<const char*>(0);
bool force = script_context.GetArgument<bool>(1); bool force = script_context.GetArgument<bool>(1);
auto pEvent = globals::gameEventManager->CreateEvent(name, force); auto pEvent = globals::gameEventManager->CreateEvent(name, force);
if (pEvent != nullptr) { if (pEvent != nullptr)
{
managed_game_events.push_back(pEvent); managed_game_events.push_back(pEvent);
} }
return pEvent; return pEvent;
} }
static void FireEvent(ScriptContext &script_context) { static void FireEvent(ScriptContext& script_context)
auto game_event = script_context.GetArgument<IGameEvent *>(0); {
auto game_event = script_context.GetArgument<IGameEvent*>(0);
bool dont_broadcast = script_context.GetArgument<bool>(1); bool dont_broadcast = script_context.GetArgument<bool>(1);
if (!game_event) { if (!game_event)
{
script_context.ThrowNativeError("Invalid game event"); script_context.ThrowNativeError("Invalid game event");
return; return;
} }
@@ -66,17 +71,19 @@ static void FireEvent(ScriptContext &script_context) {
managed_game_events.erase(std::remove(managed_game_events.begin(), managed_game_events.end(), game_event), managed_game_events.end()); managed_game_events.erase(std::remove(managed_game_events.begin(), managed_game_events.end(), game_event), managed_game_events.end());
} }
static void FireEventToClient(ScriptContext& script_context)
static void FireEventToClient(ScriptContext& script_context) { {
auto game_event = script_context.GetArgument<IGameEvent*>(0); auto game_event = script_context.GetArgument<IGameEvent*>(0);
int entityIndex = script_context.GetArgument<int>(1); int entityIndex = script_context.GetArgument<int>(1);
if (!game_event) { if (!game_event)
{
script_context.ThrowNativeError("Invalid game event"); script_context.ThrowNativeError("Invalid game event");
return; return;
} }
IGameEventListener2* pListener = globals::GetLegacyGameEventListener(CPlayerSlot(entityIndex - 1)); IGameEventListener2* pListener = globals::GetLegacyGameEventListener(CPlayerSlot(entityIndex - 1));
if (!pListener) { if (!pListener)
{
script_context.ThrowNativeError("Could not get player event listener"); script_context.ThrowNativeError("Could not get player event listener");
return; return;
} }
@@ -84,21 +91,25 @@ static void FireEventToClient(ScriptContext& script_context) {
pListener->FireGameEvent(game_event); pListener->FireGameEvent(game_event);
} }
static void FreeEvent(ScriptContext& script_context) { static void FreeEvent(ScriptContext& script_context)
{
auto game_event = script_context.GetArgument<IGameEvent*>(0); auto game_event = script_context.GetArgument<IGameEvent*>(0);
if (!game_event) { if (!game_event)
script_context.ThrowNativeError("Invalid game event"); {
return; script_context.ThrowNativeError("Invalid game event");
return;
} }
globals::gameEventManager->FreeEvent(game_event); globals::gameEventManager->FreeEvent(game_event);
managed_game_events.erase(std::remove(managed_game_events.begin(), managed_game_events.end(), game_event), managed_game_events.end()); managed_game_events.erase(std::remove(managed_game_events.begin(), managed_game_events.end(), game_event), managed_game_events.end());
} }
static const char *GetEventName(ScriptContext &script_context) { static const char* GetEventName(ScriptContext& script_context)
IGameEvent *game_event = script_context.GetArgument<IGameEvent *>(0); {
IGameEvent* game_event = script_context.GetArgument<IGameEvent*>(0);
if (!game_event) { if (!game_event)
{
script_context.ThrowNativeError("Invalid game event"); script_context.ThrowNativeError("Invalid game event");
return nullptr; return nullptr;
} }
@@ -106,11 +117,13 @@ static const char *GetEventName(ScriptContext &script_context) {
return game_event->GetName(); return game_event->GetName();
} }
static bool GetEventBool(ScriptContext &script_context) { static bool GetEventBool(ScriptContext& script_context)
IGameEvent *game_event = script_context.GetArgument<IGameEvent *>(0); {
const char *key_name = script_context.GetArgument<const char *>(1); IGameEvent* game_event = script_context.GetArgument<IGameEvent*>(0);
const char* key_name = script_context.GetArgument<const char*>(1);
if (!game_event) { if (!game_event)
{
script_context.ThrowNativeError("Invalid game event"); script_context.ThrowNativeError("Invalid game event");
return false; return false;
} }
@@ -118,11 +131,13 @@ static bool GetEventBool(ScriptContext &script_context) {
return game_event->GetBool(key_name); return game_event->GetBool(key_name);
} }
static int GetEventInt(ScriptContext &script_context) { static int GetEventInt(ScriptContext& script_context)
IGameEvent *game_event = script_context.GetArgument<IGameEvent *>(0); {
const char *key_name = script_context.GetArgument<const char *>(1); IGameEvent* game_event = script_context.GetArgument<IGameEvent*>(0);
const char* key_name = script_context.GetArgument<const char*>(1);
if (!game_event) { if (!game_event)
{
script_context.ThrowNativeError("Invalid game event"); script_context.ThrowNativeError("Invalid game event");
return -1; return -1;
} }
@@ -130,11 +145,13 @@ static int GetEventInt(ScriptContext &script_context) {
return game_event->GetInt(key_name); return game_event->GetInt(key_name);
} }
static float GetEventFloat(ScriptContext &script_context) { static float GetEventFloat(ScriptContext& script_context)
IGameEvent *game_event = script_context.GetArgument<IGameEvent *>(0); {
const char *key_name = script_context.GetArgument<const char *>(1); IGameEvent* game_event = script_context.GetArgument<IGameEvent*>(0);
const char* key_name = script_context.GetArgument<const char*>(1);
if (!game_event) { if (!game_event)
{
script_context.ThrowNativeError("Invalid game event"); script_context.ThrowNativeError("Invalid game event");
return -1; return -1;
} }
@@ -142,11 +159,13 @@ static float GetEventFloat(ScriptContext &script_context) {
return game_event->GetFloat(key_name); return game_event->GetFloat(key_name);
} }
static const char *GetEventString(ScriptContext &script_context) { static const char* GetEventString(ScriptContext& script_context)
IGameEvent *game_event = script_context.GetArgument<IGameEvent *>(0); {
const char *key_name = script_context.GetArgument<const char *>(1); IGameEvent* game_event = script_context.GetArgument<IGameEvent*>(0);
const char* key_name = script_context.GetArgument<const char*>(1);
if (!game_event) { if (!game_event)
{
script_context.ThrowNativeError("Invalid game event"); script_context.ThrowNativeError("Invalid game event");
return nullptr; return nullptr;
} }
@@ -154,51 +173,61 @@ static const char *GetEventString(ScriptContext &script_context) {
return game_event->GetString(key_name); return game_event->GetString(key_name);
} }
static void SetEventBool(ScriptContext &script_context) { static void SetEventBool(ScriptContext& script_context)
IGameEvent *game_event = script_context.GetArgument<IGameEvent *>(0); {
const char *key_name = script_context.GetArgument<const char *>(1); IGameEvent* game_event = script_context.GetArgument<IGameEvent*>(0);
const char* key_name = script_context.GetArgument<const char*>(1);
const bool value = script_context.GetArgument<bool>(2); const bool value = script_context.GetArgument<bool>(2);
if (game_event) { if (game_event)
{
game_event->SetBool(key_name, value); game_event->SetBool(key_name, value);
} }
} }
static void SetEventInt(ScriptContext &script_context) { static void SetEventInt(ScriptContext& script_context)
IGameEvent *game_event = script_context.GetArgument<IGameEvent *>(0); {
const char *key_name = script_context.GetArgument<const char *>(1); IGameEvent* game_event = script_context.GetArgument<IGameEvent*>(0);
const char* key_name = script_context.GetArgument<const char*>(1);
const int value = script_context.GetArgument<int>(2); const int value = script_context.GetArgument<int>(2);
if (game_event) { if (game_event)
{
game_event->SetInt(key_name, value); game_event->SetInt(key_name, value);
} }
} }
static void SetEventFloat(ScriptContext &script_context) { static void SetEventFloat(ScriptContext& script_context)
IGameEvent *game_event = script_context.GetArgument<IGameEvent *>(0); {
const char *key_name = script_context.GetArgument<const char *>(1); IGameEvent* game_event = script_context.GetArgument<IGameEvent*>(0);
const char* key_name = script_context.GetArgument<const char*>(1);
const float value = script_context.GetArgument<float>(2); const float value = script_context.GetArgument<float>(2);
if (game_event) { if (game_event)
{
game_event->SetFloat(key_name, value); game_event->SetFloat(key_name, value);
} }
} }
static void SetEventString(ScriptContext &script_context) { static void SetEventString(ScriptContext& script_context)
IGameEvent *game_event = script_context.GetArgument<IGameEvent *>(0); {
const char *key_name = script_context.GetArgument<const char *>(1); IGameEvent* game_event = script_context.GetArgument<IGameEvent*>(0);
const char *value = script_context.GetArgument<const char *>(2); const char* key_name = script_context.GetArgument<const char*>(1);
const char* value = script_context.GetArgument<const char*>(2);
if (game_event) { if (game_event)
{
game_event->SetString(key_name, value); game_event->SetString(key_name, value);
} }
} }
static void *GetPlayerController(ScriptContext &scriptContext) { static void* GetPlayerController(ScriptContext& scriptContext)
IGameEvent *gameEvent = scriptContext.GetArgument<IGameEvent *>(0); {
const char *keyName = scriptContext.GetArgument<const char *>(1); IGameEvent* gameEvent = scriptContext.GetArgument<IGameEvent*>(0);
const char* keyName = scriptContext.GetArgument<const char*>(1);
if (gameEvent == nullptr) { if (gameEvent == nullptr)
{
scriptContext.ThrowNativeError("Invalid game event"); scriptContext.ThrowNativeError("Invalid game event");
return nullptr; return nullptr;
} }
@@ -206,41 +235,49 @@ static void *GetPlayerController(ScriptContext &scriptContext) {
return gameEvent->GetPlayerController(keyName); return gameEvent->GetPlayerController(keyName);
} }
static void SetPlayerController(ScriptContext &scriptContext) { static void SetPlayerController(ScriptContext& scriptContext)
IGameEvent *gameEvent = scriptContext.GetArgument<IGameEvent *>(0); {
const char *keyName = scriptContext.GetArgument<const char *>(1); IGameEvent* gameEvent = scriptContext.GetArgument<IGameEvent*>(0);
auto *value = scriptContext.GetArgument<CEntityInstance *>(2); const char* keyName = scriptContext.GetArgument<const char*>(1);
auto* value = scriptContext.GetArgument<CEntityInstance*>(2);
if (gameEvent != nullptr) { if (gameEvent != nullptr)
{
gameEvent->SetPlayer(keyName, value); gameEvent->SetPlayer(keyName, value);
} }
} }
static void SetEntity(ScriptContext &scriptContext) { static void SetEntity(ScriptContext& scriptContext)
IGameEvent *gameEvent = scriptContext.GetArgument<IGameEvent *>(0); {
const char *keyName = scriptContext.GetArgument<const char *>(1); IGameEvent* gameEvent = scriptContext.GetArgument<IGameEvent*>(0);
auto *value = scriptContext.GetArgument<CEntityInstance *>(2); const char* keyName = scriptContext.GetArgument<const char*>(1);
auto* value = scriptContext.GetArgument<CEntityInstance*>(2);
if (gameEvent != nullptr) { if (gameEvent != nullptr)
{
gameEvent->SetEntity(keyName, value); gameEvent->SetEntity(keyName, value);
} }
} }
static void SetEntityIndex(ScriptContext &scriptContext) { static void SetEntityIndex(ScriptContext& scriptContext)
IGameEvent *gameEvent = scriptContext.GetArgument<IGameEvent *>(0); {
const char *keyName = scriptContext.GetArgument<const char *>(1); IGameEvent* gameEvent = scriptContext.GetArgument<IGameEvent*>(0);
const char* keyName = scriptContext.GetArgument<const char*>(1);
auto index = scriptContext.GetArgument<int>(2); auto index = scriptContext.GetArgument<int>(2);
if (gameEvent != nullptr) { if (gameEvent != nullptr)
{
gameEvent->SetEntity(keyName, CEntityIndex{ index }); gameEvent->SetEntity(keyName, CEntityIndex{ index });
} }
} }
static void *GetPlayerPawn(ScriptContext& scriptContext) { static void* GetPlayerPawn(ScriptContext& scriptContext)
IGameEvent *gameEvent = scriptContext.GetArgument<IGameEvent *>(0); {
const char *keyName = scriptContext.GetArgument<const char *>(1); IGameEvent* gameEvent = scriptContext.GetArgument<IGameEvent*>(0);
const char* keyName = scriptContext.GetArgument<const char*>(1);
if (gameEvent == nullptr) { if (gameEvent == nullptr)
{
scriptContext.ThrowNativeError("Invalid game event"); scriptContext.ThrowNativeError("Invalid game event");
return nullptr; return nullptr;
} }
@@ -248,11 +285,13 @@ static void *GetPlayerPawn(ScriptContext& scriptContext) {
return gameEvent->GetPlayerPawn(keyName); return gameEvent->GetPlayerPawn(keyName);
} }
static uint64 GetUint64(ScriptContext &scriptContext) { static uint64 GetUint64(ScriptContext& scriptContext)
IGameEvent *gameEvent = scriptContext.GetArgument<IGameEvent *>(0); {
const char *keyName = scriptContext.GetArgument<const char *>(1); IGameEvent* gameEvent = scriptContext.GetArgument<IGameEvent*>(0);
const char* keyName = scriptContext.GetArgument<const char*>(1);
if (gameEvent == nullptr) { if (gameEvent == nullptr)
{
scriptContext.ThrowNativeError("Invalid game event"); scriptContext.ThrowNativeError("Invalid game event");
return 0; return 0;
} }
@@ -260,18 +299,21 @@ static uint64 GetUint64(ScriptContext &scriptContext) {
return gameEvent->GetUint64(keyName); return gameEvent->GetUint64(keyName);
} }
static void SetUint64(ScriptContext &scriptContext) { static void SetUint64(ScriptContext& scriptContext)
IGameEvent *gameEvent = scriptContext.GetArgument<IGameEvent *>(0); {
const char *keyName = scriptContext.GetArgument<const char *>(1); IGameEvent* gameEvent = scriptContext.GetArgument<IGameEvent*>(0);
const char* keyName = scriptContext.GetArgument<const char*>(1);
auto value = scriptContext.GetArgument<uint64>(2); auto value = scriptContext.GetArgument<uint64>(2);
if (gameEvent != nullptr) { if (gameEvent != nullptr)
{
gameEvent->SetUint64(keyName, value); gameEvent->SetUint64(keyName, value);
} }
} }
static int LoadEventsFromFile(ScriptContext &script_context) { static int LoadEventsFromFile(ScriptContext& script_context)
auto [path, searchAll] = script_context.GetArguments<const char *, bool>(); {
auto [path, searchAll] = script_context.GetArguments<const char*, bool>();
return globals::gameEventManager->LoadEventsFromFile(path, searchAll); return globals::gameEventManager->LoadEventsFromFile(path, searchAll);
} }
@@ -304,8 +346,7 @@ REGISTER_NATIVES(events, {
ScriptEngine::RegisterNativeHandler("GET_EVENT_UINT64", GetUint64); ScriptEngine::RegisterNativeHandler("GET_EVENT_UINT64", GetUint64);
ScriptEngine::RegisterNativeHandler("SET_EVENT_UINT64", SetUint64); ScriptEngine::RegisterNativeHandler("SET_EVENT_UINT64", SetUint64);
ScriptEngine::RegisterNativeHandler("LOAD_EVENTS_FROM_FILE", LoadEventsFromFile); ScriptEngine::RegisterNativeHandler("LOAD_EVENTS_FROM_FILE", LoadEventsFromFile);
}) })
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -26,7 +26,5 @@ static void* MetaFactory(ScriptContext& script_context)
return ptr; return ptr;
} }
REGISTER_NATIVES(metamod, { REGISTER_NATIVES(metamod, { ScriptEngine::RegisterNativeHandler("META_FACTORY", MetaFactory); })
ScriptEngine::RegisterNativeHandler("META_FACTORY", MetaFactory);
})
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -57,12 +57,10 @@ int GetSchemaClassSize(ScriptContext& script_context)
{ {
auto className = script_context.GetArgument<const char*>(0); auto className = script_context.GetArgument<const char*>(0);
CSchemaSystemTypeScope* pType = CSchemaSystemTypeScope* pType = globals::schemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
globals::schemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className).Get(); SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className).Get();
if (!pClassInfo) if (!pClassInfo) return -1;
return -1;
return pClassInfo->m_nSize; return pClassInfo->m_nSize;
} }
@@ -78,70 +76,56 @@ void GetSchemaValueByName(ScriptContext& script_context)
const auto m_key = schema::GetOffset(className, classKey, memberName, memberKey); const auto m_key = schema::GetOffset(className, classKey, memberName, memberKey);
switch (returnType) { switch (returnType)
case DATA_TYPE_BOOL: {
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<bool>>( case DATA_TYPE_BOOL:
(uintptr_t)(instancePointer) + m_key.offset)); script_context.SetResult(*reinterpret_cast<std::add_pointer_t<bool>>((uintptr_t)(instancePointer) + m_key.offset));
break; break;
case DATA_TYPE_CHAR: case DATA_TYPE_CHAR:
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<char>>( script_context.SetResult(*reinterpret_cast<std::add_pointer_t<char>>((uintptr_t)(instancePointer) + m_key.offset));
(uintptr_t)(instancePointer) + m_key.offset)); break;
break; case DATA_TYPE_UCHAR:
case DATA_TYPE_UCHAR: script_context.SetResult(*reinterpret_cast<std::add_pointer_t<unsigned char>>((uintptr_t)(instancePointer) + m_key.offset));
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<unsigned char>>( break;
(uintptr_t)(instancePointer) + m_key.offset)); case DATA_TYPE_SHORT:
break; script_context.SetResult(*reinterpret_cast<std::add_pointer_t<short>>((uintptr_t)(instancePointer) + m_key.offset));
case DATA_TYPE_SHORT: break;
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<short>>( case DATA_TYPE_USHORT:
(uintptr_t)(instancePointer) + m_key.offset)); script_context.SetResult(*reinterpret_cast<std::add_pointer_t<unsigned short>>((uintptr_t)(instancePointer) + m_key.offset));
break; break;
case DATA_TYPE_USHORT: case DATA_TYPE_INT:
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<unsigned short>>( script_context.SetResult(*reinterpret_cast<std::add_pointer_t<int>>((uintptr_t)(instancePointer) + m_key.offset));
(uintptr_t)(instancePointer) + m_key.offset)); break;
break; case DATA_TYPE_UINT:
case DATA_TYPE_INT: script_context.SetResult(*reinterpret_cast<std::add_pointer_t<unsigned int>>((uintptr_t)(instancePointer) + m_key.offset));
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<int>>( break;
(uintptr_t)(instancePointer) + m_key.offset)); case DATA_TYPE_LONG:
break; script_context.SetResult(*reinterpret_cast<std::add_pointer_t<long>>((uintptr_t)(instancePointer) + m_key.offset));
case DATA_TYPE_UINT: break;
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<unsigned int>>( case DATA_TYPE_ULONG:
(uintptr_t)(instancePointer) + m_key.offset)); script_context.SetResult(*reinterpret_cast<std::add_pointer_t<unsigned long>>((uintptr_t)(instancePointer) + m_key.offset));
break; break;
case DATA_TYPE_LONG: case DATA_TYPE_LONG_LONG:
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<long>>( script_context.SetResult(*reinterpret_cast<std::add_pointer_t<long long>>((uintptr_t)(instancePointer) + m_key.offset));
(uintptr_t)(instancePointer) + m_key.offset)); break;
break; case DATA_TYPE_ULONG_LONG:
case DATA_TYPE_ULONG: script_context.SetResult(*reinterpret_cast<std::add_pointer_t<uint64_t>>((uintptr_t)(instancePointer) + m_key.offset));
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<unsigned long>>( break;
(uintptr_t)(instancePointer) + m_key.offset)); case DATA_TYPE_FLOAT:
break; script_context.SetResult(*reinterpret_cast<std::add_pointer_t<float>>((uintptr_t)(instancePointer) + m_key.offset));
case DATA_TYPE_LONG_LONG: break;
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<long long>>( case DATA_TYPE_DOUBLE:
(uintptr_t)(instancePointer) + m_key.offset)); script_context.SetResult(*reinterpret_cast<std::add_pointer_t<double>>((uintptr_t)(instancePointer) + m_key.offset));
break; break;
case DATA_TYPE_ULONG_LONG: case DATA_TYPE_POINTER:
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<uint64_t>>( script_context.SetResult(reinterpret_cast<std::add_pointer_t<void>>((uintptr_t)(instancePointer) + m_key.offset));
(uintptr_t)(instancePointer) + m_key.offset)); break;
break; case DATA_TYPE_STRING:
case DATA_TYPE_FLOAT: script_context.SetResult(reinterpret_cast<std::add_pointer_t<char>>((uintptr_t)(instancePointer) + m_key.offset));
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<float>>( break;
(uintptr_t)(instancePointer) + m_key.offset)); default:
break; assert(!"Unknown function return type!");
case DATA_TYPE_DOUBLE: break;
script_context.SetResult(*reinterpret_cast<std::add_pointer_t<double>>(
(uintptr_t)(instancePointer) + m_key.offset));
break;
case DATA_TYPE_POINTER:
script_context.SetResult(reinterpret_cast<std::add_pointer_t<void>>(
(uintptr_t)(instancePointer) + m_key.offset));
break;
case DATA_TYPE_STRING:
script_context.SetResult(reinterpret_cast<std::add_pointer_t<char>>(
(uintptr_t)(instancePointer) + m_key.offset));
break;
default:
assert(!"Unknown function return type!");
break;
} }
} }
@@ -152,7 +136,9 @@ void SetSchemaValueByName(ScriptContext& script_context)
auto className = script_context.GetArgument<const char*>(2); auto className = script_context.GetArgument<const char*>(2);
auto memberName = script_context.GetArgument<const char*>(3); auto memberName = script_context.GetArgument<const char*>(3);
if (globals::coreConfig->FollowCS2ServerGuidelines && std::find(schema::CS2BadList.begin(), schema::CS2BadList.end(), memberName) != schema::CS2BadList.end()) { if (globals::coreConfig->FollowCS2ServerGuidelines &&
std::find(schema::CS2BadList.begin(), schema::CS2BadList.end(), memberName) != schema::CS2BadList.end())
{
CSSHARP_CORE_ERROR("Cannot set '{}::{}' with \"FollowCS2ServerGuidelines\" option enabled.", className, memberName); CSSHARP_CORE_ERROR("Cannot set '{}::{}' with \"FollowCS2ServerGuidelines\" option enabled.", className, memberName);
return; return;
} }
@@ -162,76 +148,68 @@ void SetSchemaValueByName(ScriptContext& script_context)
const auto m_key = schema::GetOffset(className, classKey, memberName, memberKey); const auto m_key = schema::GetOffset(className, classKey, memberName, memberKey);
switch (dataType) { switch (dataType)
case DATA_TYPE_BOOL: {
*reinterpret_cast<std::add_pointer_t<bool>>((uintptr_t)(instancePointer) + m_key.offset) = case DATA_TYPE_BOOL:
script_context.GetArgument<bool>(4); *reinterpret_cast<std::add_pointer_t<bool>>((uintptr_t)(instancePointer) + m_key.offset) = script_context.GetArgument<bool>(4);
break; break;
case DATA_TYPE_CHAR: case DATA_TYPE_CHAR:
*reinterpret_cast<std::add_pointer_t<char>>((uintptr_t)(instancePointer) + m_key.offset) = *reinterpret_cast<std::add_pointer_t<char>>((uintptr_t)(instancePointer) + m_key.offset) = script_context.GetArgument<char>(4);
script_context.GetArgument<char>(4); break;
break; case DATA_TYPE_UCHAR:
case DATA_TYPE_UCHAR: *reinterpret_cast<std::add_pointer_t<unsigned char>>((uintptr_t)(instancePointer) + m_key.offset) =
*reinterpret_cast<std::add_pointer_t<unsigned char>>((uintptr_t)(instancePointer) + script_context.GetArgument<unsigned char>(4);
m_key.offset) = break;
script_context.GetArgument<unsigned char>(4); case DATA_TYPE_SHORT:
break; *reinterpret_cast<std::add_pointer_t<short>>((uintptr_t)(instancePointer) + m_key.offset) =
case DATA_TYPE_SHORT: script_context.GetArgument<short>(4);
*reinterpret_cast<std::add_pointer_t<short>>((uintptr_t)(instancePointer) + m_key.offset) = break;
script_context.GetArgument<short>(4); case DATA_TYPE_USHORT:
break; *reinterpret_cast<std::add_pointer_t<unsigned short>>((uintptr_t)(instancePointer) + m_key.offset) =
case DATA_TYPE_USHORT: script_context.GetArgument<unsigned short>(4);
*reinterpret_cast<std::add_pointer_t<unsigned short>>((uintptr_t)(instancePointer) + break;
m_key.offset) = case DATA_TYPE_INT:
script_context.GetArgument<unsigned short>(4); *reinterpret_cast<std::add_pointer_t<int>>((uintptr_t)(instancePointer) + m_key.offset) = script_context.GetArgument<int>(4);
break; break;
case DATA_TYPE_INT: case DATA_TYPE_UINT:
*reinterpret_cast<std::add_pointer_t<int>>((uintptr_t)(instancePointer) + m_key.offset) = *reinterpret_cast<std::add_pointer_t<unsigned int>>((uintptr_t)(instancePointer) + m_key.offset) =
script_context.GetArgument<int>(4); script_context.GetArgument<unsigned int>(4);
break; break;
case DATA_TYPE_UINT: case DATA_TYPE_LONG:
*reinterpret_cast<std::add_pointer_t<unsigned int>>((uintptr_t)(instancePointer) + *reinterpret_cast<std::add_pointer_t<long>>((uintptr_t)(instancePointer) + m_key.offset) = script_context.GetArgument<long>(4);
m_key.offset) = break;
script_context.GetArgument<unsigned int>(4); case DATA_TYPE_ULONG:
break; *reinterpret_cast<std::add_pointer_t<unsigned long>>((uintptr_t)(instancePointer) + m_key.offset) =
case DATA_TYPE_LONG: script_context.GetArgument<unsigned long>(4);
*reinterpret_cast<std::add_pointer_t<long>>((uintptr_t)(instancePointer) + m_key.offset) = break;
script_context.GetArgument<long>(4); case DATA_TYPE_LONG_LONG:
break; *reinterpret_cast<std::add_pointer_t<long long>>((uintptr_t)(instancePointer) + m_key.offset) =
case DATA_TYPE_ULONG: script_context.GetArgument<long long>(4);
*reinterpret_cast<std::add_pointer_t<unsigned long>>((uintptr_t)(instancePointer) + break;
m_key.offset) = case DATA_TYPE_ULONG_LONG:
script_context.GetArgument<unsigned long>(4); *reinterpret_cast<std::add_pointer_t<uint64_t>>((uintptr_t)(instancePointer) + m_key.offset) =
break; script_context.GetArgument<uint64_t>(4);
case DATA_TYPE_LONG_LONG: break;
*reinterpret_cast<std::add_pointer_t<long long>>( case DATA_TYPE_FLOAT:
(uintptr_t)(instancePointer) + m_key.offset) = script_context.GetArgument<long long>(4); *reinterpret_cast<std::add_pointer_t<float>>((uintptr_t)(instancePointer) + m_key.offset) =
break; script_context.GetArgument<float>(4);
case DATA_TYPE_ULONG_LONG: break;
*reinterpret_cast<std::add_pointer_t<uint64_t>>( case DATA_TYPE_DOUBLE:
(uintptr_t)(instancePointer) + m_key.offset) = script_context.GetArgument<uint64_t>(4); *reinterpret_cast<std::add_pointer_t<double>>((uintptr_t)(instancePointer) + m_key.offset) =
break; script_context.GetArgument<double>(4);
case DATA_TYPE_FLOAT: break;
*reinterpret_cast<std::add_pointer_t<float>>((uintptr_t)(instancePointer) + m_key.offset) = case DATA_TYPE_POINTER:
script_context.GetArgument<float>(4); *reinterpret_cast<void**>((uintptr_t)(instancePointer) + m_key.offset) = script_context.GetArgument<void*>(4);
break; break;
case DATA_TYPE_DOUBLE: case DATA_TYPE_STRING:
*reinterpret_cast<std::add_pointer_t<double>>((uintptr_t)(instancePointer) + m_key.offset) = {
script_context.GetArgument<double>(4); auto duplicated = strdup(script_context.GetArgument<const char*>(4));
break; *reinterpret_cast<char**>((uintptr_t)(instancePointer) + m_key.offset) = duplicated;
case DATA_TYPE_POINTER: break;
*reinterpret_cast<void**>((uintptr_t)(instancePointer) + m_key.offset) = }
script_context.GetArgument<void*>(4); default:
break; assert(!"Unknown function data type!");
case DATA_TYPE_STRING: { break;
auto duplicated = strdup(script_context.GetArgument<const char*>(4));
*reinterpret_cast<char**>((uintptr_t)(instancePointer) + m_key.offset) =
duplicated;
break;
}
default:
assert(!"Unknown function data type!");
break;
} }
} }
@@ -242,4 +220,4 @@ REGISTER_NATIVES(schema, {
ScriptEngine::RegisterNativeHandler("SET_SCHEMA_VALUE_BY_NAME", SetSchemaValueByName); ScriptEngine::RegisterNativeHandler("SET_SCHEMA_VALUE_BY_NAME", SetSchemaValueByName);
ScriptEngine::RegisterNativeHandler("GET_SCHEMA_CLASS_SIZE", GetSchemaClassSize); ScriptEngine::RegisterNativeHandler("GET_SCHEMA_CLASS_SIZE", GetSchemaClassSize);
}) })
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -20,18 +20,13 @@
namespace counterstrikesharp { namespace counterstrikesharp {
static void *GetEconItemSystem(ScriptContext& scriptContext) { static void* GetEconItemSystem(ScriptContext& scriptContext) { return globals::serverManager.GetEconItemSystem(); }
return globals::serverManager.GetEconItemSystem();
}
static bool IsServerPaused(ScriptContext& scriptContext) static bool IsServerPaused(ScriptContext& scriptContext) { return globals::serverManager.IsPaused(); }
{
return globals::serverManager.IsPaused();
}
REGISTER_NATIVES(server, { REGISTER_NATIVES(server, {
ScriptEngine::RegisterNativeHandler("GET_ECON_ITEM_SYSTEM", GetEconItemSystem); ScriptEngine::RegisterNativeHandler("GET_ECON_ITEM_SYSTEM", GetEconItemSystem);
ScriptEngine::RegisterNativeHandler("IS_SERVER_PAUSED", IsServerPaused); ScriptEngine::RegisterNativeHandler("IS_SERVER_PAUSED", IsServerPaused);
}) })
} } // namespace counterstrikesharp

View File

@@ -21,7 +21,8 @@
namespace counterstrikesharp { namespace counterstrikesharp {
timers::Timer *CreateTimer(ScriptContext &script_context) { timers::Timer* CreateTimer(ScriptContext& script_context)
{
auto interval = script_context.GetArgument<float>(0); auto interval = script_context.GetArgument<float>(0);
auto callback = script_context.GetArgument<CallbackT>(1); auto callback = script_context.GetArgument<CallbackT>(1);
auto flags = script_context.GetArgument<int>(2); auto flags = script_context.GetArgument<int>(2);
@@ -29,8 +30,9 @@ timers::Timer *CreateTimer(ScriptContext &script_context) {
return globals::timerSystem.CreateTimer(interval, callback, flags); return globals::timerSystem.CreateTimer(interval, callback, flags);
} }
void KillTimer(ScriptContext &script_context) { void KillTimer(ScriptContext& script_context)
auto timer = script_context.GetArgument<timers::Timer *>(0); {
auto timer = script_context.GetArgument<timers::Timer*>(0);
globals::timerSystem.KillTimer(timer); globals::timerSystem.KillTimer(timer);
} }
@@ -38,4 +40,4 @@ REGISTER_NATIVES(timers, {
ScriptEngine::RegisterNativeHandler("CREATE_TIMER", CreateTimer); ScriptEngine::RegisterNativeHandler("CREATE_TIMER", CreateTimer);
ScriptEngine::RegisterNativeHandler("KILL_TIMER", KillTimer); ScriptEngine::RegisterNativeHandler("KILL_TIMER", KillTimer);
}) })
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -13,8 +13,6 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. * * along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/ */
// clang-format off
#include "core/UserMessage.h" #include "core/UserMessage.h"
#include "core/globals.h" #include "core/globals.h"
#include "core/log.h" #include "core/log.h"
@@ -24,8 +22,6 @@
#include "core/recipientfilters.h" #include "core/recipientfilters.h"
// clang-format on
namespace counterstrikesharp { namespace counterstrikesharp {
#define GET_MESSAGE_OR_ERR() \ #define GET_MESSAGE_OR_ERR() \
@@ -620,13 +616,16 @@ static void UserMessageSend(ScriptContext& scriptContext)
CRecipientFilter filter{}; CRecipientFilter filter{};
filter.AddRecipientsFromMask(message->GetRecipientMask() ? *message->GetRecipientMask() : 0); filter.AddRecipientsFromMask(message->GetRecipientMask() ? *message->GetRecipientMask() : 0);
// This is for calling send in a UM hook, if calling normal send using the UM instance from the UM hook, it will cause an inifinite loop, then crashing the server // This is for calling send in a UM hook, if calling normal send using the UM instance from the UM hook, it will cause an inifinite
static void (IGameEventSystem::*PostEventAbstract)(CSplitScreenSlot, bool, IRecipientFilter*, INetworkMessageInternal*, const CNetMessage*, unsigned long) = &IGameEventSystem::PostEventAbstract; // loop, then crashing the server
static void (IGameEventSystem::*PostEventAbstract)(CSplitScreenSlot, bool, IRecipientFilter*, INetworkMessageInternal*,
const CNetMessage*, unsigned long) = &IGameEventSystem::PostEventAbstract;
if (message->IsManuallyAllocated()) if (message->IsManuallyAllocated())
globals::gameEventSystem->PostEventAbstract(0, false, &filter, message->GetSerializableMessage(), message->GetProtobufMessage(), 0); globals::gameEventSystem->PostEventAbstract(0, false, &filter, message->GetSerializableMessage(), message->GetProtobufMessage(), 0);
else else
SH_CALL(globals::gameEventSystem, PostEventAbstract)(0, false, &filter, message->GetSerializableMessage(), message->GetProtobufMessage(), 0); SH_CALL(globals::gameEventSystem, PostEventAbstract)(0, false, &filter, message->GetSerializableMessage(),
message->GetProtobufMessage(), 0);
} }
static void UserMessageDelete(ScriptContext& scriptContext) static void UserMessageDelete(ScriptContext& scriptContext)

View File

@@ -37,7 +37,8 @@ namespace counterstrikesharp {
std::stack<std::string> errors; std::stack<std::string> errors;
void ScriptContext::ThrowNativeError(const char *msg, ...) { void ScriptContext::ThrowNativeError(const char* msg, ...)
{
va_list arglist; va_list arglist;
char dest[256]; char dest[256];
va_start(arglist, msg); va_start(arglist, msg);
@@ -49,13 +50,15 @@ void ScriptContext::ThrowNativeError(const char *msg, ...) {
auto error_string = std::string(buff); auto error_string = std::string(buff);
errors.push(error_string); errors.push(error_string);
const char *ptr = errors.top().c_str(); const char* ptr = errors.top().c_str();
this->SetResult(ptr); this->SetResult(ptr);
*this->m_has_error = 1; *this->m_has_error = 1;
} }
void ScriptContext::Reset() { void ScriptContext::Reset()
if (*m_has_error) { {
if (*m_has_error)
{
errors.pop(); errors.pop();
} }
@@ -63,36 +66,43 @@ void ScriptContext::Reset() {
m_numArguments = 0; m_numArguments = 0;
*m_has_error = 0; *m_has_error = 0;
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++)
{
m_native_context->arguments[i] = 0; m_native_context->arguments[i] = 0;
} }
m_native_context->result = 0; m_native_context->result = 0;
} }
tl::optional<TNativeHandler> ScriptEngine::GetNativeHandler(uint64_t nativeIdentifier) { tl::optional<TNativeHandler> ScriptEngine::GetNativeHandler(uint64_t nativeIdentifier)
{
auto it = g_registeredHandlers.find(nativeIdentifier); auto it = g_registeredHandlers.find(nativeIdentifier);
if (it != g_registeredHandlers.end()) { if (it != g_registeredHandlers.end())
{
return it->second; return it->second;
} }
return tl::optional<TNativeHandler>(); return tl::optional<TNativeHandler>();
} }
tl::optional<TNativeHandler> ScriptEngine::GetNativeHandler(std::string identifier) { tl::optional<TNativeHandler> ScriptEngine::GetNativeHandler(std::string identifier)
{
auto it = g_registeredHandlers.find(hash_string(identifier.c_str())); auto it = g_registeredHandlers.find(hash_string(identifier.c_str()));
if (it != g_registeredHandlers.end()) { if (it != g_registeredHandlers.end())
{
return it->second; return it->second;
} }
return tl::optional<TNativeHandler>(); return tl::optional<TNativeHandler>();
} }
bool ScriptEngine::CallNativeHandler(uint64_t nativeIdentifier, ScriptContext &context) { bool ScriptEngine::CallNativeHandler(uint64_t nativeIdentifier, ScriptContext& context)
{
auto h = GetNativeHandler(nativeIdentifier); auto h = GetNativeHandler(nativeIdentifier);
if (h) { if (h)
{
(*h)(context); (*h)(context);
return true; return true;
@@ -101,27 +111,30 @@ bool ScriptEngine::CallNativeHandler(uint64_t nativeIdentifier, ScriptContext &c
return false; return false;
} }
void ScriptEngine::RegisterNativeHandlerInt(uint64_t nativeIdentifier, TNativeHandler function) { void ScriptEngine::RegisterNativeHandlerInt(uint64_t nativeIdentifier, TNativeHandler function)
{
g_registeredHandlers[nativeIdentifier] = function; g_registeredHandlers[nativeIdentifier] = function;
} }
void ScriptEngine::InvokeNative(counterstrikesharp::fxNativeContext &context) { void ScriptEngine::InvokeNative(counterstrikesharp::fxNativeContext& context)
{
if (context.nativeIdentifier == 0) return; if (context.nativeIdentifier == 0) return;
auto nativeHandler = auto nativeHandler = counterstrikesharp::ScriptEngine::GetNativeHandler(context.nativeIdentifier);
counterstrikesharp::ScriptEngine::GetNativeHandler(context.nativeIdentifier);
if (nativeHandler) { if (nativeHandler)
{
counterstrikesharp::ScriptContextRaw scriptContext(context); counterstrikesharp::ScriptContextRaw scriptContext(context);
(*nativeHandler)(scriptContext); (*nativeHandler)(scriptContext);
} else { }
CSSHARP_CORE_WARN("Native Handler was requested but not found: {0:x}", else
context.nativeIdentifier); {
CSSHARP_CORE_WARN("Native Handler was requested but not found: {0:x}", context.nativeIdentifier);
assert(false); assert(false);
} }
} }
ScriptContextRaw ScriptEngine::m_context; ScriptContextRaw ScriptEngine::m_context;
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -33,41 +33,46 @@
namespace counterstrikesharp { namespace counterstrikesharp {
enum HookResult { enum HookResult
{
Continue = 0, Continue = 0,
Changed = 1, Changed = 1,
Handled = 3, Handled = 3,
Stop = 4, Stop = 4,
}; };
enum HookMode { enum HookMode
{
Pre = 0, Pre = 0,
Post = 1, Post = 1,
}; };
inline uint32_t hash_string(const char *string) { inline uint32_t hash_string(const char* string)
unsigned long result = 5381;
for (size_t i = 0; i < strlen(string); i++) {
result = ((result << 5) + result) ^ string[i];
}
return result;
}
template<size_t N>
constexpr uint32_t hash_string_const(char const (&string)[N])
{ {
unsigned long result = 5381; unsigned long result = 5381;
for (size_t i = 0; i < N-1; i++) { for (size_t i = 0; i < strlen(string); i++)
{
result = ((result << 5) + result) ^ string[i]; result = ((result << 5) + result) ^ string[i];
} }
return result; return result;
} }
struct fxNativeContext { template <size_t N> constexpr uint32_t hash_string_const(char const (&string)[N])
{
unsigned long result = 5381;
for (size_t i = 0; i < N - 1; i++)
{
result = ((result << 5) + result) ^ string[i];
}
return result;
}
struct fxNativeContext
{
int numArguments; int numArguments;
int numResults; int numResults;
int hasError; int hasError;
@@ -77,76 +82,83 @@ struct fxNativeContext {
uint64_t result; uint64_t result;
}; };
typedef void (*CallbackT)(fxNativeContext *); typedef void (*CallbackT)(fxNativeContext*);
class ScriptContext { class ScriptContext
public: {
enum { MaxArguments = 32, ArgumentSize = sizeof(uint64_t) }; public:
enum
{
MaxArguments = 32,
ArgumentSize = sizeof(uint64_t)
};
protected: protected:
void *m_argumentBuffer; void* m_argumentBuffer;
int m_numArguments; int m_numArguments;
int m_numResults; int m_numResults;
int *m_has_error; int* m_has_error;
uint64_t *m_nativeIdentifier; uint64_t* m_nativeIdentifier;
void *m_result; void* m_result;
fxNativeContext *m_native_context; fxNativeContext* m_native_context;
public: public:
inline ScriptContext() = default; inline ScriptContext() = default;
public: public:
void ThrowNativeError(const char *msg, ...); void ThrowNativeError(const char* msg, ...);
bool HasError() { return *m_has_error == 1; } bool HasError() { return *m_has_error == 1; }
void Reset(); void Reset();
public: public:
template <int... Is> template <int... Is> struct index
struct index {}; {
};
template <int N, int... Is> template <int N, int... Is> struct gen_seq : gen_seq<N - 1, N - 1, Is...>
struct gen_seq : gen_seq<N - 1, N - 1, Is...> {}; {
};
template <int... Is> template <int... Is> struct gen_seq<0, Is...> : index<Is...>
struct gen_seq<0, Is...> : index<Is...> {}; {
};
template <typename... Ts> template <typename... Ts> inline const std::tuple<Ts...> GetArguments() { return GetArgumentsImpl<Ts...>(gen_seq<sizeof...(Ts)>()); }
inline const std::tuple<Ts...> GetArguments() {
return GetArgumentsImpl<Ts...>(gen_seq<sizeof...(Ts)>());
}
template <typename... Ts, int... Is> template <typename... Ts, int... Is> inline const std::tuple<Ts...> GetArgumentsImpl(index<Is...>)
inline const std::tuple<Ts...> GetArgumentsImpl(index<Is...>) { {
return std::make_tuple(GetArgument<Ts>(Is)...); return std::make_tuple(GetArgument<Ts>(Is)...);
} }
template <typename T> template <typename T> inline const T& GetArgument(int index)
inline const T &GetArgument(int index) { {
auto functionData = (uint64_t *)m_argumentBuffer; auto functionData = (uint64_t*)m_argumentBuffer;
return *reinterpret_cast<T *>(&functionData[index]); return *reinterpret_cast<T*>(&functionData[index]);
} }
template <typename T> template <typename T> inline void SetArgument(int index, const T& value)
inline void SetArgument(int index, const T &value) { {
auto functionData = (uint64_t *)m_argumentBuffer; auto functionData = (uint64_t*)m_argumentBuffer;
static_assert(sizeof(T) <= ArgumentSize, "Argument size of T"); static_assert(sizeof(T) <= ArgumentSize, "Argument size of T");
if (sizeof(T) < ArgumentSize) { if (sizeof(T) < ArgumentSize)
*reinterpret_cast<uint64_t *>(&functionData[index]) = 0; {
*reinterpret_cast<uint64_t*>(&functionData[index]) = 0;
} }
*reinterpret_cast<T *>(&functionData[index]) = value; *reinterpret_cast<T*>(&functionData[index]) = value;
} }
template <typename T> template <typename T> inline const T& CheckArgument(int index)
inline const T &CheckArgument(int index) { {
const auto &argument = GetArgument<T>(index); const auto& argument = GetArgument<T>(index);
if (argument == T()) { if (argument == T())
{
throw std::runtime_error("Argument at index %d was null."); throw std::runtime_error("Argument at index %d was null.");
} }
@@ -155,56 +167,61 @@ public:
inline int GetArgumentCount() { return m_numArguments; } inline int GetArgumentCount() { return m_numArguments; }
template <typename T> template <typename T> inline void Push(const T& value)
inline void Push(const T &value) { {
auto functionData = (uint64_t *)m_argumentBuffer; auto functionData = (uint64_t*)m_argumentBuffer;
static_assert(sizeof(T) <= ArgumentSize, "Argument size of T"); static_assert(sizeof(T) <= ArgumentSize, "Argument size of T");
if (sizeof(T) < ArgumentSize) { if (sizeof(T) < ArgumentSize)
*reinterpret_cast<uint64_t *>(&functionData[m_numArguments]) = 0; {
*reinterpret_cast<uint64_t*>(&functionData[m_numArguments]) = 0;
} }
*reinterpret_cast<T *>(&functionData[m_numArguments]) = value; *reinterpret_cast<T*>(&functionData[m_numArguments]) = value;
m_numArguments++; m_numArguments++;
m_native_context->numArguments++; m_native_context->numArguments++;
} }
inline void PushString(const char *value) { inline void PushString(const char* value)
auto functionData = (uint64_t *)m_argumentBuffer; {
auto functionData = (uint64_t*)m_argumentBuffer;
*reinterpret_cast<const char **>(&functionData[m_numArguments]) = value; *reinterpret_cast<const char**>(&functionData[m_numArguments]) = value;
} }
template <typename T> template <typename T> inline void SetResult(const T& value)
inline void SetResult(const T &value) { {
auto functionData = (uint64_t *)m_result; auto functionData = (uint64_t*)m_result;
if (sizeof(T) < ArgumentSize) { if (sizeof(T) < ArgumentSize)
*reinterpret_cast<uint64_t *>(&functionData[0]) = 0; {
*reinterpret_cast<uint64_t*>(&functionData[0]) = 0;
} }
*reinterpret_cast<T *>(&functionData[0]) = value; *reinterpret_cast<T*>(&functionData[0]) = value;
m_numResults = 1; m_numResults = 1;
m_numArguments = 0; m_numArguments = 0;
} }
template <typename T> template <typename T> inline T GetResult()
inline T GetResult() { {
auto functionData = (uint64_t *)m_result; auto functionData = (uint64_t*)m_result;
return *reinterpret_cast<T *>(functionData); return *reinterpret_cast<T*>(functionData);
} }
inline void *GetArgumentBuffer() { return m_argumentBuffer; } inline void* GetArgumentBuffer() { return m_argumentBuffer; }
inline int GetNumArguments() { return m_native_context->numArguments; } inline int GetNumArguments() { return m_native_context->numArguments; }
}; };
class ScriptContextRaw : public ScriptContext { class ScriptContextRaw : public ScriptContext
public: {
inline ScriptContextRaw(fxNativeContext &context) { public:
inline ScriptContextRaw(fxNativeContext& context)
{
m_argumentBuffer = context.arguments; m_argumentBuffer = context.arguments;
m_numArguments = context.numArguments; m_numArguments = context.numArguments;
@@ -215,31 +232,33 @@ public:
m_result = &context.result; m_result = &context.result;
} }
inline ScriptContextRaw() { inline ScriptContextRaw()
{
m_numResults = 0; m_numResults = 0;
m_numArguments = 0; m_numArguments = 0;
} }
}; };
using TNativeHandler = std::function<void(ScriptContext &)>; using TNativeHandler = std::function<void(ScriptContext&)>;
template <typename T> template <typename T> using TypedTNativeHandler = T(ScriptContext&);
using TypedTNativeHandler = T(ScriptContext &);
class ScriptEngine { class ScriptEngine
public: {
public:
static tl::optional<TNativeHandler> GetNativeHandler(uint64_t nativeIdentifier); static tl::optional<TNativeHandler> GetNativeHandler(uint64_t nativeIdentifier);
static tl::optional<TNativeHandler> GetNativeHandler(std::string name); static tl::optional<TNativeHandler> GetNativeHandler(std::string name);
static bool CallNativeHandler(uint64_t nativeIdentifier, ScriptContext &context); static bool CallNativeHandler(uint64_t nativeIdentifier, ScriptContext& context);
static void RegisterNativeHandlerInt(uint64_t nativeIdentifier, TNativeHandler function); static void RegisterNativeHandlerInt(uint64_t nativeIdentifier, TNativeHandler function);
template <typename T> template <typename T> static void RegisterNativeHandler(const char* nativeName, TypedTNativeHandler<T> function)
static void RegisterNativeHandler(const char *nativeName, TypedTNativeHandler<T> function) { {
auto lambda = [=](counterstrikesharp::ScriptContext &context) { auto lambda = [=](counterstrikesharp::ScriptContext& context) {
auto value = function(context); auto value = function(context);
if (!context.HasError()) { if (!context.HasError())
{
context.SetResult(value); context.SetResult(value);
} }
}; };
@@ -247,13 +266,14 @@ public:
RegisterNativeHandlerInt(hash_string(nativeName), lambda); RegisterNativeHandlerInt(hash_string(nativeName), lambda);
} }
static void RegisterNativeHandler(const char *nativeName, TypedTNativeHandler<void> function) { static void RegisterNativeHandler(const char* nativeName, TypedTNativeHandler<void> function)
{
RegisterNativeHandlerInt(hash_string(nativeName), function); RegisterNativeHandlerInt(hash_string(nativeName), function);
} }
static void InvokeNative(counterstrikesharp::fxNativeContext &context); static void InvokeNative(counterstrikesharp::fxNativeContext& context);
private: private:
static ScriptContextRaw m_context; static ScriptContextRaw m_context;
}; };
} // namespace counterstrikesharp } // namespace counterstrikesharp

View File

@@ -23,7 +23,8 @@ std::wstring widen(const std::string& str)
{ {
std::wostringstream wstm; std::wostringstream wstm;
const auto& ctfacet = std::use_facet<std::ctype<wchar_t>>(wstm.getloc()); const auto& ctfacet = std::use_facet<std::ctype<wchar_t>>(wstm.getloc());
for (size_t i = 0; i < str.size(); ++i) { for (size_t i = 0; i < str.size(); ++i)
{
wstm << ctfacet.widen(str[i]); wstm << ctfacet.widen(str[i]);
} }
return wstm.str(); return wstm.str();
@@ -39,9 +40,10 @@ std::string narrow(const std::wstring& str)
// Correct code. // Correct code.
const auto& ctfacet = std::use_facet<std::ctype<wchar_t>>(stm.getloc()); const auto& ctfacet = std::use_facet<std::ctype<wchar_t>>(stm.getloc());
for (size_t i = 0; i < str.size(); ++i) { for (size_t i = 0; i < str.size(); ++i)
{
stm << ctfacet.narrow(str[i], 0); stm << ctfacet.narrow(str[i], 0);
} }
return stm.str(); return stm.str();
} }
} } // namespace counterstrikesharp

View File

@@ -23,31 +23,34 @@
#define CALL_VIRTUAL(retType, idx, ...) vmt::CallVirtual<retType>(idx, __VA_ARGS__) #define CALL_VIRTUAL(retType, idx, ...) vmt::CallVirtual<retType>(idx, __VA_ARGS__)
namespace vmt { namespace vmt {
template <typename T = void *> template <typename T = void*> inline T GetVMethod(uint32 uIndex, void* pClass)
inline T GetVMethod(uint32 uIndex, void *pClass) { {
if (!pClass) { if (!pClass)
{
return T(); return T();
} }
void **pVTable = *static_cast<void ***>(pClass); void** pVTable = *static_cast<void***>(pClass);
if (!pVTable) { if (!pVTable)
{
return T(); return T();
} }
return reinterpret_cast<T>(pVTable[uIndex]); return reinterpret_cast<T>(pVTable[uIndex]);
} }
template <typename T, typename... Args> template <typename T, typename... Args> inline T CallVirtual(uint32 uIndex, void* pClass, Args... args)
inline T CallVirtual(uint32 uIndex, void *pClass, Args... args) { {
#ifdef _WIN32 #ifdef _WIN32
auto pFunc = GetVMethod<T(__thiscall *)(void *, Args...)>(uIndex, pClass); auto pFunc = GetVMethod<T(__thiscall*)(void*, Args...)>(uIndex, pClass);
#else #else
auto pFunc = GetVMethod<T(*)(void *, Args...)>(uIndex, pClass); auto pFunc = GetVMethod<T (*)(void*, Args...)>(uIndex, pClass);
#endif #endif
if (!pFunc) { if (!pFunc)
{
return T(); return T();
} }
return pFunc(pClass, args...); return pFunc(pClass, args...);
} }
} // namespace vmt } // namespace vmt