mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-30 11:17:08 -05:00
314 lines
11 KiB
C++
314 lines
11 KiB
C++
#pragma once
|
|
|
|
#include "Types.hpp"
|
|
#include "ModMetadata.hpp"
|
|
#include "Event.hpp"
|
|
#include "../utils/Result.hpp"
|
|
#include "../utils/web.hpp"
|
|
#include <unordered_set>
|
|
|
|
namespace geode {
|
|
class Index;
|
|
|
|
/**
|
|
* Status signifying an index-related download has been finished
|
|
*/
|
|
using UpdateFinished = std::monostate;
|
|
/**
|
|
* Status signifying an index-related download is in progress. First element
|
|
* in pair is percentage downloaded, second is status string
|
|
*/
|
|
using UpdateProgress = std::pair<uint8_t, std::string>;
|
|
/**
|
|
* Status signifying an index-related download has failed. Consists of the
|
|
* error string
|
|
*/
|
|
using UpdateFailed = std::string;
|
|
/**
|
|
* Status code for an index-related download
|
|
*/
|
|
using UpdateStatus = std::variant<UpdateFinished, UpdateProgress, UpdateFailed>;
|
|
|
|
/**
|
|
* Event for when a mod is being installed from the index. Automatically
|
|
* broadcast by the mods index; use ModInstallFilter to listen to these
|
|
* events
|
|
*/
|
|
struct GEODE_DLL ModInstallEvent : public Event {
|
|
/**
|
|
* The ID of the mod being installed
|
|
*/
|
|
const std::string modID;
|
|
/**
|
|
* The current status of the installation
|
|
*/
|
|
const UpdateStatus status;
|
|
|
|
private:
|
|
ModInstallEvent(std::string const& id, const UpdateStatus status);
|
|
|
|
friend class Index;
|
|
};
|
|
|
|
/**
|
|
* Basic filter for listening to mod installation events. Always propagates
|
|
* the event down the chain
|
|
* @example
|
|
* // Install "steve.hotdogs" and listen for its installation progress
|
|
*
|
|
* // Create a listener that listens for when steve.hotdogs is being installed
|
|
* auto listener = EventListener<ModInstallFilter>(+[](ModInstallEvent* ev) {
|
|
* // Check the event status using std::visit or other
|
|
* }, ModInstallFilter("steve.hotdogs"));
|
|
* // Get the latest version of steve.hotdogs from the index and install it
|
|
* if (auto mod = Index::get()->getMajorItem("steve.hotdogs")) {
|
|
* Index::get()->install(mod);
|
|
* }
|
|
*/
|
|
class GEODE_DLL ModInstallFilter : public EventFilter<ModInstallEvent> {
|
|
protected:
|
|
std::string m_id;
|
|
|
|
public:
|
|
using Callback = void(ModInstallEvent*);
|
|
|
|
ListenerResult handle(utils::MiniFunction<Callback> fn, ModInstallEvent* event);
|
|
ModInstallFilter(std::string const& id);
|
|
ModInstallFilter(ModInstallFilter const&) = default;
|
|
};
|
|
|
|
/**
|
|
* Event broadcast when the index is being updated
|
|
*/
|
|
struct GEODE_DLL IndexUpdateEvent : public Event {
|
|
const UpdateStatus status;
|
|
IndexUpdateEvent(const UpdateStatus status);
|
|
};
|
|
|
|
/**
|
|
* Basic filter for listening to index update events. Always propagates
|
|
* the event down the chain
|
|
*/
|
|
class GEODE_DLL IndexUpdateFilter : public EventFilter<IndexUpdateEvent> {
|
|
public:
|
|
using Callback = void(IndexUpdateEvent*);
|
|
|
|
ListenerResult handle(utils::MiniFunction<Callback> fn, IndexUpdateEvent* event);
|
|
IndexUpdateFilter();
|
|
IndexUpdateFilter(IndexUpdateFilter const&) = default;
|
|
};
|
|
|
|
class GEODE_DLL IndexItem final {
|
|
public:
|
|
class Impl;
|
|
|
|
private:
|
|
std::unique_ptr<Impl> m_impl;
|
|
|
|
public:
|
|
/**
|
|
* Returns the path that contains all the versions
|
|
*/
|
|
ghc::filesystem::path getRootPath() const;
|
|
|
|
/**
|
|
* Returns the path to the specific version
|
|
*/
|
|
ghc::filesystem::path getPath() const;
|
|
ModMetadata getMetadata() const;
|
|
std::string getDownloadURL() const;
|
|
std::string getPackageHash() const;
|
|
std::unordered_set<PlatformID> getAvailablePlatforms() const;
|
|
bool isFeatured() const;
|
|
std::unordered_set<std::string> getTags() const;
|
|
bool isInstalled() const;
|
|
|
|
#if defined(GEODE_EXPOSE_SECRET_INTERNALS_IN_HEADERS_DO_NOT_DEFINE_PLEASE)
|
|
void setMetadata(ModMetadata const& value);
|
|
void setDownloadURL(std::string const& value);
|
|
void setPackageHash(std::string const& value);
|
|
void setAvailablePlatforms(std::unordered_set<PlatformID> const& value);
|
|
void setIsFeatured(bool const& value);
|
|
void setTags(std::unordered_set<std::string> const& value);
|
|
void setIsInstalled(bool const& value);
|
|
#endif
|
|
|
|
IndexItem();
|
|
~IndexItem();
|
|
|
|
friend class ModMetadata;
|
|
friend class Index;
|
|
};
|
|
using IndexItemHandle = std::shared_ptr<IndexItem>;
|
|
|
|
struct IndexInstallList {
|
|
/**
|
|
* Mod being installed
|
|
*/
|
|
IndexItemHandle target;
|
|
/**
|
|
* The mod, its dependencies, everything needed to install it
|
|
*/
|
|
std::vector<IndexItemHandle> list;
|
|
};
|
|
|
|
static constexpr size_t MAX_INDEX_API_VERSION = 0;
|
|
|
|
class GEODE_DLL Index final {
|
|
private:
|
|
class Impl;
|
|
std::unique_ptr<Impl> m_impl;
|
|
|
|
Index();
|
|
~Index();
|
|
|
|
public:
|
|
static Index* get();
|
|
|
|
/**
|
|
* Get all tags
|
|
*/
|
|
std::unordered_set<std::string> getTags() const;
|
|
|
|
/**
|
|
* Get all index items
|
|
*/
|
|
std::vector<IndexItemHandle> getItems() const;
|
|
/**
|
|
* Get all featured index items
|
|
*/
|
|
std::vector<IndexItemHandle> getFeaturedItems() const;
|
|
/**
|
|
* Get all latest index items
|
|
*/
|
|
std::vector<IndexItemHandle> getLatestItems() const;
|
|
/**
|
|
* Get all index items by a developer
|
|
*/
|
|
std::vector<IndexItemHandle> getItemsByDeveloper(
|
|
std::string const& name
|
|
) const;
|
|
/**
|
|
* Get all index items for a specific mod
|
|
*/
|
|
std::vector<IndexItemHandle> getItemsByModID(
|
|
std::string const& modID
|
|
) const;
|
|
/**
|
|
* Check if an item with this ID is found on the index, and optionally
|
|
* provide the version sought after
|
|
*/
|
|
bool isKnownItem(
|
|
std::string const& id,
|
|
std::optional<VersionInfo> version
|
|
) const;
|
|
/**
|
|
* Get an item from the index by its ID and optionally version
|
|
* @param id ID of the mod
|
|
* @param version Version to match exactly; if you need to match a range
|
|
* of versions, use the getItem overload that takes a
|
|
* ComparableVersionInfo
|
|
* @returns The item, or nullptr if the item was not found
|
|
*/
|
|
IndexItemHandle getItem(
|
|
std::string const& id,
|
|
std::optional<VersionInfo> version
|
|
) const;
|
|
/**
|
|
* Get an item from the index by its ID and version range
|
|
* @param id ID of the mod
|
|
* @param version Version to match
|
|
* @returns The item, or nullptr if the item was not found
|
|
*/
|
|
IndexItemHandle getItem(
|
|
std::string const& id,
|
|
ComparableVersionInfo version
|
|
) const;
|
|
/**
|
|
* Get the most major item from the index by its ID
|
|
* @param id ID of the mod
|
|
* @returns The item, or nullptr if the item was not found
|
|
*/
|
|
IndexItemHandle getMajorItem(
|
|
std::string const& id
|
|
) const;
|
|
/**
|
|
* Get an item from the index by its mod.json
|
|
* @param info The mod's metadata
|
|
* @returns The item, or nullptr if the item was not found
|
|
*/
|
|
IndexItemHandle getItem(ModMetadata const& metadata) const;
|
|
/**
|
|
* Get an item from the index that corresponds to an installed mod
|
|
* @param mod An installed mod
|
|
* @returns The item, or nullptr if the item was not found
|
|
*/
|
|
IndexItemHandle getItem(Mod* mod) const;
|
|
|
|
/**
|
|
* Check if an item has updates available
|
|
* @param item Item to check updates for
|
|
* @returns True if the version of the item on the index is newer than
|
|
* its installed counterpart
|
|
*/
|
|
bool isUpdateAvailable(IndexItemHandle item) const;
|
|
/**
|
|
* Check if any of the mods on the index have updates available
|
|
*/
|
|
bool areUpdatesAvailable() const;
|
|
/**
|
|
* Checks if the mod and its required dependencies can be installed
|
|
* @param item Item to get the list for
|
|
* @returns Success if the mod and its required dependencies can be installed, an error otherwise
|
|
*/
|
|
Result<> canInstall(IndexItemHandle item) const;
|
|
/**
|
|
* Get the list of items needed to install this item (dependencies, etc.)
|
|
* @param item Item to get the list for
|
|
* @returns The list, or an error if some items on the list cannot be installed
|
|
*/
|
|
Result<IndexInstallList> getInstallList(IndexItemHandle item) const;
|
|
/**
|
|
* Install an index item. Add an event listener for the ModInstallEvent
|
|
* class to track the installation progress. Automatically also downloads
|
|
* all missing dependencies for the item
|
|
* @param item Item to install
|
|
*/
|
|
void install(IndexItemHandle item);
|
|
/**
|
|
* Install a list of index items. Add an event listener for the
|
|
* ModInstallEvent class to track the installation progress
|
|
* @warning Does not download any missing dependencies - use the
|
|
* `install(IndexItemHandle)` overload if you aren't sure all the
|
|
* dependencies are installed!
|
|
* @param list List of items to install
|
|
*/
|
|
void install(IndexInstallList const& list);
|
|
/**
|
|
* Cancel an installation in progress
|
|
* @param item Installation to cancel
|
|
*/
|
|
void cancelInstall(IndexItemHandle item);
|
|
|
|
/**
|
|
* Check if it has been attempted to update the index. You can check
|
|
* for errors by doing hasTriedToUpdate() && !isUpToDate()
|
|
*/
|
|
bool hasTriedToUpdate() const;
|
|
/**
|
|
* Whether the index is up-to-date, i.e. all sources are up-to-date
|
|
*/
|
|
bool isUpToDate() const;
|
|
/**
|
|
* Whether the index is currently updating
|
|
*/
|
|
bool isUpdating() const;
|
|
/**
|
|
* Update the index. Add an event listener for the IndexUpdateEvent
|
|
* class to track updating progress
|
|
* @param force Forcefully update all sources, even if some have are
|
|
* already up-to-date
|
|
*/
|
|
void update(bool force = false);
|
|
};
|
|
}
|