Skip to content

Commit 49d3b80

Browse files
committed
Initial mod mounting code
1 parent 4f0f2b2 commit 49d3b80

File tree

7 files changed

+206
-6
lines changed

7 files changed

+206
-6
lines changed

src/file/FileSystem.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
#include "FileSystem.h"
22
#include "util/Hooking.h"
33

4-
cdc::FileSystem* GetFS()
4+
cdc::FileSystem* GetFS() noexcept
55
{
66
auto addr = GET_ADDRESS(0x45C700, 0x45F640, 0x472B50);
77

88
return Hooking::CallReturn<cdc::FileSystem*>(addr);
9+
}
10+
11+
cdc::FileSystem* GetDiskFS() noexcept
12+
{
13+
return *(cdc::FileSystem**)GET_ADDRESS(0x10E58C0, 0x838890, 0x9CE27C);
914
}

src/file/FileSystem.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@
33
#include "cdc/file/FileSystem.h"
44

55
// Gets the current file system
6-
cdc::FileSystem* GetFS();
6+
cdc::FileSystem* GetFS() noexcept;
7+
8+
// Gets the disk file system
9+
cdc::FileSystem* GetDiskFS() noexcept;

src/file/ModFileSystem.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include "ModFileSystem.h"
2+
#include "Hook.h"
3+
4+
#include "modules/Log.h"
5+
#include "file/FileSystem.h"
6+
7+
ModFileSystem::ModFileSystem(const char* path) : m_specMask(1), m_langMask(1), m_path()
8+
{
9+
m_diskSystem = GetDiskFS();
10+
11+
strcpy(m_basePath, path);
12+
}
13+
14+
bool ModFileSystem::FindFile(const char* fileName, char* path) const noexcept
15+
{
16+
return false;
17+
}
18+
19+
cdc::FileRequest* ModFileSystem::RequestRead(cdc::FileReceiver* receiver, const char* fileName, unsigned int startOffset)
20+
{
21+
FindFile(fileName, m_path);
22+
23+
Hook::GetInstance().GetModule<Log>()->WriteLine("Loading %s from mods folder", fileName);
24+
25+
return m_diskSystem->RequestRead(receiver, m_path, startOffset);
26+
}
27+
28+
cdc::File* ModFileSystem::OpenFile(const char* fileName)
29+
{
30+
FindFile(fileName, m_path);
31+
32+
return m_diskSystem->OpenFile(m_path);
33+
}
34+
35+
bool ModFileSystem::FileExists(const char* fileName)
36+
{
37+
return FindFile(fileName, m_path);
38+
}
39+
40+
unsigned int ModFileSystem::GetFileSize(const char* fileName)
41+
{
42+
FindFile(fileName, m_path);
43+
44+
return m_diskSystem->GetFileSize(m_path);
45+
}
46+
47+
void ModFileSystem::SetSpecialisationMask(unsigned int specMask)
48+
{
49+
m_specMask = specMask;
50+
51+
// Unset extra bit and set our language mask
52+
m_langMask = specMask & ~0x80000000;
53+
}
54+
55+
unsigned int ModFileSystem::GetSpecialisationMask()
56+
{
57+
return m_specMask;
58+
}
59+
60+
cdc::FileSystem::Status ModFileSystem::GetStatus()
61+
{
62+
return m_diskSystem->GetStatus();
63+
}
64+
65+
void ModFileSystem::Update()
66+
{
67+
m_diskSystem->Update();
68+
}
69+
70+
void ModFileSystem::Synchronize()
71+
{
72+
m_diskSystem->Synchronize();
73+
}

src/file/ModFileSystem.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#pragma once
2+
3+
#include "cdc/file/FileSystem.h"
4+
5+
// So we don't need to include Windows.h here
6+
#define _MAX_PATH 260
7+
8+
// This file system represents a subfolder in the mods oflder
9+
class ModFileSystem : public cdc::FileSystem
10+
{
11+
private:
12+
cdc::FileSystem* m_diskSystem;
13+
14+
unsigned int m_specMask;
15+
unsigned int m_langMask;
16+
17+
char m_basePath[_MAX_PATH];
18+
char m_path[_MAX_PATH];
19+
20+
// Finds a file and returns whether it exists and the rewritten path
21+
bool FindFile(const char* fileName, char* path) const noexcept;
22+
23+
public:
24+
ModFileSystem(const char* path);
25+
26+
cdc::FileRequest* RequestRead(cdc::FileReceiver* receiver, const char* fileName, unsigned int startOffset);
27+
cdc::File* OpenFile(const char* fileName);
28+
bool FileExists(const char* fileName);
29+
unsigned int GetFileSize(const char* fileName);
30+
void SetSpecialisationMask(unsigned int specMask);
31+
unsigned int GetSpecialisationMask();
32+
Status GetStatus();
33+
void Update();
34+
void Synchronize();
35+
36+
#ifdef TR8
37+
void Suspend();
38+
bool Resume();
39+
bool IsSuspended();
40+
char* GetBufferPointer(cdc::FileRequest* request, unsigned int* bytesLocked);
41+
void ResetBufferPointer(int value);
42+
#endif
43+
};

src/file/MultiFileSystem.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "MultiFileSystem.h"
22

3+
#include "Hook.h"
4+
#include "modules/Log.h"
5+
36
MultiFileSystem::MultiFileSystem() : m_fileSystems()
47
{
58
}
@@ -21,6 +24,8 @@ cdc::FileSystem* MultiFileSystem::GetBestFileSystem(const char* fileName)
2124
void MultiFileSystem::Add(cdc::FileSystem* fileSystem)
2225
{
2326
m_fileSystems.push_back(fileSystem);
27+
28+
Hook::GetInstance().GetModule<Log>()->WriteLine("Mounted new file system %p, number of systems: %d", fileSystem, m_fileSystems.size());
2429
}
2530

2631
void MultiFileSystem::Remove(cdc::FileSystem* fileSystem)

src/modules/ModLoader.cpp

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22
#include <MinHook.h>
33

44
#include "ModLoader.h"
5+
#include "Hook.h"
6+
#include "Log.h"
57
#include "util/Hooking.h"
68

79
#include "cdc/file/MultiFileSystem.h"
10+
#include "cdc/file/ArchiveFileSystem.h"
811

912
#include "file/FileSystem.h"
1013
#include "file/HookFileSystem.h"
1114
#include "file/MultiFileSystem.h"
15+
#include "file/ModFileSystem.h"
16+
17+
static ModLoader* loader = nullptr;
1218

1319
static cdc::FileSystem* CreateHookFileSystem()
1420
{
@@ -43,10 +49,9 @@ static void InitArchive()
4349

4450
// Create our hook file system and multi file system
4551
auto fileSystem = CreateHookFileSystem();
46-
auto multiFileSystem = new MultiFileSystem();
52+
auto multiFileSystem = loader->GetFileSystem();
4753

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

5156
multiFileSystem->Add(fileSystem);
5257
multiFileSystem->Add(GetFS());
@@ -56,13 +61,67 @@ static void InitArchive()
5661
}
5762

5863
// Initialize the mod loader and insert all hooks
59-
ModLoader::ModLoader()
64+
ModLoader::ModLoader() : m_fileSystem()
6065
{
66+
loader = this;
67+
6168
#ifndef TR8
6269
MH_CreateHook((void*)GET_ADDRESS(0x45C670, 0x45F5B0, 0x473840), InitArchive, (void**)&s_InitArchive);
6370
#else
6471
MH_CreateHook((void*)0x478930, InitPatchArchive, (void**)&s_InitPatchArchive);
6572
#endif
6673

6774
MH_EnableHook(MH_ALL_HOOKS);
75+
}
76+
77+
void ModLoader::MountMods()
78+
{
79+
auto log = Hook::GetInstance().GetModule<Log>();
80+
81+
for (auto& entry : std::filesystem::directory_iterator("mods"))
82+
{
83+
auto name = entry.path().filename();
84+
85+
// Mount files with bigfile extension as archive
86+
if (entry.is_regular_file() && name.extension() == ".000")
87+
{
88+
log->WriteLine("Mounting mod archive %s", name.string().c_str());
89+
90+
MountArchive(name);
91+
}
92+
93+
// Mount folders as new mod file system
94+
if (entry.is_directory())
95+
{
96+
log->WriteLine("Mounting mod directory %s", name.string().c_str());
97+
98+
MountDirectory(name);
99+
}
100+
}
101+
}
102+
103+
void ModLoader::MountArchive(std::filesystem::path& name) noexcept
104+
{
105+
auto path = "mods" / name;
106+
107+
// Open the archive
108+
auto archive = new cdc::ArchiveFileSystem(*(cdc::FileSystem**)0x838890);
109+
archive->Open(path.string().c_str());
110+
111+
// Mount the archive
112+
m_fileSystem.Add((cdc::FileSystem*)archive);
113+
}
114+
115+
void ModLoader::MountDirectory(std::filesystem::path& name) noexcept
116+
{
117+
auto path = "mods" / name;
118+
auto fileSystem = new ModFileSystem(name.string().c_str());
119+
120+
// Mount the file system
121+
m_fileSystem.Add(fileSystem);
122+
}
123+
124+
MultiFileSystem* ModLoader::GetFileSystem() noexcept
125+
{
126+
return &m_fileSystem;
68127
}

src/modules/ModLoader.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
#pragma once
22

3+
#include <filesystem>
4+
35
#include "Module.h"
6+
#include "file/MultiFileSystem.h"
47

58
class ModLoader : public Module
69
{
10+
private:
11+
MultiFileSystem m_fileSystem;
12+
13+
void MountArchive(std::filesystem::path& name) noexcept;
14+
void MountDirectory(std::filesystem::path& name) noexcept;
15+
716
public:
817
ModLoader();
18+
void MountMods();
19+
20+
MultiFileSystem* GetFileSystem() noexcept;
921
};

0 commit comments

Comments
 (0)