From 5c765c6798299d260ecf864d298a24ce15238203 Mon Sep 17 00:00:00 2001 From: altalk23 <45172705+altalk23@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:15:20 +0300 Subject: [PATCH] Implement modified date check on geode files for unzip --- loader/src/loader/LoaderImpl.cpp | 21 +++++++++++++-------- loader/src/loader/LoaderImpl.hpp | 3 +++ loader/src/loader/ModImpl.cpp | 28 +++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/loader/src/loader/LoaderImpl.cpp b/loader/src/loader/LoaderImpl.cpp index 529e327c..d652d5e7 100644 --- a/loader/src/loader/LoaderImpl.cpp +++ b/loader/src/loader/LoaderImpl.cpp @@ -41,9 +41,6 @@ void Loader::Impl::createDirectories() { ghc::filesystem::create_directory(dirs::getSaveDir()); #endif - // try deleting geode/unzipped if it already exists - try { ghc::filesystem::remove_all(dirs::getModRuntimeDir()); } catch(...) {} - (void) utils::file::createDirectoryAll(dirs::getGeodeResourcesDir()); (void) utils::file::createDirectoryAll(dirs::getModConfigDir()); (void) utils::file::createDirectoryAll(dirs::getModsDir()); @@ -411,6 +408,7 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) { m_currentlyLoadingMod = node; m_refreshingModCount += 1; m_refreshedModCount += 1; + m_lateRefreshedModCount += early ? 0 : 1; auto unzipFunction = [this, node]() { log::debug("Unzip"); @@ -631,10 +629,16 @@ void Loader::Impl::continueRefreshModGraph() { return; } + if (m_lateRefreshedModCount > 0) { + auto end = std::chrono::high_resolution_clock::now(); + auto time = std::chrono::duration_cast(end - m_timerBegin).count(); + log::info("Took {}s", static_cast(time) / 1000.f); + } + log::info("Continuing mod graph refresh..."); log::pushNest(); - auto begin = std::chrono::high_resolution_clock::now(); + m_timerBegin = std::chrono::high_resolution_clock::now(); switch (m_loadingState) { case LoadingState::Mods: @@ -652,6 +656,11 @@ void Loader::Impl::continueRefreshModGraph() { this->findProblems(); log::popNest(); m_loadingState = LoadingState::Done; + { + auto end = std::chrono::high_resolution_clock::now(); + auto time = std::chrono::duration_cast(end - m_timerBegin).count(); + log::info("Took {}s", static_cast(time) / 1000.f); + } break; default: m_loadingState = LoadingState::Done; @@ -660,10 +669,6 @@ void Loader::Impl::continueRefreshModGraph() { break; } - auto end = std::chrono::high_resolution_clock::now(); - auto time = std::chrono::duration_cast(end - begin).count(); - log::info("Took {}s", static_cast(time) / 1000.f); - if (m_loadingState != LoadingState::Done) { queueInMainThread([&]() { this->continueRefreshModGraph(); diff --git a/loader/src/loader/LoaderImpl.hpp b/loader/src/loader/LoaderImpl.hpp index af790a5e..e697edd2 100644 --- a/loader/src/loader/LoaderImpl.hpp +++ b/loader/src/loader/LoaderImpl.hpp @@ -87,6 +87,9 @@ namespace geode { int m_refreshingModCount = 0; int m_refreshedModCount = 0; + int m_lateRefreshedModCount = 0; + + std::chrono::time_point m_timerBegin; void provideNextMod(Mod* mod); Mod* takeNextMod(); diff --git a/loader/src/loader/ModImpl.cpp b/loader/src/loader/ModImpl.cpp index d97c5b0f..7075349f 100644 --- a/loader/src/loader/ModImpl.cpp +++ b/loader/src/loader/ModImpl.cpp @@ -3,6 +3,7 @@ #include "ModMetadataImpl.hpp" #include "about.hpp" +#include #include #include #include @@ -576,13 +577,38 @@ Result<> Mod::Impl::createTempDir() { Result<> Mod::Impl::unzipGeodeFile(ModMetadata metadata) { // Unzip .geode file into temp dir + auto tempDir = dirs::getModRuntimeDir() / metadata.getID(); + + auto datePath = tempDir / "modified-at"; + std::string currentHash = file::readString(datePath).unwrapOr(""); + + auto modifiedDate = ghc::filesystem::last_write_time(metadata.getPath()); + auto modifiedCount = std::chrono::duration_cast(modifiedDate.time_since_epoch()); + auto modifiedHash = std::to_string(modifiedCount.count()); + if (currentHash == modifiedHash) { + log::debug("Same hash detected, skipping unzip"); + return Ok(); + } + log::debug("Hash mismatch detected, unzipping"); + + std::error_code ec; + ghc::filesystem::remove_all(tempDir, ec); + if (ec) { + return Err("Unable to delete temp dir: " + ec.message()); + } + + auto res = file::writeString(datePath, modifiedHash); + if (!res) { + log::warn("Failed to write modified date of geode zip"); + } + GEODE_UNWRAP_INTO(auto unzip, file::Unzip::create(metadata.getPath())); if (!unzip.hasEntry(metadata.getBinaryName())) { return Err( fmt::format("Unable to find platform binary under the name \"{}\"", metadata.getBinaryName()) ); } - GEODE_UNWRAP(unzip.extractAllTo(dirs::getModRuntimeDir() / metadata.getID())); + GEODE_UNWRAP(unzip.extractAllTo(tempDir)); return Ok(); }