From 22d5e4e97a77c8b02f2218cafa7ef3b0eda6b0f8 Mon Sep 17 00:00:00 2001
From: HJfod <60038575+HJfod@users.noreply.github.com>
Date: Mon, 22 Apr 2024 18:41:49 +0300
Subject: [PATCH] change update checking so they can use a better caching
 system

---
 loader/src/server/Server.cpp             | 30 ++++++++++++++++++++----
 loader/src/server/Server.hpp             |  3 ++-
 loader/src/ui/mods/ModsLayer.cpp         |  6 +----
 loader/src/ui/mods/sources/ModSource.cpp | 25 ++++++++++----------
 4 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/loader/src/server/Server.cpp b/loader/src/server/Server.cpp
index 29fd5025..30afffbe 100644
--- a/loader/src/server/Server.cpp
+++ b/loader/src/server/Server.cpp
@@ -640,10 +640,32 @@ ServerRequest<std::unordered_set<std::string>> server::getTags(bool useCache) {
     );
 }
 
-ServerRequest<std::vector<ServerModUpdate>> server::checkUpdates(std::vector<std::string> const& modIDs, bool useCache) {
+ServerRequest<std::optional<ServerModUpdate>> server::checkUpdates(Mod* mod) {
+    return checkAllUpdates().map(
+        [mod](Result<std::vector<ServerModUpdate>, ServerError>* result) -> Result<std::optional<ServerModUpdate>, ServerError> {
+            if (result->isOk()) {
+                for (auto& update : result->unwrap()) {
+                    if (update.id == mod->getID() && update.version > mod->getVersion()) {
+                        return Ok(update);
+                    }
+                }
+                return Ok(std::nullopt);
+            }
+            return Err(result->unwrapErr());
+        }
+    );
+}
+
+ServerRequest<std::vector<ServerModUpdate>> server::checkAllUpdates(bool useCache) {
     if (useCache) {
-        return getCache<checkUpdates>().get(modIDs);
+        return getCache<checkAllUpdates>().get();
     }
+
+    auto modIDs = ranges::map<std::vector<std::string>>(
+        Loader::get()->getAllMods(),
+        [](auto mod) { return mod->getID(); }
+    );
+    
     auto req = web::WebRequest();
     req.userAgent(getServerUserAgent());
     req.param("platform", GEODE_PLATFORM_SHORT_IDENTIFIER);
@@ -681,7 +703,7 @@ void server::clearServerCaches(bool clearGlobalCaches) {
     // Only clear global caches if explicitly requested
     if (clearGlobalCaches) {
         getCache<&getTags>().clear();
-        getCache<&checkUpdates>().clear();
+        getCache<&checkAllUpdates>().clear();
     }
 }
 
@@ -691,6 +713,6 @@ $execute {
         getCache<&server::getMod>().limit(size);
         getCache<&server::getModLogo>().limit(size);
         getCache<&server::getTags>().limit(size);
-        getCache<&server::checkUpdates>().limit(size);
+        getCache<&server::checkAllUpdates>().limit(size);
     });
 }
diff --git a/loader/src/server/Server.hpp b/loader/src/server/Server.hpp
index 97ac719e..a71feb42 100644
--- a/loader/src/server/Server.hpp
+++ b/loader/src/server/Server.hpp
@@ -120,7 +120,8 @@ namespace server {
     ServerRequest<ServerModMetadata> getMod(std::string const& id, bool useCache = true);
     ServerRequest<ByteVector> getModLogo(std::string const& id, bool useCache = true);
     ServerRequest<std::unordered_set<std::string>> getTags(bool useCache = true);
-    ServerRequest<std::vector<ServerModUpdate>> checkUpdates(std::vector<std::string> const& modIDs, bool useCache = true);
+    ServerRequest<std::optional<ServerModUpdate>> checkUpdates(Mod* mod);
+    ServerRequest<std::vector<ServerModUpdate>> checkAllUpdates(bool useCache = true);
 
     void clearServerCaches(bool clearGlobalCaches = false);
 }
diff --git a/loader/src/ui/mods/ModsLayer.cpp b/loader/src/ui/mods/ModsLayer.cpp
index 72e8b244..636cfc6d 100644
--- a/loader/src/ui/mods/ModsLayer.cpp
+++ b/loader/src/ui/mods/ModsLayer.cpp
@@ -325,11 +325,7 @@ ModsLayer* ModsLayer::scene() {
 }
 
 server::ServerRequest<std::vector<std::string>> ModsLayer::checkInstalledModsForUpdates() {
-    auto modIDs = ranges::map<std::vector<std::string>>(
-        Loader::get()->getAllMods(),
-        [](auto mod) { return mod->getID(); }
-    );
-    return server::checkUpdates(modIDs).map([](auto* result) -> Result<std::vector<std::string>, server::ServerError> {
+    return server::checkAllUpdates().map([](auto* result) -> Result<std::vector<std::string>, server::ServerError> {
         if (result->isOk()) {
             std::vector<std::string> updatesFound;
             for (auto& update : result->unwrap()) {
diff --git a/loader/src/ui/mods/sources/ModSource.cpp b/loader/src/ui/mods/sources/ModSource.cpp
index 8469c1f2..b7301780 100644
--- a/loader/src/ui/mods/sources/ModSource.cpp
+++ b/loader/src/ui/mods/sources/ModSource.cpp
@@ -136,20 +136,21 @@ server::ServerRequest<std::unordered_set<std::string>> ModSource::fetchValidTags
 }
 server::ServerRequest<std::optional<server::ServerModUpdate>> ModSource::checkUpdates() {
     m_availableUpdate = std::nullopt;
-    return server::checkUpdates({ this->getID() }).map(
-        [this](auto* result) -> Result<std::optional<server::ServerModUpdate>, server::ServerError> {
-            if (result->isOk()) {
-                auto updates = result->unwrap();
-                if (!updates.empty()) {
-                    auto update = std::move(std::move(updates).at(0));
-                    if (update.version > this->getMetadata().getVersion()) {
-                        m_availableUpdate = update;
+    return std::visit(makeVisitor {
+        [this](Mod* mod) {
+            return server::checkUpdates(mod).map(
+                [this](auto* result) -> Result<std::optional<server::ServerModUpdate>, server::ServerError> {
+                    if (result->isOk()) {
+                        m_availableUpdate = result->unwrap();
                         return Ok(m_availableUpdate);
                     }
+                    return Err(result->unwrapErr());
                 }
-                return Ok(std::nullopt);
-            }
-            return Err(result->unwrapErr());
+            );
+        },
+        [](server::ServerModMetadata const& metadata) {
+            // Server mods aren't installed so you can't install updates for them
+            return server::ServerRequest<std::optional<server::ServerModUpdate>>::immediate(Ok(std::nullopt));
         }
-    );
+    }, m_value);
 }