mirror of https://github.com/OpenRCT2/OpenRCT2.git
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:
commit
09ac8a0c59
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue