From 7a83354c8ca260b2f3e0e2ff4e7c1521f308149c Mon Sep 17 00:00:00 2001 From: matcool <26722564+matcool@users.noreply.github.com> Date: Fri, 4 Aug 2023 14:43:53 -0300 Subject: [PATCH] use std::filesystem on windows on some wine-problematic functions the code added could definitely be cleaned later by wrapping the problematic functions, but this is a working solution for now --- loader/src/hooks/MenuLayer.cpp | 4 +--- loader/src/loader/Index.cpp | 13 +++++++++++-- loader/src/loader/LoaderImpl.cpp | 12 ++++++------ loader/src/loader/ModImpl.cpp | 2 +- loader/src/ui/internal/list/ModListLayer.cpp | 8 ++++++++ loader/src/utils/file.cpp | 16 ++++++++++++++++ 6 files changed, 43 insertions(+), 12 deletions(-) diff --git a/loader/src/hooks/MenuLayer.cpp b/loader/src/hooks/MenuLayer.cpp index 0b06d30d..eb89a19d 100644 --- a/loader/src/hooks/MenuLayer.cpp +++ b/loader/src/hooks/MenuLayer.cpp @@ -205,9 +205,7 @@ struct CustomMenuLayer : Modify { #ifdef GEODE_IS_DESKTOP - try { - ghc::filesystem::create_directories(dirs::getGeodeDir() / "update" / "resources"); - } catch(...) {} + (void) utils::file::createDirectoryAll(dirs::getGeodeDir() / "update" / "resources"); createQuickPopup( "Missing Textures", diff --git a/loader/src/loader/Index.cpp b/loader/src/loader/Index.cpp index f09d6211..c3e7c394 100644 --- a/loader/src/loader/Index.cpp +++ b/loader/src/loader/Index.cpp @@ -8,6 +8,10 @@ #include #include +#ifdef GEODE_IS_WINDOWS +#include +#endif + using namespace geode::prelude; // ModInstallEvent @@ -137,8 +141,13 @@ static Result<> flattenGithubRepo(ghc::filesystem::path const& dir) { // only flatten if there is only one file and it's a directory if (files.size() == 1 && ghc::filesystem::is_directory(files[0])) { for (auto& file : ghc::filesystem::directory_iterator(files[0])) { + #ifdef GEODE_IS_WINDOWS + ghc::filesystem::path const relative = std::filesystem::relative(file.path().wstring(), files[0].wstring()).wstring(); + #else + auto const relative = ghc::filesystem::relative(file, files[0]); + #endif ghc::filesystem::rename( - file, dir / ghc::filesystem::relative(file, files[0]) + file, dir / relative ); } ghc::filesystem::remove(files[0]); @@ -351,7 +360,7 @@ void Index::Impl::updateFromLocalTree() { void Index::update(bool force) { // create index dir if it doesn't exist - (void)file::createDirectoryAll(dirs::getIndexDir()); + (void) file::createDirectoryAll(dirs::getIndexDir()); m_impl->m_triedToUpdate = true; diff --git a/loader/src/loader/LoaderImpl.cpp b/loader/src/loader/LoaderImpl.cpp index 51b37f7d..fea23f90 100644 --- a/loader/src/loader/LoaderImpl.cpp +++ b/loader/src/loader/LoaderImpl.cpp @@ -46,12 +46,12 @@ void Loader::Impl::createDirectories() { // try deleting geode/unzipped if it already exists try { ghc::filesystem::remove_all(dirs::getModRuntimeDir()); } catch(...) {} - ghc::filesystem::create_directories(dirs::getGeodeResourcesDir()); - ghc::filesystem::create_directory(dirs::getModConfigDir()); - ghc::filesystem::create_directory(dirs::getModsDir()); - ghc::filesystem::create_directory(dirs::getGeodeLogDir()); - ghc::filesystem::create_directory(dirs::getTempDir()); - ghc::filesystem::create_directory(dirs::getModRuntimeDir()); + (void) utils::file::createDirectoryAll(dirs::getGeodeResourcesDir()); + (void) utils::file::createDirectory(dirs::getModConfigDir()); + (void) utils::file::createDirectory(dirs::getModsDir()); + (void) utils::file::createDirectory(dirs::getGeodeLogDir()); + (void) utils::file::createDirectory(dirs::getTempDir()); + (void) utils::file::createDirectory(dirs::getModRuntimeDir()); if (!ranges::contains(m_modSearchDirectories, dirs::getModsDir())) { m_modSearchDirectories.push_back(dirs::getModsDir()); diff --git a/loader/src/loader/ModImpl.cpp b/loader/src/loader/ModImpl.cpp index 3ae10983..35b18858 100644 --- a/loader/src/loader/ModImpl.cpp +++ b/loader/src/loader/ModImpl.cpp @@ -34,7 +34,7 @@ Mod::Impl::~Impl() { Result<> Mod::Impl::setup() { m_saveDirPath = dirs::getModsSaveDir() / m_info.id(); - ghc::filesystem::create_directories(m_saveDirPath); + (void) utils::file::createDirectoryAll(m_saveDirPath); // always create temp dir for all mods, even if disabled, so resources can be loaded GEODE_UNWRAP(this->createTempDir().expect("Unable to create temp dir: {error}")); diff --git a/loader/src/ui/internal/list/ModListLayer.cpp b/loader/src/ui/internal/list/ModListLayer.cpp index f53f9f19..f84da844 100644 --- a/loader/src/ui/internal/list/ModListLayer.cpp +++ b/loader/src/ui/internal/list/ModListLayer.cpp @@ -19,6 +19,10 @@ #define FTS_FUZZY_MATCH_IMPLEMENTATION #include +#ifdef GEODE_IS_WINDOWS +#include +#endif + static ModListType g_tab = ModListType::Installed; static ModListLayer* g_instance = nullptr; @@ -624,7 +628,11 @@ void ModListLayer::onFilters(CCObject*) { } void ModListLayer::onOpenFolder(CCObject*) { +#ifdef GEODE_IS_WINDOWS + file::openFolder(std::filesystem::canonical(dirs::getModsDir().wstring()).wstring()); +#else file::openFolder(ghc::filesystem::canonical(dirs::getModsDir())); +#endif } void ModListLayer::onResetSearch(CCObject*) { diff --git a/loader/src/utils/file.cpp b/loader/src/utils/file.cpp index c8a6d5e5..40b6eb4e 100644 --- a/loader/src/utils/file.cpp +++ b/loader/src/utils/file.cpp @@ -13,6 +13,10 @@ #include #include +#ifdef GEODE_IS_WINDOWS +#include +#endif + using namespace geode::prelude; using namespace geode::utils::file; @@ -97,7 +101,11 @@ Result<> utils::file::writeBinary(ghc::filesystem::path const& path, ByteVector Result<> utils::file::createDirectory(ghc::filesystem::path const& path) { try { +#ifdef GEODE_IS_WINDOWS + std::filesystem::create_directory(path.wstring()); +#else ghc::filesystem::create_directory(path); +#endif return Ok(); } catch (...) { @@ -107,7 +115,11 @@ Result<> utils::file::createDirectory(ghc::filesystem::path const& path) { Result<> utils::file::createDirectoryAll(ghc::filesystem::path const& path) { try { +#ifdef GEODE_IS_WINDOWS + std::filesystem::create_directories(path.wstring()); +#else ghc::filesystem::create_directories(path); +#endif return Ok(); } catch (...) { @@ -453,7 +465,11 @@ Result<> Unzip::extractAllTo(Path const& dir) { for (auto& [entry, info] : m_impl->getEntries()) { // make sure zip files like root/../../file.txt don't get extracted to // avoid zip attacks +#ifdef GEODE_IS_WINDOWS + if (!std::filesystem::relative((dir / entry).wstring(), dir.wstring()).empty()) { +#else if (!ghc::filesystem::relative(dir / entry, dir).empty()) { +#endif if (info.isDirectory) { GEODE_UNWRAP(file::createDirectoryAll(dir / entry)); } else {