Merge pull request #10540 from IntelOrca/fix/10496-non-eng-paths

Fix #10496: Game can't handle path with non-english string
This commit is contained in:
Michael Steenbeek 2020-01-12 10:31:31 +01:00 committed by GitHub
commit 09ac8a0c59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 34 deletions

View File

@ -144,7 +144,7 @@ namespace Path
const std::string GetExtension(const std::string& path)
{
return fs::path{ path }.extension().string();
return fs::u8path(path).extension().string();
}
const utf8* GetExtension(const utf8* path)

View File

@ -42,6 +42,9 @@
#include <unordered_map>
#include <vector>
// windows.h defines CP_UTF8
#undef CP_UTF8
using namespace OpenRCT2;
struct ObjectEntryHash
@ -323,10 +326,8 @@ public:
}
else
{
utf8 path[MAX_PATH];
GetPathForNewObject(path, sizeof(path), objectName);
log_verbose("Adding object: [%s]", objectName);
auto path = GetPathForNewObject(objectName);
try
{
SaveObject(path, objectEntry, data, dataSize);
@ -334,18 +335,15 @@ public:
}
catch (const std::exception&)
{
Console::Error::WriteLine("Failed saving object: [%s] to '%s'.", objectName, path);
Console::Error::WriteLine("Failed saving object: [%s] to '%s'.", objectName, path.c_str());
}
}
}
void AddObjectFromFile(const std::string_view& objectName, const void* data, size_t dataSize) override
{
utf8 path[MAX_PATH];
std::string objectNameString(objectName);
GetPathForNewObject(path, sizeof(path), objectNameString.c_str());
log_verbose("Adding object: [%s]", objectNameString.c_str());
log_verbose("Adding object: [%s]", std::string(objectName).c_str());
auto path = GetPathForNewObject(objectName);
try
{
File::WriteAllBytes(path, data, dataSize);
@ -353,7 +351,7 @@ public:
}
catch (const std::exception&)
{
Console::Error::WriteLine("Failed saving object: [%s] to '%s'.", objectNameString.c_str(), path);
Console::Error::WriteLine("Failed saving object: [%s] to '%s'.", std::string(objectName).c_str(), path.c_str());
}
}
@ -470,7 +468,7 @@ private:
}
static void SaveObject(
const utf8* path, const rct_object_entry* entry, const void* data, size_t dataSize, bool fixChecksum = true)
const std::string_view& path, const rct_object_entry* entry, const void* data, size_t dataSize, bool fixChecksum = true)
{
if (fixChecksum)
{
@ -532,7 +530,7 @@ private:
// Save to file
try
{
auto fs = FileStream(path, FILE_MODE_WRITE);
auto fs = FileStream(std::string(path), FILE_MODE_WRITE);
fs.Write(entry, sizeof(rct_object_entry));
fs.Write(encodedDataBuffer, encodedDataSize);
@ -575,10 +573,31 @@ private:
return salt;
}
void GetPathForNewObject(utf8* buffer, size_t bufferSize, const char* name)
std::string GetPathForNewObject(const std::string_view& name)
{
// Get object directory and create it if it doesn't exist
auto userObjPath = _env->GetDirectoryPath(DIRBASE::USER, DIRID::OBJECT);
Path::CreateDirectory(userObjPath);
// Find a unique file name
auto fileName = GetFileNameForNewObject(name);
auto fullPath = Path::Combine(userObjPath, fileName + ".DAT");
auto counter = 1U;
while (File::Exists(fullPath))
{
counter++;
fullPath = Path::Combine(userObjPath, String::StdFormat("%s-%02X.DAT", fileName.c_str(), counter));
}
return fullPath;
}
std::string GetFileNameForNewObject(const std::string_view& name)
{
// Trim name
char normalisedName[9] = { 0 };
for (int32_t i = 0; i < 8; i++)
auto maxLength = std::min<size_t>(name.size(), 8);
for (size_t i = 0; i < maxLength; i++)
{
if (name[i] != ' ')
{
@ -587,28 +606,12 @@ private:
else
{
normalisedName[i] = '\0';
break;
}
}
const std::string& userObjPath = _env->GetDirectoryPath(DIRBASE::USER, DIRID::OBJECT);
String::Set(buffer, bufferSize, userObjPath.c_str());
platform_ensure_directory_exists(buffer);
Path::Append(buffer, bufferSize, normalisedName);
String::Append(buffer, bufferSize, ".DAT");
uint32_t counter = 2;
for (; platform_file_exists(buffer);)
{
utf8 counterString[8];
snprintf(counterString, sizeof(counterString), "-%02X", counter);
counter++;
String::Set(buffer, bufferSize, userObjPath.c_str());
Path::Append(buffer, bufferSize, normalisedName);
String::Append(buffer, bufferSize, counterString);
String::Append(buffer, bufferSize, ".DAT");
}
// Convert to UTF-8 filename
return String::Convert(normalisedName, CODE_PAGE::CP_1252, CODE_PAGE::CP_UTF8);
}
void WritePackedObject(IStream* stream, const rct_object_entry* entry)