diff options
author | BobTheBob <32057864+BobTheBob9@users.noreply.github.com> | 2021-07-23 15:36:18 +0100 |
---|---|---|
committer | BobTheBob <32057864+BobTheBob9@users.noreply.github.com> | 2021-07-23 15:36:18 +0100 |
commit | 844e12403400b455fe5df8c2e19145a2ed1a7d45 (patch) | |
tree | 81839795869676892b0219d4d1533fb40d6074af | |
parent | 23a1dafcde70822a9899e9aab190f36521c1aedd (diff) | |
download | NorthstarLauncher-844e12403400b455fe5df8c2e19145a2ed1a7d45.tar.gz NorthstarLauncher-844e12403400b455fe5df8c2e19145a2ed1a7d45.zip |
add support for building scripts.rson at runtime
-rw-r--r-- | NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters | 18 | ||||
-rw-r--r-- | NorthstarDedicatedTest/filesystem.cpp | 41 | ||||
-rw-r--r-- | NorthstarDedicatedTest/filesystem.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/modmanager.cpp | 15 | ||||
-rw-r--r-- | NorthstarDedicatedTest/modmanager.h | 7 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptsrson.cpp | 51 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptsrson.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/sourceconsole.cpp | 1 | ||||
-rw-r--r-- | NorthstarDedicatedTest/squirrel.cpp | 3 |
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) |