From d15320b1399c35a1853d911409d6f2bbd187e83b Mon Sep 17 00:00:00 2001 From: LemmusLemmus <63229554+LemmusLemmus@users.noreply.github.com> Date: Wed, 13 Jul 2022 22:53:57 +0200 Subject: [PATCH 1/2] Fix Unicode support for paths on Windows. [1/2] --- GlosSIConfig/UIModel.cpp | 4 ++-- GlosSIConfig/VDFParser.h | 6 +++--- GlosSIConfig/main.cpp | 5 ++--- GlosSITarget/Overlay.cpp | 5 ++++- GlosSITarget/Settings.h | 18 +++++++++--------- GlosSITarget/SteamTarget.cpp | 2 +- GlosSITarget/SteamTarget.h | 2 +- GlosSITarget/main.cpp | 22 +++++++++++++--------- 8 files changed, 35 insertions(+), 29 deletions(-) diff --git a/GlosSIConfig/UIModel.cpp b/GlosSIConfig/UIModel.cpp index 21472bd..f96bfd9 100644 --- a/GlosSIConfig/UIModel.cpp +++ b/GlosSIConfig/UIModel.cpp @@ -39,7 +39,7 @@ UIModel::UIModel() : QObject(nullptr) std::filesystem::create_directories(path); config_path_ = path; - config_dir_name_ = (path /= "Targets").string().data(); + config_dir_name_ = QString::fromStdWString((path /= "Targets").wstring().data()); if (!std::filesystem::exists(path)) std::filesystem::create_directories(path); @@ -58,7 +58,7 @@ void UIModel::readConfigs() std::for_each(entries.begin(), entries.end(), [this](const auto& name) { auto path = config_path_; - path /= config_dir_name_.toStdString(); + path /= config_dir_name_.toStdWString(); path /= name.toStdWString(); QFile file(path); if (!file.open(QIODevice::Text | QIODevice::ReadOnly)) { diff --git a/GlosSIConfig/VDFParser.h b/GlosSIConfig/VDFParser.h index 6200b48..dca5287 100644 --- a/GlosSIConfig/VDFParser.h +++ b/GlosSIConfig/VDFParser.h @@ -326,7 +326,7 @@ class Parser { { VDFFile vdffile; - ifile.open(path.string(), std::ios::binary | std::ios::in); + ifile.open(path, std::ios::binary | std::ios::in); if (!ifile.is_open()) { return {}; } @@ -489,9 +489,9 @@ class Parser { static inline bool writeShortcuts(std::filesystem::path path, const VDFFile& vdffile) { - const auto copied = std::filesystem::copy_file(path, path.string() + ".bak", std::filesystem::copy_options::update_existing); + const auto copied = std::filesystem::copy_file(path, path.wstring() + L".bak", std::filesystem::copy_options::update_existing); - ofile.open(path.string(), std::ios::binary | std::ios::out); + ofile.open(path.wstring(), std::ios::binary | std::ios::out); if (!ofile.is_open()) { return false; } diff --git a/GlosSIConfig/main.cpp b/GlosSIConfig/main.cpp index e3da593..91fc322 100644 --- a/GlosSIConfig/main.cpp +++ b/GlosSIConfig/main.cpp @@ -106,7 +106,6 @@ void myMessageHandler(QtMsgType type, const QMessageLogContext&, const QString& std::cout << txt.toStdString() << "\n"; } - int main(int argc, char* argv[]) { @@ -140,14 +139,14 @@ int main(int argc, char* argv[]) if (argc >= 4) { if (QString::fromStdString(argv[1]) == "remove") { const auto write_res = uimodel.removeFromSteam( - QString::fromStdString(argv[2]), QString::fromStdString(argv[3]), true); + QCoreApplication::arguments().at(2), QCoreApplication::arguments().at(3), true); if (write_res) { return 0; } return 1; } else if (QString::fromStdString(argv[1]) == "add") { const auto write_res = uimodel.addToSteam( - QString::fromStdString(argv[2]), QString::fromStdString(argv[3]), true); + QCoreApplication::arguments().at(2), QCoreApplication::arguments().at(3), true); if (write_res) { return 0; } diff --git a/GlosSITarget/Overlay.cpp b/GlosSITarget/Overlay.cpp index d84a938..d317175 100644 --- a/GlosSITarget/Overlay.cpp +++ b/GlosSITarget/Overlay.cpp @@ -17,6 +17,8 @@ limitations under the License. #include #include +#include +#include #include "Roboto.h" @@ -53,7 +55,8 @@ Overlay::Overlay( if (!std::filesystem::exists(config_path)) std::filesystem::create_directories(config_path); config_path /= "imgui.ini"; - config_file_name_ = config_path.string(); + // This assumes that char is utf8 and wchar_t is utf16, which is guaranteed on Windows. + config_file_name_ = std::wstring_convert>().to_bytes(config_path.wstring()); io.IniFilename = config_file_name_.data(); #endif diff --git a/GlosSITarget/Settings.h b/GlosSITarget/Settings.h index f538260..63b5afd 100644 --- a/GlosSITarget/Settings.h +++ b/GlosSITarget/Settings.h @@ -20,6 +20,8 @@ limitations under the License. #include #include #include +#include +#include namespace Settings { @@ -62,10 +64,10 @@ inline bool checkIsUwp(const std::wstring& launch_path) return false; } -inline void Parse(std::string arg1) +inline void Parse(std::wstring arg1) { - if (!arg1.ends_with(".json")) { - arg1 += ".json"; + if (!arg1.ends_with(L".json")) { + arg1 += L".json"; } std::filesystem::path path(arg1); if (path.has_extension() && !std::filesystem::exists(path)) { @@ -82,7 +84,7 @@ inline void Parse(std::string arg1) std::ifstream json_file; json_file.open(path); if (!json_file.is_open()) { - spdlog::error("Couldn't open settings file {}", path.string()); + spdlog::error(L"Couldn't open settings file {}", path.wstring()); return; } const auto json = nlohmann::json::parse(json_file); @@ -111,10 +113,8 @@ inline void Parse(std::string arg1) std::string meh; safeParseValue(object, key, meh); if (!meh.empty()) { - value.clear(); - std::ranges::transform(meh, std::back_inserter(value), [](const auto& ch) { - return static_cast(ch); - }); + // This assumes that char is utf8 and wchar_t is utf16, which is guaranteed on Windows. + value = std::wstring_convert>().from_bytes(meh); } }; @@ -146,7 +146,7 @@ inline void Parse(std::string arg1) json_file.close(); - spdlog::debug("Read config file \"{}\"", path.string()); + spdlog::debug(L"Read config file \"{}\"", path.wstring()); if (launch.launch) { launch.isUWP = checkIsUwp(launch.launchPath); diff --git a/GlosSITarget/SteamTarget.cpp b/GlosSITarget/SteamTarget.cpp index f796eb1..841ce39 100644 --- a/GlosSITarget/SteamTarget.cpp +++ b/GlosSITarget/SteamTarget.cpp @@ -30,7 +30,7 @@ limitations under the License. #include #endif -SteamTarget::SteamTarget(int argc, char* argv[]) +SteamTarget::SteamTarget() : window_( [this] { run_ = false; }, [this] { toggleGlossiOverlay(); }, diff --git a/GlosSITarget/SteamTarget.h b/GlosSITarget/SteamTarget.h index 65e47db..ccff866 100644 --- a/GlosSITarget/SteamTarget.h +++ b/GlosSITarget/SteamTarget.h @@ -32,7 +32,7 @@ limitations under the License. class SteamTarget { public: - explicit SteamTarget(int argc, char* argv[]); + explicit SteamTarget(); int run(); private: diff --git a/GlosSITarget/main.cpp b/GlosSITarget/main.cpp index c248a66..b1101ac 100644 --- a/GlosSITarget/main.cpp +++ b/GlosSITarget/main.cpp @@ -27,6 +27,7 @@ limitations under the License. #include "OverlayLogSink.h" #include "Settings.h" +#include #ifdef _WIN32 @@ -126,9 +127,10 @@ int main(int argc, char* argv[]) if (!std::filesystem::exists(path)) std::filesystem::create_directories(path); path /= "glossitarget.log"; - const auto file_sink = std::make_shared(path.string(), true); + // For "path.wstring()" to be usable here, "#define SPDLOG_WCHAR_FILENAMES" in "tweakme.h" has to be uncommented. + const auto file_sink = std::make_shared(path.wstring(), true); #else - auto file_sink = std::make_shared("/tmp/glossitarget.log", true); + auto file_sink = std::make_shared(L"/tmp/glossitarget.log", true); #endif file_sink->set_level(spdlog::level::trace); @@ -148,21 +150,23 @@ int main(int argc, char* argv[]) auto exit = 1; try { #ifdef _WIN32 - std::string argsv = ""; - if (__argc > 1) { - for (int i = 1; i < __argc; i++) - argsv += i == 1 ? __argv[i] : std::string(" ") + __argv[i]; + int numArgs; + LPWSTR* args = CommandLineToArgvW(GetCommandLine(), &numArgs); + std::wstring argsv = L""; + if (numArgs > 1) { + for (int i = 1; i < numArgs; i++) + argsv += i == 1 ? args[i] : std::wstring(L" ") + args[i]; } Settings::Parse(argsv); - SteamTarget target(__argc, __argv); -#else + SteamTarget target; +#else // Code below is broken now due to parse requiring std::wstring instead of std:string. Sorry. std::string argsv = ""; if (argc > 1) { for (int i = 1; i < argc; i++) argsv += i == 1 ? argv[i] : std::string(" ") + argv[i]; } Settings::Parse(argsv); - SteamTarget target(argc, argv); + SteamTarget target; #endif exit = target.run(); } From 4f6889d3d3b1bf9a988e4f81e7bb5f0ec665c998 Mon Sep 17 00:00:00 2001 From: LemmusLemmus <63229554+LemmusLemmus@users.noreply.github.com> Date: Tue, 26 Jul 2022 15:35:59 +0200 Subject: [PATCH 2/2] Fix Unicode support for paths on Windows. [2/2] --- GlosSITarget/GlosSITarget.vcxproj | 4 ++-- GlosSITarget/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GlosSITarget/GlosSITarget.vcxproj b/GlosSITarget/GlosSITarget.vcxproj index 7299866..0343586 100644 --- a/GlosSITarget/GlosSITarget.vcxproj +++ b/GlosSITarget/GlosSITarget.vcxproj @@ -125,7 +125,7 @@ Level3 true - _DEBUG;SPDLOG_WCHAR_TO_UTF8_SUPPORT;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;SUBHOOK_STATIC;%(PreprocessorDefinitions) + _DEBUG;SPDLOG_WCHAR_TO_UTF8_SUPPORT;SPDLOG_WCHAR_FILENAMES;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;SUBHOOK_STATIC;%(PreprocessorDefinitions) true stdcpp20 @@ -148,7 +148,7 @@ true true true - NDEBUG;SPDLOG_WCHAR_TO_UTF8_SUPPORT;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;SUBHOOK_STATIC;%(PreprocessorDefinitions) + NDEBUG;SPDLOG_WCHAR_TO_UTF8_SUPPORT;SPDLOG_WCHAR_FILENAMES;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;SUBHOOK_STATIC;%(PreprocessorDefinitions) true stdcpp20 diff --git a/GlosSITarget/main.cpp b/GlosSITarget/main.cpp index b1101ac..ec6ee4e 100644 --- a/GlosSITarget/main.cpp +++ b/GlosSITarget/main.cpp @@ -127,7 +127,7 @@ int main(int argc, char* argv[]) if (!std::filesystem::exists(path)) std::filesystem::create_directories(path); path /= "glossitarget.log"; - // For "path.wstring()" to be usable here, "#define SPDLOG_WCHAR_FILENAMES" in "tweakme.h" has to be uncommented. + // For "path.wstring()" to be usable here, SPDLOG_WCHAR_FILENAMES must be defined. const auto file_sink = std::make_shared(path.wstring(), true); #else auto file_sink = std::make_shared(L"/tmp/glossitarget.log", true);