mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #5746 from IntelOrca/fix/5507
Fix #5507: RCT1 path check is case-sensitive on Linux
This commit is contained in:
commit
cb28381990
|
@ -14,6 +14,10 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../platform/platform.h"
|
||||
|
@ -21,6 +25,7 @@ extern "C"
|
|||
#include "../util/util.h"
|
||||
}
|
||||
|
||||
#include "File.h"
|
||||
#include "Math.hpp"
|
||||
#include "Memory.hpp"
|
||||
#include "Path.hpp"
|
||||
|
@ -218,4 +223,45 @@ namespace Path
|
|||
#endif
|
||||
return String::Equals(a, b, ignoreCase);
|
||||
}
|
||||
|
||||
std::string ResolveCasing(const std::string &path)
|
||||
{
|
||||
std::string result;
|
||||
if (File::Exists(path))
|
||||
{
|
||||
// Windows is case insensitive so it will exist and that is all that matters
|
||||
// for now. We can properly resolve the casing if we ever need to.
|
||||
result = path;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
else
|
||||
{
|
||||
std::string fileName = Path::GetFileName(path);
|
||||
std::string directory = Path::GetDirectory(path);
|
||||
|
||||
struct dirent * * files;
|
||||
auto count = scandir(directory.c_str(), &files, nullptr, alphasort);
|
||||
if (count != -1)
|
||||
{
|
||||
// Find a file which matches by name (case insensitive)
|
||||
for (sint32 i = 0; i < count; i++)
|
||||
{
|
||||
if (String::Equals(files[i]->d_name, fileName.c_str(), true))
|
||||
{
|
||||
result = Path::Combine(directory, std::string(files[i]->d_name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Free memory
|
||||
for (sint32 i = 0; i < count; i++)
|
||||
{
|
||||
free(files[i]);
|
||||
}
|
||||
free(files);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,4 +43,12 @@ namespace Path
|
|||
utf8 * GetAbsolute(utf8 * buffer, size_t bufferSize, const utf8 * relativePath);
|
||||
bool Equals(const std::string &a, const std::string &b);
|
||||
bool Equals(const utf8 * a, const utf8 * b);
|
||||
|
||||
/**
|
||||
* Checks if the given path is a file. If not, checks to see if
|
||||
* there are any files with different casing and selects the first
|
||||
* one found based on a straight forward character sort.
|
||||
* Note: This will not resolve the case for Windows.
|
||||
*/
|
||||
std::string ResolveCasing(const std::string &path);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "../core/File.h"
|
||||
#include "../core/FileStream.hpp"
|
||||
#include "../core/Memory.hpp"
|
||||
#include "../core/Path.hpp"
|
||||
#include "../core/Util.hpp"
|
||||
#include "../OpenRCT2.h"
|
||||
#include "../sprites.h"
|
||||
|
@ -188,6 +189,44 @@ extern "C"
|
|||
return false;
|
||||
}
|
||||
|
||||
static utf8 * gfx_get_csg_header_path()
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
safe_strcpy(path, gConfigGeneral.rct1_path, sizeof(path));
|
||||
safe_strcat_path(path, "Data", sizeof(path));
|
||||
safe_strcat_path(path, "csg1i.dat", sizeof(path));
|
||||
|
||||
auto fixedPath = Path::ResolveCasing(path);
|
||||
utf8 * fixedPathC = new utf8[fixedPath.size() + 1];
|
||||
Memory::Copy(fixedPathC, fixedPath.data(), fixedPath.size() + 1);
|
||||
return fixedPathC;
|
||||
}
|
||||
|
||||
static utf8 * gfx_get_csg_data_path()
|
||||
{
|
||||
// csg1.1 and csg1.dat are the same file.
|
||||
// In the CD version, it's called csg1.1 on the CD and csg1.dat on the disk.
|
||||
// In the GOG version, it's always called csg1.1.
|
||||
// In the Steam version, it's always called csg1.dat.
|
||||
char path[MAX_PATH];
|
||||
safe_strcpy(path, gConfigGeneral.rct1_path, sizeof(path));
|
||||
safe_strcat_path(path, "Data", sizeof(path));
|
||||
safe_strcat_path(path, "csg1.1", sizeof(path));
|
||||
|
||||
auto fixedPath = Path::ResolveCasing(path);
|
||||
if (fixedPath.empty())
|
||||
{
|
||||
safe_strcpy(path, gConfigGeneral.rct1_path, sizeof(path));
|
||||
safe_strcat_path(path, "Data", sizeof(path));
|
||||
safe_strcat_path(path, "csg1.dat", sizeof(path));
|
||||
fixedPath = Path::ResolveCasing(path);
|
||||
}
|
||||
|
||||
utf8 * fixedPathC = new utf8[fixedPath.size() + 1];
|
||||
Memory::Copy(fixedPathC, fixedPath.data(), fixedPath.size() + 1);
|
||||
return fixedPathC;
|
||||
}
|
||||
|
||||
bool gfx_load_csg()
|
||||
{
|
||||
log_verbose("gfx_load_csg()");
|
||||
|
@ -198,31 +237,12 @@ extern "C"
|
|||
return false;
|
||||
}
|
||||
|
||||
char pathHeader[MAX_PATH];
|
||||
safe_strcpy(pathHeader, gConfigGeneral.rct1_path, sizeof(pathHeader));
|
||||
safe_strcat_path(pathHeader, "Data", sizeof(pathHeader));
|
||||
safe_strcat_path(pathHeader, "csg1i.dat", sizeof(pathHeader));
|
||||
|
||||
// csg1.1 and csg1.dat are the same file.
|
||||
// In the CD version, it's called csg1.1 on the CD and csg1.dat on the disk.
|
||||
// In the GOG version, it's always called csg1.1.
|
||||
// In the Steam version, it's always called csg1.dat.
|
||||
char pathData[MAX_PATH];
|
||||
safe_strcpy(pathData, gConfigGeneral.rct1_path, sizeof(pathData));
|
||||
safe_strcat_path(pathData, "Data", sizeof(pathData));
|
||||
safe_strcat_path(pathData, "csg1.1", sizeof(pathData));
|
||||
|
||||
if (!File::Exists(pathData))
|
||||
{
|
||||
safe_strcpy(pathData, gConfigGeneral.rct1_path, sizeof(pathData));
|
||||
safe_strcat_path(pathData, "Data", sizeof(pathData));
|
||||
safe_strcat_path(pathData, "csg1.dat", sizeof(pathData));
|
||||
}
|
||||
|
||||
auto pathHeaderPath = std::unique_ptr<utf8[]>(gfx_get_csg_header_path());
|
||||
auto pathDataPath = std::unique_ptr<utf8[]>(gfx_get_csg_data_path());
|
||||
try
|
||||
{
|
||||
auto fileHeader = FileStream(pathHeader, FILE_MODE_OPEN);
|
||||
auto fileData = FileStream(pathData, FILE_MODE_OPEN);
|
||||
auto fileHeader = FileStream(pathHeaderPath.get(), FILE_MODE_OPEN);
|
||||
auto fileData = FileStream(pathDataPath.get(), FILE_MODE_OPEN);
|
||||
size_t fileHeaderSize = fileHeader.GetLength();
|
||||
size_t fileDataSize = fileData.GetLength();
|
||||
|
||||
|
|
Loading…
Reference in New Issue