From d9ad31c4984e48e839153dba168b19a49d93e50f Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 7 Oct 2024 00:15:13 +0200 Subject: [PATCH 01/29] feat: `CBaseEntity_DispatchSpawn` in unmanaged --- src/core/managers/entity_manager.cpp | 9 +++++++++ src/core/managers/entity_manager.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/core/managers/entity_manager.cpp b/src/core/managers/entity_manager.cpp index d27ada326..8973d5496 100644 --- a/src/core/managers/entity_manager.cpp +++ b/src/core/managers/entity_manager.cpp @@ -62,6 +62,15 @@ void EntityManager::OnAllInitialized() CSSHARP_CORE_CRITICAL("Failed to find signature for \'CEntitySystem_AddEntityIOEvent\'"); } + CBaseEntity_DispatchSpawn = (decltype(CBaseEntity_DispatchSpawn))( + (modules::server->FindSignature(globals::gameConfig->GetSignature("CBaseEntity_DispatchSpawn")))); + + if (!CBaseEntity_DispatchSpawn) + { + CSSHARP_CORE_CRITICAL("Failed to find signature for \'CBaseEntity_DispatchSpawn\'"); + return; + } + auto m_hook = funchook_create(); funchook_prepare(m_hook, (void**)&m_pFireOutputInternal, (void*)&DetourFireOutputInternal); funchook_install(m_hook, 0); diff --git a/src/core/managers/entity_manager.h b/src/core/managers/entity_manager.h index 4aaeebc20..92628875c 100644 --- a/src/core/managers/entity_manager.h +++ b/src/core/managers/entity_manager.h @@ -111,6 +111,8 @@ static void DetourFireOutputInternal(CEntityIOOutput* const pThis, CEntityInstan static FireOutputInternal m_pFireOutputInternal = nullptr; +inline void (*CBaseEntity_DispatchSpawn)(void* pEntity, CEntityKeyValues* pKeyValues); + // 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); From 34a4b4bd129ad195f49315208c62ad66aedf2c02 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 7 Oct 2024 00:15:46 +0200 Subject: [PATCH 02/29] feat: entity keyvalues unmanaged implementation --- managed/CounterStrikeSharp.API/Core/API.cs | 15 ++ src/scripting/natives/natives_entities.cpp | 169 ++++++++++++++++++++ src/scripting/natives/natives_entities.yaml | 1 + 3 files changed, 185 insertions(+) diff --git a/managed/CounterStrikeSharp.API/Core/API.cs b/managed/CounterStrikeSharp.API/Core/API.cs index 40785f520..d4a2a2ce2 100644 --- a/managed/CounterStrikeSharp.API/Core/API.cs +++ b/managed/CounterStrikeSharp.API/Core/API.cs @@ -758,6 +758,21 @@ public static void AddEntityIoEvent(IntPtr ptarget, string inputname, IntPtr act } } + public static void DispatchSpawn(IntPtr entity, int count, object[] values){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(entity); + ScriptContext.GlobalScriptContext.Push(count); + foreach (var obj in values) + { + ScriptContext.GlobalScriptContext.Push(obj); + } + ScriptContext.GlobalScriptContext.SetIdentifier(0xAE01E931); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + } + } + public static void HookEvent(string name, InputArgument callback, bool ispost){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); diff --git a/src/scripting/natives/natives_entities.cpp b/src/scripting/natives/natives_entities.cpp index b01ae74ce..371dd0355 100644 --- a/src/scripting/natives/natives_entities.cpp +++ b/src/scripting/natives/natives_entities.cpp @@ -15,6 +15,7 @@ */ #include +#include "entitykeyvalues.h" #include #include @@ -27,6 +28,27 @@ #include "scripting/script_engine.h" namespace counterstrikesharp { +enum KeyValuesType_t : unsigned int +{ + TYPE_BOOL, + TYPE_INT, + TYPE_UINT, + TYPE_INT64, + TYPE_UINT64, + TYPE_FLOAT, + TYPE_DOUBLE, + TYPE_STRING, + TYPE_POINTER, + TYPE_STRING_TOKEN, + TYPE_EHANDLE, + TYPE_COLOR, + TYPE_VECTOR, + TYPE_VECTOR2D, + TYPE_VECTOR4D, + TYPE_QUATERNION, + TYPE_QANGLE, + TYPE_MATRIX3X4 +}; CEntityInstance* GetEntityFromIndex(ScriptContext& script_context) { @@ -256,6 +278,152 @@ void AddEntityIOEvent(ScriptContext& script_context) CEntitySystem_AddEntityIOEvent(GameEntitySystem(), pTarget, pInputName, pActivator, pCaller, &_value, delay, outputID); } +void DispatchSpawn(ScriptContext& scriptContext) +{ + auto entity = scriptContext.GetArgument(0); + auto count = scriptContext.GetArgument(1); + + if (count == 0) { + CBaseEntity_DispatchSpawn(entity, nullptr); + return; + } + + CEntityKeyValues* pKeyValues = new CEntityKeyValues(); + + int offset = 2; + for (int i = 0; i < count; ++i) { + const char* key = scriptContext.GetArgument(offset); + KeyValuesType_t _type = scriptContext.GetArgument(offset + 1); + switch (_type) { + case counterstrikesharp::TYPE_BOOL: + pKeyValues->SetBool(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_INT: + pKeyValues->SetInt(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_UINT: + pKeyValues->SetUint(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_INT64: + pKeyValues->SetInt64(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_UINT64: + pKeyValues->SetUint64(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_FLOAT: + pKeyValues->SetFloat(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_DOUBLE: + pKeyValues->SetDouble(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_STRING: + pKeyValues->SetString(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_POINTER: + pKeyValues->SetPtr(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_STRING_TOKEN: + pKeyValues->SetStringToken(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_EHANDLE: + pKeyValues->SetEHandle(key, scriptContext.GetArgument(offset + 2)); + offset += 3; + break; + case counterstrikesharp::TYPE_COLOR: { + char r = scriptContext.GetArgument(offset + 2); + char g = scriptContext.GetArgument(offset + 3); + char b = scriptContext.GetArgument(offset + 4); + char a = scriptContext.GetArgument(offset + 5); + + pKeyValues->SetColor(key, Color(r, g, b, a)); + offset += 6; + break; + } + case counterstrikesharp::TYPE_VECTOR: { + float x = scriptContext.GetArgument(offset + 2); + float y = scriptContext.GetArgument(offset + 3); + float z = scriptContext.GetArgument(offset + 4); + + pKeyValues->SetVector(key, Vector(x, y, z)); + offset += 5; + break; + } + case counterstrikesharp::TYPE_VECTOR2D: { + float x = scriptContext.GetArgument(offset + 2); + float y = scriptContext.GetArgument(offset + 3); + + pKeyValues->SetVector2D(key, Vector2D(x, y)); + offset += 4; + break; + } + case counterstrikesharp::TYPE_VECTOR4D: { + float x = scriptContext.GetArgument(offset + 2); + float y = scriptContext.GetArgument(offset + 3); + float z = scriptContext.GetArgument(offset + 4); + float w = scriptContext.GetArgument(offset + 5); + + pKeyValues->SetVector4D(key, Vector4D(x, y, z, w)); + offset += 6; + break; + } + case counterstrikesharp::TYPE_QUATERNION: { + float x = scriptContext.GetArgument(offset + 2); + float y = scriptContext.GetArgument(offset + 3); + float z = scriptContext.GetArgument(offset + 4); + float w = scriptContext.GetArgument(offset + 5); + + pKeyValues->SetQuaternion(key, Quaternion(x, y, z, w)); + offset += 6; + break; + } + case counterstrikesharp::TYPE_QANGLE: { + float x = scriptContext.GetArgument(offset + 2); + float y = scriptContext.GetArgument(offset + 3); + float z = scriptContext.GetArgument(offset + 4); + + pKeyValues->SetQAngle(key, QAngle(x, y, z)); + offset += 5; + break; + } + case counterstrikesharp::TYPE_MATRIX3X4: { + float m11 = scriptContext.GetArgument(offset + 2); + float m12 = scriptContext.GetArgument(offset + 3); + float m13 = scriptContext.GetArgument(offset + 4); + float m14 = scriptContext.GetArgument(offset + 5); + + float m21 = scriptContext.GetArgument(offset + 6); + float m22 = scriptContext.GetArgument(offset + 7); + float m23 = scriptContext.GetArgument(offset + 8); + float m24 = scriptContext.GetArgument(offset + 9); + + float m31 = scriptContext.GetArgument(offset + 10); + float m32 = scriptContext.GetArgument(offset + 11); + float m33 = scriptContext.GetArgument(offset + 12); + float m34 = scriptContext.GetArgument(offset + 13); + + pKeyValues->SetMatrix3x4( + key, matrix3x4_t(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34)); + offset += 14; + break; + } + default: + break; + } + } + + CBaseEntity_DispatchSpawn(entity, pKeyValues); +} + REGISTER_NATIVES(entities, { ScriptEngine::RegisterNativeHandler("GET_ENTITY_FROM_INDEX", GetEntityFromIndex); ScriptEngine::RegisterNativeHandler("GET_USERID_FROM_INDEX", GetUserIdFromIndex); @@ -273,5 +441,6 @@ REGISTER_NATIVES(entities, { ScriptEngine::RegisterNativeHandler("UNHOOK_ENTITY_OUTPUT", UnhookEntityOutput); ScriptEngine::RegisterNativeHandler("ACCEPT_INPUT", AcceptInput); ScriptEngine::RegisterNativeHandler("ADD_ENTITY_IO_EVENT", AddEntityIOEvent); + ScriptEngine::RegisterNativeHandler("DISPATCH_SPAWN", DispatchSpawn); }) } // namespace counterstrikesharp diff --git a/src/scripting/natives/natives_entities.yaml b/src/scripting/natives/natives_entities.yaml index 07b40fbba..603199398 100644 --- a/src/scripting/natives/natives_entities.yaml +++ b/src/scripting/natives/natives_entities.yaml @@ -14,3 +14,4 @@ HOOK_ENTITY_OUTPUT: classname:string, outputName:string, callback:func, mode:Hoo UNHOOK_ENTITY_OUTPUT: classname:string, outputName:string, callback:func, mode:HookMode -> void ACCEPT_INPUT: pThis:pointer, inputName:string, activator:pointer, caller:pointer, value:string, outputID:int -> void ADD_ENTITY_IO_EVENT: pTarget:pointer, inputName:string, activator:pointer, caller:pointer, value:string, delay:float, outputID:int -> void +DISPATCH_SPAWN: entity:pointer, count:int, values:object[] -> void From 787809be82f2d9ab3be99148fedb9c36bedb0581 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 7 Oct 2024 00:16:07 +0200 Subject: [PATCH 03/29] feat: entity keyvalues managed implementation --- .../Modules/Utils/CEntityKeyValues.cs | 225 ++++++++++++++++++ .../Modules/Utils/Matrix3x4.cs | 44 ++++ 2 files changed, 269 insertions(+) create mode 100644 managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs create mode 100644 managed/CounterStrikeSharp.API/Modules/Utils/Matrix3x4.cs diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs new file mode 100644 index 000000000..bd881675b --- /dev/null +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -0,0 +1,225 @@ +/* + * This file is part of CounterStrikeSharp. + * CounterStrikeSharp is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CounterStrikeSharp 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 CounterStrikeSharp. If not, see . * + */ + +using System.Drawing; +using System.Numerics; + +namespace CounterStrikeSharp.API.Modules.Utils +{ + internal enum KeyValuesType : uint + { + TYPE_BOOL, + TYPE_INT, + TYPE_UINT, + TYPE_INT64, + TYPE_UINT64, + TYPE_FLOAT, + TYPE_DOUBLE, + TYPE_STRING, + TYPE_POINTER, + TYPE_STRING_TOKEN, + TYPE_EHANDLE, + TYPE_COLOR, + TYPE_VECTOR, + TYPE_VECTOR2D, + TYPE_VECTOR4D, + TYPE_QUATERNION, + TYPE_QANGLE, + TYPE_MATRIX3X4 + } + + /// + /// EntityKeyValues + /// WARNING: This is intended to only use with for now! + /// + public class CEntityKeyValues + { + internal class KeyValueContainer + { + private KeyValuesType type; + private object value; + + public KeyValueContainer(KeyValuesType type, object value) + { + this.type = type; + this.value = value; + } + + public KeyValuesType GetContainerType() => type; + public T Get() => (T)value; +#pragma warning disable 8601 + public void Set(T val) => value = val; +#pragma warning restore + } + + internal Dictionary keyValues = new Dictionary(); + + // Getter + public bool GetBool(string key, bool defaultValue = false) => GetValue(key, defaultValue); + public int GetInt(string key, int defaultValue = 0) => GetValue(key, defaultValue); + public uint GetUInt(string key, uint defaultValue = 0) => GetValue(key, defaultValue); + public long GetInt64(string key, long defaultValue = 0) => GetValue(key, defaultValue); + public ulong GetUInt64(string key, ulong defaultValue = 0) => GetValue(key, defaultValue); + public float GetFloat(string key, float defaultValue = 0) => GetValue(key, defaultValue); + public double GetDouble(string key, double defaultValue = 0) => GetValue(key, defaultValue); + public string GetString(string key, string defaultValue = "") => GetValue(key, defaultValue); + public nint GetPointer(string key, nint defaultValue = 0) => GetValue(key, defaultValue); + public uint GetStringToken(string key, uint defaultValue = 0) => GetValue(key, defaultValue); + public CEntityHandle? GetEHandle(string key, CEntityHandle? defaultValue = null) => GetValue(key, defaultValue); + public Color GetColor(string key) => GetValue(key, Color.Empty); + public Vector3? GetVector(string key, Vector3? defaultValue = null) => GetValue(key, defaultValue); + public Vector2? GetVector2D(string key, Vector2? defaultValue = null) => GetValue(key, defaultValue); + public Vector4? GetVector4D(string key, Vector4? defaultValue = null) => GetValue(key, defaultValue); + public Vector4? GetQuaternion(string key, Vector4? defaultValue = null) => GetValue(key, defaultValue); + public QAngle? GetAngle(string key, QAngle? defaultValue = null) => GetValue(key, defaultValue); + public Matrix3x4? GetMatrix3x4(string key, Matrix3x4? defaultValue = null) => GetValue(key, defaultValue); + + // Setter + public void SetBool(string key, bool value) => SetValue(key, KeyValuesType.TYPE_BOOL, value); + public void SetInt(string key, int value) => SetValue(key, KeyValuesType.TYPE_INT, value); + public void SetUInt(string key, uint value) => SetValue(key, KeyValuesType.TYPE_UINT, value); + public void SetInt64(string key, long value) => SetValue(key, KeyValuesType.TYPE_INT64, value); + public void SetUInt64(string key, ulong value) => SetValue(key, KeyValuesType.TYPE_UINT64, value); + public void SetFloat(string key, float value) => SetValue(key, KeyValuesType.TYPE_FLOAT, value); + public void SetDouble(string key, double value) => SetValue(key, KeyValuesType.TYPE_DOUBLE, value); + public void SetString(string key, string value) => SetValue(key, KeyValuesType.TYPE_STRING, value); + public void SetPointer(string key, nint value) => SetValue(key, KeyValuesType.TYPE_POINTER, value); + public void SetStringToken(string key, uint value) => SetValue(key, KeyValuesType.TYPE_STRING_TOKEN, value); // Essentially is integer + public void SetEHandle(string key, CEntityHandle value) => SetValue(key, KeyValuesType.TYPE_EHANDLE, value); + public void SetColor(string key, Color value) => SetValue(key, KeyValuesType.TYPE_COLOR, value); + public void SetVector(string key, float x, float y, float z) => SetValue(key, KeyValuesType.TYPE_VECTOR, new Vector3(x, y, z)); + public void SetVector2D(string key, float x, float y) => SetValue(key, KeyValuesType.TYPE_VECTOR2D, new Vector2(x, y)); + public void SetVector4D(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_VECTOR4D, new Vector4(x, y, z, w)); + public void SetQuaternion(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_QUATERNION, new Vector4(x, y, z, w)); // Same class with Vector4 + public void SetAngle(string key, float pitch, float yaw, float roll) => SetValue(key, KeyValuesType.TYPE_QANGLE, new QAngle(pitch, yaw, roll)); + public void SetAngle(string key, QAngle angle) => SetValue(key, KeyValuesType.TYPE_QANGLE, angle); + public void SetMatrix3x4(string key, Matrix3x4 value) => SetValue(key, KeyValuesType.TYPE_MATRIX3X4, value); + + public bool Remove(string key) => keyValues.Remove(key); + public void Clear() => keyValues.Clear(); + public int Count => keyValues.Count; + + internal void SetValue(string key, KeyValuesType type, object value) + { + if (value == null) + throw new ArgumentNullException("Value can't be null!"); + + if (keyValues.TryGetValue(key, out KeyValueContainer? v)) + v.Set(value); + else + { + KeyValueContainer container = new(type, value); + keyValues.Add(key, container); + } + } + + internal T GetValue(string key, T defaultValue) + { + if (keyValues.TryGetValue(key, out KeyValueContainer? v)) + return v.Get(); + + return defaultValue; + } + + internal int Build(out object[] list) + { + if (keyValues.Count == 0) + { + list = Array.Empty(); + return 0; + } + + List valueLists = new(); + + foreach (var kv in keyValues) + { + valueLists.Add(kv.Key); + KeyValuesType _type = kv.Value.GetContainerType(); + valueLists.Add(_type); + switch (_type) + { + // Special type handle + case KeyValuesType.TYPE_EHANDLE: + valueLists.Add(kv.Value.Get().Raw); + break; + + case KeyValuesType.TYPE_COLOR: + Color color = kv.Value.Get(); + valueLists.Add(color.R); + valueLists.Add(color.G); + valueLists.Add(color.B); + valueLists.Add(color.A); + break; + + case KeyValuesType.TYPE_VECTOR: + Vector3 vec = kv.Value.Get(); + valueLists.Add(vec.X); + valueLists.Add(vec.Y); + valueLists.Add(vec.Z); + break; + + case KeyValuesType.TYPE_VECTOR2D: + Vector2 vec2D = kv.Value.Get(); + valueLists.Add(vec2D.X); + valueLists.Add(vec2D.Y); + break; + + // Same thing, idk why valve seperate this + case KeyValuesType.TYPE_VECTOR4D: + case KeyValuesType.TYPE_QUATERNION: + Vector4 vec4D = kv.Value.Get(); + valueLists.Add(vec4D.X); + valueLists.Add(vec4D.Y); + valueLists.Add(vec4D.Z); + valueLists.Add(vec4D.W); + break; + + case KeyValuesType.TYPE_QANGLE: + QAngle qAng = kv.Value.Get(); + valueLists.Add(qAng.X); + valueLists.Add(qAng.Y); + valueLists.Add(qAng.Z); + break; + + case KeyValuesType.TYPE_MATRIX3X4: + Matrix3x4 matrix = kv.Value.Get(); + valueLists.Add(matrix.M11); + valueLists.Add(matrix.M12); + valueLists.Add(matrix.M13); + valueLists.Add(matrix.M14); + valueLists.Add(matrix.M21); + valueLists.Add(matrix.M22); + valueLists.Add(matrix.M23); + valueLists.Add(matrix.M24); + valueLists.Add(matrix.M31); + valueLists.Add(matrix.M32); + valueLists.Add(matrix.M33); + valueLists.Add(matrix.M34); + break; + + // C# default type handle + default: + valueLists.Add(kv.Value.Get()); + break; + } + } + + list = valueLists.ToArray(); + + return keyValues.Count; + } + } +} diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/Matrix3x4.cs b/managed/CounterStrikeSharp.API/Modules/Utils/Matrix3x4.cs new file mode 100644 index 000000000..87f9d5fc8 --- /dev/null +++ b/managed/CounterStrikeSharp.API/Modules/Utils/Matrix3x4.cs @@ -0,0 +1,44 @@ +/* + * This file is part of CounterStrikeSharp. + * CounterStrikeSharp is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CounterStrikeSharp 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 CounterStrikeSharp. If not, see . * + */ + +namespace CounterStrikeSharp.API.Modules.Utils +{ + /// + /// Matrix3x4 for + /// + public class Matrix3x4 + { + public float M11; + public float M12; + public float M13; + public float M14; + public float M21; + public float M22; + public float M23; + public float M24; + public float M31; + public float M32; + public float M33; + public float M34; + + public Matrix3x4() { } + + public Matrix3x4(float M11, float M12, float M13, float M14, float M21, float M22, float M23, float M24, float M31, float M32, float M33, float M34) + { + this.M11 = M11; this.M12 = M12; this.M13 = M13; this.M14 = M14; this.M21 = M21; this.M22 = M22; this.M23 = M23; this.M24 = M24; this.M31 = M31; this.M32 = M32; this.M33 = M33; this.M34 = M34; + } + } +} From 4b1030780c8840dfcc4206afe0a308fb8b5834ef Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 7 Oct 2024 00:16:28 +0200 Subject: [PATCH 04/29] feat: overload `DispatchSpawn` --- .../Core/Model/CBaseEntity.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs b/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs index 64cd31a14..3ff976cec 100644 --- a/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs +++ b/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs @@ -24,11 +24,18 @@ public void Teleport(Vector? position = null, QAngle? angles = null, Vector? vel } /// Entity is not valid - public void DispatchSpawn() + public void DispatchSpawn(CEntityKeyValues? keyValues = null) { - Guard.IsValidEntity(this); - - VirtualFunctions.CBaseEntity_DispatchSpawn(Handle, IntPtr.Zero); + Guard.IsValidEntity(this); + + if (keyValues != null) + { + int count = keyValues.Build(out object[] values); + NativeAPI.DispatchSpawn(Handle, count, values); + } else + { + VirtualFunctions.CBaseEntity_DispatchSpawn(Handle, IntPtr.Zero); + } } /// From 10768f6b9914f22e1cdb079cc674bfff79cdbbbf Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 7 Oct 2024 00:34:21 +0200 Subject: [PATCH 05/29] chore: adjusted codestyle --- .../Modules/Utils/CEntityKeyValues.cs | 55 ++++++++++++++++--- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index bd881675b..06324e918 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -67,46 +67,83 @@ public KeyValueContainer(KeyValuesType type, object value) internal Dictionary keyValues = new Dictionary(); - // Getter +#region GETTER public bool GetBool(string key, bool defaultValue = false) => GetValue(key, defaultValue); + public int GetInt(string key, int defaultValue = 0) => GetValue(key, defaultValue); + public uint GetUInt(string key, uint defaultValue = 0) => GetValue(key, defaultValue); + public long GetInt64(string key, long defaultValue = 0) => GetValue(key, defaultValue); + public ulong GetUInt64(string key, ulong defaultValue = 0) => GetValue(key, defaultValue); + public float GetFloat(string key, float defaultValue = 0) => GetValue(key, defaultValue); + public double GetDouble(string key, double defaultValue = 0) => GetValue(key, defaultValue); + public string GetString(string key, string defaultValue = "") => GetValue(key, defaultValue); + public nint GetPointer(string key, nint defaultValue = 0) => GetValue(key, defaultValue); + public uint GetStringToken(string key, uint defaultValue = 0) => GetValue(key, defaultValue); + public CEntityHandle? GetEHandle(string key, CEntityHandle? defaultValue = null) => GetValue(key, defaultValue); + public Color GetColor(string key) => GetValue(key, Color.Empty); - public Vector3? GetVector(string key, Vector3? defaultValue = null) => GetValue(key, defaultValue); + + public Vector? GetVector(string key, Vector? defaultValue = null) => GetValue(key, defaultValue); + public Vector2? GetVector2D(string key, Vector2? defaultValue = null) => GetValue(key, defaultValue); + public Vector4? GetVector4D(string key, Vector4? defaultValue = null) => GetValue(key, defaultValue); + public Vector4? GetQuaternion(string key, Vector4? defaultValue = null) => GetValue(key, defaultValue); + public QAngle? GetAngle(string key, QAngle? defaultValue = null) => GetValue(key, defaultValue); + public Matrix3x4? GetMatrix3x4(string key, Matrix3x4? defaultValue = null) => GetValue(key, defaultValue); +#endregion - // Setter +#region SETTER public void SetBool(string key, bool value) => SetValue(key, KeyValuesType.TYPE_BOOL, value); + public void SetInt(string key, int value) => SetValue(key, KeyValuesType.TYPE_INT, value); + public void SetUInt(string key, uint value) => SetValue(key, KeyValuesType.TYPE_UINT, value); + public void SetInt64(string key, long value) => SetValue(key, KeyValuesType.TYPE_INT64, value); + public void SetUInt64(string key, ulong value) => SetValue(key, KeyValuesType.TYPE_UINT64, value); + public void SetFloat(string key, float value) => SetValue(key, KeyValuesType.TYPE_FLOAT, value); + public void SetDouble(string key, double value) => SetValue(key, KeyValuesType.TYPE_DOUBLE, value); + public void SetString(string key, string value) => SetValue(key, KeyValuesType.TYPE_STRING, value); + public void SetPointer(string key, nint value) => SetValue(key, KeyValuesType.TYPE_POINTER, value); + public void SetStringToken(string key, uint value) => SetValue(key, KeyValuesType.TYPE_STRING_TOKEN, value); // Essentially is integer + public void SetEHandle(string key, CEntityHandle value) => SetValue(key, KeyValuesType.TYPE_EHANDLE, value); + public void SetColor(string key, Color value) => SetValue(key, KeyValuesType.TYPE_COLOR, value); + public void SetVector(string key, float x, float y, float z) => SetValue(key, KeyValuesType.TYPE_VECTOR, new Vector3(x, y, z)); + public void SetVector2D(string key, float x, float y) => SetValue(key, KeyValuesType.TYPE_VECTOR2D, new Vector2(x, y)); + public void SetVector4D(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_VECTOR4D, new Vector4(x, y, z, w)); + public void SetQuaternion(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_QUATERNION, new Vector4(x, y, z, w)); // Same class with Vector4 + public void SetAngle(string key, float pitch, float yaw, float roll) => SetValue(key, KeyValuesType.TYPE_QANGLE, new QAngle(pitch, yaw, roll)); + public void SetAngle(string key, QAngle angle) => SetValue(key, KeyValuesType.TYPE_QANGLE, angle); + public void SetMatrix3x4(string key, Matrix3x4 value) => SetValue(key, KeyValuesType.TYPE_MATRIX3X4, value); +#endregion public bool Remove(string key) => keyValues.Remove(key); public void Clear() => keyValues.Clear(); @@ -115,11 +152,14 @@ public KeyValueContainer(KeyValuesType type, object value) internal void SetValue(string key, KeyValuesType type, object value) { if (value == null) + { throw new ArgumentNullException("Value can't be null!"); + } if (keyValues.TryGetValue(key, out KeyValueContainer? v)) + { v.Set(value); - else + } else { KeyValueContainer container = new(type, value); keyValues.Add(key, container); @@ -142,9 +182,9 @@ internal int Build(out object[] list) return 0; } - List valueLists = new(); + List valueLists = new List(); - foreach (var kv in keyValues) + foreach (KeyValuePair kv in keyValues) { valueLists.Add(kv.Key); KeyValuesType _type = kv.Value.GetContainerType(); @@ -165,7 +205,7 @@ internal int Build(out object[] list) break; case KeyValuesType.TYPE_VECTOR: - Vector3 vec = kv.Value.Get(); + Vector vec = kv.Value.Get(); valueLists.Add(vec.X); valueLists.Add(vec.Y); valueLists.Add(vec.Z); @@ -218,7 +258,6 @@ internal int Build(out object[] list) } list = valueLists.ToArray(); - return keyValues.Count; } } From ffc0320b8aff4583469ca05aa2a82bef249349ba Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 7 Oct 2024 00:55:28 +0200 Subject: [PATCH 06/29] chore: adjusted codestyle and cleanup --- .../Modules/Utils/CEntityKeyValues.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index 06324e918..0c4da344f 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -59,7 +59,9 @@ public KeyValueContainer(KeyValuesType type, object value) } public KeyValuesType GetContainerType() => type; + public T Get() => (T)value; + #pragma warning disable 8601 public void Set(T val) => value = val; #pragma warning restore @@ -146,7 +148,9 @@ public KeyValueContainer(KeyValuesType type, object value) #endregion public bool Remove(string key) => keyValues.Remove(key); + public void Clear() => keyValues.Clear(); + public int Count => keyValues.Count; internal void SetValue(string key, KeyValuesType type, object value) @@ -161,7 +165,7 @@ internal void SetValue(string key, KeyValuesType type, object value) v.Set(value); } else { - KeyValueContainer container = new(type, value); + KeyValueContainer container = new KeyValueContainer(type, value); keyValues.Add(key, container); } } @@ -189,9 +193,9 @@ internal int Build(out object[] list) valueLists.Add(kv.Key); KeyValuesType _type = kv.Value.GetContainerType(); valueLists.Add(_type); + switch (_type) { - // Special type handle case KeyValuesType.TYPE_EHANDLE: valueLists.Add(kv.Value.Get().Raw); break; @@ -217,7 +221,6 @@ internal int Build(out object[] list) valueLists.Add(vec2D.Y); break; - // Same thing, idk why valve seperate this case KeyValuesType.TYPE_VECTOR4D: case KeyValuesType.TYPE_QUATERNION: Vector4 vec4D = kv.Value.Get(); @@ -250,7 +253,6 @@ internal int Build(out object[] list) valueLists.Add(matrix.M34); break; - // C# default type handle default: valueLists.Add(kv.Value.Get()); break; From 7ed06c4f650283db5f35948dc27ec1a3ab185e85 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 7 Oct 2024 01:30:04 +0200 Subject: [PATCH 07/29] feat: inherit from dictionary to use indexing, adjustments --- .../Modules/Utils/CEntityKeyValues.cs | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index 0c4da344f..a5487370d 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -17,37 +17,41 @@ using System.Drawing; using System.Numerics; +using static CounterStrikeSharp.API.Modules.Utils.CEntityKeyValues; + +// TODO: change from System.Numerics to exposed native values (Vector2D, Vector4D, Quaternion) + namespace CounterStrikeSharp.API.Modules.Utils { - internal enum KeyValuesType : uint - { - TYPE_BOOL, - TYPE_INT, - TYPE_UINT, - TYPE_INT64, - TYPE_UINT64, - TYPE_FLOAT, - TYPE_DOUBLE, - TYPE_STRING, - TYPE_POINTER, - TYPE_STRING_TOKEN, - TYPE_EHANDLE, - TYPE_COLOR, - TYPE_VECTOR, - TYPE_VECTOR2D, - TYPE_VECTOR4D, - TYPE_QUATERNION, - TYPE_QANGLE, - TYPE_MATRIX3X4 - } - /// /// EntityKeyValues /// WARNING: This is intended to only use with for now! /// - public class CEntityKeyValues + public class CEntityKeyValues : Dictionary { - internal class KeyValueContainer + public enum KeyValuesType : uint + { + TYPE_BOOL, + TYPE_INT, + TYPE_UINT, + TYPE_INT64, + TYPE_UINT64, + TYPE_FLOAT, + TYPE_DOUBLE, + TYPE_STRING, + TYPE_POINTER, + TYPE_STRING_TOKEN, + TYPE_EHANDLE, + TYPE_COLOR, + TYPE_VECTOR, + TYPE_VECTOR2D, + TYPE_VECTOR4D, + TYPE_QUATERNION, + TYPE_QANGLE, + TYPE_MATRIX3X4 + } + + public class KeyValueContainer { private KeyValuesType type; private object value; @@ -62,13 +66,9 @@ public KeyValueContainer(KeyValuesType type, object value) public T Get() => (T)value; -#pragma warning disable 8601 - public void Set(T val) => value = val; -#pragma warning restore + public void Set(T val) => value = (object)val!; } - internal Dictionary keyValues = new Dictionary(); - #region GETTER public bool GetBool(string key, bool defaultValue = false) => GetValue(key, defaultValue); @@ -126,7 +126,7 @@ public KeyValueContainer(KeyValuesType type, object value) public void SetPointer(string key, nint value) => SetValue(key, KeyValuesType.TYPE_POINTER, value); - public void SetStringToken(string key, uint value) => SetValue(key, KeyValuesType.TYPE_STRING_TOKEN, value); // Essentially is integer + public void SetStringToken(string key, uint value) => SetValue(key, KeyValuesType.TYPE_STRING_TOKEN, value); public void SetEHandle(string key, CEntityHandle value) => SetValue(key, KeyValuesType.TYPE_EHANDLE, value); @@ -136,9 +136,15 @@ public KeyValueContainer(KeyValuesType type, object value) public void SetVector2D(string key, float x, float y) => SetValue(key, KeyValuesType.TYPE_VECTOR2D, new Vector2(x, y)); + public void SetVector2D(string key, Vector2 value) => SetValue(key, KeyValuesType.TYPE_VECTOR2D, value); + public void SetVector4D(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_VECTOR4D, new Vector4(x, y, z, w)); - public void SetQuaternion(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_QUATERNION, new Vector4(x, y, z, w)); // Same class with Vector4 + public void SetVector4D(string key, Vector4 value) => SetValue(key, KeyValuesType.TYPE_VECTOR4D, value); + + public void SetQuaternion(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_QUATERNION, new Vector4(x, y, z, w)); + + public void SetQuaternion(string key, Vector4 value) => SetValue(key, KeyValuesType.TYPE_QUATERNION, value); public void SetAngle(string key, float pitch, float yaw, float roll) => SetValue(key, KeyValuesType.TYPE_QANGLE, new QAngle(pitch, yaw, roll)); @@ -147,12 +153,6 @@ public KeyValueContainer(KeyValuesType type, object value) public void SetMatrix3x4(string key, Matrix3x4 value) => SetValue(key, KeyValuesType.TYPE_MATRIX3X4, value); #endregion - public bool Remove(string key) => keyValues.Remove(key); - - public void Clear() => keyValues.Clear(); - - public int Count => keyValues.Count; - internal void SetValue(string key, KeyValuesType type, object value) { if (value == null) @@ -160,19 +160,19 @@ internal void SetValue(string key, KeyValuesType type, object value) throw new ArgumentNullException("Value can't be null!"); } - if (keyValues.TryGetValue(key, out KeyValueContainer? v)) + if (this.TryGetValue(key, out KeyValueContainer? v)) { v.Set(value); } else { KeyValueContainer container = new KeyValueContainer(type, value); - keyValues.Add(key, container); + this.Add(key, container); } } internal T GetValue(string key, T defaultValue) { - if (keyValues.TryGetValue(key, out KeyValueContainer? v)) + if (this.TryGetValue(key, out KeyValueContainer? v)) return v.Get(); return defaultValue; @@ -180,7 +180,7 @@ internal T GetValue(string key, T defaultValue) internal int Build(out object[] list) { - if (keyValues.Count == 0) + if (this.Count == 0) { list = Array.Empty(); return 0; @@ -188,7 +188,7 @@ internal int Build(out object[] list) List valueLists = new List(); - foreach (KeyValuePair kv in keyValues) + foreach (KeyValuePair kv in this) { valueLists.Add(kv.Key); KeyValuesType _type = kv.Value.GetContainerType(); @@ -260,7 +260,7 @@ internal int Build(out object[] list) } list = valueLists.ToArray(); - return keyValues.Count; + return this.Count; } } } From a279da3a78332558b6dc06c37969cad59d082c55 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Mon, 7 Oct 2024 01:31:10 +0200 Subject: [PATCH 08/29] chore: edit summary --- .../CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index a5487370d..3306073de 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -24,8 +24,7 @@ namespace CounterStrikeSharp.API.Modules.Utils { /// - /// EntityKeyValues - /// WARNING: This is intended to only use with for now! + /// WARNING: This is intended to be only used with for now! /// public class CEntityKeyValues : Dictionary { From 548c76d9c216a3d0b58e8fd4999164e842b8cd05 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 02:53:28 +0200 Subject: [PATCH 09/29] fix: reimplement getter/setter natives and fully expose `CEntityKeyValues` --- managed/CounterStrikeSharp.API/Core/API.cs | 37 ++ .../Modules/Utils/CEntityKeyValues.cs | 266 ++++++------- src/scripting/natives/natives_entities.cpp | 368 ++++++++++++------ src/scripting/natives/natives_entities.yaml | 3 + 4 files changed, 411 insertions(+), 263 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Core/API.cs b/managed/CounterStrikeSharp.API/Core/API.cs index d4a2a2ce2..ab2ed27a0 100644 --- a/managed/CounterStrikeSharp.API/Core/API.cs +++ b/managed/CounterStrikeSharp.API/Core/API.cs @@ -773,6 +773,43 @@ public static void DispatchSpawn(IntPtr entity, int count, object[] values){ } } + public static IntPtr EntityKeyValuesNew(){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.SetIdentifier(0x445FE212); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + + public static T EntityKeyValuesGetValue(string key, uint type){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(key); + ScriptContext.GlobalScriptContext.Push(type); + ScriptContext.GlobalScriptContext.SetIdentifier(0xA9A569AC); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (T)ScriptContext.GlobalScriptContext.GetResult(typeof(T)); + } + } + + public static void EntityKeyValuesSetValue(string key, uint type, object[] arguments){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(key); + ScriptContext.GlobalScriptContext.Push(type); + foreach (var obj in arguments) + { + ScriptContext.GlobalScriptContext.Push(obj); + } + ScriptContext.GlobalScriptContext.SetIdentifier(0x60234AB8); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + } + } + public static void HookEvent(string name, InputArgument callback, bool ispost){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index 3306073de..5dfc3b613 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -17,8 +17,6 @@ using System.Drawing; using System.Numerics; -using static CounterStrikeSharp.API.Modules.Utils.CEntityKeyValues; - // TODO: change from System.Numerics to exposed native values (Vector2D, Vector4D, Quaternion) namespace CounterStrikeSharp.API.Modules.Utils @@ -26,9 +24,9 @@ namespace CounterStrikeSharp.API.Modules.Utils /// /// WARNING: This is intended to be only used with for now! /// - public class CEntityKeyValues : Dictionary + public class CEntityKeyValues : NativeObject { - public enum KeyValuesType : uint + internal enum KeyValuesType : uint { TYPE_BOOL, TYPE_INT, @@ -50,60 +48,48 @@ public enum KeyValuesType : uint TYPE_MATRIX3X4 } - public class KeyValueContainer - { - private KeyValuesType type; - private object value; - - public KeyValueContainer(KeyValuesType type, object value) - { - this.type = type; - this.value = value; - } - - public KeyValuesType GetContainerType() => type; - - public T Get() => (T)value; + public CEntityKeyValues() : base(NativeAPI.EntityKeyValuesNew()) + { } - public void Set(T val) => value = (object)val!; - } + public CEntityKeyValues(nint pointer) : base(pointer) + { } -#region GETTER - public bool GetBool(string key, bool defaultValue = false) => GetValue(key, defaultValue); + #region GETTER + public bool GetBool(string key, bool defaultValue = false) => GetValue(key, KeyValuesType.TYPE_BOOL, defaultValue); - public int GetInt(string key, int defaultValue = 0) => GetValue(key, defaultValue); + public int GetInt(string key, int defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_INT, defaultValue); - public uint GetUInt(string key, uint defaultValue = 0) => GetValue(key, defaultValue); + public uint GetUInt(string key, uint defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_UINT, defaultValue); - public long GetInt64(string key, long defaultValue = 0) => GetValue(key, defaultValue); + public long GetInt64(string key, long defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_INT64, defaultValue); - public ulong GetUInt64(string key, ulong defaultValue = 0) => GetValue(key, defaultValue); + public ulong GetUInt64(string key, ulong defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_UINT64, defaultValue); - public float GetFloat(string key, float defaultValue = 0) => GetValue(key, defaultValue); + public float GetFloat(string key, float defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_FLOAT, defaultValue); - public double GetDouble(string key, double defaultValue = 0) => GetValue(key, defaultValue); + public double GetDouble(string key, double defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_DOUBLE, defaultValue); - public string GetString(string key, string defaultValue = "") => GetValue(key, defaultValue); + public string GetString(string key, string defaultValue = "") => GetValue(key, KeyValuesType.TYPE_STRING, defaultValue); - public nint GetPointer(string key, nint defaultValue = 0) => GetValue(key, defaultValue); + public nint GetPointer(string key, nint defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_POINTER, defaultValue); - public uint GetStringToken(string key, uint defaultValue = 0) => GetValue(key, defaultValue); + public uint GetStringToken(string key, uint defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_STRING_TOKEN, defaultValue); - public CEntityHandle? GetEHandle(string key, CEntityHandle? defaultValue = null) => GetValue(key, defaultValue); + public CEntityHandle? GetEHandle(string key, CEntityHandle? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_EHANDLE, defaultValue); - public Color GetColor(string key) => GetValue(key, Color.Empty); + public Color GetColor(string key) => GetValue(key, KeyValuesType.TYPE_COLOR, Color.Empty); - public Vector? GetVector(string key, Vector? defaultValue = null) => GetValue(key, defaultValue); + public Vector? GetVector(string key, Vector? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_VECTOR, defaultValue); - public Vector2? GetVector2D(string key, Vector2? defaultValue = null) => GetValue(key, defaultValue); + public Vector2? GetVector2D(string key, Vector2? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_VECTOR2D, defaultValue); - public Vector4? GetVector4D(string key, Vector4? defaultValue = null) => GetValue(key, defaultValue); + public Vector4? GetVector4D(string key, Vector4? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_VECTOR4D, defaultValue); - public Vector4? GetQuaternion(string key, Vector4? defaultValue = null) => GetValue(key, defaultValue); + public Vector4? GetQuaternion(string key, Vector4? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_QUATERNION, defaultValue); - public QAngle? GetAngle(string key, QAngle? defaultValue = null) => GetValue(key, defaultValue); + public QAngle? GetAngle(string key, QAngle? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_QANGLE, defaultValue); - public Matrix3x4? GetMatrix3x4(string key, Matrix3x4? defaultValue = null) => GetValue(key, defaultValue); + public Matrix3x4? GetMatrix3x4(string key, Matrix3x4? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_MATRIX3X4, defaultValue); #endregion #region SETTER @@ -152,114 +138,120 @@ public KeyValueContainer(KeyValuesType type, object value) public void SetMatrix3x4(string key, Matrix3x4 value) => SetValue(key, KeyValuesType.TYPE_MATRIX3X4, value); #endregion - internal void SetValue(string key, KeyValuesType type, object value) + internal void SetValue(string key, KeyValuesType type, T value) { - if (value == null) - { - throw new ArgumentNullException("Value can't be null!"); - } + List arguments = new List(); - if (this.TryGetValue(key, out KeyValueContainer? v)) - { - v.Set(value); - } else + switch (type) { - KeyValueContainer container = new KeyValueContainer(type, value); - this.Add(key, container); + case KeyValuesType.TYPE_EHANDLE: + { + if (value is CEntityHandle entityHandle) + { + arguments.Add(entityHandle.Raw); + } else { BadTypeHandler(key, type, value); } + } break; + + case KeyValuesType.TYPE_COLOR: + { + if (value is Color color) + { + arguments.Add(color.R); + arguments.Add(color.G); + arguments.Add(color.B); + arguments.Add(color.A); + } else { BadTypeHandler(key, type, value); } + } break; + + case KeyValuesType.TYPE_VECTOR: + { + if (value is Vector vector) + { + arguments.Add(vector.X); + arguments.Add(vector.Y); + arguments.Add(vector.Z); + } else { BadTypeHandler(key, type, value); } + } break; + + case KeyValuesType.TYPE_VECTOR2D: + { + // TODO: Change to 'Vector2D' + if (value is Vector2 vector) + { + arguments.Add(vector.X); + arguments.Add(vector.Y); + } else { BadTypeHandler(key, type, value); } + } break; + + case KeyValuesType.TYPE_VECTOR4D: + { + // TODO: Change to 'Vector4D' + if (value is Vector4 vector) + { + arguments.Add(vector.X); + arguments.Add(vector.Y); + arguments.Add(vector.Z); + arguments.Add(vector.W); + } else { BadTypeHandler(key, type, value); } + } break; + + case KeyValuesType.TYPE_QUATERNION: + { + // TODO: Change to 'Quaternion' + if (value is Vector4 vector) + { + arguments.Add(vector.X); + arguments.Add(vector.Y); + arguments.Add(vector.Z); + arguments.Add(vector.W); + } else { BadTypeHandler(key, type, value); } + } break; + + case KeyValuesType.TYPE_QANGLE: + { + if (value is QAngle angle) + { + arguments.Add(angle.X); + arguments.Add(angle.Y); + arguments.Add(angle.Z); + } else { BadTypeHandler(key, type, value); } + } break; + + case KeyValuesType.TYPE_MATRIX3X4: + { + if (value is Matrix3x4 matrix) + { + arguments.Add(matrix.M11); + arguments.Add(matrix.M12); + arguments.Add(matrix.M13); + arguments.Add(matrix.M14); + arguments.Add(matrix.M21); + arguments.Add(matrix.M22); + arguments.Add(matrix.M23); + arguments.Add(matrix.M24); + arguments.Add(matrix.M31); + arguments.Add(matrix.M32); + arguments.Add(matrix.M33); + arguments.Add(matrix.M34); + } else { BadTypeHandler(key, type, value); } + } break; + + default: + arguments.Add((object)value!); + break; } + + NativeAPI.EntityKeyValuesSetValue(key, (uint)type, arguments.ToArray()); } - internal T GetValue(string key, T defaultValue) + internal T GetValue(string key, KeyValuesType type, T defaultValue) { - if (this.TryGetValue(key, out KeyValueContainer? v)) - return v.Get(); - - return defaultValue; + return NativeAPI.EntityKeyValuesGetValue(key, (uint)type) ?? defaultValue; } - internal int Build(out object[] list) + internal void BadTypeHandler(string key, KeyValuesType type, T value) { - if (this.Count == 0) - { - list = Array.Empty(); - return 0; - } - - List valueLists = new List(); - - foreach (KeyValuePair kv in this) - { - valueLists.Add(kv.Key); - KeyValuesType _type = kv.Value.GetContainerType(); - valueLists.Add(_type); - - switch (_type) - { - case KeyValuesType.TYPE_EHANDLE: - valueLists.Add(kv.Value.Get().Raw); - break; - - case KeyValuesType.TYPE_COLOR: - Color color = kv.Value.Get(); - valueLists.Add(color.R); - valueLists.Add(color.G); - valueLists.Add(color.B); - valueLists.Add(color.A); - break; - - case KeyValuesType.TYPE_VECTOR: - Vector vec = kv.Value.Get(); - valueLists.Add(vec.X); - valueLists.Add(vec.Y); - valueLists.Add(vec.Z); - break; - - case KeyValuesType.TYPE_VECTOR2D: - Vector2 vec2D = kv.Value.Get(); - valueLists.Add(vec2D.X); - valueLists.Add(vec2D.Y); - break; - - case KeyValuesType.TYPE_VECTOR4D: - case KeyValuesType.TYPE_QUATERNION: - Vector4 vec4D = kv.Value.Get(); - valueLists.Add(vec4D.X); - valueLists.Add(vec4D.Y); - valueLists.Add(vec4D.Z); - valueLists.Add(vec4D.W); - break; - - case KeyValuesType.TYPE_QANGLE: - QAngle qAng = kv.Value.Get(); - valueLists.Add(qAng.X); - valueLists.Add(qAng.Y); - valueLists.Add(qAng.Z); - break; - - case KeyValuesType.TYPE_MATRIX3X4: - Matrix3x4 matrix = kv.Value.Get(); - valueLists.Add(matrix.M11); - valueLists.Add(matrix.M12); - valueLists.Add(matrix.M13); - valueLists.Add(matrix.M14); - valueLists.Add(matrix.M21); - valueLists.Add(matrix.M22); - valueLists.Add(matrix.M23); - valueLists.Add(matrix.M24); - valueLists.Add(matrix.M31); - valueLists.Add(matrix.M32); - valueLists.Add(matrix.M33); - valueLists.Add(matrix.M34); - break; - - default: - valueLists.Add(kv.Value.Get()); - break; - } - } - - list = valueLists.ToArray(); - return this.Count; + throw new ArgumentException($"Bad type for EntityKeyValues: got '{typeof(T)}' expected: '{type}'"); } } } diff --git a/src/scripting/natives/natives_entities.cpp b/src/scripting/natives/natives_entities.cpp index 371dd0355..1e85941f7 100644 --- a/src/scripting/natives/natives_entities.cpp +++ b/src/scripting/natives/natives_entities.cpp @@ -281,147 +281,260 @@ void AddEntityIOEvent(ScriptContext& script_context) void DispatchSpawn(ScriptContext& scriptContext) { auto entity = scriptContext.GetArgument(0); - auto count = scriptContext.GetArgument(1); + auto keyValues = scriptContext.GetArgument(1); + CBaseEntity_DispatchSpawn(entity, keyValues); +} - if (count == 0) { - CBaseEntity_DispatchSpawn(entity, nullptr); - return; - } +CEntityKeyValues* EntityKeyValuesNew(ScriptContext& script_context) +{ + return new CEntityKeyValues(); +} - CEntityKeyValues* pKeyValues = new CEntityKeyValues(); +void EntityKeyValuesSetValue(ScriptContext& script_context) +{ + CEntityKeyValues* keyValues = script_context.GetArgument(0); + const char* key = script_context.GetArgument(1); + KeyValuesType_t type = script_context.GetArgument(2); - int offset = 2; - for (int i = 0; i < count; ++i) { - const char* key = scriptContext.GetArgument(offset); - KeyValuesType_t _type = scriptContext.GetArgument(offset + 1); - switch (_type) { - case counterstrikesharp::TYPE_BOOL: - pKeyValues->SetBool(key, scriptContext.GetArgument(offset + 2)); - offset += 3; - break; - case counterstrikesharp::TYPE_INT: - pKeyValues->SetInt(key, scriptContext.GetArgument(offset + 2)); - offset += 3; - break; - case counterstrikesharp::TYPE_UINT: - pKeyValues->SetUint(key, scriptContext.GetArgument(offset + 2)); - offset += 3; - break; - case counterstrikesharp::TYPE_INT64: - pKeyValues->SetInt64(key, scriptContext.GetArgument(offset + 2)); - offset += 3; - break; - case counterstrikesharp::TYPE_UINT64: - pKeyValues->SetUint64(key, scriptContext.GetArgument(offset + 2)); - offset += 3; - break; - case counterstrikesharp::TYPE_FLOAT: - pKeyValues->SetFloat(key, scriptContext.GetArgument(offset + 2)); - offset += 3; - break; - case counterstrikesharp::TYPE_DOUBLE: - pKeyValues->SetDouble(key, scriptContext.GetArgument(offset + 2)); - offset += 3; - break; - case counterstrikesharp::TYPE_STRING: - pKeyValues->SetString(key, scriptContext.GetArgument(offset + 2)); - offset += 3; - break; - case counterstrikesharp::TYPE_POINTER: - pKeyValues->SetPtr(key, scriptContext.GetArgument(offset + 2)); - offset += 3; - break; - case counterstrikesharp::TYPE_STRING_TOKEN: - pKeyValues->SetStringToken(key, scriptContext.GetArgument(offset + 2)); - offset += 3; - break; - case counterstrikesharp::TYPE_EHANDLE: - pKeyValues->SetEHandle(key, scriptContext.GetArgument(offset + 2)); - offset += 3; + int offset = 3; + + switch (type) { + case counterstrikesharp::TYPE_BOOL: + keyValues->SetBool(key, script_context.GetArgument(offset)); + break; + + case counterstrikesharp::TYPE_INT: + keyValues->SetInt(key, script_context.GetArgument(offset)); + break; + + case counterstrikesharp::TYPE_UINT: + keyValues->SetUint(key, script_context.GetArgument(offset)); break; - case counterstrikesharp::TYPE_COLOR: { - char r = scriptContext.GetArgument(offset + 2); - char g = scriptContext.GetArgument(offset + 3); - char b = scriptContext.GetArgument(offset + 4); - char a = scriptContext.GetArgument(offset + 5); - - pKeyValues->SetColor(key, Color(r, g, b, a)); - offset += 6; + + case counterstrikesharp::TYPE_INT64: + keyValues->SetInt64(key, script_context.GetArgument(offset)); break; - } - case counterstrikesharp::TYPE_VECTOR: { - float x = scriptContext.GetArgument(offset + 2); - float y = scriptContext.GetArgument(offset + 3); - float z = scriptContext.GetArgument(offset + 4); - - pKeyValues->SetVector(key, Vector(x, y, z)); - offset += 5; + + case counterstrikesharp::TYPE_UINT64: + keyValues->SetUint64(key, script_context.GetArgument(offset)); break; - } - case counterstrikesharp::TYPE_VECTOR2D: { - float x = scriptContext.GetArgument(offset + 2); - float y = scriptContext.GetArgument(offset + 3); - pKeyValues->SetVector2D(key, Vector2D(x, y)); - offset += 4; + case counterstrikesharp::TYPE_FLOAT: + keyValues->SetFloat(key, script_context.GetArgument(offset)); break; - } - case counterstrikesharp::TYPE_VECTOR4D: { - float x = scriptContext.GetArgument(offset + 2); - float y = scriptContext.GetArgument(offset + 3); - float z = scriptContext.GetArgument(offset + 4); - float w = scriptContext.GetArgument(offset + 5); - - pKeyValues->SetVector4D(key, Vector4D(x, y, z, w)); - offset += 6; + + case counterstrikesharp::TYPE_DOUBLE: + keyValues->SetDouble(key, script_context.GetArgument(offset)); break; - } - case counterstrikesharp::TYPE_QUATERNION: { - float x = scriptContext.GetArgument(offset + 2); - float y = scriptContext.GetArgument(offset + 3); - float z = scriptContext.GetArgument(offset + 4); - float w = scriptContext.GetArgument(offset + 5); - - pKeyValues->SetQuaternion(key, Quaternion(x, y, z, w)); - offset += 6; + + case counterstrikesharp::TYPE_STRING: + keyValues->SetString(key, script_context.GetArgument(offset)); break; - } - case counterstrikesharp::TYPE_QANGLE: { - float x = scriptContext.GetArgument(offset + 2); - float y = scriptContext.GetArgument(offset + 3); - float z = scriptContext.GetArgument(offset + 4); - - pKeyValues->SetQAngle(key, QAngle(x, y, z)); - offset += 5; + + case counterstrikesharp::TYPE_POINTER: + keyValues->SetPtr(key, script_context.GetArgument(offset)); break; - } - case counterstrikesharp::TYPE_MATRIX3X4: { - float m11 = scriptContext.GetArgument(offset + 2); - float m12 = scriptContext.GetArgument(offset + 3); - float m13 = scriptContext.GetArgument(offset + 4); - float m14 = scriptContext.GetArgument(offset + 5); - - float m21 = scriptContext.GetArgument(offset + 6); - float m22 = scriptContext.GetArgument(offset + 7); - float m23 = scriptContext.GetArgument(offset + 8); - float m24 = scriptContext.GetArgument(offset + 9); - - float m31 = scriptContext.GetArgument(offset + 10); - float m32 = scriptContext.GetArgument(offset + 11); - float m33 = scriptContext.GetArgument(offset + 12); - float m34 = scriptContext.GetArgument(offset + 13); - - pKeyValues->SetMatrix3x4( - key, matrix3x4_t(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34)); - offset += 14; + + case counterstrikesharp::TYPE_STRING_TOKEN: + keyValues->SetStringToken(key, script_context.GetArgument(offset)); break; - } - default: + + case counterstrikesharp::TYPE_EHANDLE: + keyValues->SetEHandle(key, script_context.GetArgument(offset)); break; - } + + case counterstrikesharp::TYPE_COLOR: + { + char r = script_context.GetArgument(offset); + char g = script_context.GetArgument(offset + 1); + char b = script_context.GetArgument(offset + 2); + char a = script_context.GetArgument(offset + 3); + keyValues->SetColor(key, Color(r, g, b, a)); + break; + } + + case counterstrikesharp::TYPE_VECTOR: + { + float x = script_context.GetArgument(offset); + float y = script_context.GetArgument(offset + 1); + float z = script_context.GetArgument(offset + 2); + keyValues->SetVector(key, Vector(x, y, z)); + break; + } + + case counterstrikesharp::TYPE_VECTOR2D: + { + float x = script_context.GetArgument(offset); + float y = script_context.GetArgument(offset + 1); + keyValues->SetVector2D(key, Vector2D(x, y)); + break; + } + + case counterstrikesharp::TYPE_VECTOR4D: + { + float x = script_context.GetArgument(offset); + float y = script_context.GetArgument(offset + 1); + float z = script_context.GetArgument(offset + 2); + float w = script_context.GetArgument(offset + 3); + keyValues->SetVector4D(key, Vector4D(x, y, z, w)); + break; + } + + case counterstrikesharp::TYPE_QUATERNION: + { + float x = script_context.GetArgument(offset); + float y = script_context.GetArgument(offset + 1); + float z = script_context.GetArgument(offset + 2); + float w = script_context.GetArgument(offset + 3); + keyValues->SetQuaternion(key, Quaternion(x, y, z, w)); + break; + } + + case counterstrikesharp::TYPE_QANGLE: + { + float x = script_context.GetArgument(offset); + float y = script_context.GetArgument(offset + 1); + float z = script_context.GetArgument(offset + 2); + keyValues->SetQAngle(key, QAngle(x, y, z)); + break; + } + + case counterstrikesharp::TYPE_MATRIX3X4: + { + float m11 = script_context.GetArgument(offset); + float m12 = script_context.GetArgument(offset + 1); + float m13 = script_context.GetArgument(offset + 2); + float m14 = script_context.GetArgument(offset + 3); + + float m21 = script_context.GetArgument(offset + 4); + float m22 = script_context.GetArgument(offset + 5); + float m23 = script_context.GetArgument(offset + 6); + float m24 = script_context.GetArgument(offset + 7); + + float m31 = script_context.GetArgument(offset + 8); + float m32 = script_context.GetArgument(offset + 9); + float m33 = script_context.GetArgument(offset + 10); + float m34 = script_context.GetArgument(offset + 11); + + keyValues->SetMatrix3x4(key, matrix3x4_t(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34)); + break; + } + + default: + script_context.ThrowNativeError("Invalid KeyValues Type! ({})", type); + break; } +} - CBaseEntity_DispatchSpawn(entity, pKeyValues); +void EntityKeyValuesGetValue(ScriptContext& script_context) +{ + CEntityKeyValues* keyValues = script_context.GetArgument(0); + const char* key = script_context.GetArgument(1); + KeyValuesType_t type = script_context.GetArgument(2); + + switch (type) { + case counterstrikesharp::TYPE_BOOL: + { + script_context.SetResult(keyValues->GetBool(key)); + } break; + + case counterstrikesharp::TYPE_INT: + { + script_context.SetResult(keyValues->GetInt(key)); + } break; + + case counterstrikesharp::TYPE_UINT: + { + script_context.SetResult(keyValues->GetUint(key)); + } break; + + case counterstrikesharp::TYPE_INT64: + { + script_context.SetResult(keyValues->GetUint64(key)); + } break; + + case counterstrikesharp::TYPE_UINT64: + { + script_context.SetResult(keyValues->GetUint64(key)); + } break; + + case counterstrikesharp::TYPE_FLOAT: + { + script_context.SetResult(keyValues->GetFloat(key)); + } break; + + case counterstrikesharp::TYPE_DOUBLE: + { + script_context.SetResult(keyValues->GetDouble(key)); + } break; + + case counterstrikesharp::TYPE_STRING: + { + script_context.SetResult(keyValues->GetString(key)); + } break; + + case counterstrikesharp::TYPE_POINTER: + { + script_context.SetResult(keyValues->GetPtr(key)); + } break; + + case counterstrikesharp::TYPE_STRING_TOKEN: + { + script_context.SetResult(keyValues->GetStringToken(key)); + } break; + + case counterstrikesharp::TYPE_EHANDLE: + { + script_context.SetResult(keyValues->GetEHandle(key)); + } break; + + case counterstrikesharp::TYPE_COLOR: + { + script_context.SetResult(keyValues->GetColor(key)); + break; + } + + case counterstrikesharp::TYPE_VECTOR: + { + script_context.SetResult(keyValues->GetVector(key)); + break; + } + + case counterstrikesharp::TYPE_VECTOR2D: + { + script_context.SetResult(keyValues->GetVector2D(key)); + break; + } + + case counterstrikesharp::TYPE_VECTOR4D: + { + script_context.SetResult(keyValues->GetVector4D(key)); + break; + } + + case counterstrikesharp::TYPE_QUATERNION: + { + script_context.SetResult(keyValues->GetQuaternion(key)); + break; + } + + case counterstrikesharp::TYPE_QANGLE: + { + script_context.SetResult(keyValues->GetQAngle(key)); + break; + } + + case counterstrikesharp::TYPE_MATRIX3X4: + { + script_context.SetResult(keyValues->GetMatrix3x4(key)); + break; + } + + default: + { + script_context.ThrowNativeError("Invalid KeyValues Type! ({})", type); + } break; + } } REGISTER_NATIVES(entities, { @@ -442,5 +555,8 @@ REGISTER_NATIVES(entities, { ScriptEngine::RegisterNativeHandler("ACCEPT_INPUT", AcceptInput); ScriptEngine::RegisterNativeHandler("ADD_ENTITY_IO_EVENT", AddEntityIOEvent); ScriptEngine::RegisterNativeHandler("DISPATCH_SPAWN", DispatchSpawn); + ScriptEngine::RegisterNativeHandler("ENTITY_KEY_VALUES_NEW", EntityKeyValuesNew); + ScriptEngine::RegisterNativeHandler("ENTITY_KEY_VALUES_GET_VALUE", EntityKeyValuesGetValue); + ScriptEngine::RegisterNativeHandler("ENTITY_KEY_VALUES_SET_VALUE", EntityKeyValuesSetValue); }) } // namespace counterstrikesharp diff --git a/src/scripting/natives/natives_entities.yaml b/src/scripting/natives/natives_entities.yaml index 603199398..6220c8d25 100644 --- a/src/scripting/natives/natives_entities.yaml +++ b/src/scripting/natives/natives_entities.yaml @@ -15,3 +15,6 @@ UNHOOK_ENTITY_OUTPUT: classname:string, outputName:string, callback:func, mode:H ACCEPT_INPUT: pThis:pointer, inputName:string, activator:pointer, caller:pointer, value:string, outputID:int -> void ADD_ENTITY_IO_EVENT: pTarget:pointer, inputName:string, activator:pointer, caller:pointer, value:string, delay:float, outputID:int -> void DISPATCH_SPAWN: entity:pointer, count:int, values:object[] -> void +ENTITY_KEY_VALUES_NEW: -> pointer +ENTITY_KEY_VALUES_GET_VALUE: key:string, type:uint -> any +ENTITY_KEY_VALUES_SET_VALUE: key:string, type:uint, arguments:object[] -> void \ No newline at end of file From e1225ba9b3f52e298483599f865444ec70be6d7b Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 02:54:38 +0200 Subject: [PATCH 10/29] chore: FIX GETTER REGION --- .../CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index 5dfc3b613..c725a6a31 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -54,7 +54,7 @@ public CEntityKeyValues() : base(NativeAPI.EntityKeyValuesNew()) public CEntityKeyValues(nint pointer) : base(pointer) { } - #region GETTER +#region GETTER public bool GetBool(string key, bool defaultValue = false) => GetValue(key, KeyValuesType.TYPE_BOOL, defaultValue); public int GetInt(string key, int defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_INT, defaultValue); From 71de499f0bedb64e944990ec43a2c0870b1d1218 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 03:33:49 +0200 Subject: [PATCH 11/29] feat: default implementations for `Vector2D`, `Vector4D`, `Quaternion`, `matrix3x4_t` --- managed/CounterStrikeSharp.API/Core/API.cs | 40 ++++++++++++++++ .../Modules/Utils/Quaternion.cs | 23 ++++++++-- .../Modules/Utils/Vector.cs | 2 + .../Modules/Utils/Vector2D.cs | 15 ++++-- .../Modules/Utils/Vector4D.cs | 23 +++++++--- .../Modules/Utils/matrix3x4_t.cs | 46 +++++++++++++++++-- src/scripting/natives/natives_vector.cpp | 24 ++++++++++ src/scripting/natives/natives_vector.yaml | 4 ++ 8 files changed, 156 insertions(+), 21 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Core/API.cs b/managed/CounterStrikeSharp.API/Core/API.cs index ab2ed27a0..a717e824c 100644 --- a/managed/CounterStrikeSharp.API/Core/API.cs +++ b/managed/CounterStrikeSharp.API/Core/API.cs @@ -1687,6 +1687,46 @@ public static IntPtr VectorNew(){ } } + public static IntPtr Vector2dNew(){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.SetIdentifier(0x2CD71169); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + + public static IntPtr Vector4dNew(){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.SetIdentifier(0x16585EAF); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + + public static IntPtr Matrix3x4New(){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.SetIdentifier(0xA2E1A42); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + + public static IntPtr QuaternionNew(){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.SetIdentifier(0xD27D7946); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr)); + } + } + public static IntPtr AngleNew(){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/Quaternion.cs b/managed/CounterStrikeSharp.API/Modules/Utils/Quaternion.cs index 84622c298..abf9d8590 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/Quaternion.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/Quaternion.cs @@ -14,18 +14,33 @@ * along with CounterStrikeSharp. If not, see . * */ -using System; using System.Runtime.CompilerServices; -using CounterStrikeSharp.API.Core; namespace CounterStrikeSharp.API.Modules.Utils { public class Quaternion : NativeObject { + // Not sure who made this one? maybe mark it as 'obsolete' to don't break existing plugins but warn them? + public unsafe ref float Value => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 0); + + public unsafe ref float X => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 0); + + public unsafe ref float Y => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 1); + + public unsafe ref float Z => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 2); + + public unsafe ref float W => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 3); + public Quaternion(IntPtr pointer) : base(pointer) { } - public unsafe ref float Value => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 0); + public Quaternion(float? x = null, float? y = null, float? z = null, float? w = null) : this(NativeAPI.QuaternionNew()) + { + this.X = x ?? 0; + this.Y = y ?? 0; + this.Z = z ?? 0; + this.W = w ?? 0; + } } -} \ No newline at end of file +} diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/Vector.cs b/managed/CounterStrikeSharp.API/Modules/Utils/Vector.cs index 7dfe83990..d7fda7872 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/Vector.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/Vector.cs @@ -48,7 +48,9 @@ public Vector(float? x = null, float? y = null, float? z = null) : this(NativeAP } public unsafe ref float X => ref Unsafe.Add(ref *(float*)Handle, 0); + public unsafe ref float Y => ref Unsafe.Add(ref *(float*)Handle, 1); + public unsafe ref float Z => ref Unsafe.Add(ref *(float*)Handle, 2); /// diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/Vector2D.cs b/managed/CounterStrikeSharp.API/Modules/Utils/Vector2D.cs index c6047451c..3121cbd57 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/Vector2D.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/Vector2D.cs @@ -14,19 +14,24 @@ * along with CounterStrikeSharp. If not, see . * */ -using System; using System.Runtime.CompilerServices; -using CounterStrikeSharp.API.Core; namespace CounterStrikeSharp.API.Modules.Utils { public class Vector2D : NativeObject { + public unsafe ref float X => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 0); + + public unsafe ref float Y => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 1); + public Vector2D(IntPtr pointer) : base(pointer) { } - public unsafe ref float X => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 0); - public unsafe ref float Y => ref Unsafe.Add(ref *(float*)Handle, 1); + public Vector2D(float? x = null, float? y = null) : this(NativeAPI.Vector2dNew()) + { + this.X = x ?? 0; + this.Y = y ?? 0; + } } -} \ No newline at end of file +} diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/Vector4D.cs b/managed/CounterStrikeSharp.API/Modules/Utils/Vector4D.cs index 758719773..effcab0c4 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/Vector4D.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/Vector4D.cs @@ -14,21 +14,30 @@ * along with CounterStrikeSharp. If not, see . * */ -using System; using System.Runtime.CompilerServices; -using CounterStrikeSharp.API.Core; namespace CounterStrikeSharp.API.Modules.Utils { public class Vector4D : NativeObject { + public unsafe ref float X => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 0); + + public unsafe ref float Y => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 1); + + public unsafe ref float Z => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 2); + + public unsafe ref float W => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 3); + public Vector4D(IntPtr pointer) : base(pointer) { } - public unsafe ref float X => ref Unsafe.Add(ref *(float*)Handle.ToPointer(), 0); - public unsafe ref float Y => ref Unsafe.Add(ref *(float*)Handle, 1); - public unsafe ref float Z => ref Unsafe.Add(ref *(float*)Handle, 2); - public unsafe ref float W => ref Unsafe.Add(ref *(float*)Handle, 3); + public Vector4D(float? x = null, float? y = null, float? z = null, float? w = null) : this(NativeAPI.Vector4dNew()) + { + this.X = x ?? 0; + this.Y = y ?? 0; + this.Z = z ?? 0; + this.W = w ?? 0; + } } -} \ No newline at end of file +} diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs b/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs index 9b40c5be3..52e70a196 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs @@ -1,13 +1,49 @@ -using System; +/* + * This file is part of CounterStrikeSharp. + * CounterStrikeSharp is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CounterStrikeSharp 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 CounterStrikeSharp. If not, see . * + */ + using System.Runtime.CompilerServices; namespace CounterStrikeSharp.API.Modules.Utils; public partial class matrix3x4_t : NativeObject -{ +{ + public unsafe ref float this[int row, int column] => ref Unsafe.Add(ref *(float*)Handle, row * 4 + column); + public matrix3x4_t(IntPtr pointer) : base(pointer) { + } + + public matrix3x4_t(float? m00 = null, float? m01 = null, float? m02 = null, float? m03 = null, + float? m10 = null, float? m11 = null, float? m12 = null, float? m13 = null, + float? m20 = null, float? m21 = null, float? m22 = null, float? m23 = null) : this(NativeAPI.Matrix3x4New()) + { + this[0, 0] = m00 ?? 0; + this[0, 1] = m01 ?? 0; + this[0, 2] = m02 ?? 0; + this[0, 3] = m03 ?? 0; + + this[1, 0] = m10 ?? 0; + this[1, 1] = m11 ?? 0; + this[1, 2] = m12 ?? 0; + this[1, 3] = m13 ?? 0; + + this[2, 0] = m20 ?? 0; + this[2, 1] = m21 ?? 0; + this[2, 2] = m22 ?? 0; + this[2, 3] = m23 ?? 0; } - - public unsafe ref float this[int row, int column] => ref Unsafe.Add(ref *(float*)Handle, row * 4 + column); -} \ No newline at end of file + +} diff --git a/src/scripting/natives/natives_vector.cpp b/src/scripting/natives/natives_vector.cpp index 4fca493a8..c7b68b89e 100644 --- a/src/scripting/natives/natives_vector.cpp +++ b/src/scripting/natives/natives_vector.cpp @@ -45,6 +45,26 @@ Vector* VectorNew(ScriptContext& script_context) return vec; } +Vector2D* Vector2DNew(ScriptContext& script_context) +{ + return new Vector2D(); +} + +Vector4D* Vector4DNew(ScriptContext& script_context) +{ + return new Vector4D(); +} + +matrix3x4_t* Matrix3x4New(ScriptContext& script_context) +{ + return new matrix3x4_t(); +} + +Quaternion* QuaternionNew(ScriptContext& script_context) +{ + return new Quaternion(); +} + // TODO: These need to be cleared out somehow std::vector managed_angles; @@ -83,6 +103,10 @@ void NativeAngleVectors(ScriptContext& script_context) REGISTER_NATIVES(vector, { ScriptEngine::RegisterNativeHandler("VECTOR_NEW", VectorNew); + ScriptEngine::RegisterNativeHandler("VECTOR2D_NEW", Vector2DNew); + ScriptEngine::RegisterNativeHandler("VECTOR4D_NEW", Vector4DNew); + ScriptEngine::RegisterNativeHandler("MATRIX3X4_NEW", Matrix3x4New); + ScriptEngine::RegisterNativeHandler("QUATERNION_NEW", QuaternionNew); ScriptEngine::RegisterNativeHandler("ANGLE_NEW", AngleNew); ScriptEngine::RegisterNativeHandler("VECTOR_SET_X", VectorSetX); diff --git a/src/scripting/natives/natives_vector.yaml b/src/scripting/natives/natives_vector.yaml index e594c773b..d315902cb 100644 --- a/src/scripting/natives/natives_vector.yaml +++ b/src/scripting/natives/natives_vector.yaml @@ -1,4 +1,8 @@ VECTOR_NEW: -> pointer +VECTOR2D_NEW: -> pointer +VECTOR4D_NEW: -> pointer +MATRIX3X4_NEW: -> pointer +QUATERNION_NEW: -> pointer ANGLE_NEW: -> pointer VECTOR_GET_X: vector:pointer -> float VECTOR_GET_Y: vector:pointer -> float From 62089d24a23b93aa35ea1153d39516474bcaeaf1 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 03:33:58 +0200 Subject: [PATCH 12/29] tweak: adjust changes --- .../Modules/Utils/CEntityKeyValues.cs | 76 +++++++++---------- .../Modules/Utils/Matrix3x4.cs | 44 ----------- 2 files changed, 36 insertions(+), 84 deletions(-) delete mode 100644 managed/CounterStrikeSharp.API/Modules/Utils/Matrix3x4.cs diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index c725a6a31..6d8447005 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -15,9 +15,6 @@ */ using System.Drawing; -using System.Numerics; - -// TODO: change from System.Numerics to exposed native values (Vector2D, Vector4D, Quaternion) namespace CounterStrikeSharp.API.Modules.Utils { @@ -69,7 +66,7 @@ public CEntityKeyValues(nint pointer) : base(pointer) public double GetDouble(string key, double defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_DOUBLE, defaultValue); - public string GetString(string key, string defaultValue = "") => GetValue(key, KeyValuesType.TYPE_STRING, defaultValue); + public string? GetString(string key, string defaultValue = "") => GetValue(key, KeyValuesType.TYPE_STRING, defaultValue); public nint GetPointer(string key, nint defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_POINTER, defaultValue); @@ -81,15 +78,15 @@ public CEntityKeyValues(nint pointer) : base(pointer) public Vector? GetVector(string key, Vector? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_VECTOR, defaultValue); - public Vector2? GetVector2D(string key, Vector2? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_VECTOR2D, defaultValue); + public Vector2D? GetVector2D(string key, Vector2D? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_VECTOR2D, defaultValue); - public Vector4? GetVector4D(string key, Vector4? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_VECTOR4D, defaultValue); + public Vector4D? GetVector4D(string key, Vector4D? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_VECTOR4D, defaultValue); - public Vector4? GetQuaternion(string key, Vector4? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_QUATERNION, defaultValue); + public Quaternion? GetQuaternion(string key, Quaternion? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_QUATERNION, defaultValue); public QAngle? GetAngle(string key, QAngle? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_QANGLE, defaultValue); - public Matrix3x4? GetMatrix3x4(string key, Matrix3x4? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_MATRIX3X4, defaultValue); + public matrix3x4_t? GetMatrix3x4(string key, matrix3x4_t? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_MATRIX3X4, defaultValue); #endregion #region SETTER @@ -117,25 +114,25 @@ public CEntityKeyValues(nint pointer) : base(pointer) public void SetColor(string key, Color value) => SetValue(key, KeyValuesType.TYPE_COLOR, value); - public void SetVector(string key, float x, float y, float z) => SetValue(key, KeyValuesType.TYPE_VECTOR, new Vector3(x, y, z)); + public void SetVector(string key, float x, float y, float z) => SetValue(key, KeyValuesType.TYPE_VECTOR, new Vector(x, y, z)); - public void SetVector2D(string key, float x, float y) => SetValue(key, KeyValuesType.TYPE_VECTOR2D, new Vector2(x, y)); + public void SetVector2D(string key, float x, float y) => SetValue(key, KeyValuesType.TYPE_VECTOR2D, new Vector2D(x, y)); - public void SetVector2D(string key, Vector2 value) => SetValue(key, KeyValuesType.TYPE_VECTOR2D, value); + public void SetVector2D(string key, Vector2D value) => SetValue(key, KeyValuesType.TYPE_VECTOR2D, value); - public void SetVector4D(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_VECTOR4D, new Vector4(x, y, z, w)); + public void SetVector4D(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_VECTOR4D, new Vector4D(x, y, z, w)); - public void SetVector4D(string key, Vector4 value) => SetValue(key, KeyValuesType.TYPE_VECTOR4D, value); + public void SetVector4D(string key, Vector4D value) => SetValue(key, KeyValuesType.TYPE_VECTOR4D, value); - public void SetQuaternion(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_QUATERNION, new Vector4(x, y, z, w)); + public void SetQuaternion(string key, float x, float y, float z, float w) => SetValue(key, KeyValuesType.TYPE_QUATERNION, new Quaternion(x, y, z, w)); - public void SetQuaternion(string key, Vector4 value) => SetValue(key, KeyValuesType.TYPE_QUATERNION, value); + public void SetQuaternion(string key, Quaternion value) => SetValue(key, KeyValuesType.TYPE_QUATERNION, value); public void SetAngle(string key, float pitch, float yaw, float roll) => SetValue(key, KeyValuesType.TYPE_QANGLE, new QAngle(pitch, yaw, roll)); public void SetAngle(string key, QAngle angle) => SetValue(key, KeyValuesType.TYPE_QANGLE, angle); - public void SetMatrix3x4(string key, Matrix3x4 value) => SetValue(key, KeyValuesType.TYPE_MATRIX3X4, value); + public void SetMatrix3x4(string key, matrix3x4_t value) => SetValue(key, KeyValuesType.TYPE_MATRIX3X4, value); #endregion internal void SetValue(string key, KeyValuesType type, T value) @@ -175,8 +172,7 @@ internal void SetValue(string key, KeyValuesType type, T value) case KeyValuesType.TYPE_VECTOR2D: { - // TODO: Change to 'Vector2D' - if (value is Vector2 vector) + if (value is Vector2D vector) { arguments.Add(vector.X); arguments.Add(vector.Y); @@ -185,8 +181,7 @@ internal void SetValue(string key, KeyValuesType type, T value) case KeyValuesType.TYPE_VECTOR4D: { - // TODO: Change to 'Vector4D' - if (value is Vector4 vector) + if (value is Vector4D vector) { arguments.Add(vector.X); arguments.Add(vector.Y); @@ -197,13 +192,12 @@ internal void SetValue(string key, KeyValuesType type, T value) case KeyValuesType.TYPE_QUATERNION: { - // TODO: Change to 'Quaternion' - if (value is Vector4 vector) + if (value is Quaternion quaternion) { - arguments.Add(vector.X); - arguments.Add(vector.Y); - arguments.Add(vector.Z); - arguments.Add(vector.W); + arguments.Add(quaternion.X); + arguments.Add(quaternion.Y); + arguments.Add(quaternion.Z); + arguments.Add(quaternion.W); } else { BadTypeHandler(key, type, value); } } break; @@ -219,20 +213,22 @@ internal void SetValue(string key, KeyValuesType type, T value) case KeyValuesType.TYPE_MATRIX3X4: { - if (value is Matrix3x4 matrix) + if (value is matrix3x4_t matrix) { - arguments.Add(matrix.M11); - arguments.Add(matrix.M12); - arguments.Add(matrix.M13); - arguments.Add(matrix.M14); - arguments.Add(matrix.M21); - arguments.Add(matrix.M22); - arguments.Add(matrix.M23); - arguments.Add(matrix.M24); - arguments.Add(matrix.M31); - arguments.Add(matrix.M32); - arguments.Add(matrix.M33); - arguments.Add(matrix.M34); + arguments.Add(matrix[1, 1]); + arguments.Add(matrix[1, 2]); + arguments.Add(matrix[1, 3]); + arguments.Add(matrix[1, 4]); + + arguments.Add(matrix[2, 1]); + arguments.Add(matrix[2, 2]); + arguments.Add(matrix[2, 3]); + arguments.Add(matrix[2, 4]); + + arguments.Add(matrix[3, 1]); + arguments.Add(matrix[3, 2]); + arguments.Add(matrix[3, 3]); + arguments.Add(matrix[3, 4]); } else { BadTypeHandler(key, type, value); } } break; @@ -244,7 +240,7 @@ internal void SetValue(string key, KeyValuesType type, T value) NativeAPI.EntityKeyValuesSetValue(key, (uint)type, arguments.ToArray()); } - internal T GetValue(string key, KeyValuesType type, T defaultValue) + internal T? GetValue(string key, KeyValuesType type, T? defaultValue) { return NativeAPI.EntityKeyValuesGetValue(key, (uint)type) ?? defaultValue; } diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/Matrix3x4.cs b/managed/CounterStrikeSharp.API/Modules/Utils/Matrix3x4.cs deleted file mode 100644 index 87f9d5fc8..000000000 --- a/managed/CounterStrikeSharp.API/Modules/Utils/Matrix3x4.cs +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of CounterStrikeSharp. - * CounterStrikeSharp is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CounterStrikeSharp 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 CounterStrikeSharp. If not, see . * - */ - -namespace CounterStrikeSharp.API.Modules.Utils -{ - /// - /// Matrix3x4 for - /// - public class Matrix3x4 - { - public float M11; - public float M12; - public float M13; - public float M14; - public float M21; - public float M22; - public float M23; - public float M24; - public float M31; - public float M32; - public float M33; - public float M34; - - public Matrix3x4() { } - - public Matrix3x4(float M11, float M12, float M13, float M14, float M21, float M22, float M23, float M24, float M31, float M32, float M33, float M34) - { - this.M11 = M11; this.M12 = M12; this.M13 = M13; this.M14 = M14; this.M21 = M21; this.M22 = M22; this.M23 = M23; this.M24 = M24; this.M31 = M31; this.M32 = M32; this.M33 = M33; this.M34 = M34; - } - } -} From 4c09221ccfd173c295b32e355c1953dfbf8c2883 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 03:40:22 +0200 Subject: [PATCH 13/29] fix: adjusted natives --- managed/CounterStrikeSharp.API/Core/API.cs | 14 ++++++-------- .../Core/Model/CBaseEntity.cs | 3 +-- .../Modules/Utils/CEntityKeyValues.cs | 4 ++-- src/scripting/natives/natives_entities.yaml | 6 +++--- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Core/API.cs b/managed/CounterStrikeSharp.API/Core/API.cs index a717e824c..2cb9e1b0c 100644 --- a/managed/CounterStrikeSharp.API/Core/API.cs +++ b/managed/CounterStrikeSharp.API/Core/API.cs @@ -758,15 +758,11 @@ public static void AddEntityIoEvent(IntPtr ptarget, string inputname, IntPtr act } } - public static void DispatchSpawn(IntPtr entity, int count, object[] values){ + public static void DispatchSpawn(IntPtr entity, IntPtr keyvalues){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); ScriptContext.GlobalScriptContext.Push(entity); - ScriptContext.GlobalScriptContext.Push(count); - foreach (var obj in values) - { - ScriptContext.GlobalScriptContext.Push(obj); - } + ScriptContext.GlobalScriptContext.Push(keyvalues); ScriptContext.GlobalScriptContext.SetIdentifier(0xAE01E931); ScriptContext.GlobalScriptContext.Invoke(); ScriptContext.GlobalScriptContext.CheckErrors(); @@ -783,9 +779,10 @@ public static IntPtr EntityKeyValuesNew(){ } } - public static T EntityKeyValuesGetValue(string key, uint type){ + public static T EntityKeyValuesGetValue(IntPtr keyvalues, string key, uint type){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(keyvalues); ScriptContext.GlobalScriptContext.Push(key); ScriptContext.GlobalScriptContext.Push(type); ScriptContext.GlobalScriptContext.SetIdentifier(0xA9A569AC); @@ -795,9 +792,10 @@ public static T EntityKeyValuesGetValue(string key, uint type){ } } - public static void EntityKeyValuesSetValue(string key, uint type, object[] arguments){ + public static void EntityKeyValuesSetValue(IntPtr keyvalues, string key, uint type, object[] arguments){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(keyvalues); ScriptContext.GlobalScriptContext.Push(key); ScriptContext.GlobalScriptContext.Push(type); foreach (var obj in arguments) diff --git a/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs b/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs index 3ff976cec..8d36c21b4 100644 --- a/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs +++ b/managed/CounterStrikeSharp.API/Core/Model/CBaseEntity.cs @@ -30,8 +30,7 @@ public void DispatchSpawn(CEntityKeyValues? keyValues = null) if (keyValues != null) { - int count = keyValues.Build(out object[] values); - NativeAPI.DispatchSpawn(Handle, count, values); + NativeAPI.DispatchSpawn(Handle, keyValues.Handle); } else { VirtualFunctions.CBaseEntity_DispatchSpawn(Handle, IntPtr.Zero); diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index 6d8447005..30b9a9efe 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -237,12 +237,12 @@ internal void SetValue(string key, KeyValuesType type, T value) break; } - NativeAPI.EntityKeyValuesSetValue(key, (uint)type, arguments.ToArray()); + NativeAPI.EntityKeyValuesSetValue(Handle, key, (uint)type, arguments.ToArray()); } internal T? GetValue(string key, KeyValuesType type, T? defaultValue) { - return NativeAPI.EntityKeyValuesGetValue(key, (uint)type) ?? defaultValue; + return NativeAPI.EntityKeyValuesGetValue(Handle, key, (uint)type) ?? defaultValue; } internal void BadTypeHandler(string key, KeyValuesType type, T value) diff --git a/src/scripting/natives/natives_entities.yaml b/src/scripting/natives/natives_entities.yaml index 6220c8d25..9e29c2662 100644 --- a/src/scripting/natives/natives_entities.yaml +++ b/src/scripting/natives/natives_entities.yaml @@ -14,7 +14,7 @@ HOOK_ENTITY_OUTPUT: classname:string, outputName:string, callback:func, mode:Hoo UNHOOK_ENTITY_OUTPUT: classname:string, outputName:string, callback:func, mode:HookMode -> void ACCEPT_INPUT: pThis:pointer, inputName:string, activator:pointer, caller:pointer, value:string, outputID:int -> void ADD_ENTITY_IO_EVENT: pTarget:pointer, inputName:string, activator:pointer, caller:pointer, value:string, delay:float, outputID:int -> void -DISPATCH_SPAWN: entity:pointer, count:int, values:object[] -> void +DISPATCH_SPAWN: entity:pointer, keyvalues:pointer -> void ENTITY_KEY_VALUES_NEW: -> pointer -ENTITY_KEY_VALUES_GET_VALUE: key:string, type:uint -> any -ENTITY_KEY_VALUES_SET_VALUE: key:string, type:uint, arguments:object[] -> void \ No newline at end of file +ENTITY_KEY_VALUES_GET_VALUE: keyvalues:pointer, key:string, type:uint -> any +ENTITY_KEY_VALUES_SET_VALUE: keyvalues:pointer, key:string, type:uint, arguments:object[] -> void \ No newline at end of file From 321782f65842aabe705a1e477b7d93815b024816 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 03:54:02 +0200 Subject: [PATCH 14/29] feat: overload `SetVector` --- .../CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index 30b9a9efe..b493df43b 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -116,6 +116,8 @@ public CEntityKeyValues(nint pointer) : base(pointer) public void SetVector(string key, float x, float y, float z) => SetValue(key, KeyValuesType.TYPE_VECTOR, new Vector(x, y, z)); + public void SetVector(string key, Vector vector) => SetValue(key, KeyValuesType.TYPE_VECTOR, vector); + public void SetVector2D(string key, float x, float y) => SetValue(key, KeyValuesType.TYPE_VECTOR2D, new Vector2D(x, y)); public void SetVector2D(string key, Vector2D value) => SetValue(key, KeyValuesType.TYPE_VECTOR2D, value); From 84fe54cbbbcb5c0e5eac0ecd5151c9055d6e2afa Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 04:11:48 +0200 Subject: [PATCH 15/29] feat: overloaded `ToString` method --- managed/CounterStrikeSharp.API/Modules/Utils/Quaternion.cs | 5 +++++ managed/CounterStrikeSharp.API/Modules/Utils/Vector2D.cs | 5 +++++ managed/CounterStrikeSharp.API/Modules/Utils/Vector4D.cs | 5 +++++ .../CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs | 7 +++++++ 4 files changed, 22 insertions(+) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/Quaternion.cs b/managed/CounterStrikeSharp.API/Modules/Utils/Quaternion.cs index abf9d8590..62d8dcfb0 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/Quaternion.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/Quaternion.cs @@ -42,5 +42,10 @@ public Quaternion(float? x = null, float? y = null, float? z = null, float? w = this.Z = z ?? 0; this.W = w ?? 0; } + + public override string ToString() + { + return $"{X:n2} {Y:n2} {Z:n2} {W:n2}"; + } } } diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/Vector2D.cs b/managed/CounterStrikeSharp.API/Modules/Utils/Vector2D.cs index 3121cbd57..52178228c 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/Vector2D.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/Vector2D.cs @@ -33,5 +33,10 @@ public Vector2D(float? x = null, float? y = null) : this(NativeAPI.Vector2dNew() this.X = x ?? 0; this.Y = y ?? 0; } + + public override string ToString() + { + return $"{X:n2} {Y:n2}"; + } } } diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/Vector4D.cs b/managed/CounterStrikeSharp.API/Modules/Utils/Vector4D.cs index effcab0c4..c6ce79d06 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/Vector4D.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/Vector4D.cs @@ -39,5 +39,10 @@ public Vector4D(float? x = null, float? y = null, float? z = null, float? w = nu this.Z = z ?? 0; this.W = w ?? 0; } + + public override string ToString() + { + return $"{X:n2} {Y:n2} {Z:n2} {W:n2}"; + } } } diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs b/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs index 52e70a196..fe2c768da 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs @@ -45,5 +45,12 @@ public matrix3x4_t(float? m00 = null, float? m01 = null, float? m02 = null, floa this[2, 2] = m22 ?? 0; this[2, 3] = m23 ?? 0; } + + public override string ToString() + { + return $"{this[0, 0]:n2} {this[0, 1]:n2} {this[0, 2]:n2} {this[0, 3]:n2}\n" + + $"{this[1, 0]:n2} {this[1, 1]:n2} {this[1, 2]:n2} {this[1, 3]:n2}\n" + + $"{this[2, 0]:n2} {this[2, 1]:n2} {this[2, 2]:n2} {this[2, 3]:n2}"; + } } From 1fb3803edce530bfb034f53eba8f8350620a1024 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 04:56:24 +0200 Subject: [PATCH 16/29] tweak: replaced with `CUtlStringToken` --- .../CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index b493df43b..257606af0 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -70,7 +70,7 @@ public CEntityKeyValues(nint pointer) : base(pointer) public nint GetPointer(string key, nint defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_POINTER, defaultValue); - public uint GetStringToken(string key, uint defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_STRING_TOKEN, defaultValue); + public CUtlStringToken? GetStringToken(string key, CUtlStringToken? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_STRING_TOKEN, defaultValue); public CEntityHandle? GetEHandle(string key, CEntityHandle? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_EHANDLE, defaultValue); @@ -108,7 +108,7 @@ public CEntityKeyValues(nint pointer) : base(pointer) public void SetPointer(string key, nint value) => SetValue(key, KeyValuesType.TYPE_POINTER, value); - public void SetStringToken(string key, uint value) => SetValue(key, KeyValuesType.TYPE_STRING_TOKEN, value); + public void SetStringToken(string key, CUtlStringToken value) => SetValue(key, KeyValuesType.TYPE_STRING_TOKEN, value); public void SetEHandle(string key, CEntityHandle value) => SetValue(key, KeyValuesType.TYPE_EHANDLE, value); From 78e1bf224d2cdba1b282aee3d3c52d18df4453d1 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 05:03:41 +0200 Subject: [PATCH 17/29] fix: Added `Color` to `ScriptContext.GetResult` --- managed/CounterStrikeSharp.API/Core/ScriptContext.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/managed/CounterStrikeSharp.API/Core/ScriptContext.cs b/managed/CounterStrikeSharp.API/Core/ScriptContext.cs index 11a3bdc6b..e7389ee78 100644 --- a/managed/CounterStrikeSharp.API/Core/ScriptContext.cs +++ b/managed/CounterStrikeSharp.API/Core/ScriptContext.cs @@ -25,6 +25,7 @@ using System; using System.Collections.Concurrent; +using System.Drawing; using System.Runtime.InteropServices; using System.Security; using System.Text; @@ -449,6 +450,12 @@ internal unsafe object GetResult(Type type, byte* ptr) return Activator.CreateInstance(type, pointer); } + if (type == typeof(Color)) + { + var pointer = (IntPtr)GetResult(typeof(IntPtr), ptr); + return Marshaling.ColorMarshaler.NativeToManaged(pointer); + } + if (type == typeof(object)) { // var dataPtr = *(IntPtr*)&ptr[0]; From f064354d2b6e7ab9958cfe0d6761ab19e63c9453 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 05:04:11 +0200 Subject: [PATCH 18/29] fix: these should return a pointer instead --- src/scripting/natives/natives_entities.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/scripting/natives/natives_entities.cpp b/src/scripting/natives/natives_entities.cpp index 1e85941f7..9c06221ae 100644 --- a/src/scripting/natives/natives_entities.cpp +++ b/src/scripting/natives/natives_entities.cpp @@ -490,43 +490,43 @@ void EntityKeyValuesGetValue(ScriptContext& script_context) case counterstrikesharp::TYPE_COLOR: { - script_context.SetResult(keyValues->GetColor(key)); + script_context.SetResult(new Color(keyValues->GetColor(key))); break; } case counterstrikesharp::TYPE_VECTOR: { - script_context.SetResult(keyValues->GetVector(key)); + script_context.SetResult(new Vector(keyValues->GetVector(key))); break; } case counterstrikesharp::TYPE_VECTOR2D: { - script_context.SetResult(keyValues->GetVector2D(key)); + script_context.SetResult(new Vector2D(keyValues->GetVector2D(key))); break; } case counterstrikesharp::TYPE_VECTOR4D: { - script_context.SetResult(keyValues->GetVector4D(key)); + script_context.SetResult(new Vector4D(keyValues->GetVector4D(key))); break; } case counterstrikesharp::TYPE_QUATERNION: { - script_context.SetResult(keyValues->GetQuaternion(key)); + script_context.SetResult(new Quaternion(keyValues->GetQuaternion(key))); break; } case counterstrikesharp::TYPE_QANGLE: { - script_context.SetResult(keyValues->GetQAngle(key)); + script_context.SetResult(new QAngle(keyValues->GetQAngle(key))); break; } case counterstrikesharp::TYPE_MATRIX3X4: { - script_context.SetResult(keyValues->GetMatrix3x4(key)); + script_context.SetResult(new matrix3x4_t(keyValues->GetMatrix3x4(key))); break; } From c42319cb0fafbfcffdba8bd4d4575199dcd5c6d5 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 05:15:37 +0200 Subject: [PATCH 19/29] fix: *GetInt64 --- src/scripting/natives/natives_entities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripting/natives/natives_entities.cpp b/src/scripting/natives/natives_entities.cpp index 9c06221ae..7858e366f 100644 --- a/src/scripting/natives/natives_entities.cpp +++ b/src/scripting/natives/natives_entities.cpp @@ -450,7 +450,7 @@ void EntityKeyValuesGetValue(ScriptContext& script_context) case counterstrikesharp::TYPE_INT64: { - script_context.SetResult(keyValues->GetUint64(key)); + script_context.SetResult(keyValues->GetInt64(key)); } break; case counterstrikesharp::TYPE_UINT64: From 13fb3af58fa5c4019933969c1c89eeb1f78822ac Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 05:47:24 +0200 Subject: [PATCH 20/29] feat: `CEntityKeyValues`.`HasValue` --- managed/CounterStrikeSharp.API/Core/API.cs | 12 ++++++++++++ .../Modules/Utils/CEntityKeyValues.cs | 5 +++++ src/scripting/natives/natives_entities.cpp | 8 ++++++++ src/scripting/natives/natives_entities.yaml | 3 ++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/managed/CounterStrikeSharp.API/Core/API.cs b/managed/CounterStrikeSharp.API/Core/API.cs index 2cb9e1b0c..da6b5aae4 100644 --- a/managed/CounterStrikeSharp.API/Core/API.cs +++ b/managed/CounterStrikeSharp.API/Core/API.cs @@ -808,6 +808,18 @@ public static void EntityKeyValuesSetValue(IntPtr keyvalues, string key, uint ty } } + public static bool EntityKeyValuesHasValue(IntPtr keyvalues, string key){ + lock (ScriptContext.GlobalScriptContext.Lock) { + ScriptContext.GlobalScriptContext.Reset(); + ScriptContext.GlobalScriptContext.Push(keyvalues); + ScriptContext.GlobalScriptContext.Push(key); + ScriptContext.GlobalScriptContext.SetIdentifier(0xD3E04DA0); + ScriptContext.GlobalScriptContext.Invoke(); + ScriptContext.GlobalScriptContext.CheckErrors(); + return (bool)ScriptContext.GlobalScriptContext.GetResult(typeof(bool)); + } + } + public static void HookEvent(string name, InputArgument callback, bool ispost){ lock (ScriptContext.GlobalScriptContext.Lock) { ScriptContext.GlobalScriptContext.Reset(); diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index 257606af0..4dd1c51ef 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -137,6 +137,11 @@ public CEntityKeyValues(nint pointer) : base(pointer) public void SetMatrix3x4(string key, matrix3x4_t value) => SetValue(key, KeyValuesType.TYPE_MATRIX3X4, value); #endregion + public bool HasValue(string key) + { + return NativeAPI.EntityKeyValuesHasValue(Handle, key); + } + internal void SetValue(string key, KeyValuesType type, T value) { List arguments = new List(); diff --git a/src/scripting/natives/natives_entities.cpp b/src/scripting/natives/natives_entities.cpp index 7858e366f..54083725a 100644 --- a/src/scripting/natives/natives_entities.cpp +++ b/src/scripting/natives/natives_entities.cpp @@ -290,6 +290,13 @@ CEntityKeyValues* EntityKeyValuesNew(ScriptContext& script_context) return new CEntityKeyValues(); } +bool EntityKeyValuesHasValue(ScriptContext& script_context) +{ + CEntityKeyValues* keyValues = script_context.GetArgument(0); + const char* key = script_context.GetArgument(1); + return keyValues->HasValue(key); +} + void EntityKeyValuesSetValue(ScriptContext& script_context) { CEntityKeyValues* keyValues = script_context.GetArgument(0); @@ -558,5 +565,6 @@ REGISTER_NATIVES(entities, { ScriptEngine::RegisterNativeHandler("ENTITY_KEY_VALUES_NEW", EntityKeyValuesNew); ScriptEngine::RegisterNativeHandler("ENTITY_KEY_VALUES_GET_VALUE", EntityKeyValuesGetValue); ScriptEngine::RegisterNativeHandler("ENTITY_KEY_VALUES_SET_VALUE", EntityKeyValuesSetValue); + ScriptEngine::RegisterNativeHandler("ENTITY_KEY_VALUES_HAS_VALUE", EntityKeyValuesHasValue); }) } // namespace counterstrikesharp diff --git a/src/scripting/natives/natives_entities.yaml b/src/scripting/natives/natives_entities.yaml index 9e29c2662..1c045ac80 100644 --- a/src/scripting/natives/natives_entities.yaml +++ b/src/scripting/natives/natives_entities.yaml @@ -17,4 +17,5 @@ ADD_ENTITY_IO_EVENT: pTarget:pointer, inputName:string, activator:pointer, calle DISPATCH_SPAWN: entity:pointer, keyvalues:pointer -> void ENTITY_KEY_VALUES_NEW: -> pointer ENTITY_KEY_VALUES_GET_VALUE: keyvalues:pointer, key:string, type:uint -> any -ENTITY_KEY_VALUES_SET_VALUE: keyvalues:pointer, key:string, type:uint, arguments:object[] -> void \ No newline at end of file +ENTITY_KEY_VALUES_SET_VALUE: keyvalues:pointer, key:string, type:uint, arguments:object[] -> void +ENTITY_KEY_VALUES_HAS_VALUE: keyvalues:pointer, key:string -> bool \ No newline at end of file From aa1dc6b6f7a364df5e725d7ee548536875742449 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 06:11:20 +0200 Subject: [PATCH 21/29] feat: indexing operator --- .../Modules/Utils/CEntityKeyValues.cs | 145 +++++++++++++++--- 1 file changed, 123 insertions(+), 22 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index 4dd1c51ef..a17b7beb9 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -18,39 +18,140 @@ namespace CounterStrikeSharp.API.Modules.Utils { + /// + /// WARNING: This is intended to be only used with for now! + /// + public enum KeyValuesType : uint + { + TYPE_BOOL, + TYPE_INT, + TYPE_UINT, + TYPE_INT64, + TYPE_UINT64, + TYPE_FLOAT, + TYPE_DOUBLE, + TYPE_STRING, + TYPE_POINTER, + TYPE_STRING_TOKEN, + TYPE_EHANDLE, + TYPE_COLOR, + TYPE_VECTOR, + TYPE_VECTOR2D, + TYPE_VECTOR4D, + TYPE_QUATERNION, + TYPE_QANGLE, + TYPE_MATRIX3X4 + } + /// /// WARNING: This is intended to be only used with for now! /// public class CEntityKeyValues : NativeObject { - internal enum KeyValuesType : uint - { - TYPE_BOOL, - TYPE_INT, - TYPE_UINT, - TYPE_INT64, - TYPE_UINT64, - TYPE_FLOAT, - TYPE_DOUBLE, - TYPE_STRING, - TYPE_POINTER, - TYPE_STRING_TOKEN, - TYPE_EHANDLE, - TYPE_COLOR, - TYPE_VECTOR, - TYPE_VECTOR2D, - TYPE_VECTOR4D, - TYPE_QUATERNION, - TYPE_QANGLE, - TYPE_MATRIX3X4 - } - public CEntityKeyValues() : base(NativeAPI.EntityKeyValuesNew()) { } public CEntityKeyValues(nint pointer) : base(pointer) { } + public object? this[string key, KeyValuesType type] + { + get + { + return type switch + { + KeyValuesType.TYPE_BOOL => GetBool(key), + KeyValuesType.TYPE_INT => GetInt(key), + KeyValuesType.TYPE_UINT => GetUInt(key), + KeyValuesType.TYPE_INT64 => GetInt64(key), + KeyValuesType.TYPE_UINT64 => GetUInt64(key), + KeyValuesType.TYPE_FLOAT => GetFloat(key), + KeyValuesType.TYPE_DOUBLE => GetDouble(key), + KeyValuesType.TYPE_STRING => GetString(key), + KeyValuesType.TYPE_POINTER => GetPointer(key), + KeyValuesType.TYPE_STRING_TOKEN => GetStringToken(key), + KeyValuesType.TYPE_EHANDLE => GetEHandle(key), + KeyValuesType.TYPE_COLOR => GetColor(key), + KeyValuesType.TYPE_VECTOR => GetVector(key), + KeyValuesType.TYPE_VECTOR2D => GetVector2D(key), + KeyValuesType.TYPE_VECTOR4D => GetVector4D(key), + KeyValuesType.TYPE_QUATERNION => GetQuaternion(key), + KeyValuesType.TYPE_QANGLE => GetAngle(key), + KeyValuesType.TYPE_MATRIX3X4 => GetMatrix3x4(key), + _ => null + }; + } + + set + { +#pragma warning disable CS8605 // Unboxing a possibly null value. +#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. +#pragma warning disable CS8604 // Possible null reference argument. + switch (type) + { + case KeyValuesType.TYPE_BOOL: + SetBool(key, (bool)value); + break; + case KeyValuesType.TYPE_INT: + SetInt(key, (int)value); + break; + case KeyValuesType.TYPE_UINT: + SetUInt(key, (uint)value); + break; + case KeyValuesType.TYPE_INT64: + SetInt64(key, (long)value); + break; + case KeyValuesType.TYPE_UINT64: + SetUInt64(key, (ulong)value); + break; + case KeyValuesType.TYPE_FLOAT: + SetFloat(key, (float)value); + break; + case KeyValuesType.TYPE_DOUBLE: + SetDouble(key, (double)value); + break; + case KeyValuesType.TYPE_STRING: + SetString(key, (string)value); + break; + case KeyValuesType.TYPE_POINTER: + SetPointer(key, (nint)value); + break; + case KeyValuesType.TYPE_STRING_TOKEN: + SetStringToken(key, (CUtlStringToken)value); + break; + case KeyValuesType.TYPE_EHANDLE: + SetEHandle(key, (CEntityHandle)value); + break; + case KeyValuesType.TYPE_COLOR: + SetColor(key, (Color)value); + break; + case KeyValuesType.TYPE_VECTOR: + SetVector(key, (Vector)value); + break; + case KeyValuesType.TYPE_VECTOR2D: + SetVector2D(key, (Vector2D)value); + break; + case KeyValuesType.TYPE_VECTOR4D: + SetVector4D(key, (Vector4D)value); + break; + case KeyValuesType.TYPE_QUATERNION: + SetQuaternion(key, (Quaternion)value); + break; + case KeyValuesType.TYPE_QANGLE: + SetAngle(key, (QAngle)value); + break; + case KeyValuesType.TYPE_MATRIX3X4: + SetMatrix3x4(key, (matrix3x4_t)value); + break; + default: + throw new InvalidOperationException("Unsupported KeyValuesType."); + } +#pragma warning restore CS8605 // Unboxing a possibly null value. +#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. +#pragma warning restore CS8604 // Possible null reference argument. + } + } + #region GETTER public bool GetBool(string key, bool defaultValue = false) => GetValue(key, KeyValuesType.TYPE_BOOL, defaultValue); From a9085b7e942330f229d971155d6de8415e29fd85 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 06:11:34 +0200 Subject: [PATCH 22/29] fix: wrong types --- src/scripting/natives/natives_entities.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scripting/natives/natives_entities.cpp b/src/scripting/natives/natives_entities.cpp index 54083725a..d82b95c7d 100644 --- a/src/scripting/natives/natives_entities.cpp +++ b/src/scripting/natives/natives_entities.cpp @@ -315,15 +315,15 @@ void EntityKeyValuesSetValue(ScriptContext& script_context) break; case counterstrikesharp::TYPE_UINT: - keyValues->SetUint(key, script_context.GetArgument(offset)); + keyValues->SetUint(key, script_context.GetArgument(offset)); break; case counterstrikesharp::TYPE_INT64: - keyValues->SetInt64(key, script_context.GetArgument(offset)); + keyValues->SetInt64(key, script_context.GetArgument(offset)); break; case counterstrikesharp::TYPE_UINT64: - keyValues->SetUint64(key, script_context.GetArgument(offset)); + keyValues->SetUint64(key, script_context.GetArgument(offset)); break; case counterstrikesharp::TYPE_FLOAT: From 8261147a417af8a0d4dc56eaff1e965975dbe83a Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 06:45:13 +0200 Subject: [PATCH 23/29] fix: indentation --- src/scripting/natives/natives_entities.cpp | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/scripting/natives/natives_entities.cpp b/src/scripting/natives/natives_entities.cpp index d82b95c7d..278a3c593 100644 --- a/src/scripting/natives/natives_entities.cpp +++ b/src/scripting/natives/natives_entities.cpp @@ -315,40 +315,40 @@ void EntityKeyValuesSetValue(ScriptContext& script_context) break; case counterstrikesharp::TYPE_UINT: - keyValues->SetUint(key, script_context.GetArgument(offset)); - break; + keyValues->SetUint(key, script_context.GetArgument(offset)); + break; case counterstrikesharp::TYPE_INT64: - keyValues->SetInt64(key, script_context.GetArgument(offset)); - break; + keyValues->SetInt64(key, script_context.GetArgument(offset)); + break; case counterstrikesharp::TYPE_UINT64: - keyValues->SetUint64(key, script_context.GetArgument(offset)); - break; + keyValues->SetUint64(key, script_context.GetArgument(offset)); + break; case counterstrikesharp::TYPE_FLOAT: - keyValues->SetFloat(key, script_context.GetArgument(offset)); - break; + keyValues->SetFloat(key, script_context.GetArgument(offset)); + break; case counterstrikesharp::TYPE_DOUBLE: - keyValues->SetDouble(key, script_context.GetArgument(offset)); - break; + keyValues->SetDouble(key, script_context.GetArgument(offset)); + break; case counterstrikesharp::TYPE_STRING: - keyValues->SetString(key, script_context.GetArgument(offset)); - break; + keyValues->SetString(key, script_context.GetArgument(offset)); + break; case counterstrikesharp::TYPE_POINTER: - keyValues->SetPtr(key, script_context.GetArgument(offset)); - break; + keyValues->SetPtr(key, script_context.GetArgument(offset)); + break; case counterstrikesharp::TYPE_STRING_TOKEN: - keyValues->SetStringToken(key, script_context.GetArgument(offset)); - break; + keyValues->SetStringToken(key, script_context.GetArgument(offset)); + break; case counterstrikesharp::TYPE_EHANDLE: - keyValues->SetEHandle(key, script_context.GetArgument(offset)); - break; + keyValues->SetEHandle(key, script_context.GetArgument(offset)); + break; case counterstrikesharp::TYPE_COLOR: { From 9d03cea6b8ffb481810408bb288bb857b4ce170d Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 06:58:04 +0200 Subject: [PATCH 24/29] fix: now works with CEntityHandle --- managed/CounterStrikeSharp.API/Core/ScriptContext.cs | 7 ++++++- src/scripting/natives/natives_entities.cpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Core/ScriptContext.cs b/managed/CounterStrikeSharp.API/Core/ScriptContext.cs index e7389ee78..6846eaf95 100644 --- a/managed/CounterStrikeSharp.API/Core/ScriptContext.cs +++ b/managed/CounterStrikeSharp.API/Core/ScriptContext.cs @@ -23,7 +23,6 @@ * under GNU Lesser General Public License, version 2. */ -using System; using System.Collections.Concurrent; using System.Drawing; using System.Runtime.InteropServices; @@ -456,6 +455,12 @@ internal unsafe object GetResult(Type type, byte* ptr) return Marshaling.ColorMarshaler.NativeToManaged(pointer); } + // this one only works if the 'Raw'/uint is passed, otherwise big bum + if (type == typeof(CEntityHandle)) + { + return new CEntityHandle((uint)GetResult(typeof(uint), ptr)); + } + if (type == typeof(object)) { // var dataPtr = *(IntPtr*)&ptr[0]; diff --git a/src/scripting/natives/natives_entities.cpp b/src/scripting/natives/natives_entities.cpp index 278a3c593..48d6b6d47 100644 --- a/src/scripting/natives/natives_entities.cpp +++ b/src/scripting/natives/natives_entities.cpp @@ -347,7 +347,7 @@ void EntityKeyValuesSetValue(ScriptContext& script_context) break; case counterstrikesharp::TYPE_EHANDLE: - keyValues->SetEHandle(key, script_context.GetArgument(offset)); + keyValues->SetEHandle(key, CEntityHandle(script_context.GetArgument(offset))); break; case counterstrikesharp::TYPE_COLOR: From 79cdd928300d00e24e75aace6808de5a0aaf4b36 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 06:58:46 +0200 Subject: [PATCH 25/29] chore: added text --- managed/CounterStrikeSharp.API/Core/ScriptContext.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/managed/CounterStrikeSharp.API/Core/ScriptContext.cs b/managed/CounterStrikeSharp.API/Core/ScriptContext.cs index 6846eaf95..2914e782a 100644 --- a/managed/CounterStrikeSharp.API/Core/ScriptContext.cs +++ b/managed/CounterStrikeSharp.API/Core/ScriptContext.cs @@ -456,6 +456,7 @@ internal unsafe object GetResult(Type type, byte* ptr) } // this one only works if the 'Raw'/uint is passed, otherwise big bum + // maybe do this with a marshaler?! if (type == typeof(CEntityHandle)) { return new CEntityHandle((uint)GetResult(typeof(uint), ptr)); From 76d48c1223b598ab514cab9ed5aac3b2ca9b672f Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 07:03:43 +0200 Subject: [PATCH 26/29] fix: matrix3x4_t being passed correctly --- .../Modules/Utils/CEntityKeyValues.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index a17b7beb9..77cb3ceb7 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -323,20 +323,20 @@ internal void SetValue(string key, KeyValuesType type, T value) { if (value is matrix3x4_t matrix) { + arguments.Add(matrix[0, 0]); + arguments.Add(matrix[0, 1]); + arguments.Add(matrix[0, 2]); + arguments.Add(matrix[0, 3]); + + arguments.Add(matrix[1, 0]); arguments.Add(matrix[1, 1]); arguments.Add(matrix[1, 2]); arguments.Add(matrix[1, 3]); - arguments.Add(matrix[1, 4]); + arguments.Add(matrix[2, 0]); arguments.Add(matrix[2, 1]); arguments.Add(matrix[2, 2]); arguments.Add(matrix[2, 3]); - arguments.Add(matrix[2, 4]); - - arguments.Add(matrix[3, 1]); - arguments.Add(matrix[3, 2]); - arguments.Add(matrix[3, 3]); - arguments.Add(matrix[3, 4]); } else { BadTypeHandler(key, type, value); } } break; From 8b5dc874458686d04e3cbcad6bad0f58dd7547f1 Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 07:06:16 +0200 Subject: [PATCH 27/29] feat: properties for accessing values --- .../Modules/Utils/matrix3x4_t.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs b/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs index fe2c768da..caec40f06 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs @@ -21,6 +21,30 @@ namespace CounterStrikeSharp.API.Modules.Utils; public partial class matrix3x4_t : NativeObject { public unsafe ref float this[int row, int column] => ref Unsafe.Add(ref *(float*)Handle, row * 4 + column); + + public float M00 => this[0, 0]; + + public float M01 => this[0, 1]; + + public float M02 => this[0, 2]; + + public float M03 => this[0, 3]; + + public float M10 => this[1, 0]; + + public float M11 => this[1, 1]; + + public float M12 => this[1, 2]; + + public float M13 => this[1, 3]; + + public float M20 => this[2, 0]; + + public float M21 => this[2, 1]; + + public float M22 => this[2, 2]; + + public float M23 => this[2, 3]; public matrix3x4_t(IntPtr pointer) : base(pointer) { From b684fef02689fce0aceaed2cdc609c8e03bc4a8a Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 07:07:05 +0200 Subject: [PATCH 28/29] tweak: adjusted matrix3x4_t changes --- .../Modules/Utils/CEntityKeyValues.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index 77cb3ceb7..ac630769a 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -323,20 +323,20 @@ internal void SetValue(string key, KeyValuesType type, T value) { if (value is matrix3x4_t matrix) { - arguments.Add(matrix[0, 0]); - arguments.Add(matrix[0, 1]); - arguments.Add(matrix[0, 2]); - arguments.Add(matrix[0, 3]); - - arguments.Add(matrix[1, 0]); - arguments.Add(matrix[1, 1]); - arguments.Add(matrix[1, 2]); - arguments.Add(matrix[1, 3]); - - arguments.Add(matrix[2, 0]); - arguments.Add(matrix[2, 1]); - arguments.Add(matrix[2, 2]); - arguments.Add(matrix[2, 3]); + arguments.Add(matrix.M00); + arguments.Add(matrix.M01); + arguments.Add(matrix.M02); + arguments.Add(matrix.M03); + + arguments.Add(matrix.M10); + arguments.Add(matrix.M11); + arguments.Add(matrix.M12); + arguments.Add(matrix.M13); + + arguments.Add(matrix.M20); + arguments.Add(matrix.M21); + arguments.Add(matrix.M22); + arguments.Add(matrix.M23); } else { BadTypeHandler(key, type, value); } } break; From 7d346df6afe5c8a19f8dc74dee672f8ad3518fbb Mon Sep 17 00:00:00 2001 From: KillStr3aK Date: Tue, 8 Oct 2024 07:27:57 +0200 Subject: [PATCH 29/29] fix: changed from `CUtlStringToken` to `uint` --- .../Modules/Utils/CEntityKeyValues.cs | 9 ++++++--- src/scripting/natives/natives_entities.cpp | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs index ac630769a..a853a7cc7 100644 --- a/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs +++ b/managed/CounterStrikeSharp.API/Modules/Utils/CEntityKeyValues.cs @@ -117,7 +117,8 @@ public CEntityKeyValues(nint pointer) : base(pointer) SetPointer(key, (nint)value); break; case KeyValuesType.TYPE_STRING_TOKEN: - SetStringToken(key, (CUtlStringToken)value); + // TODO: use 'CUtlStringToken' once we have it + SetStringToken(key, (uint)value); break; case KeyValuesType.TYPE_EHANDLE: SetEHandle(key, (CEntityHandle)value); @@ -171,7 +172,8 @@ public CEntityKeyValues(nint pointer) : base(pointer) public nint GetPointer(string key, nint defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_POINTER, defaultValue); - public CUtlStringToken? GetStringToken(string key, CUtlStringToken? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_STRING_TOKEN, defaultValue); + // TODO: use 'CUtlStringToken' once we have it + public uint GetStringToken(string key, uint defaultValue = 0) => GetValue(key, KeyValuesType.TYPE_STRING_TOKEN, defaultValue); public CEntityHandle? GetEHandle(string key, CEntityHandle? defaultValue = null) => GetValue(key, KeyValuesType.TYPE_EHANDLE, defaultValue); @@ -209,7 +211,8 @@ public CEntityKeyValues(nint pointer) : base(pointer) public void SetPointer(string key, nint value) => SetValue(key, KeyValuesType.TYPE_POINTER, value); - public void SetStringToken(string key, CUtlStringToken value) => SetValue(key, KeyValuesType.TYPE_STRING_TOKEN, value); + // TODO: use 'CUtlStringToken' once we have it + public void SetStringToken(string key, uint value) => SetValue(key, KeyValuesType.TYPE_STRING_TOKEN, value); public void SetEHandle(string key, CEntityHandle value) => SetValue(key, KeyValuesType.TYPE_EHANDLE, value); diff --git a/src/scripting/natives/natives_entities.cpp b/src/scripting/natives/natives_entities.cpp index 48d6b6d47..7aab34f99 100644 --- a/src/scripting/natives/natives_entities.cpp +++ b/src/scripting/natives/natives_entities.cpp @@ -343,7 +343,7 @@ void EntityKeyValuesSetValue(ScriptContext& script_context) break; case counterstrikesharp::TYPE_STRING_TOKEN: - keyValues->SetStringToken(key, script_context.GetArgument(offset)); + keyValues->SetStringToken(key, CUtlStringToken(script_context.GetArgument(offset))); break; case counterstrikesharp::TYPE_EHANDLE: @@ -487,7 +487,7 @@ void EntityKeyValuesGetValue(ScriptContext& script_context) case counterstrikesharp::TYPE_STRING_TOKEN: { - script_context.SetResult(keyValues->GetStringToken(key)); + script_context.SetResult(keyValues->GetStringToken(key).GetHashCode()); } break; case counterstrikesharp::TYPE_EHANDLE: