aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2021-07-23 15:36:18 +0100
committerBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2021-07-23 15:36:18 +0100
commit844e12403400b455fe5df8c2e19145a2ed1a7d45 (patch)
tree81839795869676892b0219d4d1533fb40d6074af
parent23a1dafcde70822a9899e9aab190f36521c1aedd (diff)
downloadNorthstarLauncher-844e12403400b455fe5df8c2e19145a2ed1a7d45.tar.gz
NorthstarLauncher-844e12403400b455fe5df8c2e19145a2ed1a7d45.zip
add support for building scripts.rson at runtime
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj2
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters18
-rw-r--r--NorthstarDedicatedTest/filesystem.cpp41
-rw-r--r--NorthstarDedicatedTest/filesystem.h3
-rw-r--r--NorthstarDedicatedTest/modmanager.cpp15
-rw-r--r--NorthstarDedicatedTest/modmanager.h7
-rw-r--r--NorthstarDedicatedTest/scriptsrson.cpp51
-rw-r--r--NorthstarDedicatedTest/scriptsrson.h3
-rw-r--r--NorthstarDedicatedTest/sourceconsole.cpp1
-rw-r--r--NorthstarDedicatedTest/squirrel.cpp3
10 files changed, 135 insertions, 9 deletions
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
index a565acab..ef652d9d 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
@@ -307,6 +307,7 @@
<ClInclude Include="main.h" />
<ClInclude Include="modmanager.h" />
<ClInclude Include="pch.h" />
+ <ClInclude Include="scriptsrson.h" />
<ClInclude Include="sigscanning.h" />
<ClInclude Include="sourceconsole.h" />
<ClInclude Include="sourceinterface.h" />
@@ -330,6 +331,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="scriptsrson.cpp" />
<ClCompile Include="sigscanning.cpp" />
<ClCompile Include="sourceconsole.cpp" />
<ClCompile Include="sourceinterface.cpp" />
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
index 74491c39..7bd160c6 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
@@ -25,9 +25,6 @@
<Filter Include="Source Files\Shared">
<UniqueIdentifier>{4f525372-34a8-40b3-8a95-81d77cdfcf7f}</UniqueIdentifier>
</Filter>
- <Filter Include="Source Files\Shared\Hooks">
- <UniqueIdentifier>{4db0d1e9-9035-457f-87f1-5dc3f13b6b9e}</UniqueIdentifier>
- </Filter>
<Filter Include="Source Files\Dedicated">
<UniqueIdentifier>{947835db-67d6-42c0-870d-62743f85231f}</UniqueIdentifier>
</Filter>
@@ -82,6 +79,15 @@
<Filter Include="Header Files\include\rapidjson\msinttypes">
<UniqueIdentifier>{85aacdee-0f92-4ec4-b20c-0739c1175055}</UniqueIdentifier>
</Filter>
+ <Filter Include="Source Files\Shared\Hooks">
+ <UniqueIdentifier>{4db0d1e9-9035-457f-87f1-5dc3f13b6b9e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\Shared\Mods\Compiled">
+ <UniqueIdentifier>{d1f93d1e-0ecb-44fe-a277-d3e75aec2570}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Shared\Mods\Compiled">
+ <UniqueIdentifier>{14fc0931-acad-46ec-a55e-94f4469d4235}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
@@ -510,6 +516,9 @@
<ClInclude Include="filesystem.h">
<Filter>Header Files\Shared</Filter>
</ClInclude>
+ <ClInclude Include="scriptsrson.h">
+ <Filter>Header Files\Shared\Mods\Compiled</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
@@ -560,6 +569,9 @@
<ClCompile Include="filesystem.cpp">
<Filter>Source Files\Shared</Filter>
</ClCompile>
+ <ClCompile Include="scriptsrson.cpp">
+ <Filter>Source Files\Shared\Mods\Compiled</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="include\spdlog\fmt\bundled\LICENSE.rst">
diff --git a/NorthstarDedicatedTest/filesystem.cpp b/NorthstarDedicatedTest/filesystem.cpp
index 877898ee..aa6975fe 100644
--- a/NorthstarDedicatedTest/filesystem.cpp
+++ b/NorthstarDedicatedTest/filesystem.cpp
@@ -6,6 +6,7 @@
#include "modmanager.h"
#include <iostream>
+#include <sstream>
// hook forward declares
typedef FileHandle_t(*ReadFileFromVPKType)(VPKData* vpkInfo, __int64* b, const char* filename);
@@ -16,6 +17,7 @@ typedef bool(*ReadFromCacheType)(IFileSystem* filesystem, const char* path, void
ReadFromCacheType readFromCache;
bool ReadFromCacheHook(IFileSystem* filesystem, const char* path, void* result);
+bool readingOriginalFile;
SourceInterface<IFileSystem>* g_Filesystem;
void InitialiseFilesystem(HMODULE baseAddress)
@@ -28,15 +30,52 @@ void InitialiseFilesystem(HMODULE baseAddress)
ENABLER_CREATEHOOK(hook, (*g_Filesystem)->m_vtable->ReadFromCache, &ReadFromCacheHook, reinterpret_cast<LPVOID*>(&readFromCache));
}
+std::string ReadVPKFile(const char* path)
+{
+ // read scripts.rson file, todo: check if this can be overwritten
+ FileHandle_t fileHandle = (*g_Filesystem)->m_vtable2->Open(&(*g_Filesystem)->m_vtable2, path, "rb", "GAME", 0);
+
+ std::stringstream fileStream;
+ int bytesRead = 0;
+ char data[4096];
+ do
+ {
+ bytesRead = (*g_Filesystem)->m_vtable2->Read(&(*g_Filesystem)->m_vtable2, data, std::size(data), fileHandle);
+ fileStream.write(data, bytesRead);
+ } while (bytesRead == std::size(data));
+
+ (*g_Filesystem)->m_vtable2->Close(*g_Filesystem, fileHandle);
+
+ return fileStream.str();
+}
+
+std::string ReadVPKOriginalFile(const char* path)
+{
+ readingOriginalFile = true;
+ std::string ret = ReadVPKFile(path);
+ readingOriginalFile = false;
+
+ return ret;
+}
+
void SetNewModSearchPaths(Mod* mod)
{
// put our new path to the head
// in future we should look into manipulating paths at head manually, might be effort tho
- (*g_Filesystem)->m_vtable->AddSearchPath(&*(*g_Filesystem), (fs::absolute(mod->ModDirectory) / "mod").string().c_str(), "GAME", PATH_ADD_TO_HEAD);
+ // potentially we could also determine whether the file we're setting paths for needs a mod dir, or compiled assets
+ if (mod != nullptr)
+ (*g_Filesystem)->m_vtable->AddSearchPath(&*(*g_Filesystem), (fs::absolute(mod->ModDirectory) / MOD_OVERRIDE_DIR).string().c_str(), "GAME", PATH_ADD_TO_HEAD);
+
+ (*g_Filesystem)->m_vtable->AddSearchPath(&*(*g_Filesystem), fs::absolute(COMPILED_ASSETS_PATH).string().c_str(), "GAME", PATH_ADD_TO_HEAD);
}
bool TryReplaceFile(const char* path)
{
+ if (readingOriginalFile)
+ return false;
+
+ (*g_ModManager).CompileAssetsForFile(path);
+
// is this efficient? no clue
for (ModOverrideFile* modFile : g_ModManager->m_modFiles)
{
diff --git a/NorthstarDedicatedTest/filesystem.h b/NorthstarDedicatedTest/filesystem.h
index 597a03ff..cf93df8d 100644
--- a/NorthstarDedicatedTest/filesystem.h
+++ b/NorthstarDedicatedTest/filesystem.h
@@ -66,5 +66,8 @@ public:
VTable2* m_vtable2;
};
+std::string ReadVPKFile(const char* path);
+std::string ReadVPKOriginalFile(const char* path);
+
void InitialiseFilesystem(HMODULE baseAddress);
extern SourceInterface<IFileSystem>* g_Filesystem; \ No newline at end of file
diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp
index 14182017..05974d4e 100644
--- a/NorthstarDedicatedTest/modmanager.cpp
+++ b/NorthstarDedicatedTest/modmanager.cpp
@@ -225,16 +225,16 @@ void ModManager::LoadMods()
// register mod files
- if (fs::exists(mod->ModDirectory / "mod"))
+ if (fs::exists(mod->ModDirectory / MOD_OVERRIDE_DIR))
{
- for (fs::directory_entry file : fs::recursive_directory_iterator(mod->ModDirectory / "mod"))
+ for (fs::directory_entry file : fs::recursive_directory_iterator(mod->ModDirectory / MOD_OVERRIDE_DIR))
{
if (file.is_regular_file())
{
// super temp because it relies hard on load order
ModOverrideFile* modFile = new ModOverrideFile;
modFile->owningMod = mod;
- modFile->path = file.path().lexically_relative(mod->ModDirectory / "mod").lexically_normal();
+ modFile->path = file.path().lexically_relative(mod->ModDirectory / MOD_OVERRIDE_DIR).lexically_normal();
m_modFiles.push_back(modFile);
}
}
@@ -243,6 +243,15 @@ void ModManager::LoadMods()
}
+void ModManager::CompileAssetsForFile(const char* filename)
+{
+ fs::path path(filename);
+
+ if (!path.filename().compare("scripts.rson"))
+ BuildScriptsRson();
+
+}
+
void InitialiseModManager(HMODULE baseAddress)
{
g_ModManager = new ModManager();
diff --git a/NorthstarDedicatedTest/modmanager.h b/NorthstarDedicatedTest/modmanager.h
index 60e51308..662c34c4 100644
--- a/NorthstarDedicatedTest/modmanager.h
+++ b/NorthstarDedicatedTest/modmanager.h
@@ -6,6 +6,9 @@
namespace fs = std::filesystem;
const fs::path MOD_FOLDER_PATH = "R2Northstar/mods";
+const fs::path MOD_OVERRIDE_DIR = "mod";
+
+const fs::path COMPILED_ASSETS_PATH = "R2Northstar/runtime/compiled";
struct ModConVar
{
@@ -92,6 +95,10 @@ public:
public:
ModManager();
void LoadMods();
+ void CompileAssetsForFile(const char* filename);
+
+ // compile asset type stuff, these are done in files under Mods/Compiled/
+ void BuildScriptsRson();
};
void InitialiseModManager(HMODULE baseAddress);
diff --git a/NorthstarDedicatedTest/scriptsrson.cpp b/NorthstarDedicatedTest/scriptsrson.cpp
new file mode 100644
index 00000000..05386910
--- /dev/null
+++ b/NorthstarDedicatedTest/scriptsrson.cpp
@@ -0,0 +1,51 @@
+#include "pch.h"
+#include "modmanager.h"
+#include "scriptsrson.h"
+#include "filesystem.h"
+
+#include <sstream>
+#include <fstream>
+
+void ModManager::BuildScriptsRson()
+{
+ spdlog::info("Building custom scripts.rson");
+ fs::remove(MOD_SCRIPTS_RSON_PATH);
+
+ // not really important since it doesn't affect actual functionality at all, but the rson we output is really weird
+ // has a shitload of newlines added, even in places where we don't modify it at all
+
+ std::string scriptsRson = ReadVPKOriginalFile("scripts/vscripts/scripts.rson");
+ scriptsRson += "\n\n// START MODDED SCRIPT CONTENT\n\n"; // newline before we start custom stuff
+
+ for (Mod* mod : m_loadedMods)
+ {
+ for (ModScript* script : mod->Scripts)
+ {
+ /* should create something with the format
+ When: "CONTEXT"
+ Scripts:
+ [
+ "_coolscript.gnut"
+ ]*/
+
+ scriptsRson += "When: \"";
+ scriptsRson += script->RsonRunOn;
+ scriptsRson += "\"\n";
+
+ scriptsRson += "Scripts:\n[\n\t";
+ scriptsRson += script->Path;
+ scriptsRson += "\n]\n\n";
+ }
+ }
+
+ fs::create_directories(MOD_SCRIPTS_RSON_PATH.parent_path());
+
+ std::ofstream writeStream(MOD_SCRIPTS_RSON_PATH);
+ writeStream << scriptsRson;
+ writeStream.close();
+
+ ModOverrideFile* overrideFile = new ModOverrideFile;
+ overrideFile->owningMod = nullptr;
+ overrideFile->path = "scripts/vscripts/scripts.rson";
+ m_modFiles.push_back(overrideFile);
+} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/scriptsrson.h b/NorthstarDedicatedTest/scriptsrson.h
new file mode 100644
index 00000000..f9297065
--- /dev/null
+++ b/NorthstarDedicatedTest/scriptsrson.h
@@ -0,0 +1,3 @@
+#pragma once
+
+const fs::path MOD_SCRIPTS_RSON_PATH = COMPILED_ASSETS_PATH / "scripts/vscripts/scripts.rson"; \ No newline at end of file
diff --git a/NorthstarDedicatedTest/sourceconsole.cpp b/NorthstarDedicatedTest/sourceconsole.cpp
index b6e69568..88d038df 100644
--- a/NorthstarDedicatedTest/sourceconsole.cpp
+++ b/NorthstarDedicatedTest/sourceconsole.cpp
@@ -51,7 +51,6 @@ void InitialiseSourceConsole(HMODULE baseAddress)
{
g_SourceGameConsole = new SourceInterface<CGameConsole>("client.dll", "GameConsole004");
RegisterConCommand("toggleconsole", ConCommand_toggleconsole, "toggles the console", FCVAR_NONE);
- RegisterConVar("ns_test", "yeah", 0, "fuck");
}
diff --git a/NorthstarDedicatedTest/squirrel.cpp b/NorthstarDedicatedTest/squirrel.cpp
index 4eae96a4..4462eb7f 100644
--- a/NorthstarDedicatedTest/squirrel.cpp
+++ b/NorthstarDedicatedTest/squirrel.cpp
@@ -133,7 +133,7 @@ template<Context context> void* CreateNewVMHook(void* a1, Context realContext)
g_ServerSquirrelManager->sqvm = sqvm;
}
- spdlog::info("CreateNewVM {} {}", GetContextName(context), sqvm);
+ spdlog::info("CreateNewVM {} {}", GetContextName(realContext), sqvm);
return sqvm;
}
@@ -199,6 +199,7 @@ template<Context context> char CallScriptInitCallbackHook(void* sqvm, const char
shouldCallCustomCallbacks = true;
// run before callbacks
+ // todo: we need to verify if RunOn is valid for current state before calling callbacks
if (shouldCallCustomCallbacks)
{
for (Mod* mod : g_ModManager->m_loadedMods)