Skip to content

Commit

Permalink
Entity Manipulation/Schema System (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
roflmuffin authored Oct 15, 2023
1 parent 4ccb091 commit 7fffc96
Show file tree
Hide file tree
Showing 26 changed files with 928 additions and 37 deletions.
30 changes: 20 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,34 @@ SET(SOURCE_FILES
src/core/managers/con_command_manager.cpp
src/core/managers/con_command_manager.h
src/scripting/natives/natives_commands.cpp
src/core/memory_module.h
src/core/cs2_sdk/interfaces/cgameresourceserviceserver.h
src/core/cs2_sdk/interfaces/cschemasystem.h
src/core/cs2_sdk/interfaces/centitysystem.cpp
src/core/cs2_sdk/interfaces/cs2_interfaces.h
src/core/cs2_sdk/interfaces/cs2_interfaces.cpp
src/core/cs2_sdk/schema.h
src/core/cs2_sdk/schema.cpp
src/core/function.cpp
src/core/function.h
src/scripting/natives/natives_memory.cpp
src/scripting/natives/natives_schema.cpp
)

set(PROTO_DIRS -I${CMAKE_CURRENT_SOURCE_DIR}/libraries/GameTracking-CS2/Protobufs)
file(GLOB PROTOS "${CMAKE_CURRENT_SOURCE_DIR}/libraries/GameTracking-CS2/Protobufs/*.proto")

## Generate protobuf source & headers
add_custom_command(
OUTPUT protobuf_output_stamp
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf/compile.sh
COMMENT "Generating protobuf files using compile.sh script"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf/compile.sh
VERBATIM
)

SET(SOURCE_FILES ${SOURCE_FILES} protobuf_output_stamp)
#add_custom_command(
# OUTPUT protobuf_output_stamp
# COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf/compile.sh
# COMMENT "Generating protobuf files using compile.sh script"
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf
# DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf/compile.sh
# VERBATIM
#)
#
#SET(SOURCE_FILES ${SOURCE_FILES} protobuf_output_stamp)

# Sources
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${NATIVES_SOURCES} ${CONVERSIONS_SOURCES} ${CONVERSIONS_HEADERS})
Expand All @@ -80,6 +89,7 @@ target_include_directories(
${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src/core/cs2_sdk
)

include("makefiles/linux.base.cmake")
Expand Down
1 change: 1 addition & 0 deletions makefiles/shared.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ include_directories(
${SOURCESDK}/public/mathlib
${SOURCESDK}/public/tier0
${SOURCESDK}/public/tier1
${SOURCESDK}/public/entity2
${SOURCESDK}/public/game/server
${SOURCESDK}/public/entity2
${METAMOD_DIR}/core
Expand Down
32 changes: 30 additions & 2 deletions managed/CounterStrikeSharp.API/Core/API.cs
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ public static IntPtr CreateVirtualFunctionBySignature(IntPtr pointer, string bin
}
}

public static object ExecuteVirtualFunction(IntPtr function, object[] arguments){
public static T ExecuteVirtualFunction<T>(IntPtr function, object[] arguments){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(function);
Expand All @@ -645,7 +645,7 @@ public static object ExecuteVirtualFunction(IntPtr function, object[] arguments)
ScriptContext.GlobalScriptContext.SetIdentifier(0x376A0359);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (object)ScriptContext.GlobalScriptContext.GetResult(typeof(object));
return (T)ScriptContext.GlobalScriptContext.GetResult(typeof(T));
}
}

Expand All @@ -661,6 +661,34 @@ public static IntPtr FindSignature(string modulepath, string signature){
}
}

public static T GetSchemaValueByName<T>(IntPtr instance, int returntype, string classname, string propname){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(instance);
ScriptContext.GlobalScriptContext.Push(returntype);
ScriptContext.GlobalScriptContext.Push(classname);
ScriptContext.GlobalScriptContext.Push(propname);
ScriptContext.GlobalScriptContext.SetIdentifier(0xD01E4EB5);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (T)ScriptContext.GlobalScriptContext.GetResult(typeof(T));
}
}

public static void SetSchemaValueByName<T>(IntPtr instance, int returntype, string classname, string propname, T value){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(instance);
ScriptContext.GlobalScriptContext.Push(returntype);
ScriptContext.GlobalScriptContext.Push(classname);
ScriptContext.GlobalScriptContext.Push(propname);
ScriptContext.GlobalScriptContext.Push(value);
ScriptContext.GlobalScriptContext.SetIdentifier(0xAB9AA921);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}

public static IntPtr CreateTimer(float interval, InputArgument callback, int flags){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
Expand Down
10 changes: 5 additions & 5 deletions managed/CounterStrikeSharp.API/Core/ScriptContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -422,11 +422,11 @@ internal unsafe object GetResult(Type type, byte* ptr)

if (type == typeof(object))
{
var dataPtr = *(IntPtr*)&ptr[0];
var dataLength = *(long*)&ptr[8];

byte[] data = new byte[dataLength];
Marshal.Copy(dataPtr, data, 0, (int)dataLength);
// var dataPtr = *(IntPtr*)&ptr[0];
// var dataLength = *(long*)&ptr[8];
//
// byte[] data = new byte[dataLength];
// Marshal.Copy(dataPtr, data, 0, (int)dataLength);

return null;
//return MsgPackDeserializer.Deserialize(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,12 @@ public VirtualFunction(IntPtr objPtr, string signature, DataType?[] arguments, D

public T InvokeInternal<T>(object[] arguments)
{
NativeAPI.ExecuteVirtualFunction(Handle, arguments);
return ScriptContext.GlobalScriptContext.GetResult<T>();
return NativeAPI.ExecuteVirtualFunction<T>(Handle, arguments);
}

protected void InvokeInternal(object[] arguments)
{
NativeAPI.ExecuteVirtualFunction(Handle, arguments);
NativeAPI.ExecuteVirtualFunction<object>(Handle, arguments);
}

private static void ExecuteFunction(IntPtr objPtr, int offset, DataType?[] argumentTypes, DataType returnType,
Expand All @@ -159,7 +158,7 @@ private static void ExecuteFunction(IntPtr objPtr, int offset, DataType?[] argum
var ptr = NativeAPI.CreateVirtualFunction(objPtr, offset, convertedArguments.Length, (int)returnType,
convertedArguments);

NativeAPI.ExecuteVirtualFunction(ptr, arguments);
NativeAPI.ExecuteVirtualFunction<object>(ptr, arguments);
}

private static void ExecuteFunction(IntPtr objPtr, string signature, DataType?[] argumentTypes,
Expand All @@ -175,7 +174,7 @@ private static void ExecuteFunction(IntPtr objPtr, string signature, DataType?[]
var ptr = NativeAPI.CreateVirtualFunctionBySignature(objPtr, Addresses.ServerPath, signature,
convertedArguments.Length, (int)returnType, convertedArguments);

NativeAPI.ExecuteVirtualFunction(ptr, arguments);
NativeAPI.ExecuteVirtualFunction<object>(ptr, arguments);
}

public static VirtualFunctionVoid<TArg1, TArg2, TArg3> CreateObject<TArg1, TArg2, TArg3>(IntPtr objPtr,
Expand Down
20 changes: 14 additions & 6 deletions managed/TestPlugin/TestPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,22 @@ public override void Load(bool hotReload)
RegisterEventHandler<EventPlayerBlind>(GenericEventHandler);
RegisterEventHandler<EventBulletImpact>(@event =>
{
var steamId = NativeAPI.GetSchemaValueByName<ulong>(@event.Userid.Handle,
(int)DataType.DATA_TYPE_ULONG_LONG,
"CBasePlayerController", "m_steamID");

var playerName = NativeAPI.GetSchemaValueByName<string>(@event.Userid.Handle,
(int)DataType.DATA_TYPE_STRING, "CBasePlayerController", "m_iszPlayerName");
var playerHealth = NativeAPI.GetSchemaValueByName<int>(@event.Userid.PawnHandle,
(int)DataType.DATA_TYPE_INT, "CBaseEntity", "m_iHealth");
NativeAPI.SetSchemaValueByName<int>(@event.Userid.PawnHandle, (int)DataType.DATA_TYPE_INT,
"CBaseEntity", "m_iHealth", playerHealth + 5);
Log($"Found steamID {new SteamID(steamId)} for player {playerName}:{playerHealth}");
Log($"{@event.Userid}, {@event.X},{@event.Y},{@event.Z}");
});

// Hook global listeners defined by CounterStrikeSharp
RegisterListener<Listeners.OnMapStart>(mapName =>
{
Log($"Map {mapName} has started!");
});
RegisterListener<Listeners.OnMapStart>(mapName => { Log($"Map {mapName} has started!"); });
RegisterListener<Listeners.OnClientConnect>((index, name, ip) =>
{
Log($"Client {name} from {ip} has connected!");
Expand All @@ -59,7 +67,7 @@ public override void Load(bool hotReload)
{
Log($"Client {index} with address {id}");
});

// You can use `ModuleDirectory` to get the directory of the plugin (for storing config files, saving database files etc.)
File.WriteAllText(Path.Join(ModuleDirectory, "example.txt"),
$"Test file created by TestPlugin at {DateTime.Now}");
Expand Down
1 change: 1 addition & 0 deletions src/core/cs2_sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Credit for these files goes to [CS2Fixes](https://github.com/Source2ZE/CS2Fixes), licensed under GPLv3 and modified for use in CounterStrikeSharp
61 changes: 61 additions & 0 deletions src/core/cs2_sdk/interfaces/centitysystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* =============================================================================
* CS2Fixes
* Copyright (C) 2023 Source2ZE
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "utlstring.h"
#include "entity2/entitysystem.h"

#include "tier0/memdbgon.h"

CBaseEntity* CEntitySystem::GetBaseEntity(CEntityIndex entnum)
{
if (entnum.Get() <= -1 || entnum.Get() >= (MAX_TOTAL_ENTITIES - 1))
return nullptr;

CEntityIdentity* pChunkToUse = m_EntityList.m_pIdentityChunks[entnum.Get() / MAX_ENTITIES_IN_LIST];
if (!pChunkToUse)
return nullptr;

CEntityIdentity* pIdentity = &pChunkToUse[entnum.Get() % MAX_ENTITIES_IN_LIST];
if (!pIdentity)
return nullptr;

if (pIdentity->m_EHandle.GetEntryIndex() != entnum.Get())
return nullptr;

return dynamic_cast<CBaseEntity*>(pIdentity->m_pInstance);
}

CBaseEntity* CEntitySystem::GetBaseEntity(const CEntityHandle& hEnt)
{
if (!hEnt.IsValid())
return nullptr;

CEntityIdentity* pChunkToUse = m_EntityList.m_pIdentityChunks[hEnt.GetEntryIndex() / MAX_ENTITIES_IN_LIST];
if (!pChunkToUse)
return nullptr;

CEntityIdentity* pIdentity = &pChunkToUse[hEnt.GetEntryIndex() % MAX_ENTITIES_IN_LIST];
if (!pIdentity)
return nullptr;

if (pIdentity->m_EHandle != hEnt)
return nullptr;

return dynamic_cast<CBaseEntity*>(pIdentity->m_pInstance);
}
34 changes: 34 additions & 0 deletions src/core/cs2_sdk/interfaces/cgameresourceserviceserver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* =============================================================================
* CS2Fixes
* Copyright (C) 2023 Source2ZE
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once
#include <platform.h>
#include "interfaces/interfaces.h"
#include <cstdint>

class CGameEntitySystem;

class CGameResourceService
{
public:
CGameEntitySystem *GetGameEntitySystem()
{
return *reinterpret_cast<CGameEntitySystem **>((uintptr_t)(this) + 0x50);
}
};
37 changes: 37 additions & 0 deletions src/core/cs2_sdk/interfaces/cs2_interfaces.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* =============================================================================
* CS2Fixes
* Copyright (C) 2023 Source2ZE
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "cs2_interfaces.h"
#include "interfaces/interfaces.h"

#include "tier0/memdbgon.h"
#include "core/memory_module.h"
#include "core/globals.h"

namespace counterstrikesharp {
void interfaces::Initialize() {
pGameResourceServiceServer = (CGameResourceService*)modules::engine->FindInterface(
GAMERESOURCESERVICESERVER_INTERFACE_VERSION);
g_pCVar = (ICvar*)modules::tier0->FindInterface(CVAR_INTERFACE_VERSION);
g_pSource2GameEntities = (ISource2GameEntities*)modules::server->FindInterface(
SOURCE2GAMEENTITIES_INTERFACE_VERSION);
pSchemaSystem =
(CSchemaSystem*)modules::schemasystem->FindInterface(SCHEMASYSTEM_INTERFACE_VERSION);
}
} // namespace counterstrikesharp
32 changes: 32 additions & 0 deletions src/core/cs2_sdk/interfaces/cs2_interfaces.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* =============================================================================
* CS2Fixes
* Copyright (C) 2023 Source2ZE
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "cgameresourceserviceserver.h"
#include "cschemasystem.h"

namespace counterstrikesharp {
namespace interfaces {
void Initialize();

inline CGameResourceService *pGameResourceServiceServer = nullptr;
inline CSchemaSystem *pSchemaSystem = nullptr;
} // namespace interfaces
} // namespace counterstrikesharp
Loading

0 comments on commit 7fffc96

Please sign in to comment.