Skip to content

Commit

Permalink
Implement database stacking.
Browse files Browse the repository at this point in the history
  • Loading branch information
blueskythlikesclouds committed Jun 8, 2022
1 parent 3c562a9 commit d6469c8
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 5 deletions.
2 changes: 2 additions & 0 deletions Source/DivaModLoader/Context.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Context.h"

#include "CodeLoader.h"
#include "DatabaseLoader.h"
#include "ModLoader.h"
#include "Patches.h"
#include "SigScan.h"
Expand Down Expand Up @@ -28,6 +29,7 @@ void Context::initCore()
Patches::init();
ModLoader::init();
CodeLoader::init();
DatabaseLoader::init();
}

void Context::init()
Expand Down
72 changes: 72 additions & 0 deletions Source/DivaModLoader/DatabaseLoader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "DatabaseLoader.h"

#include "ModLoader.h"
#include "Types.h"
#include "Utilities.h"

// The game contains a list of database prefixes in the mount data manager.
// We insert all mod directory paths into this list along with a magic value wrapping it.

// For example, object database becomes "rom/objset/<magic><mod path><magic>_obj_db.bin".
// We detect this pattern in the file resolver function and fix it to become a valid file path.
// It becomes "<mod path>/rom/objset/mod_obj_db.bin" as a result.

constexpr char MAGIC = 0x01;

void resolveModFilePath(prj::string& filePath)
{
const size_t magicIdx0 = filePath.find(MAGIC);
if (magicIdx0 == std::string::npos)
return;

const size_t magicIdx1 = filePath.find(MAGIC, magicIdx0 + 1);
if (magicIdx1 == std::string::npos)
return;

const prj::string left = filePath.substr(0, magicIdx0); // folder
const prj::string center = filePath.substr(magicIdx0 + 1, magicIdx1 - magicIdx0 - 1); // mod folder
const prj::string right = filePath.substr(magicIdx1 + 1); // file name

filePath = center;
filePath += "/";
filePath += left;
filePath += "mod";
filePath += right;
}

HOOK(size_t, __fastcall, ResolveFilePath, sigResolveFilePath(), prj::string& filePath, prj::string* a2)
{
resolveModFilePath(filePath);

// I don't know what this is. It always seems to be the same as the input file path.
if (a2)
resolveModFilePath(*a2);

return originalResolveFilePath(filePath, a2);
}

void DatabaseLoader::init()
{
INSTALL_HOOK(ResolveFilePath);

// Safe to do this as this list is initialized in a C++ static
// initializer function which gets called before WinMain.

// Get the list address from the lea instruction that loads it.
uint8_t* instrAddr = (uint8_t*)sigInitMdataMgr() + 0xFE;
auto& list = *(prj::list<prj::string>*)(instrAddr + readUnalignedU32(instrAddr + 0x3) + 0x7);

// Traverse mod folders in reverse to have correct priority.
for (auto it = ModLoader::modDirectoryPaths.rbegin(); it != ModLoader::modDirectoryPaths.rend(); ++it)
{
prj::string path;

path += MAGIC;
path += *it;
path += MAGIC;
path += "_";

list.push_back(path);
}
}

7 changes: 7 additions & 0 deletions Source/DivaModLoader/DatabaseLoader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

