mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2025-12-23 08:22:29 +00:00
Improve error message behavior on installer for invalid sources. (#77)
This commit is contained in:
parent
5f9fdcf934
commit
5c98a34084
8 changed files with 51 additions and 15 deletions
|
|
@ -7,10 +7,12 @@
|
||||||
struct DirectoryFileSystem : VirtualFileSystem
|
struct DirectoryFileSystem : VirtualFileSystem
|
||||||
{
|
{
|
||||||
std::filesystem::path directoryPath;
|
std::filesystem::path directoryPath;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
DirectoryFileSystem(const std::filesystem::path &directoryPath)
|
DirectoryFileSystem(const std::filesystem::path &directoryPath)
|
||||||
{
|
{
|
||||||
this->directoryPath = directoryPath;
|
this->directoryPath = directoryPath;
|
||||||
|
name = (const char *)(directoryPath.filename().u8string().data());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load(const std::string &path, uint8_t *fileData, size_t fileDataMaxByteCount) const override
|
bool load(const std::string &path, uint8_t *fileData, size_t fileDataMaxByteCount) const override
|
||||||
|
|
@ -51,6 +53,11 @@ struct DirectoryFileSystem : VirtualFileSystem
|
||||||
return std::filesystem::exists(directoryPath / std::filesystem::path(std::u8string_view((const char8_t *)(path.c_str()))));
|
return std::filesystem::exists(directoryPath / std::filesystem::path(std::u8string_view((const char8_t *)(path.c_str()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string &getName() const override
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
static std::unique_ptr<VirtualFileSystem> create(const std::filesystem::path &directoryPath)
|
static std::unique_ptr<VirtualFileSystem> create(const std::filesystem::path &directoryPath)
|
||||||
{
|
{
|
||||||
if (std::filesystem::exists(directoryPath))
|
if (std::filesystem::exists(directoryPath))
|
||||||
|
|
|
||||||
|
|
@ -73,14 +73,14 @@ static bool copyFile(const FilePair &pair, const uint64_t *fileHashes, VirtualFi
|
||||||
if (!sourceVfs.exists(filename))
|
if (!sourceVfs.exists(filename))
|
||||||
{
|
{
|
||||||
journal.lastResult = Journal::Result::FileMissing;
|
journal.lastResult = Journal::Result::FileMissing;
|
||||||
journal.lastErrorMessage = fmt::format("File {} does not exist in the file system.", filename);
|
journal.lastErrorMessage = fmt::format("File {} does not exist in {}.", filename, sourceVfs.getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sourceVfs.load(filename, fileData))
|
if (!sourceVfs.load(filename, fileData))
|
||||||
{
|
{
|
||||||
journal.lastResult = Journal::Result::FileReadFailed;
|
journal.lastResult = Journal::Result::FileReadFailed;
|
||||||
journal.lastErrorMessage = fmt::format("Failed to read file {} from the file system.", filename);
|
journal.lastErrorMessage = fmt::format("Failed to read file {} from {}.", filename, sourceVfs.getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,7 +96,7 @@ static bool copyFile(const FilePair &pair, const uint64_t *fileHashes, VirtualFi
|
||||||
if (!fileHashFound)
|
if (!fileHashFound)
|
||||||
{
|
{
|
||||||
journal.lastResult = Journal::Result::FileHashFailed;
|
journal.lastResult = Journal::Result::FileHashFailed;
|
||||||
journal.lastErrorMessage = fmt::format("File {} from the file system did not match any of the known hashes.", filename);
|
journal.lastErrorMessage = fmt::format("File {} from {} did not match any of the known hashes.", filename, sourceVfs.getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -150,7 +150,7 @@ static DLC detectDLC(const std::filesystem::path &sourcePath, VirtualFileSystem
|
||||||
if (!sourceVfs.load(DLCValidationFile, dlcXmlBytes))
|
if (!sourceVfs.load(DLCValidationFile, dlcXmlBytes))
|
||||||
{
|
{
|
||||||
journal.lastResult = Journal::Result::FileMissing;
|
journal.lastResult = Journal::Result::FileMissing;
|
||||||
journal.lastErrorMessage = fmt::format("File {} does not exist in the file system.", DLCValidationFile);
|
journal.lastErrorMessage = fmt::format("File {} does not exist in {}.", DLCValidationFile, sourceVfs.getName());
|
||||||
return DLC::Unknown;
|
return DLC::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,7 +164,7 @@ static DLC detectDLC(const std::filesystem::path &sourcePath, VirtualFileSystem
|
||||||
if (typeStartLocation == nullptr || typeEndLocation == nullptr)
|
if (typeStartLocation == nullptr || typeEndLocation == nullptr)
|
||||||
{
|
{
|
||||||
journal.lastResult = Journal::Result::DLCParsingFailed;
|
journal.lastResult = Journal::Result::DLCParsingFailed;
|
||||||
journal.lastErrorMessage = "Failed to find DLC type for " + fromPath(sourcePath) + ".";
|
journal.lastErrorMessage = fmt::format("Failed to find DLC type for {}.", sourceVfs.getName());
|
||||||
return DLC::Unknown;
|
return DLC::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,7 +173,7 @@ static DLC detectDLC(const std::filesystem::path &sourcePath, VirtualFileSystem
|
||||||
if (typeNumberCount != 1)
|
if (typeNumberCount != 1)
|
||||||
{
|
{
|
||||||
journal.lastResult = Journal::Result::UnknownDLCType;
|
journal.lastResult = Journal::Result::UnknownDLCType;
|
||||||
journal.lastErrorMessage = "DLC type for " + fromPath(sourcePath) + " is unknown.";
|
journal.lastErrorMessage = fmt::format("DLC type for {} is unknown.", sourceVfs.getName());
|
||||||
return DLC::Unknown;
|
return DLC::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,7 +193,7 @@ static DLC detectDLC(const std::filesystem::path &sourcePath, VirtualFileSystem
|
||||||
return DLC::EmpireCityAdabat;
|
return DLC::EmpireCityAdabat;
|
||||||
default:
|
default:
|
||||||
journal.lastResult = Journal::Result::UnknownDLCType;
|
journal.lastResult = Journal::Result::UnknownDLCType;
|
||||||
journal.lastErrorMessage = "DLC type for " + fromPath(sourcePath) + " is unknown.";
|
journal.lastErrorMessage = fmt::format("DLC type for {} is unknown.", sourceVfs.getName());
|
||||||
return DLC::Unknown;
|
return DLC::Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -246,7 +246,7 @@ bool Installer::computeTotalSize(std::span<const FilePair> filePairs, const uint
|
||||||
if (!sourceVfs.exists(filename))
|
if (!sourceVfs.exists(filename))
|
||||||
{
|
{
|
||||||
journal.lastResult = Journal::Result::FileMissing;
|
journal.lastResult = Journal::Result::FileMissing;
|
||||||
journal.lastErrorMessage = fmt::format("File {} does not exist in the file system.", filename);
|
journal.lastErrorMessage = fmt::format("File {} does not exist in {}.", filename, sourceVfs.getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -300,7 +300,7 @@ bool Installer::copyFiles(std::span<const FilePair> filePairs, const uint64_t *f
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
journal.lastResult = Journal::Result::ValidationFileMissing;
|
journal.lastResult = Journal::Result::ValidationFileMissing;
|
||||||
journal.lastErrorMessage = fmt::format("Unable to find validation file {} in file system.", validationFile);
|
journal.lastErrorMessage = fmt::format("Unable to find validation file {} in {}.", validationFile, sourceVfs.getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,7 +317,7 @@ bool Installer::parseContent(const std::filesystem::path &sourcePath, std::uniqu
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
journal.lastResult = Journal::Result::VirtualFileSystemFailed;
|
journal.lastResult = Journal::Result::VirtualFileSystemFailed;
|
||||||
journal.lastErrorMessage = "Unable to open file system at " + fromPath(sourcePath);
|
journal.lastErrorMessage = "Unable to open " + fromPath(sourcePath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ ISOFileSystem::ISOFileSystem(const std::filesystem::path &isoPath)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = (const char *)(isoPath.filename().u8string().data());
|
||||||
|
|
||||||
// Find root sector.
|
// Find root sector.
|
||||||
const uint8_t *mappedFileData = mappedFile.data();
|
const uint8_t *mappedFileData = mappedFile.data();
|
||||||
uint32_t gameOffset = 0;
|
uint32_t gameOffset = 0;
|
||||||
|
|
@ -173,6 +175,11 @@ bool ISOFileSystem::exists(const std::string &path) const
|
||||||
return fileMap.find(path) != fileMap.end();
|
return fileMap.find(path) != fileMap.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string &ISOFileSystem::getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
bool ISOFileSystem::empty() const
|
bool ISOFileSystem::empty() const
|
||||||
{
|
{
|
||||||
return !mappedFile.isOpen();
|
return !mappedFile.isOpen();
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,13 @@ struct ISOFileSystem : VirtualFileSystem
|
||||||
{
|
{
|
||||||
MemoryMappedFile mappedFile;
|
MemoryMappedFile mappedFile;
|
||||||
std::map<std::string, std::tuple<size_t, size_t>> fileMap;
|
std::map<std::string, std::tuple<size_t, size_t>> fileMap;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
ISOFileSystem(const std::filesystem::path &isoPath);
|
ISOFileSystem(const std::filesystem::path &isoPath);
|
||||||
bool load(const std::string &path, uint8_t *fileData, size_t fileDataMaxByteCount) const override;
|
bool load(const std::string &path, uint8_t *fileData, size_t fileDataMaxByteCount) const override;
|
||||||
size_t getSize(const std::string &path) const override;
|
size_t getSize(const std::string &path) const override;
|
||||||
bool exists(const std::string &path) const override;
|
bool exists(const std::string &path) const override;
|
||||||
|
const std::string &getName() const override;
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
|
||||||
static std::unique_ptr<ISOFileSystem> create(const std::filesystem::path &isoPath);
|
static std::unique_ptr<ISOFileSystem> create(const std::filesystem::path &isoPath);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ struct VirtualFileSystem {
|
||||||
virtual bool load(const std::string &path, uint8_t *fileData, size_t fileDataMaxByteCount) const = 0;
|
virtual bool load(const std::string &path, uint8_t *fileData, size_t fileDataMaxByteCount) const = 0;
|
||||||
virtual size_t getSize(const std::string &path) const = 0;
|
virtual size_t getSize(const std::string &path) const = 0;
|
||||||
virtual bool exists(const std::string &path) const = 0;
|
virtual bool exists(const std::string &path) const = 0;
|
||||||
|
virtual const std::string &getName() const = 0;
|
||||||
|
|
||||||
// Concrete implementation shortcut.
|
// Concrete implementation shortcut.
|
||||||
bool load(const std::string &path, std::vector<uint8_t> &fileData)
|
bool load(const std::string &path, std::vector<uint8_t> &fileData)
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,8 @@ XContentFileSystem::XContentFileSystem(const std::filesystem::path &contentPath)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = (const char *)(contentPath.filename().u8string().data());
|
||||||
|
|
||||||
const uint8_t *rootMappedFileData = rootMappedFile.data();
|
const uint8_t *rootMappedFileData = rootMappedFile.data();
|
||||||
if (sizeof(XContentContainerHeader) > rootMappedFile.size())
|
if (sizeof(XContentContainerHeader) > rootMappedFile.size())
|
||||||
{
|
{
|
||||||
|
|
@ -607,6 +609,11 @@ bool XContentFileSystem::exists(const std::string &path) const
|
||||||
return fileMap.find(path) != fileMap.end();
|
return fileMap.find(path) != fileMap.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string &XContentFileSystem::getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
bool XContentFileSystem::empty() const
|
bool XContentFileSystem::empty() const
|
||||||
{
|
{
|
||||||
return mappedFiles.empty();
|
return mappedFiles.empty();
|
||||||
|
|
|
||||||
|
|
@ -49,11 +49,13 @@ struct XContentFileSystem : VirtualFileSystem
|
||||||
std::vector<MemoryMappedFile> mappedFiles;
|
std::vector<MemoryMappedFile> mappedFiles;
|
||||||
uint64_t baseOffset = 0;
|
uint64_t baseOffset = 0;
|
||||||
std::map<std::string, File> fileMap;
|
std::map<std::string, File> fileMap;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
XContentFileSystem(const std::filesystem::path &contentPath);
|
XContentFileSystem(const std::filesystem::path &contentPath);
|
||||||
bool load(const std::string &path, uint8_t *fileData, size_t fileDataMaxByteCount) const override;
|
bool load(const std::string &path, uint8_t *fileData, size_t fileDataMaxByteCount) const override;
|
||||||
size_t getSize(const std::string &path) const override;
|
size_t getSize(const std::string &path) const override;
|
||||||
bool exists(const std::string &path) const override;
|
bool exists(const std::string &path) const override;
|
||||||
|
const std::string &getName() const override;
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
|
||||||
static std::unique_ptr<XContentFileSystem> create(const std::filesystem::path &contentPath);
|
static std::unique_ptr<XContentFileSystem> create(const std::filesystem::path &contentPath);
|
||||||
|
|
|
||||||
|
|
@ -1123,7 +1123,7 @@ static void InstallerStart()
|
||||||
g_installerThread = std::make_unique<std::thread>(InstallerThread);
|
g_installerThread = std::make_unique<std::thread>(InstallerThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool InstallerParseSources()
|
static bool InstallerParseSources(std::string &errorMessage)
|
||||||
{
|
{
|
||||||
std::error_code spaceErrorCode;
|
std::error_code spaceErrorCode;
|
||||||
std::filesystem::space_info spaceInfo = std::filesystem::space(g_installPath, spaceErrorCode);
|
std::filesystem::space_info spaceInfo = std::filesystem::space(g_installPath, spaceErrorCode);
|
||||||
|
|
@ -1136,14 +1136,17 @@ static bool InstallerParseSources()
|
||||||
installerInput.gameSource = g_gameSourcePath;
|
installerInput.gameSource = g_gameSourcePath;
|
||||||
installerInput.updateSource = g_updateSourcePath;
|
installerInput.updateSource = g_updateSourcePath;
|
||||||
|
|
||||||
for (std::filesystem::path &path : g_dlcSourcePaths) {
|
for (std::filesystem::path &path : g_dlcSourcePaths)
|
||||||
|
{
|
||||||
if (!path.empty())
|
if (!path.empty())
|
||||||
{
|
{
|
||||||
installerInput.dlcSources.push_back(path);
|
installerInput.dlcSources.push_back(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Installer::parseSources(installerInput, g_installerJournal, g_installerSources);
|
bool sourcesParsed = Installer::parseSources(installerInput, g_installerJournal, g_installerSources);
|
||||||
|
errorMessage = g_installerJournal.lastErrorMessage;
|
||||||
|
return sourcesParsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawNextButton()
|
static void DrawNextButton()
|
||||||
|
|
@ -1195,10 +1198,17 @@ static void DrawNextButton()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dlcInstallerMode = g_gameSourcePath.empty();
|
bool dlcInstallerMode = g_gameSourcePath.empty();
|
||||||
if (!InstallerParseSources())
|
std::string sourcesErrorMessage;
|
||||||
|
if (!InstallerParseSources(sourcesErrorMessage))
|
||||||
{
|
{
|
||||||
// Some of the sources that were provided to the installer are not valid. Restart the file selection process.
|
// Some of the sources that were provided to the installer are not valid. Restart the file selection process.
|
||||||
g_currentMessagePrompt = Localise("Installer_Message_InvalidFiles");
|
std::stringstream stringStream;
|
||||||
|
stringStream << Localise("Installer_Message_InvalidFiles");
|
||||||
|
if (!sourcesErrorMessage.empty()) {
|
||||||
|
stringStream << std::endl << std::endl << sourcesErrorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_currentMessagePrompt = stringStream.str();
|
||||||
g_currentMessagePromptConfirmation = false;
|
g_currentMessagePromptConfirmation = false;
|
||||||
g_currentPage = dlcInstallerMode ? WizardPage::SelectDLC : WizardPage::SelectGameAndUpdate;
|
g_currentPage = dlcInstallerMode ? WizardPage::SelectDLC : WizardPage::SelectGameAndUpdate;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue