From fe8cb4212942d59bdb2420ae1f14feceb8a77311 Mon Sep 17 00:00:00 2001
From: altalk23 <45172705+altalk23@users.noreply.github.com>
Date: Wed, 2 Aug 2023 15:58:37 +0300
Subject: [PATCH] change getSaveDir and implement autoupdate macos

---
 loader/launcher/mac/CMakeLists.txt | 10 ++--
 loader/launcher/mac/Updater.cpp    |  0
 loader/src/platform/mac/main.mm    | 93 +++++++++++++++++++++++++++++-
 loader/src/platform/mac/util.mm    | 12 +++-
 4 files changed, 106 insertions(+), 9 deletions(-)
 delete mode 100644 loader/launcher/mac/Updater.cpp

diff --git a/loader/launcher/mac/CMakeLists.txt b/loader/launcher/mac/CMakeLists.txt
index a2d91df2..8c36c921 100644
--- a/loader/launcher/mac/CMakeLists.txt
+++ b/loader/launcher/mac/CMakeLists.txt
@@ -1,16 +1,16 @@
 cmake_minimum_required(VERSION 3.3.0)
 
 
-add_library(Bootstrapper SHARED Bootstrapper.cpp)
-target_compile_features(Bootstrapper PUBLIC cxx_std_17)
-set_target_properties(Bootstrapper PROPERTIES
+add_library(GeodeBootstrapper SHARED Bootstrapper.cpp)
+target_compile_features(GeodeBootstrapper PUBLIC cxx_std_17)
+set_target_properties(GeodeBootstrapper PROPERTIES
 	PREFIX "" 
 	OUTPUT_NAME "GeodeBootstrapper"
 	LIBRARY_OUTPUT_DIRECTORY "${GEODE_BIN_PATH}/nightly"
 	RUNTIME_OUTPUT_DIRECTORY "${GEODE_BIN_PATH}/nightly"
 )
 
-target_link_libraries(Bootstrapper PRIVATE)
+target_link_libraries(GeodeBootstrapper PRIVATE)
 
 add_library(FakeGeode SHARED FakeGeode.cpp)
 target_compile_features(FakeGeode PUBLIC cxx_std_17)
@@ -19,4 +19,4 @@ set_target_properties(FakeGeode PROPERTIES
 	OUTPUT_NAME "Geode"
 )
 
-target_link_libraries(Bootstrapper PRIVATE geode-loader)
+target_link_libraries(GeodeBootstrapper PRIVATE geode-loader)
diff --git a/loader/launcher/mac/Updater.cpp b/loader/launcher/mac/Updater.cpp
deleted file mode 100644
index e69de29b..00000000
diff --git a/loader/src/platform/mac/main.mm b/loader/src/platform/mac/main.mm
index da59deaa..ec92b1cd 100644
--- a/loader/src/platform/mac/main.mm
+++ b/loader/src/platform/mac/main.mm
@@ -9,8 +9,11 @@
 #include <unistd.h>
 #include <tulip/TulipHook.hpp>
 #include <array>
-
+#include <ghc/filesystem.hpp>
+#include <Geode/Loader.hpp>
+#include "../../loader/LoaderImpl.hpp"
 #include <thread>
+#include <variant>
 
 using namespace geode::prelude;
 
@@ -20,10 +23,96 @@ std::length_error::~length_error() _NOEXCEPT {} // do not ask...
 // from dynamic to static thats why she needs to define it
 // this is what old versions does to a silly girl
 
+void updateFiles() {
+    auto frameworkDir = dirs::getGameDir() / "Frameworks";
+    auto updatesDir = dirs::getGeodeDir() / "update";
+    auto resourcesDir = dirs::getGeodeResourcesDir();
+
+    if (ghc::filesystem::exists(frameworkDir) && ghc::filesystem::exists(updatesDir)) {
+        std::error_code error;
+        auto bootFile = "GeodeBootstrapper.dylib";
+        auto geodeFile = "Geode.dylib";
+
+        if (ghc::filesystem::exists(updatesDir / bootFile)) {
+            ghc::filesystem::remove(frameworkDir / bootFile, error);
+            if (error) {
+                log::warn("Couldn't remove old GeodeBootstrapper.dylib: {}", error.message());
+            }
+            else {
+                ghc::filesystem::rename(updatesDir / bootFile, frameworkDir / bootFile, error);
+                if (error) {
+                    log::warn("Couldn't move new GeodeBootstrapper.dylib: {}", error.message());
+                }
+                else {
+                    log::info("Updated GeodeBootstrapper.dylib");
+                }
+            }
+        }
+        if (ghc::filesystem::exists(updatesDir / geodeFile)) {
+            ghc::filesystem::remove(frameworkDir / geodeFile, error);
+            if (error) {
+                log::warn("Couldn't remove old Geode.dylib: {}", error.message());
+            }
+            else {
+                ghc::filesystem::rename(updatesDir / geodeFile, frameworkDir / geodeFile, error);
+                if (error) {
+                    log::warn("Couldn't move new Geode.dylib: {}", error.message());
+                }
+                else {
+                    log::info("Updated Geode.dylib");
+                }
+            }
+        }
+        if (ghc::filesystem::exists(updatesDir / "resources")) {
+            ghc::filesystem::remove_all(resourcesDir / "geode.loader", error);
+            if (error) {
+                log::warn("Couldn't remove old resources: {}", error.message());
+            }
+            else {
+                ghc::filesystem::rename(updatesDir / "resources", resourcesDir / "geode.loader", error);
+                if (error) {
+                    log::warn("Couldn't move new resources: {}", error.message());
+                }
+                else {
+                    log::info("Updated resources");
+                }
+            }
+        }
+        ghc::filesystem::remove_all(updatesDir, error);
+        if (error) {
+            log::warn("Couldn't remove old update directory: {}", error.message());
+        }
+    }
+}
+
+$execute {
+    new EventListener(+[](LoaderUpdateEvent* event) {
+        if (std::holds_alternative<UpdateFinished>(event->status)) {
+            updateFiles();
+        }
+        return;
+    }, LoaderUpdateFilter());
+};
+
+void updateGeode() {
+    ghc::filesystem::path oldSavePath = "/Users/Shared/Geode/geode";
+    auto newSavePath = dirs::getSaveDir() / "geode";
+    if (ghc::filesystem::exists(oldSavePath)) {
+        std::error_code error;
+
+        ghc::filesystem::rename(oldSavePath, newSavePath, error);
+        if (error) {
+            log::warn("Couldn't migrate old save files from {} to {}", oldSavePath.string(), newSavePath.string());
+        }
+    }
+
+    updateFiles();
+}
+
 extern "C" void fake() {}
 
 void applicationDidFinishLaunchingHook(void* self, SEL sel, NSNotification* notification) {
-    // updateGeode();
+    updateGeode();
 
     std::array<uint8_t, 6> patchBytes = {
         0x55,
diff --git a/loader/src/platform/mac/util.mm b/loader/src/platform/mac/util.mm
index 192494f9..80838c56 100644
--- a/loader/src/platform/mac/util.mm
+++ b/loader/src/platform/mac/util.mm
@@ -188,8 +188,16 @@ ghc::filesystem::path dirs::getGameDir() {
 }
 
 ghc::filesystem::path dirs::getSaveDir() {
-    // not using ~/Library/Caches
-    return ghc::filesystem::path("/Users/Shared/Geode");
+    static auto path = [] {
+        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
+        NSString *applicationSupportDirectory = [paths firstObject];
+
+        ghc::filesystem::path supportPath = [applicationSupportDirectory UTF8String];
+        auto currentPath = supportPath / "GeometryDash";
+        return currentPath;
+    }();
+
+    return path;
 }
 
 #endif