Skip to content

Commit

Permalink
Initial mod mounting code
Browse files Browse the repository at this point in the history
  • Loading branch information
TheIndra55 committed May 21, 2024
1 parent 4f0f2b2 commit 49d3b80
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 6 deletions.
7 changes: 6 additions & 1 deletion src/file/FileSystem.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
#include "FileSystem.h"
#include "util/Hooking.h"

cdc::FileSystem* GetFS()
cdc::FileSystem* GetFS() noexcept
{
auto addr = GET_ADDRESS(0x45C700, 0x45F640, 0x472B50);

return Hooking::CallReturn<cdc::FileSystem*>(addr);
}

cdc::FileSystem* GetDiskFS() noexcept
{
return *(cdc::FileSystem**)GET_ADDRESS(0x10E58C0, 0x838890, 0x9CE27C);
}
5 changes: 4 additions & 1 deletion src/file/FileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
#include "cdc/file/FileSystem.h"

// Gets the current file system
cdc::FileSystem* GetFS();
cdc::FileSystem* GetFS() noexcept;

// Gets the disk file system
cdc::FileSystem* GetDiskFS() noexcept;
73 changes: 73 additions & 0 deletions src/file/ModFileSystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "ModFileSystem.h"
#include "Hook.h"

#include "modules/Log.h"
#include "file/FileSystem.h"

ModFileSystem::ModFileSystem(const char* path) : m_specMask(1), m_langMask(1), m_path()
{
m_diskSystem = GetDiskFS();

strcpy(m_basePath, path);
}

bool ModFileSystem::FindFile(const char* fileName, char* path) const noexcept
{
return false;
}

cdc::FileRequest* ModFileSystem::RequestRead(cdc::FileReceiver* receiver, const char* fileName, unsigned int startOffset)
{
FindFile(fileName, m_path);

Hook::GetInstance().GetModule<Log>()->WriteLine("Loading %s from mods folder", fileName);

return m_diskSystem->RequestRead(receiver, m_path, startOffset);
}

cdc::File* ModFileSystem::OpenFile(const char* fileName)
{
FindFile(fileName, m_path);

return m_diskSystem->OpenFile(m_path);
}

bool ModFileSystem::FileExists(const char* fileName)
{
return FindFile(fileName, m_path);
}

unsigned int ModFileSystem::GetFileSize(const char* fileName)
{
FindFile(fileName, m_path);

return m_diskSystem->GetFileSize(m_path);
}

void ModFileSystem::SetSpecialisationMask(unsigned int specMask)
{
m_specMask = specMask;

// Unset extra bit and set our language mask
m_langMask = specMask & ~0x80000000;
}

unsigned int ModFileSystem::GetSpecialisationMask()
{
return m_specMask;
}

cdc::FileSystem::Status ModFileSystem::GetStatus()
{
return m_diskSystem->GetStatus();
}

void ModFileSystem::Update()
{
m_diskSystem->Update();
}

void ModFileSystem::Synchronize()
{
m_diskSystem->Synchronize();
}
43 changes: 43 additions & 0 deletions src/file/ModFileSystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#pragma once

#include "cdc/file/FileSystem.h"

// So we don't need to include Windows.h here
#define _MAX_PATH 260

// This file system represents a subfolder in the mods oflder
class ModFileSystem : public cdc::FileSystem
{
private:
cdc::FileSystem* m_diskSystem;

unsigned int m_specMask;
unsigned int m_langMask;

char m_basePath[_MAX_PATH];
char m_path[_MAX_PATH];

// Finds a file and returns whether it exists and the rewritten path
bool FindFile(const char* fileName, char* path) const noexcept;

public:
ModFileSystem(const char* path);

cdc::FileRequest* RequestRead(cdc::FileReceiver* receiver, const char* fileName, unsigned int startOffset);
cdc::File* OpenFile(const char* fileName);
bool FileExists(const char* fileName);
unsigned int GetFileSize(const char* fileName);
void SetSpecialisationMask(unsigned int specMask);
unsigned int GetSpecialisationMask();
Status GetStatus();
void Update();
void Synchronize();

#ifdef TR8
void Suspend();
bool Resume();
bool IsSuspended();
char* GetBufferPointer(cdc::FileRequest* request, unsigned int* bytesLocked);
void ResetBufferPointer(int value);
#endif
};
5 changes: 5 additions & 0 deletions src/file/MultiFileSystem.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "MultiFileSystem.h"

