mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-24 03:39:56 -04:00
move fetch from Index to exported utils + add close button as a member
to Popup and move setup to be last in init + add GEODE_PLATFORM_SHORT_IDENTIFIER macro for the platform's identifier in GitHub release zips + add GEODE_VERSION to cmake + move unzipTo from Index to be an exported util in file namespace + add mod resources directories in accordance with new CLI
This commit is contained in:
parent
34878e97b7
commit
b1776d1d26
23 changed files with 232 additions and 144 deletions
CMakeLists.txt
loader
|
@ -1,6 +1,8 @@
|
|||
cmake_minimum_required(VERSION 3.21 FATAL_ERROR)
|
||||
|
||||
project(geode-sdk VERSION 0.3.0 LANGUAGES CXX C)
|
||||
set(GEODE_VERSION 0.3.0)
|
||||
|
||||
project(geode-sdk VERSION ${GEODE_VERSION} LANGUAGES CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.21 FATAL_ERROR)
|
||||
|
||||
project(geode-loader VERSION 0.2.1 LANGUAGES C CXX)
|
||||
project(geode-loader VERSION ${GEODE_VERSION} LANGUAGES C CXX)
|
||||
set(PROJECT_VERSION_TYPE Alpha)
|
||||
|
||||
# Package info file for internal representation
|
||||
|
@ -28,6 +28,7 @@ file(GLOB CORE_SOURCES
|
|||
src/utils/zip/*.cpp
|
||||
src/index/*.cpp
|
||||
src/ui/nodes/*.cpp
|
||||
src/ui/internal/*.cpp
|
||||
src/ui/internal/credits/*.cpp
|
||||
src/ui/internal/dev/*.cpp
|
||||
src/ui/internal/info/*.cpp
|
||||
|
|
|
@ -60,25 +60,6 @@ namespace geode {
|
|||
bool m_isSetup = false;
|
||||
static bool s_unloading;
|
||||
|
||||
/**
|
||||
* Lowest supported mod version.
|
||||
* Any mod targeting a geode version
|
||||
* lower than this will not be loaded,
|
||||
* as they will be considered out-of-date.
|
||||
*/
|
||||
static constexpr VersionInfo s_supportedVersionMin { 0, 1, 0 };
|
||||
/**
|
||||
* Highest support mod version.
|
||||
* Any mod targeting a geode version
|
||||
* higher than this will not be loaded,
|
||||
* as a higher version means that
|
||||
* the user's geode is out-of-date,
|
||||
* or that the user is a time traveller
|
||||
* and has downloaded a mod from the
|
||||
* future.
|
||||
*/
|
||||
static constexpr VersionInfo s_supportedVersionMax { 0, 2, 1 };
|
||||
|
||||
Result<std::string> createTempDirectoryForMod(ModInfo const& info);
|
||||
Result<Mod*> loadModFromFile(std::string const& file);
|
||||
size_t loadModsFromDirectory(
|
||||
|
@ -107,8 +88,8 @@ namespace geode {
|
|||
*/
|
||||
static Loader* get();
|
||||
|
||||
VersionInfo getVersion() const;
|
||||
std::string getVersionType() const;
|
||||
static VersionInfo getVersion();
|
||||
static std::string getVersionType();
|
||||
|
||||
Result<> saveSettings();
|
||||
Result<> loadSettings();
|
||||
|
@ -133,10 +114,18 @@ namespace geode {
|
|||
*/
|
||||
ghc::filesystem::path getGeodeSaveDirectory() const;
|
||||
|
||||
/**
|
||||
* Minimum supported mod version
|
||||
*/
|
||||
static VersionInfo minModVersion();
|
||||
/**
|
||||
* Maximum supported mod version
|
||||
*/
|
||||
static VersionInfo maxModVersion();
|
||||
/**
|
||||
* Check if a mod's version is within the supported range
|
||||
*/
|
||||
bool supportedModVersion(VersionInfo const& version);
|
||||
static bool supportedModVersion(VersionInfo const& version);
|
||||
|
||||
/**
|
||||
* Whether mod specified with ID is enabled
|
||||
|
|
|
@ -332,7 +332,7 @@ namespace geode {
|
|||
bool m_hasArrows = true;
|
||||
bool m_hasBigArrows = false;
|
||||
size_t m_arrowStep = 1;
|
||||
size_t m_bigArrowStep = 1;
|
||||
size_t m_bigArrowStep = 5;
|
||||
|
||||
public:
|
||||
Result<> parseArrows(JsonMaybeObject<ModJson>& obj) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define GEODE_PLATFORM_TARGET PlatformID::Windows
|
||||
#define GEODE_CALL __stdcall
|
||||
#define GEODE_PLATFORM_EXTENSION ".dll"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "win"
|
||||
#else
|
||||
#define GEODE_WINDOWS(...)
|
||||
#endif
|
||||
|
@ -26,6 +27,7 @@
|
|||
#define GEODE_PLATFORM_NAME "iOS"
|
||||
#define GEODE_PLATFORM_TARGET PlatformID::iOS
|
||||
#define GEODE_PLATFORM_EXTENSION ".ios.dylib"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "ios"
|
||||
#else
|
||||
#define GEODE_IOS(...)
|
||||
#define GEODE_MACOS(...) __VA_ARGS__
|
||||
|
@ -34,6 +36,7 @@
|
|||
#define GEODE_PLATFORM_NAME "MacOS"
|
||||
#define GEODE_PLATFORM_TARGET PlatformID::MacOS
|
||||
#define GEODE_PLATFORM_EXTENSION ".dylib"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "mac"
|
||||
#endif
|
||||
#define GEODE_CALL
|
||||
#else
|
||||
|
@ -50,6 +53,7 @@
|
|||
#define GEODE_PLATFORM_TARGET PlatformID::Android
|
||||
#define GEODE_CALL
|
||||
#define GEODE_PLATFORM_EXTENSION ".so"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "android"
|
||||
#else
|
||||
#define GEODE_ANDROID(...)
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define GEODE_PLATFORM_NAME "Windows"
|
||||
#define GEODE_CALL __stdcall
|
||||
#define GEODE_PLATFORM_EXTENSION ".dll"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "win"
|
||||
|
||||
#ifdef GEODE_EXPORTING
|
||||
#undef GEODE_C_DLL
|
||||
|
@ -43,6 +44,7 @@
|
|||
#define GEODE_IS_MOBILE
|
||||
#define GEODE_PLATFORM_NAME "iOS"
|
||||
#define GEODE_PLATFORM_EXTENSION ".ios.dylib"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "ios"
|
||||
#else
|
||||
#define GEODE_IOS(...)
|
||||
#define GEODE_MACOS(...) __VA_ARGS__
|
||||
|
@ -50,6 +52,7 @@
|
|||
#define GEODE_IS_DESKTOP
|
||||
#define GEODE_PLATFORM_NAME "MacOS"
|
||||
#define GEODE_PLATFORM_EXTENSION ".dylib"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "mac"
|
||||
#endif
|
||||
#define GEODE_CALL
|
||||
#else
|
||||
|
@ -65,6 +68,7 @@
|
|||
#define GEODE_PLATFORM_NAME "Android"
|
||||
#define GEODE_CALL
|
||||
#define GEODE_PLATFORM_EXTENSION ".so"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "android"
|
||||
#else
|
||||
#define GEODE_ANDROID(...)
|
||||
#endif
|
||||
|
|
|
@ -77,6 +77,7 @@ namespace std {
|
|||
#define GEODE_VIRTUAL_CONSTEXPR
|
||||
#define GEODE_NOINLINE __declspec(noinline)
|
||||
#define GEODE_PLATFORM_EXTENSION ".dll"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "win"
|
||||
|
||||
#ifdef GEODE_EXPORTING
|
||||
#define GEODE_DLL __declspec(dllexport)
|
||||
|
@ -111,6 +112,7 @@ namespace std {
|
|||
#define GEODE_VIRTUAL_CONSTEXPR constexpr
|
||||
#define GEODE_NOINLINE __attribute__((noinline))
|
||||
#define GEODE_PLATFORM_EXTENSION ".ios.dylib"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "ios"
|
||||
|
||||
#ifdef GEODE_EXPORTING
|
||||
#define GEODE_DLL __attribute__((visibility("default")))
|
||||
|
@ -137,6 +139,7 @@ namespace std {
|
|||
#define GEODE_VIRTUAL_CONSTEXPR constexpr
|
||||
#define GEODE_NOINLINE __attribute__((noinline))
|
||||
#define GEODE_PLATFORM_EXTENSION ".dylib"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "mac"
|
||||
|
||||
#ifdef GEODE_EXPORTING
|
||||
#define GEODE_DLL __attribute__((visibility("default")))
|
||||
|
@ -169,6 +172,7 @@ namespace std {
|
|||
#define GEODE_VIRTUAL_CONSTEXPR constexpr
|
||||
#define GEODE_NOINLINE __attribute__((noinline))
|
||||
#define GEODE_PLATFORM_EXTENSION ".so"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "android"
|
||||
|
||||
#ifdef GEODE_EXPORTING
|
||||
#define GEODE_DLL __attribute__((visibility("default")))
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace geode {
|
|||
cocos2d::CCSize m_size;
|
||||
cocos2d::extension::CCScale9Sprite* m_bgSprite;
|
||||
cocos2d::CCLabelBMFont* m_title = nullptr;
|
||||
CCMenuItemSpriteExtra* m_closeBtn;
|
||||
|
||||
bool init(
|
||||
float width,
|
||||
|
@ -36,21 +37,21 @@ namespace geode {
|
|||
cocos2d::CCDirector::sharedDirector()->getTouchDispatcher()->incrementForcePrio(2);
|
||||
this->registerWithTouchDispatcher();
|
||||
|
||||
if (!setup(std::forward<InitArgs>(args)...)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto closeSpr = cocos2d::CCSprite::createWithSpriteFrameName("GJ_closeBtn_001.png");
|
||||
closeSpr->setScale(.8f);
|
||||
|
||||
auto closeBtn = CCMenuItemSpriteExtra::create(
|
||||
m_closeBtn = CCMenuItemSpriteExtra::create(
|
||||
closeSpr, this, (cocos2d::SEL_MenuHandler)(&Popup::onClose)
|
||||
);
|
||||
closeBtn->setPosition(
|
||||
m_closeBtn->setPosition(
|
||||
-m_size.width / 2 + 3.f,
|
||||
m_size.height / 2 - 3.f
|
||||
);
|
||||
m_buttonMenu->addChild(closeBtn);
|
||||
m_buttonMenu->addChild(m_closeBtn);
|
||||
|
||||
if (!setup(std::forward<InitArgs>(args)...)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->setKeypadEnabled(true);
|
||||
this->setTouchEnabled(true);
|
||||
|
|
50
loader/include/Geode/utils/fetch.hpp
Normal file
50
loader/include/Geode/utils/fetch.hpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
|
||||
#include "../DefaultInclude.hpp"
|
||||
#include <fs/filesystem.hpp>
|
||||
#include "Result.hpp"
|
||||
#include "json.hpp"
|
||||
|
||||
namespace geode::utils::web {
|
||||
using FileProgressCallback = std::function<bool(double, double)>;
|
||||
|
||||
/**
|
||||
* Synchronously fetch data from the internet
|
||||
* @param url URL to fetch
|
||||
* @returns Returned data as string, or error on error
|
||||
*/
|
||||
GEODE_DLL Result<std::string> fetch(std::string const& url);
|
||||
|
||||
/**
|
||||
* Syncronously download a file from the internet
|
||||
* @param url URL to fetch
|
||||
* @param into Path to download file into
|
||||
* @param prog Progress function; first parameter is bytes downloaded so
|
||||
* far, and second is total bytes to download. Return true to continue
|
||||
* downloading, and false to interrupt. Note that interrupting does not
|
||||
* automatically remove the file that was being downloaded
|
||||
* @returns Returned data as JSON, or error on error
|
||||
*/
|
||||
GEODE_DLL Result<> fetchFile(
|
||||
std::string const& url,
|
||||
ghc::filesystem::path const& into,
|
||||
FileProgressCallback prog = nullptr
|
||||
);
|
||||
|
||||
/**
|
||||
* Synchronously fetch data from the internet and parse it as JSON
|
||||
* @param url URL to fetch
|
||||
* @returns Returned data as JSON, or error on error
|
||||
*/
|
||||
template<class Json = nlohmann::json>
|
||||
Result<Json> fetchJSON(std::string const& url) {
|
||||
auto res = fetch(url);
|
||||
if (!res) return Err(res.error());
|
||||
try {
|
||||
return Ok(Json::parse(res.value()));
|
||||
} catch(std::exception& e) {
|
||||
return Err(e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
#include "Result.hpp"
|
||||
#include <string>
|
||||
#include "types.hpp"
|
||||
#include "fs/filesystem.hpp"
|
||||
#include <fs/filesystem.hpp>
|
||||
|
||||
namespace geode::utils::file {
|
||||
GEODE_DLL Result<std::string> readString(std::string const& path);
|
||||
|
@ -25,4 +25,15 @@ namespace geode::utils::file {
|
|||
GEODE_DLL Result<> createDirectoryAll(std::string const& path);
|
||||
GEODE_DLL Result<std::vector<std::string>> listFiles(std::string const& path);
|
||||
GEODE_DLL Result<std::vector<std::string>> listFilesRecursively(std::string const& path);
|
||||
|
||||
/**
|
||||
* Unzip file to directory
|
||||
* @param from File to unzip
|
||||
* @param to Directory to unzip to
|
||||
* @returns Ok on success, Error on error
|
||||
*/
|
||||
GEODE_DLL Result<> unzipTo(
|
||||
ghc::filesystem::path const& from,
|
||||
ghc::filesystem::path const& to
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define GEODE_PLATFORM_TARGET PlatformID::Windows
|
||||
#define GEODE_CALL __stdcall
|
||||
#define GEODE_PLATFORM_EXTENSION ".dll"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "win"
|
||||
#else
|
||||
#define GEODE_WINDOWS(...)
|
||||
#endif
|
||||
|
@ -26,6 +27,7 @@
|
|||
#define GEODE_PLATFORM_NAME "iOS"
|
||||
#define GEODE_PLATFORM_TARGET PlatformID::iOS
|
||||
#define GEODE_PLATFORM_EXTENSION ".ios.dylib"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "ios"
|
||||
#else
|
||||
#define GEODE_IOS(...)
|
||||
#define GEODE_MACOS(...) __VA_ARGS__
|
||||
|
@ -34,6 +36,7 @@
|
|||
#define GEODE_PLATFORM_NAME "MacOS"
|
||||
#define GEODE_PLATFORM_TARGET PlatformID::MacOS
|
||||
#define GEODE_PLATFORM_EXTENSION ".dylib"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "mac"
|
||||
#endif
|
||||
#define GEODE_CALL
|
||||
#else
|
||||
|
@ -50,6 +53,7 @@
|
|||
#define GEODE_PLATFORM_TARGET PlatformID::Android
|
||||
#define GEODE_CALL
|
||||
#define GEODE_PLATFORM_EXTENSION ".so"
|
||||
#define GEODE_PLATFORM_SHORT_IDENTIFIER "android"
|
||||
#else
|
||||
#define GEODE_ANDROID(...)
|
||||
#endif
|
||||
|
|
|
@ -52,7 +52,13 @@
|
|||
"type": "bool",
|
||||
"default": false,
|
||||
"name": "Show Platform Console",
|
||||
"description": "Show the native console (if one exists). <cr>This setting is meant for developers</c>."
|
||||
"description": "Show the native console (if one exists). <cr>This setting is meant for developers</c>"
|
||||
},
|
||||
"auto-check-updates": {
|
||||
"type": "bool",
|
||||
"default": true,
|
||||
"name": "Check For Updates",
|
||||
"description": "Automatically check for <cy>updates</c> to Geode on startup"
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <Geode/ui/MDPopup.hpp>
|
||||
#include <InternalMod.hpp>
|
||||
#include "../ui/internal/info/ModInfoLayer.hpp"
|
||||
#include <InternalLoader.hpp>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <thread>
|
||||
#include <Geode/utils/json.hpp>
|
||||
#include <Geode/utils/JsonValidation.hpp>
|
||||
#include "fetch.hpp"
|
||||
#include <Geode/utils/fetch.hpp>
|
||||
|
||||
#define GITHUB_DONT_RATE_LIMIT_ME_PLS 0
|
||||
|
||||
|
@ -19,61 +19,6 @@ static Result<Json> readJSON(ghc::filesystem::path const& path) {
|
|||
}
|
||||
}
|
||||
|
||||
static Result<> unzipTo(
|
||||
ghc::filesystem::path const& from,
|
||||
ghc::filesystem::path const& to
|
||||
) {
|
||||
// unzip downloaded
|
||||
auto unzip = ZipFile(from.string());
|
||||
if (!unzip.isLoaded()) {
|
||||
return Err("Unable to unzip index.zip");
|
||||
}
|
||||
|
||||
for (auto file : unzip.getAllFiles()) {
|
||||
// this is a very bad check for seeing
|
||||
// if file is a directory. it seems to
|
||||
// work on windows at least. idk why
|
||||
// getAllFiles returns the directories
|
||||
// aswell now
|
||||
if (
|
||||
utils::string::endsWith(file, "\\") ||
|
||||
utils::string::endsWith(file, "/")
|
||||
) continue;
|
||||
|
||||
auto zipPath = file;
|
||||
|
||||
// dont include the github repo folder
|
||||
file = file.substr(file.find_first_of("/") + 1);
|
||||
|
||||
auto path = ghc::filesystem::path(file);
|
||||
if (path.has_parent_path()) {
|
||||
if (
|
||||
!ghc::filesystem::exists(to / path.parent_path()) &&
|
||||
!ghc::filesystem::create_directories(to / path.parent_path())
|
||||
) {
|
||||
return Err(
|
||||
"Unable to create directories \"" +
|
||||
path.parent_path().string() + "\""
|
||||
);
|
||||
}
|
||||
}
|
||||
unsigned long size;
|
||||
auto data = unzip.getFileData(zipPath, &size);
|
||||
if (!data || !size) {
|
||||
return Err("Unable to read \"" + std::string(zipPath) + "\"");
|
||||
}
|
||||
auto wrt = utils::file::writeBinary(
|
||||
to / file,
|
||||
byte_array(data, data + size)
|
||||
);
|
||||
if (!wrt) {
|
||||
return Err("Unable to write \"" + file + "\": " + wrt.error());
|
||||
}
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
static PlatformID platformFromString(std::string const& str) {
|
||||
switch (hash(utils::string::trim(utils::string::toLower(str)).c_str())) {
|
||||
default:
|
||||
|
@ -126,7 +71,7 @@ void Index::updateIndexThread(bool force) {
|
|||
);
|
||||
|
||||
// get all commits in index repo
|
||||
auto commit = fetchJSON(
|
||||
auto commit = web::fetchJSON(
|
||||
"https://api.github.com/repos/geode-sdk/mods/commits"
|
||||
);
|
||||
if (!commit) {
|
||||
|
@ -202,7 +147,7 @@ void Index::updateIndexThread(bool force) {
|
|||
"Downloading index",
|
||||
50
|
||||
);
|
||||
auto gotZip = fetchFile(
|
||||
auto gotZip = web::fetchFile(
|
||||
"https://github.com/geode-sdk/mods/zipball/main",
|
||||
indexDir / "index.zip"
|
||||
);
|
||||
|
@ -218,7 +163,7 @@ void Index::updateIndexThread(bool force) {
|
|||
ghc::filesystem::remove_all(indexDir / "index");
|
||||
}
|
||||
|
||||
auto unzip = unzipTo(indexDir / "index.zip", indexDir);
|
||||
auto unzip = file::unzipTo(indexDir / "index.zip", indexDir);
|
||||
if (!unzip) {
|
||||
return indexUpdateProgress(
|
||||
UpdateStatus::Failed, unzip.error()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <thread>
|
||||
#include <Geode/utils/json.hpp>
|
||||
#include <hash.hpp>
|
||||
#include "fetch.hpp"
|
||||
#include <Geode/utils/fetch.hpp>
|
||||
|
||||
void InstallTicket::postProgress(
|
||||
UpdateStatus status,
|
||||
|
@ -46,7 +46,7 @@ void InstallTicket::install(std::string const& id) {
|
|||
auto tempFile = indexDir / item.m_download.m_filename;
|
||||
|
||||
this->postProgress(UpdateStatus::Progress, "Fetching binary", 0);
|
||||
auto res = fetchFile(
|
||||
auto res = web::fetchFile(
|
||||
item.m_download.m_url,
|
||||
tempFile,
|
||||
[this, tempFile](double now, double total) -> int {
|
||||
|
@ -54,7 +54,7 @@ void InstallTicket::install(std::string const& id) {
|
|||
std::lock_guard cancelLock(m_cancelMutex);
|
||||
if (m_cancelling) {
|
||||
try { ghc::filesystem::remove(tempFile); } catch(...) {}
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// no need to scope the lock guard more as this
|
||||
|
@ -65,7 +65,7 @@ void InstallTicket::install(std::string const& id) {
|
|||
"Downloading binary",
|
||||
static_cast<uint8_t>(now / total * 100.0)
|
||||
);
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
);
|
||||
if (!res) {
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/Geode.hpp>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
Result<std::string> fetch(std::string const& url);
|
||||
Result<> fetchFile(
|
||||
std::string const& url,
|
||||
ghc::filesystem::path const& into,
|
||||
std::function<int(double, double)> prog = nullptr
|
||||
);
|
||||
|
||||
template<class Json = nlohmann::json>
|
||||
Result<Json> fetchJSON(std::string const& url) {
|
||||
auto res = fetch(url);
|
||||
if (!res) return Err(res.error());
|
||||
try {
|
||||
return Ok(Json::parse(res.value()));
|
||||
} catch(std::exception& e) {
|
||||
return Err(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
#include <Geode/loader/Log.hpp>
|
||||
#include <Geode/loader/Loader.hpp>
|
||||
#include <Geode/Geode.hpp>
|
||||
#include <Geode/utils/fetch.hpp>
|
||||
#include <thread>
|
||||
|
||||
InternalLoader::InternalLoader() : Loader() {}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <Geode/loader/Log.hpp>
|
||||
#include <Geode/utils/Result.hpp>
|
||||
#include <unordered_set>
|
||||
#include <Geode/utils/json.hpp>
|
||||
#include <optional>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
|
@ -52,6 +54,6 @@ public:
|
|||
void openPlatformConsole();
|
||||
void closePlatformConsole();
|
||||
static void platformMessageBox(const char* title, std::string const& info);
|
||||
|
||||
|
||||
friend int geodeEntry(void* platformData);
|
||||
};
|
||||
|
|
|
@ -19,11 +19,11 @@ USE_GEODE_NAMESPACE();
|
|||
bool Loader::s_unloading = false;
|
||||
std::mutex g_unloadMutex;
|
||||
|
||||
VersionInfo Loader::getVersion() const {
|
||||
VersionInfo Loader::getVersion() {
|
||||
return LOADER_VERSION;
|
||||
}
|
||||
|
||||
std::string Loader::getVersionType() const {
|
||||
std::string Loader::getVersionType() {
|
||||
return LOADER_VERSION_TYPE;
|
||||
}
|
||||
|
||||
|
@ -51,14 +51,23 @@ void Loader::createDirectories() {
|
|||
}
|
||||
|
||||
void Loader::updateResourcePaths() {
|
||||
// add own resources directory
|
||||
// add own geode/resources directory
|
||||
CCFileUtils::sharedFileUtils()->addSearchPath(
|
||||
(this->getGeodeDirectory() / GEODE_RESOURCE_DIRECTORY).string().c_str()
|
||||
);
|
||||
// add mods directory
|
||||
CCFileUtils::sharedFileUtils()->addSearchPath(
|
||||
(this->getGeodeDirectory() / GEODE_TEMP_DIRECTORY).string().c_str()
|
||||
);
|
||||
|
||||
// add geode/temp for accessing root resources in mods
|
||||
auto tempDir = this->getGeodeDirectory() / GEODE_TEMP_DIRECTORY;
|
||||
CCFileUtils::sharedFileUtils()->addSearchPath(tempDir.string().c_str());
|
||||
|
||||
// add geode/temp/mod.id/resources for accessing additional resources in mods
|
||||
for (auto& [_, mod] : m_mods) {
|
||||
if (mod->m_addResourcesToSearchPath) {
|
||||
CCFileUtils::sharedFileUtils()->addSearchPath(
|
||||
(tempDir / mod->getID() / "resources").string().c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Loader::updateModResources(Mod* mod) {
|
||||
|
@ -447,10 +456,18 @@ size_t Loader::getFieldIndexForClass(size_t hash) {
|
|||
return nextIndex[hash]++;
|
||||
}
|
||||
|
||||
VersionInfo Loader::minModVersion() {
|
||||
return { 0, 1, 0 };
|
||||
}
|
||||
|
||||
VersionInfo Loader::maxModVersion() {
|
||||
return Loader::getVersion();
|
||||
}
|
||||
|
||||
bool Loader::supportedModVersion(VersionInfo const& version) {
|
||||
return
|
||||
version >= s_supportedVersionMin &&
|
||||
version <= s_supportedVersionMax;
|
||||
version >= Loader::minModVersion() &&
|
||||
version <= Loader::maxModVersion();
|
||||
}
|
||||
|
||||
void Loader::openPlatformConsole() {
|
||||
|
|
|
@ -148,28 +148,28 @@ Result<ModInfo> ModInfo::create(ModJson const& json) {
|
|||
"specified, or it is invalidally formatted (required: \"[v]X.X.X\")!"
|
||||
);
|
||||
}
|
||||
if (schema < Loader::s_supportedVersionMin) {
|
||||
if (schema < Loader::minModVersion()) {
|
||||
return Err(
|
||||
"[mod.json] is built for an older version (" +
|
||||
schema.toString() + ") of Geode (current: " +
|
||||
Loader::s_supportedVersionMin.toString() +
|
||||
Loader::minModVersion().toString() +
|
||||
"). Please update the mod to the latest version, "
|
||||
"and if the problem persists, contact the developer "
|
||||
"to update it."
|
||||
);
|
||||
}
|
||||
if (schema > Loader::s_supportedVersionMax) {
|
||||
if (schema > Loader::maxModVersion()) {
|
||||
return Err(
|
||||
"[mod.json] is built for a newer version (" +
|
||||
schema.toString() + ") of Geode (current: " +
|
||||
Loader::s_supportedVersionMax.toString() +
|
||||
Loader::maxModVersion().toString() +
|
||||
"). You need to update Geode in order to use "
|
||||
"this mod."
|
||||
);
|
||||
}
|
||||
|
||||
// Handle mod.json data based on target
|
||||
if (schema <= VersionInfo(0, 2, 1)) {
|
||||
if (schema >= VersionInfo(0, 1, 0)) {
|
||||
return ModInfo::createFromSchemaV010(json);
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ int geodeEntry(void* platformData) {
|
|||
if (InternalMod::get()->getSettingValue<bool>("show-platform-console")) {
|
||||
Loader::get()->openPlatformConsole();
|
||||
}
|
||||
|
||||
|
||||
InternalMod::get()->log()
|
||||
<< Severity::Debug
|
||||
<< "Entry done.";
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "fetch.hpp"
|
||||
#include <Geode/utils/fetch.hpp>
|
||||
#include <curl/curl.h>
|
||||
#include <Geode/utils/casts.hpp>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
namespace geode::utils::fetch {
|
||||
static size_t writeData(char* data, size_t size, size_t nmemb, void* str) {
|
||||
|
@ -13,14 +16,14 @@ namespace geode::utils::fetch {
|
|||
}
|
||||
|
||||
static int progress(void* ptr, double total, double now, double, double) {
|
||||
return (*as<std::function<int(double, double)>*>(ptr))(now, total);
|
||||
return (*as<web::FileProgressCallback*>(ptr))(now, total) != true;
|
||||
}
|
||||
}
|
||||
|
||||
Result<> fetchFile(
|
||||
Result<> web::fetchFile(
|
||||
std::string const& url,
|
||||
ghc::filesystem::path const& into,
|
||||
std::function<int(double, double)> prog
|
||||
FileProgressCallback prog
|
||||
) {
|
||||
auto curl = curl_easy_init();
|
||||
|
||||
|
@ -46,7 +49,7 @@ Result<> fetchFile(
|
|||
auto res = curl_easy_perform(curl);
|
||||
if (res != CURLE_OK) {
|
||||
curl_easy_cleanup(curl);
|
||||
return Err("Fetch failed");
|
||||
return Err("Fetch failed: " + std::string(curl_easy_strerror(res)));
|
||||
}
|
||||
|
||||
char* ct;
|
||||
|
@ -59,7 +62,7 @@ Result<> fetchFile(
|
|||
return Err("Error getting info: " + std::string(curl_easy_strerror(res)));
|
||||
}
|
||||
|
||||
Result<std::string> fetch(std::string const& url) {
|
||||
Result<std::string> web::fetch(std::string const& url) {
|
||||
auto curl = curl_easy_init();
|
||||
|
||||
if (!curl) return Err("Curl not initialized!");
|
|
@ -1,5 +1,7 @@
|
|||
#include <Geode/utils/file.hpp>
|
||||
#include <Geode/utils/string.hpp>
|
||||
#include <fstream>
|
||||
#include <Geode/Bindings.hpp>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
|
@ -188,3 +190,69 @@ Result<std::vector<std::string>> utils::file::listFilesRecursively(std::string c
|
|||
}
|
||||
return Ok<>(res);
|
||||
}
|
||||
|
||||
Result<> utils::file::unzipTo(
|
||||
ghc::filesystem::path const& from,
|
||||
ghc::filesystem::path const& to
|
||||
) {
|
||||
// unzip downloaded
|
||||
auto unzip = ZipFile(from.string());
|
||||
if (!unzip.isLoaded()) {
|
||||
return Err("Unable to unzip index.zip");
|
||||
}
|
||||
|
||||
if (
|
||||
!ghc::filesystem::exists(to) &&
|
||||
!ghc::filesystem::create_directories(to)
|
||||
) {
|
||||
return Err(
|
||||
"Unable to create directories \"" +
|
||||
to.string() + "\""
|
||||
);
|
||||
}
|
||||
|
||||
for (auto file : unzip.getAllFiles()) {
|
||||
// this is a very bad check for seeing
|
||||
// if file is a directory. it seems to
|
||||
// work on windows at least. idk why
|
||||
// getAllFiles returns the directories
|
||||
// aswell now
|
||||
if (
|
||||
utils::string::endsWith(file, "\\") ||
|
||||
utils::string::endsWith(file, "/")
|
||||
) continue;
|
||||
|
||||
auto zipPath = file;
|
||||
|
||||
// dont include the github repo folder
|
||||
file = file.substr(file.find_first_of("/") + 1);
|
||||
|
||||
auto path = ghc::filesystem::path(file);
|
||||
if (path.has_parent_path()) {
|
||||
auto dir = to / path.parent_path();
|
||||
if (
|
||||
!ghc::filesystem::exists(dir) &&
|
||||
!ghc::filesystem::create_directories(dir)
|
||||
) {
|
||||
return Err(
|
||||
"Unable to create directories \"" +
|
||||
dir.string() + "\""
|
||||
);
|
||||
}
|
||||
}
|
||||
unsigned long size;
|
||||
auto data = unzip.getFileData(zipPath, &size);
|
||||
if (!data || !size) {
|
||||
return Err("Unable to read \"" + std::string(zipPath) + "\"");
|
||||
}
|
||||
auto wrt = utils::file::writeBinary(
|
||||
to / file,
|
||||
byte_array(data, data + size)
|
||||
);
|
||||
if (!wrt) {
|
||||
return Err("Unable to write \"" + (to / file).string() + "\": " + wrt.error());
|
||||
}
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue