diff --git a/loader/include/Geode/platform/platform.hpp b/loader/include/Geode/platform/platform.hpp index aa0f0cbc..d22bf6a5 100644 --- a/loader/include/Geode/platform/platform.hpp +++ b/loader/include/Geode/platform/platform.hpp @@ -158,6 +158,20 @@ namespace geode { return "Undefined"; } + static constexpr char const* toShortString(Type lp, bool ignoreArch = false) { + switch (lp) { + case Unknown: return "unknown"; + case Windows: return "win"; + case MacOS: return "mac"; + case iOS: return "ios"; + case Android32: return ignoreArch ? "android" : "android32"; + case Android64: return ignoreArch ? "android" : "android64"; + case Linux: return "linux"; + default: break; + } + return "undefined"; + } + template requires requires(T t) { static_cast(t); diff --git a/loader/src/loader/LoaderImpl.cpp b/loader/src/loader/LoaderImpl.cpp index d97b676e..727f68a3 100644 --- a/loader/src/loader/LoaderImpl.cpp +++ b/loader/src/loader/LoaderImpl.cpp @@ -403,9 +403,6 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) { return; } - if (node->getID() == "absolllute.megahack") - log::debug("megahack creepypasta"); - for (auto const& dep : node->m_impl->m_dependants) { m_modsToLoad.push_front(dep); } diff --git a/loader/src/loader/LoaderImpl.hpp b/loader/src/loader/LoaderImpl.hpp index f3810aa4..2f6ab2d0 100644 --- a/loader/src/loader/LoaderImpl.hpp +++ b/loader/src/loader/LoaderImpl.hpp @@ -83,6 +83,7 @@ namespace geode { void updateModResources(Mod* mod); void addSearchPaths(); + void addNativeBinariesPath(ghc::filesystem::path const& path); Result<> setup(); void forceReset(); diff --git a/loader/src/loader/ModImpl.cpp b/loader/src/loader/ModImpl.cpp index 9d5db133..5ad862ff 100644 --- a/loader/src/loader/ModImpl.cpp +++ b/loader/src/loader/ModImpl.cpp @@ -46,8 +46,13 @@ Result<> Mod::Impl::setup() { } if (!m_resourcesLoaded) { auto searchPathRoot = dirs::getModRuntimeDir() / m_metadata.getID() / "resources"; + // TODO: why is this commented out // CCFileUtils::get()->addSearchPath(searchPathRoot.string().c_str()); + const auto binariesDir = searchPathRoot / m_metadata.getID() / "binaries" / PlatformID::toShortString(GEODE_PLATFORM_TARGET); + if (ghc::filesystem::exists(binariesDir)) + LoaderImpl::get()->addNativeBinariesPath(binariesDir); + m_resourcesLoaded = true; } diff --git a/loader/src/loader/ModMetadataImpl.cpp b/loader/src/loader/ModMetadataImpl.cpp index c9eee2cd..b3e7c7e8 100644 --- a/loader/src/loader/ModMetadataImpl.cpp +++ b/loader/src/loader/ModMetadataImpl.cpp @@ -8,6 +8,7 @@ #include #include "ModMetadataImpl.hpp" +#include "LoaderImpl.hpp" using namespace geode::prelude; @@ -181,18 +182,7 @@ Result ModMetadata::Impl::create(ModJson const& json) { if (json["gd"].is_string()) { ver = json["gd"].as_string(); } else if (json["gd"].is_object()) { - std::string key; - switch (GEODE_PLATFORM_TARGET) { - case PlatformID::Android32: - case PlatformID::Android64: - key = "android"; break; - case PlatformID::MacOS: - key = "mac"; break; - case PlatformID::Windows: - key = "win"; break; - case PlatformID::iOS: - key = "ios"; break; - } + auto key = PlatformID::toShortString(GEODE_PLATFORM_TARGET, true); if (json["gd"].contains(key)) ver = json["gd"][ver].as_string(); } else { @@ -201,8 +191,24 @@ Result ModMetadata::Impl::create(ModJson const& json) { if (ver.empty()) { return Err("[mod.json] could not find GD version for current platform"); } - if (ver != "*" && ver != GEODE_STR(GEODE_GD_VERSION)) { - return Err(fmt::format("[mod.json] doesn't support this GD version ({} != {})", ver, GEODE_STR(GEODE_GD_VERSION))); + if (ver != "*") { + // probably a bad idea but oh well + double modTargetVer; + try { + // assume gd version is always a valid double + modTargetVer = std::stod(ver); + } catch (...) { + return Err("[mod.json] has invalid target GD version"); + } + if (LoaderImpl::get()->isForwardCompatMode()) { + // this means current gd version is > GEODE_GD_VERSION + if (modTargetVer <= GEODE_GD_VERSION) { + return Err(fmt::format("[mod.json] doesn't support this GD version ({} < current version)", ver)); + } + } else if (ver != GEODE_STR(GEODE_GD_VERSION)) { + // we are not in forward compat mode, so GEODE_GD_VERSION is the current gd version + return Err(fmt::format("[mod.json] doesn't support this GD version ({} != {})", ver, GEODE_STR(GEODE_GD_VERSION))); + } } } else { return Err("[mod.json] is missing target GD version"); diff --git a/loader/src/platform/android/LoaderImpl.cpp b/loader/src/platform/android/LoaderImpl.cpp index c4b08e84..25b111f1 100644 --- a/loader/src/platform/android/LoaderImpl.cpp +++ b/loader/src/platform/android/LoaderImpl.cpp @@ -32,3 +32,7 @@ std::string Loader::Impl::getGameVersion() { bool Loader::Impl::userTriedToLoadDLLs() const { return false; } + +void Loader::Impl::addNativeBinariesPath(ghc::filesystem::path const& path) { + log::warn("LoaderImpl::addNativeBinariesPath not implement on this platform, not adding path {}", path.string()); +} diff --git a/loader/src/platform/mac/LoaderImpl.mm b/loader/src/platform/mac/LoaderImpl.mm index 27e08b40..706134ab 100644 --- a/loader/src/platform/mac/LoaderImpl.mm +++ b/loader/src/platform/mac/LoaderImpl.mm @@ -135,3 +135,8 @@ void Loader::Impl::setupIPC() { bool Loader::Impl::userTriedToLoadDLLs() const { return false; } + +void Loader::Impl::addNativeBinariesPath(ghc::filesystem::path const& path) { + log::warn("LoaderImpl::addNativeBinariesPath not implement on this platform, not adding path {}", path.string()); +} + diff --git a/loader/src/platform/windows/LoaderImpl.cpp b/loader/src/platform/windows/LoaderImpl.cpp index 2b432eb2..16c16bdf 100644 --- a/loader/src/platform/windows/LoaderImpl.cpp +++ b/loader/src/platform/windows/LoaderImpl.cpp @@ -74,3 +74,12 @@ bool Loader::Impl::userTriedToLoadDLLs() const { return triedToLoadDLLs; } + +void Loader::Impl::addNativeBinariesPath(ghc::filesystem::path const& path) { + // https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-adddlldirectory#remarks + static auto runOnce = [] { + SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + return 0; + }(); + AddDllDirectory(path.wstring().c_str()); +} diff --git a/loader/src/platform/windows/main.cpp b/loader/src/platform/windows/main.cpp index e369a6eb..ddd4f16d 100644 --- a/loader/src/platform/windows/main.cpp +++ b/loader/src/platform/windows/main.cpp @@ -42,19 +42,18 @@ int WINAPI gdMainHook(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmd "Unable to Load Geode!", fmt::format( "This version of Geode is made for Geometry Dash {} " - "but you're trying to play with GD {}." + "but you're trying to play with GD {}.\n" "Please, update your game or install an older version of Geode.", GEODE_STR(GEODE_GD_VERSION), LoaderImpl::get()->getGameVersion() ) ); - return 2; + } else { + int exitCode = geodeEntry(hInstance); + if (exitCode != 0) + return exitCode; } - int exitCode = geodeEntry(hInstance); - if (exitCode != 0) - return exitCode; - return reinterpret_cast(mainTrampolineAddr)(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } diff --git a/loader/src/utils/PlatformID.cpp b/loader/src/utils/PlatformID.cpp index 034e766d..b05019ea 100644 --- a/loader/src/utils/PlatformID.cpp +++ b/loader/src/utils/PlatformID.cpp @@ -6,14 +6,25 @@ using namespace geode::prelude; PlatformID PlatformID::from(const char* str) { switch (hash(str)) { - default: - case hash("unknown"): return PlatformID::Unknown; + case hash("win"): + case hash("Windows"): case hash("windows"): return PlatformID::Windows; + + case hash("mac"): + case hash("MacOS"): case hash("macos"): return PlatformID::MacOS; + + case hash("iOS"): case hash("ios"): return PlatformID::iOS; + + case hash("Android32"): case hash("android32"): return PlatformID::Android32; + case hash("Android64"): case hash("android64"): return PlatformID::Android64; + + case hash("Linux"): case hash("linux"): return PlatformID::Linux; + default: return PlatformID::Unknown; } }