#include "Hook.h"
#include "modules/Log.h"

MultiFileSystem::MultiFileSystem() : m_fileSystems()
{
}
Expand All @@ -21,6 +24,8 @@ cdc::FileSystem* MultiFileSystem::GetBestFileSystem(const char* fileName)
void MultiFileSystem::Add(cdc::FileSystem* fileSystem)
{
m_fileSystems.push_back(fileSystem);

Hook::GetInstance().GetModule<Log>()->WriteLine("Mounted new file system %p, number of systems: %d", fileSystem, m_fileSystems.size());
}

void MultiFileSystem::Remove(cdc::FileSystem* fileSystem)
Expand Down
67 changes: 63 additions & 4 deletions src/modules/ModLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@
#include <MinHook.h>

#include "ModLoader.h"
#include "Hook.h"
#include "Log.h"
#include "util/Hooking.h"

#include "cdc/file/MultiFileSystem.h"
#include "cdc/file/ArchiveFileSystem.h"

#include "file/FileSystem.h"
#include "file/HookFileSystem.h"
#include "file/MultiFileSystem.h"
#include "file/ModFileSystem.h"

static ModLoader* loader = nullptr;

static cdc::FileSystem* CreateHookFileSystem()
{
Expand Down Expand Up @@ -43,10 +49,9 @@ static void InitArchive()

// Create our hook file system and multi file system
auto fileSystem = CreateHookFileSystem();
auto multiFileSystem = new MultiFileSystem();
auto multiFileSystem = loader->GetFileSystem();

//auto archiveFile = new cdc::ArchiveFileSystem(*(cdc::FileSystem**)0x838890);
//archiveFile->Open("mods/bigfile.000");
loader->MountMods();

multiFileSystem->Add(fileSystem);
multiFileSystem->Add(GetFS());
Expand All @@ -56,13 +61,67 @@ static void InitArchive()
}

// Initialize the mod loader and insert all hooks
ModLoader::ModLoader()
ModLoader::ModLoader() : m_fileSystem()
{
loader = this;

#ifndef TR8
MH_CreateHook((void*)GET_ADDRESS(0x45C670, 0x45F5B0, 0x473840), InitArchive, (void**)&s_InitArchive);
#else
MH_CreateHook((void*)0x478930, InitPatchArchive, (void**)&s_InitPatchArchive);
#endif

MH_EnableHook(MH_ALL_HOOKS);
}

void ModLoader::MountMods()
{
auto log = Hook::GetInstance().GetModule<Log>();

for (auto& entry : std::filesystem::directory_iterator("mods"))
{
auto name = entry.path().filename();

// Mount files with bigfile extension as archive
if (entry.is_regular_file() && name.extension() == ".000")
{
log->WriteLine("Mounting mod archive %s", name.string().c_str());

MountArchive(name);
}

// Mount folders as new mod file system
if (entry.is_directory())
{
log->WriteLine("Mounting mod directory %s", name.string().c_str());

MountDirectory(name);
}
}
}

void ModLoader::MountArchive(std::filesystem::path& name) noexcept
{
auto path = "mods" / name;

// Open the archive
auto archive = new cdc::ArchiveFileSystem(*(cdc::FileSystem**)0x838890);
archive->Open(path.string().c_str());

// Mount the archive
m_fileSystem.Add((cdc::FileSystem*)archive);
}

void ModLoader::MountDirectory(std::filesystem::path& name) noexcept
{
auto path = "mods" / name;
auto fileSystem = new ModFileSystem(name.string().c_str());

// Mount the file system
m_fileSystem.Add(fileSystem);
}

MultiFileSystem* ModLoader::GetFileSystem() noexcept
{
return &m_fileSystem;
}
12 changes: 12 additions & 0 deletions src/modules/ModLoader.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
#pragma once

#include <filesystem>

#include "Module.h"
#include "file/MultiFileSystem.h"

class ModLoader : public Module
{
private:
MultiFileSystem m_fileSystem;

void MountArchive(std::filesystem::path& name) noexcept;
void MountDirectory(std::filesystem::path& name) noexcept;

public:
ModLoader();
void MountMods();

MultiFileSystem* GetFileSystem() noexcept;
};

0 comments on commit 49d3b80

Please sign in to comment.