class DatabaseLoader
{
public:
static void init();
};
2 changes: 2 additions & 0 deletions Source/DivaModLoader/DivaModLoader.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
<ClInclude Include="CodeLoader.h" />
<ClInclude Include="Config.h" />
<ClInclude Include="Context.h" />
<ClInclude Include="DatabaseLoader.h" />
<ClInclude Include="ModLoader.h" />
<ClInclude Include="Patches.h" />
<ClInclude Include="Pch.h" />
Expand All @@ -114,6 +115,7 @@
<ClCompile Include="CodeLoader.cpp" />
<ClCompile Include="Config.cpp" />
<ClCompile Include="Context.cpp" />
<ClCompile Include="DatabaseLoader.cpp" />
<ClCompile Include="DllMain.cpp" />
<ClCompile Include="ModLoader.cpp" />
<ClCompile Include="Patches.cpp" />
Expand Down
2 changes: 2 additions & 0 deletions Source/DivaModLoader/DivaModLoader.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<ClInclude Include="CodeLoader.h" />
<ClInclude Include="Patches.h" />
<ClInclude Include="SigScan.h" />
<ClInclude Include="DatabaseLoader.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="DllMain.cpp" />
Expand All @@ -21,5 +22,6 @@
<ClCompile Include="Config.cpp" />
<ClCompile Include="Patches.cpp" />
<ClCompile Include="SigScan.cpp" />
<ClCompile Include="DatabaseLoader.cpp" />
</ItemGroup>
</Project>
8 changes: 5 additions & 3 deletions Source/DivaModLoader/ModLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,10 @@ void ModLoader::init()
{
LOG("Mods: \"%s\"", getRelativePath(Config::modsDirectoryPath).c_str())

if (Config::priorityPaths.size() > 0)
if (!Config::priorityPaths.empty())
{
LOG("Using priority array")
LOG(" Using priority array")

for (auto& path : Config::priorityPaths)
{
const std::string modDirectory = Config::modsDirectoryPath + "\\" + path;
Expand All @@ -102,7 +103,8 @@ void ModLoader::init()
}
else
{
LOG("Using alphanumeric folder name order for priority")
LOG(" Using alphanumeric folder name order for priority")

for (auto& modDirectory : std::filesystem::directory_iterator(Config::modsDirectoryPath))
{
if (std::filesystem::is_directory(modDirectory))
Expand Down
1 change: 1 addition & 0 deletions Source/DivaModLoader/Pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <string>
#include <vector>
#include <list>

#undef _ITERATOR_DEBUG_LEVEL
#pragma pop_macro("_ITERATOR_DEBUG_LEVEL")
Expand Down
4 changes: 3 additions & 1 deletion Source/DivaModLoader/SigScan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,6 @@ SIG_SCAN(sigWinMain, "\x40\x55\x53\x57\x41\x54\x41\x55\x48\x8D\xAC\x24\x00\x00\x
SIG_SCAN(sigOperatorNew, "\x40\x53\x48\x83\xEC\x20\x48\x8B\xD9\xEB\x0F\x48\x8B\xCB\xE8\x00\x00\x00\x00\x85\xC0\x74\x13\x48\x8B\xCB\xE8\x00\x00\x00\x00\x48\x85\xC0\x74\xE7\x48\x83\xC4\x20\x5B\xC3\x48\x83\xFB\xFF\x74\x06\xE8\x00\x00\x00\x00\xCC\xE8\x00\x00\x00\x00\xCC\x40\x53", "xxxxxxxxxxxxxxx????xxxxxxxx????xxxxxxxxxxxxxxxxxx????xx????xxx")
SIG_SCAN(sigOperatorDelete, "\x48\x85\xC9\x74\x37\x53\x48\x83\xEC\x20\x4C\x8B\xC1\x33\xD2\x48\x8B\x0D\x00\x00\x00\x00\xFF\x15\x00\x00\x00\x00\x85\xC0\x75\x17\xE8\x00\x00\x00\x00\x48\x8B\xD8\xFF\x15\x00\x00\x00\x00\x8B\xC8\xE8\x00\x00\x00\x00\x89\x03\x48\x83\xC4\x20\x5B\xC3", "xxxxxxxxxxxxxxxxxx????xx????xxxxx????xxxxx????xxx????xxxxxxxx")
SIG_SCAN(sigInitRomDirectoryPaths, "\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x48\x89\x7C\x24\x00\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8B\xEC\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x45\xF0\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x33\xF6\x48\x89\x75\xD0\x48\x89\x75\xE0\xBF\x00\x00\x00\x00\x48\x89\x7D\xE8\x40\x88\x75\xD0\x45\x33\xC0\x48\x8D\x15\x00\x00\x00\x00\x48\x8D\x4D\xD0\xE8\x00\x00\x00\x00\x90\x44\x8D\x46\x02\x48\x8D\x15\x00\x00\x00\x00\x48\x8D\x4D\xD0\xE8\x00\x00\x00\x00\x89\x75\xC0\x4C\x8D\x25\x00\x00\x00\x00\x48\x8D\x5E\xFF\x0F\x1F\x80\x00\x00\x00\x00", "xxxx?xxxx?xxxx?xxxxxxxxxxxxxxx????xxx????xxxxxxxxxx????x????xxxxxxxxxxx????xxxxxxxxxxxxxx????xxxxx????xxxxxxxx????xxxxx????xxxxxx????xxxxxxx????")
SIG_SCAN(sigInitSteamAPIManager, "\x48\x89\x5C\x24\x00\x57\x48\x83\xEC\x20\x48\x8B\xF9\x80\x79\x08\x00\x0F\x85\x00\x00\x00\x00\xB9\x00\x00\x00\x00\xFF\x15\x00\x00\x00\x00\x84\xC0\x74\x0F\xC6\x47\x08\x00\x48\x8B\x5C\x24\x00\x48\x83\xC4\x20\x5F\xC3", "xxxx?xxxxxxxxxxxxxx????x????xx????xxxxxxxxxxxx?xxxxxx")
SIG_SCAN(sigInitSteamAPIManager, "\x48\x89\x5C\x24\x00\x57\x48\x83\xEC\x20\x48\x8B\xF9\x80\x79\x08\x00\x0F\x85\x00\x00\x00\x00\xB9\x00\x00\x00\x00\xFF\x15\x00\x00\x00\x00\x84\xC0\x74\x0F\xC6\x47\x08\x00\x48\x8B\x5C\x24\x00\x48\x83\xC4\x20\x5F\xC3", "xxxx?xxxxxxxxxxxxxx????x????xx????xxxxxxxxxxxx?xxxxxx")
SIG_SCAN(sigResolveFilePath, "\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x40\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x44\x24\x00\x4C\x8B\xE2\x4C\x8B\xF9\x33\xC0\x0F\x57\xC9\xF3\x0F\x7F\x4C\x24\x00\x48\x89\x44\x24\x00\x48\x8D\x54\x24\x00\xE8\x00\x00\x00\x00\x83\xF8\x01\x75\x46\x49\x8B\xCF\xE8\x00\x00\x00\x00\x84\xC0\x74\x28\x4D\x85\xE4\x0F\x84\x00\x00\x00\x00\x4D\x3B\xE7\x0F\x84\x00\x00\x00\x00\x49\x8B\xD7\x49\x83\x7F\x00\x00\x72\x03\x49\x8B\x17", "xxxx?xxxxxxxxxxxxxxxxxx????xxxxxxx?xxxxxxxxxxxxxxxx?xxxx?xxxx?x????xxxxxxxxx????xxxxxxxxx????xxxxx????xxxxxx??xxxxx")
SIG_SCAN(sigInitMdataMgr, "\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x48\x89\x7C\x24\x00\x41\x54\x41\x56\x41\x57\x48\x83\xEC\x60\x48\x8B\x44\x24\x00\x48\x89\x44\x24\x00\x4C\x8D\x25\x00\x00\x00\x00\x4C\x89\x64\x24\x00\x49\x8B\xCC", "xxxx?xxxx?xxxx?xxxx?xxxxxxxxxxxxxx?xxxx?xxx????xxxx?xxx")
5 changes: 4 additions & 1 deletion Source/DivaModLoader/SigScan.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ extern void* sigOperatorDelete(); // 0x1409B8580

extern void* sigInitRomDirectoryPaths(); // 0x1402A2040

extern void* sigInitSteamAPIManager(); // 0x1406051D0
extern void* sigInitSteamAPIManager(); // 0x1406051D0

extern void* sigResolveFilePath(); // 0x1402A5030
extern void* sigInitMdataMgr(); // 0x140442D50
3 changes: 3 additions & 0 deletions Source/DivaModLoader/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ namespace prj

template<typename T>
using vector = std::vector<T, Allocator<T>>;

template<typename T>
using list = std::list<T, Allocator<T>>;
}

0 comments on commit d6469c8

Please sign in to comment.