aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDedicatedTest
diff options
context:
space:
mode:
authorMaya <malte.hoermeyer@web.de>2022-07-21 02:54:00 +0200
committerGitHub <noreply@github.com>2022-07-21 02:54:00 +0200
commit938d89713eb055340b5e8866de3000b61e4a0f13 (patch)
tree65c266a244c27ff47ec0f4086a15a97a099ee493 /NorthstarDedicatedTest
parentd20cf6f08af37830d3bfc934cef356fa6a1aa102 (diff)
downloadNorthstarLauncher-938d89713eb055340b5e8866de3000b61e4a0f13.tar.gz
NorthstarLauncher-938d89713eb055340b5e8866de3000b61e4a0f13.zip
Implemented Json into the squirrel vm (#172)
* Implemented Json into the squirrel vm * Formatting * More Formatting * Even more Formatting * Added Init functions to dllMain * Formatting * Changed to use Source Allocator * Renaming Part 1 * Renaming Part 2
Diffstat (limited to 'NorthstarDedicatedTest')
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj2
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters6
-rw-r--r--NorthstarDedicatedTest/dllmain.cpp3
-rw-r--r--NorthstarDedicatedTest/scriptjson.cpp609
-rw-r--r--NorthstarDedicatedTest/scriptjson.h2
-rw-r--r--NorthstarDedicatedTest/squirrel.cpp65
-rw-r--r--NorthstarDedicatedTest/squirrel.h481
7 files changed, 1168 insertions, 0 deletions
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
index ff6ca2ea..0bb2fe02 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
@@ -122,6 +122,7 @@
<ClInclude Include="plugins.h" />
<ClInclude Include="plugin_abi.h" />
<ClInclude Include="scriptutility.h" />
+ <ClInclude Include="scriptjson.h" />
<ClInclude Include="serverchathooks.h" />
<ClInclude Include="clientauthhooks.h" />
<ClInclude Include="color.h" />
@@ -613,6 +614,7 @@
<ClCompile Include="plugins.cpp" />
<ClCompile Include="rpakfilesystem.cpp" />
<ClCompile Include="scriptbrowserhooks.cpp" />
+ <ClCompile Include="scriptjson.cpp" />
<ClCompile Include="scriptmainmenupromos.cpp" />
<ClCompile Include="scriptmodmenu.cpp" />
<ClCompile Include="scriptserverbrowser.cpp" />
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
index 0e48f4a0..6496c796 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
@@ -1518,6 +1518,9 @@
<ClInclude Include="scriptutility.h">
<Filter>Header Files\Shared</Filter>
</ClInclude>
+ <ClInclude Include="scriptjson.h">
+ <Filter>Header Files\Shared</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
@@ -1685,6 +1688,9 @@
<ClCompile Include="clientruihooks.cpp">
<Filter>Source Files\Client</Filter>
</ClCompile>
+ <ClCompile Include="scriptjson.cpp">
+ <Filter>Source Files\Shared</Filter>
+ </ClCompile>
<ClCompile Include="scriptutility.cpp">
<Filter>Source Files\Shared</Filter>
</ClCompile>
diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp
index d64cc34f..41236506 100644
--- a/NorthstarDedicatedTest/dllmain.cpp
+++ b/NorthstarDedicatedTest/dllmain.cpp
@@ -52,6 +52,7 @@
#include "rapidjson/writer.h"
#include "rapidjson/error/en.h"
#include "ExploitFixes.h"
+#include "scriptJson.h"
typedef void (*initPluginFuncPtr)(void* getPluginObject);
@@ -256,6 +257,7 @@ bool InitialiseNorthstar()
AddDllLoadCallbackForClient("client.dll", InitialiseClientVideoOverrides);
AddDllLoadCallbackForClient("engine.dll", InitialiseEngineClientRUIHooks);
AddDllLoadCallbackForClient("engine.dll", InitialiseDebugOverlay);
+ AddDllLoadCallbackForClient("client.dll", InitialiseClientSquirrelJson);
AddDllLoadCallbackForClient("client.dll", InitialiseClientSquirrelUtilityFunctions);
// audio hooks
AddDllLoadCallbackForClient("client.dll", InitialiseMilesAudioHooks);
@@ -270,6 +272,7 @@ bool InitialiseNorthstar()
AddDllLoadCallback("server.dll", InitialiseMiscServerFixes);
AddDllLoadCallback("server.dll", InitialiseBuildAINFileHooks);
AddDllLoadCallback("server.dll", InitialiseServerSquirrelUtilityFunctions);
+ AddDllLoadCallback("server.dll", InitialiseServerSquirrelJson);
AddDllLoadCallback("engine.dll", InitialisePlaylistHooks);
diff --git a/NorthstarDedicatedTest/scriptjson.cpp b/NorthstarDedicatedTest/scriptjson.cpp
new file mode 100644
index 00000000..220f4968
--- /dev/null
+++ b/NorthstarDedicatedTest/scriptjson.cpp
@@ -0,0 +1,609 @@
+#include "pch.h"
+#include "scriptJson.h"
+#include "rapidjson/document.h"
+#include "rapidjson/writer.h"
+#include "rapidjson/stringbuffer.h"
+
+#include "squirrel.h"
+
+#ifdef _MSC_VER
+#undef GetObject // fuck microsoft developers
+#endif
+
+void SQ_EncodeJSON_Table(
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj,
+ SQTable* sqTable,
+ rapidjson_document* allocatorDoc);
+void SQ_EncodeJSON_Array(
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj,
+ SQArray* sqArray,
+ rapidjson_document* allocatorDoc);
+void ServerSq_DecodeJSON_Table(
+ void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj);
+void ServerSq_DecodeJSON_Array(
+ void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr);
+void ClientSq_DecodeJSON_Table(
+ void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj);
+void ClientSq_DecodeJSON_Array(
+ void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr);
+
+SQRESULT ServerSq_DecodeJSON(void* sqvm)
+{
+ const char* json = ServerSq_getstring(sqvm, 1);
+ rapidjson_document doc;
+ doc.Parse(json);
+ if (doc.HasParseError())
+ {
+ ServerSq_newTable(sqvm);
+ return SQRESULT_NOTNULL;
+ }
+ ServerSq_newTable(sqvm);
+
+ for (int i = 0; i < doc.MemberCount(); i++)
+ {
+
+ rapidjson::GenericMember<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>& itr = doc.MemberBegin()[i];
+
+ switch (itr.value.GetType())
+ {
+ case rapidjson::kObjectType:
+ ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ServerSq_DecodeJSON_Table(
+ sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kArrayType:
+ ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ServerSq_DecodeJSON_Array(
+ sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kStringType:
+ ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ServerSq_pushstring(sqvm, itr.value.GetString(), -1);
+
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kTrueType:
+ if ((long long)itr.name.GetString() == -1)
+ {
+ spdlog::info("Neagative String decoding True");
+ continue;
+ }
+
+ ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ServerSq_pushbool(sqvm, true);
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kFalseType:
+ if ((long long)itr.name.GetString() == -1)
+ {
+
+ continue;
+ }
+
+ ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ServerSq_pushbool(sqvm, false);
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kNumberType:
+ if (itr.value.IsDouble() || itr.value.IsFloat())
+ {
+
+ ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ServerSq_pushfloat(sqvm, itr.value.GetFloat());
+ }
+ else
+ {
+ ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ServerSq_pushinteger(sqvm, itr.value.GetInt());
+ }
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ }
+ }
+ return SQRESULT_NOTNULL;
+}
+
+void ServerSq_DecodeJSON_Table(
+ void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj)
+{
+ ServerSq_newTable(sqvm);
+
+ for (int i = 0; i < obj->MemberCount(); i++)
+ {
+ rapidjson::GenericMember<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>& itr = obj->MemberBegin()[i];
+ if (!itr.name.IsString())
+ {
+ spdlog::info("Decoding table with non-string key");
+ continue;
+ }
+ const char* key = itr.name.GetString();
+ switch (itr.value.GetType())
+ {
+ case rapidjson::kObjectType:
+ ServerSq_pushstring(sqvm, key, -1);
+ ServerSq_DecodeJSON_Table(
+ sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kArrayType:
+ ServerSq_pushstring(sqvm, key, -1);
+ ServerSq_DecodeJSON_Array(
+ sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kStringType:
+ ServerSq_pushstring(sqvm, key, -1);
+ ServerSq_pushstring(sqvm, itr.value.GetString(), -1);
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kTrueType:
+
+ ServerSq_pushstring(sqvm, key, -1);
+ ServerSq_pushbool(sqvm, true);
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kFalseType:
+ ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ServerSq_pushbool(sqvm, false);
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kNumberType:
+ if (itr.value.IsDouble() || itr.value.IsFloat())
+ {
+ ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ServerSq_pushfloat(sqvm, itr.value.GetFloat());
+ }
+ else
+ {
+ ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ServerSq_pushinteger(sqvm, itr.value.GetInt());
+ }
+ ServerSq_newSlot(sqvm, -3, false);
+ break;
+ }
+ }
+}
+
+void ServerSq_DecodeJSON_Array(
+ void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr)
+{
+ int usedType = arr->GetArray().Begin()->GetType();
+ bool isFloat = arr->GetArray().Begin()->IsDouble() || arr->GetArray().Begin()->IsFloat();
+ ServerSq_newarray(sqvm, 0);
+ for (auto& itr : arr->GetArray())
+ {
+ switch (itr.GetType())
+ {
+ case rapidjson::kObjectType:
+
+ if (usedType != itr.GetType())
+ continue;
+ ServerSq_DecodeJSON_Table(sqvm, &itr);
+ ServerSq_arrayappend(sqvm, -2);
+ break;
+ case rapidjson::kArrayType:
+
+ if (usedType != itr.GetType())
+ continue;
+ ServerSq_DecodeJSON_Array(sqvm, &itr);
+ ServerSq_arrayappend(sqvm, -2);
+ break;
+ case rapidjson::kStringType:
+ if ((long long)itr.GetString() == -1)
+ {
+
+ continue;
+ }
+ if (usedType != itr.GetType())
+ continue;
+ ServerSq_pushstring(sqvm, itr.GetString(), -1);
+ ServerSq_arrayappend(sqvm, -2);
+ break;
+ case rapidjson::kTrueType:
+ if (usedType != rapidjson::kTrueType && usedType != rapidjson::kFalseType)
+ continue;
+ ServerSq_pushbool(sqvm, true);
+ ServerSq_arrayappend(sqvm, -2);
+ break;
+ case rapidjson::kFalseType:
+ if (usedType != rapidjson::kTrueType && usedType != rapidjson::kFalseType)
+ continue;
+ ServerSq_pushbool(sqvm, false);
+ ServerSq_arrayappend(sqvm, -2);
+ break;
+ case rapidjson::kNumberType:
+ if (usedType != itr.GetType())
+ continue;
+ if (itr.IsDouble() || itr.IsFloat())
+ {
+
+ if (!isFloat)
+ continue;
+ ServerSq_pushfloat(sqvm, itr.GetFloat());
+ }
+ else
+ {
+ if (isFloat)
+ continue;
+ ServerSq_pushinteger(sqvm, itr.GetInt());
+ }
+ ServerSq_arrayappend(sqvm, -2);
+ break;
+ }
+ }
+}
+
+SQRESULT ClientSq_DecodeJSON(void* sqvm)
+{
+ const char* json = ClientSq_getstring(sqvm, 1);
+ rapidjson_document doc;
+ doc.Parse(json);
+ if (doc.HasParseError())
+ {
+ ClientSq_newTable(sqvm);
+ return SQRESULT_NOTNULL;
+ }
+ ServerSq_newTable(sqvm);
+
+ for (int i = 0; i < doc.MemberCount(); i++)
+ {
+
+ rapidjson::GenericMember<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>& itr = doc.MemberBegin()[i];
+
+ switch (itr.value.GetType())
+ {
+ case rapidjson::kObjectType:
+ ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ClientSq_DecodeJSON_Table(
+ sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kArrayType:
+ ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ClientSq_DecodeJSON_Array(
+ sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kStringType:
+ ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ClientSq_pushstring(sqvm, itr.value.GetString(), -1);
+
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kTrueType:
+ if ((long long)itr.name.GetString() == -1)
+ {
+ spdlog::info("Neagative String decoding True");
+ continue;
+ }
+
+ ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ClientSq_pushbool(sqvm, true);
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kFalseType:
+ if ((long long)itr.name.GetString() == -1)
+ {
+
+ continue;
+ }
+
+ ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ClientSq_pushbool(sqvm, false);
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kNumberType:
+ if (itr.value.IsDouble() || itr.value.IsFloat())
+ {
+
+ ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ClientSq_pushfloat(sqvm, itr.value.GetFloat());
+ }
+ else
+ {
+ ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ClientSq_pushinteger(sqvm, itr.value.GetInt());
+ }
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ }
+ }
+ return SQRESULT_NOTNULL;
+}
+
+void ClientSq_DecodeJSON_Table(
+ void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj)
+{
+ ClientSq_newTable(sqvm);
+
+ for (int i = 0; i < obj->MemberCount(); i++)
+ {
+ rapidjson::GenericMember<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>& itr = obj->MemberBegin()[i];
+ if (!itr.name.IsString())
+ {
+ spdlog::info("Decoding table with non-string key");
+ continue;
+ }
+ const char* key = itr.name.GetString();
+
+ switch (itr.value.GetType())
+ {
+ case rapidjson::kObjectType:
+ ClientSq_pushstring(sqvm, key, -1);
+ ClientSq_DecodeJSON_Table(
+ sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kArrayType:
+ ClientSq_pushstring(sqvm, key, -1);
+ ClientSq_DecodeJSON_Array(
+ sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kStringType:
+ ClientSq_pushstring(sqvm, key, -1);
+ ClientSq_pushstring(sqvm, itr.value.GetString(), -1);
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kTrueType:
+
+ ClientSq_pushstring(sqvm, key, -1);
+ ClientSq_pushbool(sqvm, true);
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kFalseType:
+ ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ClientSq_pushbool(sqvm, false);
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ case rapidjson::kNumberType:
+ if (itr.value.IsDouble() || itr.value.IsFloat())
+ {
+ ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ClientSq_pushfloat(sqvm, itr.value.GetFloat());
+ }
+ else
+ {
+ ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
+ ClientSq_pushinteger(sqvm, itr.value.GetInt());
+ }
+ ClientSq_newSlot(sqvm, -3, false);
+ break;
+ }
+ }
+}
+
+void ClientSq_DecodeJSON_Array(
+ void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr)
+{
+ int usedType = arr->GetArray().Begin()->GetType();
+ bool isFloat = arr->GetArray().Begin()->IsDouble() || arr->GetArray().Begin()->IsFloat();
+ ClientSq_newarray(sqvm, 0);
+ for (auto& itr : arr->GetArray())
+ {
+ switch (itr.GetType())
+ {
+ case rapidjson::kObjectType:
+
+ if (usedType != itr.GetType())
+ continue;
+ ClientSq_DecodeJSON_Table(sqvm, &itr);
+ ClientSq_arrayappend(sqvm, -2);
+ break;
+ case rapidjson::kArrayType:
+
+ if (usedType != itr.GetType())
+ continue;
+ ClientSq_DecodeJSON_Array(sqvm, &itr);
+ ClientSq_arrayappend(sqvm, -2);
+ break;
+ case rapidjson::kStringType:
+ if ((long long)itr.GetString() == -1)
+ {
+
+ continue;
+ }
+ if (usedType != itr.GetType())
+ continue;
+ ClientSq_pushstring(sqvm, itr.GetString(), -1);
+ ClientSq_arrayappend(sqvm, -2);
+ break;
+ case rapidjson::kTrueType:
+ if (usedType != rapidjson::kTrueType && usedType != rapidjson::kFalseType)
+ continue;
+ ClientSq_pushbool(sqvm, true);
+ ClientSq_arrayappend(sqvm, -2);
+ break;
+ case rapidjson::kFalseType:
+ if (usedType != rapidjson::kTrueType && usedType != rapidjson::kFalseType)
+ continue;
+ ClientSq_pushbool(sqvm, false);
+ ClientSq_arrayappend(sqvm, -2);
+ break;
+ case rapidjson::kNumberType:
+ if (usedType != itr.GetType())
+ continue;
+ if (itr.IsDouble() || itr.IsFloat())
+ {
+
+ if (!isFloat)
+ continue;
+ ClientSq_pushfloat(sqvm, itr.GetFloat());
+ }
+ else
+ {
+ if (isFloat)
+ continue;
+ ClientSq_pushinteger(sqvm, itr.GetInt());
+ }
+ ClientSq_arrayappend(sqvm, -2);
+ break;
+ }
+ }
+}
+
+SQRESULT SQ_EncodeJSON(void* sqvm)
+{
+ rapidjson_document doc;
+ doc.SetObject();
+
+ HSquirrelVM* vm = (HSquirrelVM*)sqvm;
+ SQTable* table = vm->_stackOfCurrentFunction[1]._VAL.asTable;
+ SQ_EncodeJSON_Table(&doc, table, &doc);
+ rapidjson::StringBuffer buffer;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
+ doc.Accept(writer);
+ const char* json = buffer.GetString();
+
+ ServerSq_pushstring(sqvm, json, -1);
+ return SQRESULT_NOTNULL;
+}
+
+void SQ_EncodeJSON_Table(
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj,
+ SQTable* table,
+ rapidjson_document* allocatorDoc)
+{
+ for (int i = 0; i < table->_numOfNodes; i++)
+ {
+ tableNode* node = &table->_nodes[i];
+ if (node->key._Type == OT_STRING)
+ {
+
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newObj(rapidjson::kObjectType);
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newArray(rapidjson::kArrayType);
+
+ switch (node->val._Type)
+ {
+ case OT_STRING:
+
+ obj->AddMember(
+ rapidjson::StringRef(node->key._VAL.asString->_val),
+ rapidjson::StringRef(node->val._VAL.asString->_val),
+ allocatorDoc->GetAllocator());
+ break;
+ case OT_INTEGER:
+ obj->AddMember(
+ rapidjson::StringRef(node->key._VAL.asString->_val),
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(
+ (int)node->val._VAL.asInteger),
+ allocatorDoc->GetAllocator());
+ break;
+ case OT_FLOAT:
+
+ obj->AddMember(
+ rapidjson::StringRef(node->key._VAL.asString->_val),
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(node->val._VAL.asFloat),
+ allocatorDoc->GetAllocator());
+ break;
+ case OT_BOOL:
+ if (node->val._VAL.asInteger)
+ {
+ obj->AddMember(
+ rapidjson::StringRef(node->key._VAL.asString->_val),
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(true),
+ allocatorDoc->GetAllocator());
+ }
+ else
+ {
+ obj->AddMember(
+ rapidjson::StringRef(node->key._VAL.asString->_val),
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(false),
+ allocatorDoc->GetAllocator());
+ }
+ break;
+ case OT_TABLE:
+
+ SQ_EncodeJSON_Table(&newObj, node->val._VAL.asTable, allocatorDoc);
+ obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), newObj, allocatorDoc->GetAllocator());
+ break;
+ case OT_ARRAY:
+
+ SQ_EncodeJSON_Array(&newArray, node->val._VAL.asArray, allocatorDoc);
+ obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), newArray, allocatorDoc->GetAllocator());
+ break;
+ default:
+ spdlog::info("SQ encode Json type {} not supported", sq_getTypeName(node->val._Type));
+ break;
+ }
+ }
+ }
+}
+
+void SQ_EncodeJSON_Array(
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj,
+ SQArray* sqArray,
+ rapidjson_document* allocatorDoc)
+{
+ int usedType = sqArray->_values->_Type;
+ for (int i = 0; i < sqArray->_usedSlots; i++)
+ {
+ SQObject* node = &sqArray->_values[i];
+ if (node->_Type != usedType)
+ {
+ const char* typeName = sq_getTypeName(node->_Type);
+ const char* usedTypeName = sq_getTypeName(usedType);
+ spdlog::info("SQ encode Json array not same type got %s expected %s", typeName, usedTypeName);
+ continue;
+ }
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newObj(rapidjson::kObjectType);
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newArray(rapidjson::kArrayType);
+ switch (node->_Type)
+ {
+ case OT_STRING:
+ obj->PushBack(rapidjson::StringRef(node->_VAL.asString->_val), allocatorDoc->GetAllocator());
+ break;
+ case OT_INTEGER:
+ obj->PushBack(
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>((int)node->_VAL.asInteger),
+ allocatorDoc->GetAllocator());
+ break;
+ case OT_FLOAT:
+ obj->PushBack(
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(node->_VAL.asFloat),
+ allocatorDoc->GetAllocator());
+ break;
+ case OT_BOOL:
+ if (node->_VAL.asInteger)
+ {
+ obj->PushBack(rapidjson::StringRef("true"), allocatorDoc->GetAllocator());
+ }
+ else
+ {
+ obj->PushBack(rapidjson::StringRef("false"), allocatorDoc->GetAllocator());
+ }
+ break;
+ case OT_TABLE:
+
+ SQ_EncodeJSON_Table(&newObj, node->_VAL.asTable, allocatorDoc);
+ obj->PushBack(newObj, allocatorDoc->GetAllocator());
+ break;
+ case OT_ARRAY:
+
+ SQ_EncodeJSON_Array(&newArray, node->_VAL.asArray, allocatorDoc);
+ obj->PushBack(newArray, allocatorDoc->GetAllocator());
+ break;
+ default:
+
+ spdlog::info("SQ encode Json type {} not supported", sq_getTypeName(node->_Type));
+ }
+ }
+}
+
+void InitialiseServerSquirrelJson(HMODULE baseAddress)
+{
+
+ g_ServerSquirrelManager->AddFuncRegistration("table", "DecodeJSON", "string json", "", ServerSq_DecodeJSON);
+ g_ServerSquirrelManager->AddFuncRegistration("string", "EncodeJSON", "table data", "", SQ_EncodeJSON);
+}
+
+void InitialiseClientSquirrelJson(HMODULE baseAddress)
+{
+ g_ClientSquirrelManager->AddFuncRegistration("table", "DecodeJSON", "string json", "", ClientSq_DecodeJSON);
+ g_ClientSquirrelManager->AddFuncRegistration("string", "EncodeJSON", "table data", "", SQ_EncodeJSON);
+
+ g_UISquirrelManager->AddFuncRegistration("table", "DecodeJSON", "string json", "", ClientSq_DecodeJSON);
+ g_UISquirrelManager->AddFuncRegistration("string", "EncodeJSON", "table data", "", SQ_EncodeJSON);
+} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/scriptjson.h b/NorthstarDedicatedTest/scriptjson.h
new file mode 100644
index 00000000..5dd66855
--- /dev/null
+++ b/NorthstarDedicatedTest/scriptjson.h
@@ -0,0 +1,2 @@
+void InitialiseServerSquirrelJson(HMODULE baseAddress);
+void InitialiseClientSquirrelJson(HMODULE baseAddress); \ No newline at end of file
diff --git a/NorthstarDedicatedTest/squirrel.cpp b/NorthstarDedicatedTest/squirrel.cpp
index a0680d9a..4d305ee2 100644
--- a/NorthstarDedicatedTest/squirrel.cpp
+++ b/NorthstarDedicatedTest/squirrel.cpp
@@ -94,6 +94,12 @@ sq_getboolType ServerSq_getbool;
sq_getType ClientSq_sq_get;
sq_getType ServerSq_sq_get;
+sq_newSlotType ServerSq_newSlot;
+sq_newSlotType ClientSq_newSlot;
+
+sq_newTableType ServerSq_newTable;
+sq_newTableType ClientSq_newTable;
+
template <ScriptContext context> void ExecuteCodeCommand(const CCommand& args);
// inits
@@ -153,6 +159,10 @@ void InitialiseClientSquirrel(HMODULE baseAddress)
ClientSq_defconst = (sq_defconst)((char*)baseAddress + 0x12120);
+ // Table functions
+ ClientSq_newTable = (sq_newTableType)((char*)baseAddress + 0x5940);
+ ClientSq_newSlot = (sq_newSlotType)((char*)baseAddress + 0x70B0);
+
ENABLER_CREATEHOOK(
hook,
(char*)baseAddress + 0x26130,
@@ -210,6 +220,9 @@ void InitialiseServerSquirrel(HMODULE baseAddress)
ServerSq_defconst = (sq_defconst)((char*)baseAddress + 0x1F550);
+ ServerSq_newSlot = (sq_newSlotType)((char*)baseAddress + 0x7080);
+ ServerSq_newTable = (sq_newTableType)((char*)baseAddress + 0x3960);
+
ENABLER_CREATEHOOK(
hook,
(char*)baseAddress + 0x1FE90,
@@ -499,6 +512,58 @@ template <ScriptContext context> int64_t RegisterSquirrelFuncHook(void* sqvm, SQ
return ClientRegisterSquirrelFunc(sqvm, funcReg, unknown);
}
+const char* sq_getTypeName(int type)
+{
+ switch (type)
+ {
+ case OT_ASSET:
+ return "asset";
+ case OT_INTEGER:
+ return "int";
+ case OT_BOOL:
+ return "bool";
+ case SQOBJECT_NUMERIC:
+ return "float or int";
+ case OT_NULL:
+ return "null";
+ case OT_VECTOR:
+ return "vector";
+ case 0:
+ return "var";
+ case OT_USERDATA:
+ return "userdata";
+ case OT_FLOAT:
+ return "float";
+ case OT_STRING:
+ return "string";
+ case 0x8000040:
+ return "array";
+ case 0x8000200:
+ return "function";
+ case 0x8100000:
+ return "structdef";
+ case OT_THREAD:
+ return "thread";
+ case OT_FUNCPROTO:
+ return "function";
+ case OT_CLAAS:
+ return "class";
+ case OT_WEAKREF:
+ return "weakref";
+ case 0x8080000:
+ return "unimplemented function";
+ case 0x8200000:
+ return "struct instance";
+ case 0xA000020:
+ return "table";
+ case 0xA008000:
+ return "instance";
+ case 0xA400000:
+ return "entity";
+ }
+ return "";
+}
+
SQReturnTypeEnum GetReturnTypeEnumFromString(const char* returnTypeString)
{
diff --git a/NorthstarDedicatedTest/squirrel.h b/NorthstarDedicatedTest/squirrel.h
index 0e49c7f8..fd271dc2 100644
--- a/NorthstarDedicatedTest/squirrel.h
+++ b/NorthstarDedicatedTest/squirrel.h
@@ -13,6 +13,8 @@ typedef char SQChar;
typedef SQUnsignedInteger SQBool;
typedef SQInteger SQRESULT;
+#define uint8 char
+
const SQRESULT SQRESULT_ERROR = -1;
const SQRESULT SQRESULT_NULL = 0;
const SQRESULT SQRESULT_NOTNULL = 1;
@@ -33,6 +35,8 @@ enum SQReturnTypeEnum
SqReturnTable = 0x26,
};
+const char* sq_getTypeName(int type);
+
struct CompileBufferState
{
const SQChar* buffer;
@@ -74,6 +78,474 @@ struct SQFuncRegistration
SQReturnTypeEnum GetReturnTypeEnumFromString(const char* returnTypeString);
+struct CallInfo;
+struct SQTable;
+struct SQString;
+struct SQFunctionProto;
+struct SQClosure;
+struct SQSharedState;
+struct StringTable;
+struct SQStructInstance;
+struct SQStructDef;
+struct SQNativeClosure;
+struct SQArray;
+struct SQInstruction;
+
+/* 127 */
+enum SQObjectType : __int32
+{
+ _RT_NULL = 0x1,
+ _RT_INTEGER = 0x2,
+ _RT_FLOAT = 0x4,
+ _RT_BOOL = 0x8,
+ _RT_STRING = 0x10,
+ _RT_TABLE = 0x20,
+ _RT_ARRAY = 0x40,
+ _RT_USERDATA = 0x80,
+ _RT_CLOSURE = 0x100,
+ _RT_NATIVECLOSURE = 0x200,
+ _RT_GENERATOR = 0x400,
+ OT_USERPOINTER = 0x800,
+ _RT_USERPOINTER = 0x800,
+ _RT_THREAD = 0x1000,
+ _RT_FUNCPROTO = 0x2000,
+ _RT_CLASS = 0x4000,
+ _RT_INSTANCE = 0x8000,
+ _RT_WEAKREF = 0x10000,
+ OT_VECTOR = 0x40000,
+ SQOBJECT_CANBEFALSE = 0x1000000,
+ OT_NULL = 0x1000001,
+ OT_BOOL = 0x1000008,
+ SQOBJECT_DELEGABLE = 0x2000000,
+ SQOBJECT_NUMERIC = 0x4000000,
+ OT_INTEGER = 0x5000002,
+ OT_FLOAT = 0x5000004,
+ SQOBJECT_REF_COUNTED = 0x8000000,
+ OT_STRING = 0x8000010,
+ OT_ARRAY = 0x8000040,
+ OT_CLOSURE = 0x8000100,
+ OT_NATIVECLOSURE = 0x8000200,
+ OT_ASSET = 0x8000400,
+ OT_THREAD = 0x8001000,
+ OT_FUNCPROTO = 0x8002000,
+ OT_CLAAS = 0x8004000,
+ OT_STRUCT = 0x8200000,
+ OT_WEAKREF = 0x8010000,
+ OT_TABLE = 0xA000020,
+ OT_USERDATA = 0xA000080,
+ OT_INSTANCE = 0xA008000,
+ OT_ENTITY = 0xA400000,
+};
+
+/* 156 */
+union __declspec(align(8)) SQObjectValue
+{
+ SQString* asString;
+ SQTable* asTable;
+ SQClosure* asClosure;
+ SQFunctionProto* asFuncProto;
+ SQStructDef* asStructDef;
+ __int64 asInteger;
+ SQStructInstance* asStructInstance;
+ float asFloat;
+ SQNativeClosure* asNativeClosure;
+ SQArray* asArray;
+};
+
+/* 128 */
+struct __declspec(align(8)) SQObject
+{
+ SQObjectType _Type;
+ __int32 _structOffset;
+ SQObjectValue _VAL;
+};
+
+struct tableNode
+{
+ SQObject val;
+ SQObject key;
+ tableNode* next;
+};
+
+/* 138 */
+struct __declspec(align(8)) SQString
+{
+ __int64* vftable;
+ __int32 uiRef;
+ __int32 uiRef1;
+ SQString* _next_maybe;
+ SQSharedState* sharedState;
+ __int32 length;
+ uint8 gap_24[4];
+ char _hash[8];
+ char _val[1];
+};
+
+/* 137 */
+struct __declspec(align(8)) SQTable
+{
+ __int64* vftable;
+ uint8 gap_08[4];
+ __int32 uiRef;
+ uint8 gap_10[8];
+ void* pointer_18;
+ void* pointer_20;
+ void* _sharedState;
+ __int64 field_30;
+ tableNode* _nodes;
+ __int32 _numOfNodes;
+ __int32 size;
+ __int32 field_48;
+ __int32 _usedNodes;
+ uint8 _gap_50[20];
+ __int32 field_64;
+ uint8 _gap_68[80];
+};
+
+/* 140 */
+struct __declspec(align(8)) SQClosure
+{
+ void* vftable;
+ uint8 gap_08[4];
+ __int32 uiRef;
+ void* pointer_10;
+ void* pointer_18;
+ void* pointer_20;
+ void* sharedState;
+ SQObject obj_30;
+ SQObject _function;
+ SQObject* _outervalues;
+ uint8 gap_58[8];
+ uint8 gap_60[96];
+ SQObject* objectPointer_C0;
+};
+
+/* 139 */
+struct __declspec(align(8)) SQFunctionProto
+{
+ void* vftable;
+ uint8 gap_08[4];
+ __int32 uiRef;
+ uint8 gap_10[8];
+ void* pointer_18;
+ void* pointer_20;
+ void* sharedState;
+ void* pointer_30;
+ SQObject fileName;
+ SQObject funcName;
+ SQObject obj_58;
+ uint8 gap_68[64];
+ __int32 nParameters;
+ uint8 gap_AC[60];
+ __int32 nDefaultParams;
+ uint8 gap_EC[200];
+};
+
+/* 152 */
+struct SQStructDef
+{
+ uint8 gap_0[56];
+ SQString* name;
+ uint8 gap_[300];
+};
+
+/* 150 */
+struct SQStructInstance
+{
+ void* vftable;
+ uint8 gap_8[16];
+ void* pointer_18;
+ uint8 gap_20[8];
+ SQSharedState* _sharedState;
+ uint8 gap_30[8];
+ SQObject data[1];
+};
+
+/* 157 */
+struct __declspec(align(8)) SQNativeClosure
+{
+ void* vftable;
+ uint8 gap_08[4];
+ __int32 uiRef;
+ uint8 gap_10[88];
+ SQString* _name;
+ uint8 gap_0[300];
+};
+
+/* 148 */
+struct SQSharedState
+{
+ uint8 gap_0[72];
+ StringTable* _stringtable;
+ uint8 gap_50[30000];
+};
+
+/* 149 */
+struct StringTable
+{
+ uint8 gap_0[12];
+ int _numofslots;
+ uint8 gap_10[200];
+};
+
+/* 129 */
+struct __declspec(align(8)) HSquirrelVM
+{
+ void* vftable;
+ __int32 uiRef;
+ uint8 gap_8[12];
+ void* _toString;
+ void* _roottable_pointer;
+ void* pointer_28;
+ CallInfo* ci;
+ CallInfo* _callsstack;
+ __int32 _callsstacksize;
+ __int32 _stackbase;
+ SQObject* _stackOfCurrentFunction;
+ SQSharedState* sharedState;
+ void* pointer_58;
+ void* pointer_60;
+ __int32 _top;
+ SQObject* _stack;
+ uint8 gap_78[8];
+ SQObject* _vargsstack;
+ uint8 gap_88[8];
+ SQObject temp_reg;
+ uint8 gapA0[8];
+ void* pointer_A8;
+ uint8 gap_B0[8];
+ SQObject _roottable_object;
+ SQObject _lasterror;
+ SQObject _errorHandler;
+ __int64 field_E8;
+ __int32 traps;
+ uint8 gap_F4[12];
+ __int32 _nnativecalls;
+ __int32 _suspended;
+ __int32 _suspended_root;
+ __int32 _callstacksize;
+ __int32 _suspended_target;
+ __int32 field_114;
+ __int32 _suspend_varargs;
+ SQObject* _object_pointer_120;
+};
+
+/* 136 */
+struct __declspec(align(8)) CallInfo
+{
+ SQInstruction* ip;
+ SQObject* _literals;
+ SQObject obj10;
+ SQObject closure;
+ __int32 _etraps[4];
+ __int32 _root;
+ short _vargs_size;
+ short _vargs_base;
+};
+
+/* 135 */
+enum SQOpcode : int
+{
+ _OP_LOAD = 0x0,
+ _OP_LOADCOPY = 0x1,
+ _OP_LOADINT = 0x2,
+ _OP_LOADFLOAT = 0x3,
+ _OP_DLOAD = 0x4,
+ _OP_TAILCALL = 0x5,
+ _OP_CALL = 0x6,
+ _OP_PREPCALL = 0x7,
+ _OP_PREPCALLK = 0x8,
+ _OP_GETK = 0x9,
+ _OP_MOVE = 0xA,
+ _OP_NEWSLOT = 0xB,
+ _OP_DELETE = 0xC,
+ _OP_SET = 0xD,
+ _OP_GET = 0xE,
+ _OP_EQ = 0xF,
+ _OP_NE = 0x10,
+ _OP_ARITH = 0x11,
+ _OP_BITW = 0x12,
+ _OP_RETURN = 0x13,
+ _OP_LOADNULLS = 0x14,
+ _OP_LOADROOTTABLE = 0x15,
+ _OP_LOADBOOL = 0x16,
+ _OP_DMOVE = 0x17,
+ _OP_JMP = 0x18,
+ _OP_JNZ = 0x19,
+ _OP_JZ = 0x1A,
+ _OP_LOADFREEVAR = 0x1B,
+ _OP_VARGC = 0x1C,
+ _OP_GETVARGV = 0x1D,
+ _OP_NEWTABLE = 0x1E,
+ _OP_NEWARRAY = 0x1F,
+ _OP_APPENDARRAY = 0x20,
+ _OP_GETPARENT = 0x21,
+ _OP_COMPOUND_ARITH = 0x22,
+ _OP_COMPOUND_ARITH_LOCAL = 0x23,
+ _OP_INCREMENT_PREFIX = 0x24,
+ _OP_INCREMENT_PREFIX_LOCAL = 0x25,
+ _OP_INCREMENT_PREFIX_STRUCTFIELD = 0x26,
+ _OP_INCREMENT_POSTFIX = 0x27,
+ _OP_INCREMENT_POSTFIX_LOCAL = 0x28,
+ _OP_INCREMENT_POSTFIX_STRUCTFIELD = 0x29,
+ _OP_CMP = 0x2A,
+ _OP_EXISTS = 0x2B,
+ _OP_INSTANCEOF = 0x2C,
+ _OP_NEG = 0x2D,
+ _OP_NOT = 0x2E,
+ _OP_BWNOT = 0x2F,
+ _OP_CLOSURE = 0x30,
+ _OP_FOREACH = 0x31,
+ _OP_FOREACH_STATICARRAY_START = 0x32,
+ _OP_FOREACH_STATICARRAY_NEXT = 0x33,
+ _OP_FOREACH_STATICARRAY_NESTEDSTRUCT_START = 0x34,
+ _OP_FOREACH_STATICARRAY_NESTEDSTRUCT_NEXT = 0x35,
+ _OP_DELEGATE = 0x36,
+ _OP_CLONE = 0x37,
+ _OP_TYPEOF = 0x38,
+ _OP_PUSHTRAP = 0x39,
+ _OP_POPTRAP = 0x3A,
+ _OP_THROW = 0x3B,
+ _OP_CLASS = 0x3C,
+ _OP_NEWSLOTA = 0x3D,
+ _OP_EQ_LITERAL = 0x3E,
+ _OP_NE_LITERAL = 0x3F,
+ _OP_FOREACH_SETUP = 0x40,
+ _OP_ASSERT_FAILED = 0x41,
+ _OP_ADD = 0x42,
+ _OP_SUB = 0x43,
+ _OP_MUL = 0x44,
+ _OP_DIV = 0x45,
+ _OP_MOD = 0x46,
+ _OP_PREPCALLK_CALL = 0x47,
+ _OP_PREPCALLK_MOVE_CALL = 0x48,
+ _OP_PREPCALLK_LOADINT_CALL = 0x49,
+ _OP_CMP_JZ = 0x4A,
+ _OP_INCREMENT_LOCAL_DISCARD_JMP = 0x4B,
+ _OP_JZ_RETURN = 0x4C,
+ _OP_JZ_LOADBOOL_RETURN = 0x4D,
+ _OP_NEWVECTOR = 0x4E,
+ _OP_ZEROVECTOR = 0x4F,
+ _OP_GET_VECTOR_COMPONENT = 0x50,
+ _OP_SET_VECTOR_COMPONENT = 0x51,
+ _OP_VECTOR_COMPONENT_MINUSEQ = 0x52,
+ _OP_VECTOR_COMPONENT_PLUSEQ = 0x53,
+ _OP_VECTOR_COMPONENT_MULEQ = 0x54,
+ _OP_VECTOR_COMPONENT_DIVEQ = 0x55,
+ _OP_VECTOR_NORMALIZE = 0x56,
+ _OP_VECTOR_NORMALIZE_IN_PLACE = 0x57,
+ _OP_VECTOR_DOT_PRODUCT = 0x58,
+ _OP_VECTOR_DOT_PRODUCT2D = 0x59,
+ _OP_VECTOR_CROSS_PRODUCT = 0x5A,
+ _OP_VECTOR_CROSS_PRODUCT2D = 0x5B,
+ _OP_VECTOR_LENGTH = 0x5C,
+ _OP_VECTOR_LENGTHSQR = 0x5D,
+ _OP_VECTOR_LENGTH2D = 0x5E,
+ _OP_VECTOR_LENGTH2DSQR = 0x5F,
+ _OP_VECTOR_DISTANCE = 0x60,
+ _OP_VECTOR_DISTANCESQR = 0x61,
+ _OP_VECTOR_DISTANCE2D = 0x62,
+ _OP_VECTOR_DISTANCE2DSQR = 0x63,
+ _OP_INCREMENT_LOCAL_DISCARD = 0x64,
+ _OP_FASTCALL = 0x65,
+ _OP_FASTCALL_NATIVE = 0x66,
+ _OP_FASTCALL_NATIVE_ARGTYPECHECK = 0x67,
+ _OP_FASTCALL_ENV = 0x68,
+ _OP_FASTCALL_NATIVE_ENV = 0x69,
+ _OP_FASTCALL_NATIVE_ENV_ARGTYPECHECK = 0x6A,
+ _OP_LOADGLOBALARRAY = 0x6B,
+ _OP_GETGLOBAL = 0x6C,
+ _OP_SETGLOBAL = 0x6D,
+ _OP_COMPOUND_ARITH_GLOBAL = 0x6E,
+ _OP_GETSTRUCTFIELD = 0x6F,
+ _OP_SETSTRUCTFIELD = 0x70,
+ _OP_COMPOUND_ARITH_STRUCTFIELD = 0x71,
+ _OP_NEWSTRUCT = 0x72,
+ _OP_GETSUBSTRUCT = 0x73,
+ _OP_GETSUBSTRUCT_DYNAMIC = 0x74,
+ _OP_TYPECAST = 0x75,
+ _OP_TYPECHECK = 0x76,
+ _OP_TYPECHECK_ORNULL = 0x77,
+ _OP_TYPECHECK_NOTNULL = 0x78,
+ _OP_CHECK_ENTITY_CLASS = 0x79,
+ _OP_UNREACHABLE = 0x7A,
+ _OP_ARRAY_RESIZE = 0x7B,
+};
+
+/* 141 */
+struct __declspec(align(8)) SQStackInfos
+{
+ char* _name;
+ char* _sourceName;
+ __int32 _line;
+};
+
+/* 151 */
+struct __declspec(align(4)) SQInstruction
+{
+ int op;
+ int arg1;
+ int output;
+ __int16 arg2;
+ __int16 arg3;
+};
+
+/* 154 */
+struct SQLexer
+{
+ uint8 gap_0[112];
+};
+
+/* 153 */
+struct SQCompiler
+{
+ uint8 gap_0[4];
+ __int32 _token;
+ uint8 gap_8[8];
+ SQObject object_10;
+ SQLexer lexer;
+ uint8 gap_1[768];
+};
+
+/* 155 */
+struct CSquirrelVM
+{
+ uint8 gap_0[8];
+ HSquirrelVM* sqvm;
+};
+
+struct SQVector
+{
+ SQObjectType _Type;
+ float x;
+ float y;
+ float z;
+};
+
+struct SQArray
+{
+ void* vftable;
+ __int32 uiRef;
+ uint8 gap_24[36];
+ SQObject* _values;
+ __int32 _usedSlots;
+ __int32 _allocated;
+};
+
+#define INCREMENT_REFERENCECOUNT(val) \
+ if ((val->_Type & SQOBJECT_REF_COUNTED) != 0) \
+ ++val->_VAL.asString->uiRef;
+
+#define DECREMENT_REFERENCECOUNT(val) \
+ if ((val->_Type & SQOBJECT_REF_COUNTED) != 0) \
+ { \
+ if (val->_VAL.asString->uiRef-- == 1) \
+ { \
+ spdlog::info("Deleted SQObject of type {} with address {:X}", sq_getTypeName(val->_Type), val->_VAL.asInteger); \
+ (*(void(__fastcall**)(SQString*))(&val->_VAL.asString->vftable[1]))(val->_VAL.asString); \
+ } \
+ }
+
// core sqvm funcs
typedef SQRESULT (*sq_compilebufferType)(void* sqvm, CompileBufferState* compileBuffer, const char* file, int a1, ScriptContext a2);
extern sq_compilebufferType ClientSq_compilebuffer;
@@ -151,6 +623,15 @@ typedef SQRESULT (*sq_getType)(void* sqvm, SQInteger idx);
extern sq_getType ServerSq_sq_get;
extern sq_getType ClientSq_sq_get;
+// sq table functions
+typedef SQRESULT (*sq_newTableType)(void* sqvm);
+extern sq_newTableType ServerSq_newTable;
+extern sq_newTableType ClientSq_newTable;
+
+typedef SQRESULT (*sq_newSlotType)(void* sqvm, int idx, bool bStatic);
+extern sq_newSlotType ServerSq_newSlot;
+extern sq_newSlotType ClientSq_newSlot;
+
template <ScriptContext context> class SquirrelManager
{
private: