Skip to content

Commit e9835d6

Browse files
committed
fix utf8 filepaths
1 parent 0f8416c commit e9835d6

16 files changed

Lines changed: 74 additions & 24 deletions

File tree

cmake/deps/spdlog.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ FetchContent_Declare(spdlog
1010
message(STATUS "Fetch spdlog ...")
1111
option(SPDLOG_DISABLE_DEFAULT_LOGGER "" ON)
1212
option(SPDLOG_BUILD_PIC "" "${SATISFACTORY3DMAP_BUILD_PIC}")
13+
if (WIN32)
14+
option(SPDLOG_WCHAR_FILENAMES "" ON)
15+
endif ()
1316
FetchContent_MakeAvailable(spdlog)
1417
set_target_properties(spdlog PROPERTIES
1518
FOLDER libs

libsave/include/SatisfactorySave/IO/IOStream.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <string>
1111
#include <vector>
1212

13+
#include "../Utils/StringUtils.h"
1314
#include "satisfactorysave_export.h"
1415

1516
namespace SatisfactorySave {
@@ -156,7 +157,7 @@ namespace SatisfactorySave {
156157
file_.exceptions(std::ifstream::badbit);
157158
file_.open(path, std::ios::binary);
158159
if (!file_.is_open()) {
159-
throw std::runtime_error("FileIStream: Failed to open file for reading: " + path.string());
160+
throw std::runtime_error("FileIStream: Failed to open file for reading: " + pathToString(path));
160161
}
161162
file_.seekg(0, std::ios::end);
162163
size_ = static_cast<pos_type>(file_.tellg());
@@ -222,7 +223,7 @@ namespace SatisfactorySave {
222223
file_.exceptions(std::ofstream::badbit);
223224
file_.open(path, std::ios::binary | std::ios::trunc);
224225
if (!file_.is_open()) {
225-
throw std::runtime_error("FileOStream: Failed to open file for writing: " + path.string());
226+
throw std::runtime_error("FileOStream: Failed to open file for writing: " + pathToString(path));
226227
}
227228
}
228229

libsave/include/SatisfactorySave/Utils/StringUtils.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,27 @@
55
#include <functional>
66
#include <sstream>
77
#include <string>
8+
#include <string_view>
89
#include <vector>
910

1011
#include "satisfactorysave_export.h"
1112

1213
namespace SatisfactorySave {
14+
static inline std::filesystem::path toPath(std::string_view s) {
15+
return {std::u8string(s.begin(), s.end())};
16+
}
17+
18+
static inline std::filesystem::path toPath(const char* s) {
19+
if (s == nullptr) {
20+
return {};
21+
}
22+
return toPath(std::string_view(s));
23+
}
24+
25+
static inline std::string pathToString(const std::filesystem::path& p) {
26+
std::u8string u8 = p.u8string();
27+
return {u8.begin(), u8.end()};
28+
}
1329

1430
static inline std::vector<std::string> splitPathName(const std::string& name) {
1531
std::vector<std::string> result;
@@ -26,9 +42,9 @@ namespace SatisfactorySave {
2642
static inline std::vector<std::string> splitPathName(const std::filesystem::path& path) {
2743
std::vector<std::string> segments;
2844
for (const auto& element : path) {
29-
const auto& s = element.string();
30-
if (!s.empty() && s != "/") {
31-
segments.push_back(s);
45+
const auto& s = element.u8string();
46+
if (!s.empty() && s != u8"/") {
47+
segments.emplace_back(s.begin(), s.end());
3248
}
3349
}
3450
return segments;

libsave/src/Pak/IoStoreFile.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "GameTypes/UE/Core/IO/IoStore.h"
44
#include "IO/OodleUtils.h"
5+
#include "Utils/StringUtils.h"
56
#include "Utils/VectorUtils.h"
67

78
SatisfactorySave::DirectoryIndexReader::DirectoryIndexReader(const FIoDirectoryIndexResource& res) : res_(res) {
@@ -43,12 +44,12 @@ SatisfactorySave::IoStoreFile::IoStoreFile(Private p, std::shared_ptr<PakManager
4344
const std::filesystem::path& path)
4445
: AbstractPakFile(p, std::move(pakManager)) {
4546
if (!std::filesystem::is_regular_file(path)) {
46-
throw std::runtime_error("IoStore utoc file invalid: " + path.string());
47+
throw std::runtime_error("IoStore utoc file invalid: " + pathToString(path));
4748
}
4849
std::filesystem::path ucas_path = path;
4950
ucas_path.replace_extension(std::filesystem::path(".ucas"));
5051
if (!std::filesystem::is_regular_file(ucas_path)) {
51-
throw std::runtime_error("IoStore ucas file invalid: " + ucas_path.string());
52+
throw std::runtime_error("IoStore ucas file invalid: " + pathToString(ucas_path));
5253
}
5354

5455
IStreamArchive utocAr(path);

libsave/src/Pak/PakFile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ SatisfactorySave::PakFile::PakFile(Private p, std::shared_ptr<PakManager> pakMan
1212
NumEntries(0),
1313
PathHashSeed(0) {
1414
if (!std::filesystem::is_regular_file(pakPath)) {
15-
throw std::runtime_error("Pak file invalid: " + pakPath.string());
15+
throw std::runtime_error("Pak file invalid: " + pathToString(pakPath));
1616
}
1717

1818
pakAr_ = std::make_unique<IStreamArchive>(pakPath);

libsave/src/Pak/PakManager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "Utils/StringUtils.h"
88

99
void SatisfactorySave::PakManager::init(const std::filesystem::path& gameDir) {
10-
spdlog::info("PakManager init dir: {}", gameDir.string());
10+
spdlog::info("PakManager init dir: {}", pathToString(gameDir));
1111

1212
const std::filesystem::path globalUtocPath = gameDir / "FactoryGame/Content/Paks/global.utoc";
1313
const std::filesystem::path mainPakPath = gameDir / "FactoryGame/Content/Paks/FactoryGame-Windows.pak";
@@ -65,7 +65,7 @@ void SatisfactorySave::PakManager::init(const std::filesystem::path& gameDir) {
6565
// Check if dirname matches "<ModName>/Content/Paks/Windows", if we find pak/utoc files with a different
6666
// structure, the assumptions made on fixing path names are probably not matching.
6767
const auto filePath = std::filesystem::canonical(dirEntry.path());
68-
spdlog::info("Found pak/utoc file: {}", filePath.string());
68+
spdlog::info("Found pak/utoc file: {}", pathToString(filePath));
6969
std::filesystem::path relativePath = std::filesystem::relative(filePath, modsDir);
7070
const auto pathSegments = splitPathName(relativePath);
7171
if (pathSegments.size() < 4 || pathSegments[1] != "Content" || pathSegments[2] != "Paks" ||

map/src/MapWindow/BaseWindow.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
#include <implot3d.h>
1212
#include <spdlog/spdlog.h>
1313

14+
#include "SatisfactorySave/Utils/StringUtils.h"
15+
1416
#include "Utils/GLUtil.h"
1517
#include "Utils/ResourceUtils.h"
1618

19+
namespace s = SatisfactorySave;
20+
1721
namespace {
1822
// GLFW mods parameter is not platform independent, see https://github.com/glfw/glfw/issues/1630.
1923
inline int fixKeyboardMods(int mods, int key, int action) {
@@ -157,10 +161,10 @@ Satisfactory3DMap::BaseWindow::BaseWindow(std::string title, int width, int heig
157161
}
158162
});
159163
glfwSetDropCallback(window_, [](GLFWwindow* window, int path_count, const char* paths[]) {
160-
std::vector<std::string> path_list;
164+
std::vector<std::filesystem::path> path_list;
161165
path_list.reserve(path_count);
162166
for (int i = 0; i < path_count; i++) {
163-
path_list.emplace_back(std::string(paths[i]));
167+
path_list.emplace_back(s::toPath(paths[i]));
164168
}
165169
static_cast<BaseWindow*>(glfwGetWindowUserPointer(window))->dropEvent(path_list);
166170
});

map/src/MapWindow/BaseWindow.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <filesystem>
34
#include <memory>
45
#include <string>
56
#include <vector>
@@ -31,7 +32,7 @@ namespace Satisfactory3DMap {
3132
[[maybe_unused]] int mods) {}
3233
virtual void mouseMoveEvent([[maybe_unused]] double xpos, [[maybe_unused]] double ypos) {}
3334
virtual void mouseScrollEvent([[maybe_unused]] double xoffset, [[maybe_unused]] double yoffset) {}
34-
virtual void dropEvent([[maybe_unused]] const std::vector<std::string>& paths) {}
35+
virtual void dropEvent([[maybe_unused]] const std::vector<std::filesystem::path>& paths) {}
3536

3637
std::shared_ptr<Configuration> config_;
3738
std::shared_ptr<StringSetting> imguiIniSetting_;

map/src/MapWindow/Config/Configuration.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55

66
#include <spdlog/spdlog.h>
77

8+
#include "SatisfactorySave/Utils/StringUtils.h"
9+
810
#include "Utils/FilesystemUtil.h"
911

12+
namespace s = SatisfactorySave;
13+
1014
Satisfactory3DMap::Configuration::Configuration() {
1115
auto cfgFile = getConfigFile();
1216
if (!std::filesystem::exists(cfgFile)) {
@@ -15,10 +19,10 @@ Satisfactory3DMap::Configuration::Configuration() {
1519
}
1620
cfgFile = std::filesystem::canonical(cfgFile);
1721
if (!std::filesystem::is_regular_file(cfgFile)) {
18-
spdlog::error("Config file path is not a file: {}", cfgFile.string());
22+
spdlog::error("Config file path is not a file: {}", s::pathToString(cfgFile));
1923
return;
2024
}
21-
spdlog::info("Read config file: {}", cfgFile.string());
25+
spdlog::info("Read config file: {}", s::pathToString(cfgFile));
2226
try {
2327
std::ifstream file(cfgFile);
2428
file >> json_;

map/src/MapWindow/Config/PathSetting.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#include "PathSetting.h"
22

3+
#include "SatisfactorySave/Utils/StringUtils.h"
4+
35
#include "SettingVisitor.h"
46

7+
namespace s = SatisfactorySave;
8+
59
void Satisfactory3DMap::PathSetting::accept(Satisfactory3DMap::SettingVisitor& v) {
610
v.visit(*this);
711
}
@@ -15,7 +19,7 @@ void Satisfactory3DMap::PathSetting::serializeFromJson(const nlohmann::json& j)
1519
}
1620

1721
void Satisfactory3DMap::PathSetting::serializeToJson(nlohmann::json& j) {
18-
j = value_.string();
22+
j = s::pathToString(value_);
1923
}
2024

2125
bool Satisfactory3DMap::PathSetting::validate(const std::filesystem::path& path) {

0 commit comments

Comments
 (0)