Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement CVariant functions #569

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ set(SOURCE_FILES
src/scripting/natives/natives_schema.cpp
src/scripting/natives/natives_entities.cpp
src/scripting/natives/natives_voice.cpp
src/scripting/natives/natives_cvariant.cpp
src/scripting/natives/natives_cutil.cpp
src/core/managers/entity_manager.cpp
src/core/managers/entity_manager.h
src/core/managers/chat_manager.cpp
Expand Down
132 changes: 132 additions & 0 deletions managed/CounterStrikeSharp.API/Core/API.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,138 @@ public static void SetFakeClientConvarValue(int clientindex, string convarname,
}
}

public static string GetStringFromSymbolLarge(IntPtr pointer){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pointer);
ScriptContext.GlobalScriptContext.SetIdentifier(0x600A804B);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
}
}

public static uint GetVariantType(IntPtr pvariant){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.SetIdentifier(0x7AC3DA1C);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (uint)ScriptContext.GlobalScriptContext.GetResult(typeof(uint));
}
}

public static int GetVariantInt(IntPtr pvariant){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.SetIdentifier(0x78156617);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (int)ScriptContext.GlobalScriptContext.GetResult(typeof(int));
}
}

public static uint GetVariantUint(IntPtr pvariant){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.SetIdentifier(0x7AC49FA2);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (uint)ScriptContext.GlobalScriptContext.GetResult(typeof(uint));
}
}

public static float GetVariantFloat(IntPtr pvariant){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.SetIdentifier(0xD20595B4);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (float)ScriptContext.GlobalScriptContext.GetResult(typeof(float));
}
}

public static string GetVariantString(IntPtr pvariant){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.SetIdentifier(0x41C49F71);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
}
}

public static bool GetVariantBool(IntPtr pvariant){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.SetIdentifier(0x7ABC76EA);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (bool)ScriptContext.GlobalScriptContext.GetResult(typeof(bool));
}
}

public static void SetVariantInt(IntPtr pvariant, int value){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.Push(value);
ScriptContext.GlobalScriptContext.SetIdentifier(0x801EC403);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}

public static void SetVariantUint(IntPtr pvariant, uint value){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.Push(value);
ScriptContext.GlobalScriptContext.SetIdentifier(0x83EC7436);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}

public static void SetVariantFloat(IntPtr pvariant, float value){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.Push(value);
ScriptContext.GlobalScriptContext.SetIdentifier(0x266E8A0);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}

public static void SetVariantString(IntPtr pvariant, string value){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.Push(value);
ScriptContext.GlobalScriptContext.SetIdentifier(0x2450A3E5);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}

public static void SetVariantBool(IntPtr pvariant, bool value){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(pvariant);
ScriptContext.GlobalScriptContext.Push(value);
ScriptContext.GlobalScriptContext.SetIdentifier(0x83F1967E);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}

public static T DynamicHookGetReturn<T>(IntPtr hook, int datatype){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
Expand Down
20 changes: 20 additions & 0 deletions managed/CounterStrikeSharp.API/Core/Model/CUtlSymbolLarge.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Reflection.Metadata;
zonical marked this conversation as resolved.
Show resolved Hide resolved

namespace CounterStrikeSharp.API.Core;

public class CUtlSymbolLarge : NativeObject
{
public CUtlSymbolLarge(IntPtr pointer) : base(pointer)
{
}

public bool IsValid => Handle != IntPtr.Zero;

public string String
{
get
{
return NativeAPI.GetStringFromSymbolLarge(Handle);
}
}
}
57 changes: 50 additions & 7 deletions managed/CounterStrikeSharp.API/Core/Model/CVariant.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,56 @@
namespace CounterStrikeSharp.API.Core;
using System.Reflection.Metadata;

zonical marked this conversation as resolved.
Show resolved Hide resolved
/// <summary>
/// Placeholder for CVariant
/// <see href="https://github.com/alliedmodders/hl2sdk/blob/cs2/public/variant.h"/>
/// <remarks>A lot of entity outputs do not use this value</remarks>
/// </summary>
namespace CounterStrikeSharp.API.Core;

public class CVariant : NativeObject
{
public CVariant(IntPtr pointer) : base(pointer)
{
}

public bool IsValid => Handle != IntPtr.Zero;

public fieldtype_t FieldType => (fieldtype_t)NativeAPI.GetVariantType(Handle);

public T Get<T>(string name)
{
var type = typeof(T);
object result = type switch
{
_ when type == typeof(float) => NativeAPI.GetVariantFloat(Handle),
_ when type == typeof(int) => NativeAPI.GetVariantInt(Handle),
_ when type == typeof(uint) => NativeAPI.GetVariantUint(Handle),
_ when type == typeof(string) => NativeAPI.GetVariantString(Handle),
_ when type == typeof(bool) => NativeAPI.GetVariantBool(Handle),
_ => throw new NotSupportedException(),
};

return (T)result;
}

public void Set<T>(string name, T value)
{
var type = typeof(T);
switch (type)
{
case var _ when value is float f:
NativeAPI.SetVariantFloat(Handle, f);
break;
case var _ when value is int i:
NativeAPI.SetVariantInt(Handle, i);
break;
case var _ when value is uint ui:
NativeAPI.SetVariantUint(Handle, ui);
break;
case var _ when value is bool b:
NativeAPI.SetVariantBool(Handle, b);
break;
case var _ when value is string s:
NativeAPI.SetVariantString(Handle, s);
break;

default:
throw new NotSupportedException();
}
}
}
}
44 changes: 44 additions & 0 deletions src/scripting/natives/natives_cutil.cpp
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>. *
*/

#include <public/entity2/entitysystem.h>

#include <ios>
#include <sstream>

#include "core/log.h"
#include "core/memory.h"
zonical marked this conversation as resolved.
Show resolved Hide resolved
#include "scripting/autonative.h"
#include "scripting/script_engine.h"
#include "utlsymbollarge.h"

namespace counterstrikesharp {

const char* GetStringFromSymbolLarge(ScriptContext& script_context)
{
CUtlSymbolLarge* pSymbolLarge = script_context.GetArgument<CUtlSymbolLarge*>(0);
if (!pSymbolLarge)
{
script_context.ThrowNativeError("Invalid CUtlSymbolLarge pointer");
return "";
}
return pSymbolLarge->String();
}

REGISTER_NATIVES(cutil, {
ScriptEngine::RegisterNativeHandler("GET_STRING_FROM_SYMBOL_LARGE", GetStringFromSymbolLarge);
})
} // namespace counterstrikesharp
1 change: 1 addition & 0 deletions src/scripting/natives/natives_cutil.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GET_STRING_FROM_SYMBOL_LARGE: pointer:pointer -> string
Loading
Loading