Skip to content

Commit

Permalink
Improve MultiFileSystem to allow more file systems
Browse files Browse the repository at this point in the history
  • Loading branch information
TheIndra55 committed May 14, 2024
1 parent 8e53227 commit b3091ee
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 34 deletions.
14 changes: 14 additions & 0 deletions src/cdc/file/ArchiveFileSystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "ArchiveFileSystem.h"

#include "util/Hooking.h"

cdc::ArchiveFileSystem::ArchiveFileSystem(FileSystem* pDiskFS)
{
// Call the original constructor
Hooking::ThisCall(0x47E0D0, this, pDiskFS);
}

bool cdc::ArchiveFileSystem::Open(const char* archiveFileName)
{
return Hooking::ThisCallReturn<bool>(0x47DDF0, this, archiveFileName);
}
14 changes: 14 additions & 0 deletions src/cdc/file/ArchiveFileSystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include "FileSystem.h"

namespace cdc
{
class ArchiveFileSystem : public FileSystem
{
public:
ArchiveFileSystem(FileSystem* pDiskFS);

bool Open(const char* archiveFileName);
};
}
2 changes: 1 addition & 1 deletion src/cdc/file/MultiFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace cdc
{
class MultiFileSystem : public cdc::FileSystem
class MultiFileSystem : public FileSystem
{
public:
void Add(FileSystem* fileSystem, bool bReprioritize, bool bAddToFront);
Expand Down
80 changes: 56 additions & 24 deletions src/file/MultiFileSystem.cpp
Original file line number Diff line number Diff line change
@@ -1,73 +1,105 @@
#include "MultiFileSystem.h"
#include "MultiFileSystem.h"

MultiFileSystem::MultiFileSystem(cdc::FileSystem* pFS, cdc::FileSystem* pHookFS)
MultiFileSystem::MultiFileSystem() : m_fileSystems()
{
m_pFS = pFS;
m_pHookFS = pHookFS;
}

// Gets the best file system for a file simply by checking the hook file system first
// Gets the best file system for a file by checking all file systems
cdc::FileSystem* MultiFileSystem::GetBestFileSystem(const char* fileName)
{
// First check the hook file system, else fall back to default filesystem
if (m_pHookFS->FileExists(fileName))
for (auto fileSystem : m_fileSystems)
{
return m_pHookFS;
if (fileSystem->FileExists(fileName))
{
return fileSystem;
}
}

return m_pFS;
return nullptr;
}

void MultiFileSystem::Add(cdc::FileSystem* fileSystem)
{
m_fileSystems.push_back(fileSystem);
}

cdc::FileRequest* MultiFileSystem::RequestRead(cdc::FileReceiver* receiver, const char* fileName, unsigned int startOffset)
{
auto pFS = GetBestFileSystem(fileName);
auto fileSystem = GetBestFileSystem(fileName);

return pFS->RequestRead(receiver, fileName, startOffset);
return fileSystem->RequestRead(receiver, fileName, startOffset);
}

cdc::File* MultiFileSystem::OpenFile(char const* fileName)
{
auto pFS = GetBestFileSystem(fileName);
auto fileSystem = GetBestFileSystem(fileName);

return pFS->OpenFile(fileName);
return fileSystem->OpenFile(fileName);
}

bool MultiFileSystem::FileExists(char const* fileName)
{
return m_pFS->FileExists(fileName) || m_pHookFS->FileExists(fileName);
for (auto fileSystem : m_fileSystems)
{
if (fileSystem->FileExists(fileName))
{
return true;
}
}

return false;
}

unsigned int MultiFileSystem::GetFileSize(char const* fileName)
{
auto pFS = GetBestFileSystem(fileName);
auto fileSystem = GetBestFileSystem(fileName);

return pFS->GetFileSize(fileName);
return fileSystem->GetFileSize(fileName);
}

void MultiFileSystem::SetSpecialisationMask(unsigned int specMask)
{
m_pFS->SetSpecialisationMask(specMask);
m_pHookFS->SetSpecialisationMask(specMask);
for (auto fileSystem : m_fileSystems)
{
fileSystem->SetSpecialisationMask(specMask);
}
}

unsigned int MultiFileSystem::GetSpecialisationMask()
{
return m_pFS->GetSpecialisationMask();
}
if (m_fileSystems.empty())
{
return 0xFFFFFFFF;
}

// These only need to call the default file system, both will end at the same place
return m_fileSystems[0]->GetSpecialisationMask();
}

cdc::FileSystem::Status MultiFileSystem::GetStatus()
{
return m_pFS->GetStatus();
for (auto fileSystem : m_fileSystems)
{
if (fileSystem->GetStatus() == BUSY)
{
return BUSY;
}
}

return IDLE;
}

void MultiFileSystem::Update()
{
m_pFS->Update();
for (auto fileSystem : m_fileSystems)
{
fileSystem->Update();
}
}

void MultiFileSystem::Synchronize()
{
m_pFS->Synchronize();
for (auto fileSystem : m_fileSystems)
{
fileSystem->Synchronize();
}
}
13 changes: 5 additions & 8 deletions src/file/MultiFileSystem.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
#pragma once

#include <vector>

#include "cdc/file/FileSystem.h"

// Simplified version for cdc::MultiFileSystem since it does not exist in Legend and Anniversary
// The real MultiFileSystem can dynamically add and re-order systems
//
// This just checks the hook file system first and else falls back to the
// original file system
class MultiFileSystem : public cdc::FileSystem
{
private:
cdc::FileSystem* m_pFS;
cdc::FileSystem* m_pHookFS;
std::vector<FileSystem*> m_fileSystems;

cdc::FileSystem* GetBestFileSystem(const char* fileName);
public:
MultiFileSystem(cdc::FileSystem* pFS, cdc::FileSystem* pHookFS);
MultiFileSystem();
void Add(cdc::FileSystem* fileSystem);

cdc::FileRequest* RequestRead(cdc::FileReceiver* receiver, const char* fileName, unsigned int startOffset);
cdc::File* OpenFile(const char* fileName);
Expand Down
8 changes: 7 additions & 1 deletion src/modules/ModLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ static void InitArchive()

// Create our hook file system and multi file system
auto fileSystem = CreateHookFileSystem();
auto multiFileSystem = new MultiFileSystem(GetFS(), fileSystem);
auto multiFileSystem = new MultiFileSystem();

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

multiFileSystem->Add(fileSystem);
multiFileSystem->Add(GetFS());

// Overwrite the original file system with ours
*(cdc::FileSystem**)GET_ADDRESS(0x10E58BC, 0x83888C, 0x9CE278) = multiFileSystem;
Expand Down

0 comments on commit b3091ee

Please sign in to comment.