summaryrefslogtreecommitdiff
path: root/sourcemod/scripting/momsurffix/utils.sp
diff options
context:
space:
mode:
authornavewindre <nw@moneybot.cc>2023-12-04 18:06:10 +0100
committernavewindre <nw@moneybot.cc>2023-12-04 18:06:10 +0100
commitaef0d1c1268ab7d4bc18996c9c6b4da16a40aadc (patch)
tree43e766b51704f4ab8b383583bdc1871eeeb9c698 /sourcemod/scripting/momsurffix/utils.sp
parent38f1140c11724da05a23a10385061200b907cf6e (diff)
bbbbbbbbwaaaaaaaaaaa
Diffstat (limited to 'sourcemod/scripting/momsurffix/utils.sp')
-rw-r--r--sourcemod/scripting/momsurffix/utils.sp279
1 files changed, 279 insertions, 0 deletions
diff --git a/sourcemod/scripting/momsurffix/utils.sp b/sourcemod/scripting/momsurffix/utils.sp
new file mode 100644
index 0000000..e68e342
--- /dev/null
+++ b/sourcemod/scripting/momsurffix/utils.sp
@@ -0,0 +1,279 @@
+#define MALLOC(%1) view_as<%1>(AllocatableBase._malloc(%1.Size(), #%1))
+#define MEMORYPOOL_NAME_MAX 128
+
+enum struct MemoryPoolEntry
+{
+ Address addr;
+ char name[MEMORYPOOL_NAME_MAX];
+}
+
+methodmap AllocatableBase < AddressBase
+{
+ public static Address _malloc(int size, const char[] name)
+ {
+ Address addr = Malloc(size, name);
+
+ return addr;
+ }
+
+ public void Free()
+ {
+ Free(this.Address);
+ }
+}
+
+methodmap PseudoStackArray < AddressBase
+{
+ public Address Get8(int idx, int size = 4)
+ {
+ ASSERT(idx >= 0);
+ ASSERT(size > 0);
+
+ return view_as<Address>(LoadFromAddress(this.Address + (idx * size), NumberType_Int8));
+ }
+
+ public Address Get16(int idx, int size = 4)
+ {
+ ASSERT(idx >= 0);
+ ASSERT(size > 0);
+
+ return view_as<Address>(LoadFromAddress(this.Address + (idx * size), NumberType_Int16));
+ }
+
+ public Address Get32(int idx, int size = 4)
+ {
+ ASSERT(idx >= 0);
+ ASSERT(size > 0);
+
+ return this.Address + (idx * size);
+ }
+}
+
+methodmap Vector < AllocatableBase
+{
+ public static int Size()
+ {
+ return 12;
+ }
+
+ public Vector()
+ {
+ return MALLOC(Vector);
+ }
+
+ property float x
+ {
+ public set(float _x) { StoreToAddress(this.Address, view_as<int>(_x), NumberType_Int32, false); }
+ public get() { return view_as<float>(LoadFromAddress(this.Address, NumberType_Int32)); }
+ }
+
+ property float y
+ {
+ public set(float _y) { StoreToAddress(this.Address + 4, view_as<int>(_y), NumberType_Int32, false); }
+ public get() { return view_as<float>(LoadFromAddress(this.Address + 4, NumberType_Int32)); }
+ }
+
+ property float z
+ {
+ public set(float _z) { StoreToAddress(this.Address + 8, view_as<int>(_z), NumberType_Int32, false); }
+ public get() { return view_as<float>(LoadFromAddress(this.Address + 8, NumberType_Int32)); }
+ }
+
+ public void ToArray(float buff[3])
+ {
+ buff[0] = this.x;
+ buff[1] = this.y;
+ buff[2] = this.z;
+ }
+
+ public void FromArray(float buff[3])
+ {
+ this.x = buff[0];
+ this.y = buff[1];
+ this.z = buff[2];
+ }
+
+ public void CopyTo(Vector dst)
+ {
+ dst.x = this.x;
+ dst.y = this.y;
+ dst.z = this.z;
+ }
+
+ public float LengthSqr()
+ {
+ return this.x*this.x + this.y*this.y + this.z*this.z;
+ }
+
+ public float Length()
+ {
+ return SquareRoot(this.LengthSqr());
+ }
+
+ public float Dot(float vec[3])
+ {
+ return this.x*vec[0] + this.y*vec[1] + this.z*vec[2];
+ }
+}
+
+static Address g_pMemAlloc;
+static Handle gMalloc, gFree, gCreateInterface;
+static ArrayList gMemoryPool;
+
+stock void InitUtils(GameData gd)
+{
+ gMemoryPool = new ArrayList(sizeof(MemoryPoolEntry));
+
+ //CreateInterface
+ StartPrepSDKCall(SDKCall_Static);
+
+ ASSERT_MSG(PrepSDKCall_SetFromConf(gd, SDKConf_Signature, "CreateInterface"), "Failed to get \"CreateInterface\" signature. Gamedata needs an update.");
+
+ PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer);
+ PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
+
+ PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
+
+ gCreateInterface = EndPrepSDKCall();
+ ASSERT(gCreateInterface);
+
+ if(gEngineVersion == Engine_CSGO || gOSType == OSWindows)
+ {
+ //g_pMemAlloc
+ g_pMemAlloc = gd.GetAddress("g_pMemAlloc");
+ ASSERT_MSG(g_pMemAlloc != Address_Null, "Can't get \"g_pMemAlloc\" address from gamedata. Gamedata needs an update.");
+
+ //Malloc
+ StartPrepSDKCall(SDKCall_Raw);
+
+ PrepSDKCall_SetVirtual(gd.GetOffset("Malloc"));
+
+ PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
+ PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
+
+ gMalloc = EndPrepSDKCall();
+ ASSERT(gMalloc);
+
+ //Free
+ StartPrepSDKCall(SDKCall_Raw);
+
+ PrepSDKCall_SetVirtual(gd.GetOffset("Free"));
+
+ PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
+
+ gFree = EndPrepSDKCall();
+ ASSERT(gFree);
+ }
+ else
+ {
+ //Malloc
+ StartPrepSDKCall(SDKCall_Static);
+ ASSERT_MSG(PrepSDKCall_SetFromConf(gd, SDKConf_Signature, "malloc"), "Failed to get \"malloc\" signature. Gamedata needs an update.");
+
+ PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
+ PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
+
+ PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
+
+ gMalloc = EndPrepSDKCall();
+ ASSERT(gMalloc);
+
+ //Free
+ StartPrepSDKCall(SDKCall_Static);
+ ASSERT_MSG(PrepSDKCall_SetFromConf(gd, SDKConf_Signature, "free"), "Failed to get \"free\" signature. Gamedata needs an update.");
+
+ PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
+ PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
+
+ gFree = EndPrepSDKCall();
+ ASSERT(gFree);
+ }
+}
+
+stock Address CreateInterface(const char[] name)
+{
+ return SDKCall(gCreateInterface, name, 0);
+}
+
+stock Address Malloc(int size, const char[] name)
+{
+ ASSERT(gMemoryPool);
+ ASSERT(size > 0);
+
+ MemoryPoolEntry entry;
+ strcopy(entry.name, sizeof(MemoryPoolEntry::name), name);
+
+ if(gEngineVersion == Engine_CSS && gOSType == OSLinux)
+ entry.addr = SDKCall(gMalloc, 0, size);
+ else
+ entry.addr = SDKCall(gMalloc, g_pMemAlloc, size);
+
+ ASSERT_FMT(entry.addr != Address_Null, "Failed to allocate memory (size: %i)!", size);
+ gMemoryPool.PushArray(entry);
+
+ return entry.addr;
+}
+
+stock void Free(Address addr)
+{
+ ASSERT(addr != Address_Null);
+ ASSERT(gMemoryPool);
+ int idx = gMemoryPool.FindValue(addr, MemoryPoolEntry::addr);
+
+ //Memory wasn't allocated by this plugin, return.
+ if(idx == -1)
+ return;
+
+ gMemoryPool.Erase(idx);
+
+ if(gEngineVersion == Engine_CSS && gOSType == OSLinux)
+ SDKCall(gFree, 0, addr);
+ else
+ SDKCall(gFree, g_pMemAlloc, addr);
+}
+
+stock void AddToMemoryPool(Address addr, const char[] name)
+{
+ ASSERT(addr != Address_Null);
+ ASSERT(gMemoryPool);
+
+ MemoryPoolEntry entry;
+ strcopy(entry.name, sizeof(MemoryPoolEntry::name), name);
+ entry.addr = addr;
+
+ gMemoryPool.PushArray(entry);
+}
+
+stock void CleanUpUtils()
+{
+ if(!gMemoryPool)
+ return;
+
+ MemoryPoolEntry entry;
+
+ for(int i = 0; i < gMemoryPool.Length; i++)
+ {
+ gMemoryPool.GetArray(i, entry, sizeof(MemoryPoolEntry));
+ view_as<AllocatableBase>(entry.addr).Free();
+ }
+
+ delete gMemoryPool;
+}
+
+stock void DumpMemoryUsage()
+{
+ if(!gMemoryPool || (gMemoryPool && gMemoryPool.Length == 0))
+ {
+ PrintToServer(SNAME..."Theres's currently no active pool or it's empty!");
+ return;
+ }
+
+ MemoryPoolEntry entry;
+
+ PrintToServer(SNAME..."Active memory pool (%i):", gMemoryPool.Length);
+ for(int i = 0; i < gMemoryPool.Length; i++)
+ {
+ gMemoryPool.GetArray(i, entry, sizeof(MemoryPoolEntry));
+ PrintToServer(SNAME..."[%i]: 0x%08X \"%s\"", i, entry.addr, entry.name);
+ }
+} \ No newline at end of file