mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-17 16:17:06 +02:00
Paths: the last few written as text go through UTF-8, so a non-ASCII name no longer throws
path::string() uses the ANSI code page and throws on a character it lacks (a Cyrillic folder on an English Windows). The remaining places it was used now go through path_utf8: - Mods: a deck folder or a mod folder named outside the code page no longer leaves the Board Break decks empty, or the Mods folder ignored altogether. - Game and mod archives: a file under Win32 with such a name is passed over instead of stopping the read. - pose-dump no longer ends the multiplayer session when the game folder is not ASCII. - The item browser's status line and a Board Break warning no longer fail on such a path. - Launcher: system fonts are named to ImGui in UTF-8, which it reads.
This commit is contained in:
1 parent
571d57f603
commit
320086381c
6 files changed
+17
-11
No files matched your search
@@ -74,12 +74,13 @@ GameArchives::GameArchives(fs::path root, const native_db::Node& layout) : root_
|
||||
const auto win32 = root_ / "Win32";
|
||||
for (fs::recursive_directory_iterator it(win32, error), end; it != end && !error; it.increment(error)) {
|
||||
if (!it->is_regular_file(error) || error) { error.clear(); continue; }
|
||||
if (lower(it->path().extension().string()) != ".cas") continue;
|
||||
const auto index = archive_index(it->path().stem().string());
|
||||
if (lower(path_utf8(it->path().extension())) != ".cas") continue;
|
||||
const auto index = archive_index(path_utf8(it->path().stem()));
|
||||
if (!index) continue;
|
||||
// Relative to Win32, because read() adds that itself.
|
||||
const auto directory = fs::relative(it->path().parent_path(), win32, error).generic_string();
|
||||
const auto relative = fs::relative(it->path().parent_path(), win32, error).generic_u8string();
|
||||
if (error) { error.clear(); continue; }
|
||||
const std::string directory(relative.begin(), relative.end());
|
||||
directories_[directory].insert(*index);
|
||||
}
|
||||
for (const auto& [directory, archives] : directories_) byArchives[archives].push_back(directory);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "mod_catalog.h"
|
||||
#include "Engine/Core/Platform/path_text.h"
|
||||
#include "builtin_packs.h"
|
||||
|
||||
#include "mod_merge.h"
|
||||
@@ -128,7 +129,7 @@ std::vector<std::pair<std::string, fs::path>> decks_inside(const fs::path& mod)
|
||||
std::error_code error;
|
||||
for (fs::directory_iterator at(mod / L"decks", error), end; !error && at != end; at.increment(error)) {
|
||||
if (!at->is_directory(error) || !fs::is_regular_file(at->path() / L"layout.toc", error)) continue;
|
||||
auto name = lower(at->path().filename().string());
|
||||
auto name = lower(path_utf8(at->path().filename()));
|
||||
if (deck_name(name)) found.emplace_back(std::move(name), at->path());
|
||||
}
|
||||
std::sort(found.begin(), found.end(), [](const auto& a, const auto& b) { return deck_before(a.first, b.first); });
|
||||
@@ -144,7 +145,7 @@ std::vector<std::pair<std::string, fs::path>> installed_decks() {
|
||||
auto inside = decks_inside(at->path());
|
||||
for (auto& one : inside) decks.emplace_back(std::move(one.first), at->path());
|
||||
if (!inside.empty()) continue;
|
||||
if (auto deck = board_break_deck_of(at->path().filename().string()); !deck.empty()) decks.emplace_back(std::move(deck), at->path());
|
||||
if (auto deck = board_break_deck_of(path_utf8(at->path().filename())); !deck.empty()) decks.emplace_back(std::move(deck), at->path());
|
||||
}
|
||||
std::stable_sort(decks.begin(), decks.end(), [](const auto& a, const auto& b) { return deck_before(a.first, b.first); });
|
||||
return decks;
|
||||
@@ -230,7 +231,7 @@ std::filesystem::path board_break_deck_folder(std::string_view deck) noexcept {
|
||||
const auto inside = decks_inside(at->path());
|
||||
for (const auto& one : inside)
|
||||
if (one.first == wanted) return one.second;
|
||||
if (inside.empty() && board_break_deck_of(at->path().filename().string()) == wanted) return at->path();
|
||||
if (inside.empty() && board_break_deck_of(path_utf8(at->path().filename())) == wanted) return at->path();
|
||||
}
|
||||
} catch (...) {}
|
||||
return {};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "board_break_audio.h"
|
||||
#include "Engine/Core/Platform/path_text.h"
|
||||
#include "Engine/Core/Log/logging.h"
|
||||
#include <Windows.h>
|
||||
#include <mmsystem.h>
|
||||
@@ -137,7 +138,7 @@ void load(Kind kind, const std::vector<std::filesystem::path>& files) noexcept {
|
||||
Sound sound;
|
||||
if (read_wave(file, sound)) read.push_back(std::move(sound));
|
||||
else logging::log(logging::Level::warning, logging::Channel::skater, "Board Break: {} is not a wave file it can play.",
|
||||
file.filename().string());
|
||||
path_utf8(file.filename()));
|
||||
} catch (...) {}
|
||||
}
|
||||
std::lock_guard lock(e.mutex);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "item_browser.h"
|
||||
#include "Engine/Core/Platform/path_text.h"
|
||||
#include "local_customization_runtime.h"
|
||||
#include "Engine/Core/Json/json.h"
|
||||
#include "Engine/Core/Log/logging.h"
|
||||
@@ -507,7 +508,7 @@ void log_roots(State& s, const md::Context& context) {
|
||||
void log_status(const State& s) {
|
||||
logging::log(Level::info, Channel::customization, "Item browser: {} grid(s), search \"{}\", filter {}, {} favorite(s), file {}.",
|
||||
s.grids.size(), s.search, filter_names[static_cast<std::size_t>(s.filter)], s.favorites.keys.size(),
|
||||
s.favorites.file.string());
|
||||
path_utf8(s.favorites.file));
|
||||
for (const auto& grid : s.grids) {
|
||||
std::string focus = "-";
|
||||
if (grid.focused >= 0 && static_cast<std::size_t>(grid.focused) < grid.shown.size())
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "session_internal.h"
|
||||
#include "Engine/Core/Platform/path_text.h"
|
||||
#include "Extension/Multiplayer/Steam/steam_social.h"
|
||||
#include "Extension/Multiplayer/Hud/native_indicators.h"
|
||||
#include "Extension/Multiplayer/Hud/native_player_ui.h"
|
||||
@@ -435,11 +436,11 @@ std::string start_pose_dump(Session &s, std::string_view argument) {
|
||||
s.pose_dump.close();
|
||||
s.pose_dump.clear();
|
||||
s.pose_dump.open(file, std::ios::binary | std::ios::trunc);
|
||||
if (!s.pose_dump) return "Could not write " + file.string() + ".";
|
||||
if (!s.pose_dump) return "Could not write " + path_utf8(file) + ".";
|
||||
s.pose_dump.write("RSPD1\n", 6);
|
||||
s.pose_dump_until = now_us() + static_cast<std::uint64_t>(seconds) * 1000000;
|
||||
s.pose_dump_count = 0;
|
||||
return "Recording your poses for " + std::to_string(seconds) + " s to " + file.string() + ". Skate as you normally would.";
|
||||
return "Recording your poses for " + std::to_string(seconds) + " s to " + path_utf8(file) + ". Skate as you normally would.";
|
||||
}
|
||||
std::string edit_direct_connections(Session &s, std::string_view argument) {
|
||||
const auto enabled = parse_switch(argument, s.prefer_direct);
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "gui_internal.h"
|
||||
#include "gui_renderer.h"
|
||||
#include "Engine/Core/Platform/path_text.h"
|
||||
|
||||
#include "Engine/Core/Log/logging.h"
|
||||
|
||||
@@ -254,7 +255,7 @@ ImFont* system_font(const wchar_t* file, float size) {
|
||||
const auto path = fs::path(windows.data()) / L"Fonts" / file;
|
||||
std::error_code error;
|
||||
if (!fs::is_regular_file(path, error)) return nullptr;
|
||||
return ImGui::GetIO().Fonts->AddFontFromFileTTF(path.string().c_str(), S(size));
|
||||
return ImGui::GetIO().Fonts->AddFontFromFileTTF(path_utf8(path).c_str(), S(size)); // (ImGui reads UTF-8)
|
||||
}
|
||||
|
||||
Fonts load_fonts() {
|
||||
|
||||
Reference in new issue
Block a user