mirror of
https://github.com/N64Recomp/N64ModernRuntime.git
synced 2026-04-29 13:32:09 +00:00
Add deprecation versions.
This commit is contained in:
parent
8693dbdd35
commit
ca568b6ad7
4 changed files with 70 additions and 19 deletions
|
|
@ -46,6 +46,14 @@ namespace recomp {
|
|||
int patch = -1;
|
||||
std::string suffix;
|
||||
|
||||
Version() = default;
|
||||
Version(int major, int minor, int patch, std::string suffix = std::string()) {
|
||||
this->major = major;
|
||||
this->minor = minor;
|
||||
this->patch = patch;
|
||||
this->suffix = suffix;
|
||||
}
|
||||
|
||||
std::string to_string() const {
|
||||
return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(patch) + suffix;
|
||||
}
|
||||
|
|
@ -60,7 +68,11 @@ namespace recomp {
|
|||
return minor <=> rhs.minor;
|
||||
}
|
||||
return patch <=> rhs.patch;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_null() const {
|
||||
return (major == -1) && (minor == -1) && (patch == -1) && suffix.empty();
|
||||
}
|
||||
};
|
||||
enum class RomValidationError {
|
||||
Good,
|
||||
|
|
|
|||
|
|
@ -158,7 +158,18 @@ namespace recomp {
|
|||
Unknown,
|
||||
|
||||
// The mod was integrated as part of the project.
|
||||
Integrated
|
||||
Integrated,
|
||||
|
||||
// The mod is known to have a game breaking issue, but can be fixed by updating it.
|
||||
BrokenVersion,
|
||||
|
||||
// The mod is known to have a game breaking issue that is not fixable.
|
||||
BrokenPermanent
|
||||
};
|
||||
|
||||
struct DeprecatedMod {
|
||||
DeprecationStatus status;
|
||||
Version maximum_version;
|
||||
};
|
||||
|
||||
struct ModFileHandle {
|
||||
|
|
@ -329,15 +340,16 @@ namespace recomp {
|
|||
|
||||
void register_game(const std::string& mod_game_id);
|
||||
void register_embedded_mod(const std::string& mod_id, std::span<const uint8_t> mod_bytes);
|
||||
void register_deprecated_mod(const std::string& mod_id, DeprecationStatus deprecation_status);
|
||||
void register_deprecated_mod(const std::string& mod_id, DeprecationStatus deprecation_status, const Version& maximum_version);
|
||||
std::vector<ModOpenErrorDetails> scan_mod_folder(const std::filesystem::path& mod_folder);
|
||||
void close_mods();
|
||||
void load_mods_config();
|
||||
void enable_mod(const std::string& mod_id, bool enabled, bool trigger_save);
|
||||
bool is_mod_enabled(const std::string& mod_id) const;
|
||||
bool is_mod_auto_enabled(const std::string& mod_id) const;
|
||||
bool is_mod_deprecated(const std::string& mod_id) const;
|
||||
bool is_mod_deprecated(const std::string& mod_id, const Version& mod_version) const;
|
||||
DeprecationStatus get_mod_deprecation_status(const std::string& mod_id) const;
|
||||
Version get_mod_deprecation_version(const std::string& mod_id) const;
|
||||
size_t num_opened_mods();
|
||||
std::vector<ModLoadErrorDetails> load_mods(const GameEntry& game_entry, const std::string& game_mode_id, uint8_t* rdram, int32_t load_address, uint32_t& ram_used);
|
||||
void unload_mods();
|
||||
|
|
@ -404,7 +416,7 @@ namespace recomp {
|
|||
std::unordered_set<std::string> mod_ids;
|
||||
std::unordered_set<std::string> enabled_mods;
|
||||
std::unordered_set<std::string> auto_enabled_mods;
|
||||
std::unordered_map<std::string, DeprecationStatus> deprecated_mods;
|
||||
std::unordered_map<std::string, DeprecatedMod> deprecated_mods;
|
||||
std::unordered_map<recomp_func_t*, PatchData> patched_funcs;
|
||||
std::unordered_map<std::string, size_t> loaded_mods_by_id;
|
||||
std::unique_ptr<std::thread> mod_configuration_thread;
|
||||
|
|
@ -610,7 +622,7 @@ namespace recomp {
|
|||
|
||||
void initialize_mods();
|
||||
void register_embedded_mod(const std::string& mod_id, std::span<const uint8_t> mod_bytes);
|
||||
void register_deprecated_mod(const std::string &mod_id, recomp::mods::DeprecationStatus deprecation_status);
|
||||
void register_deprecated_mod(const std::string& mod_id, DeprecationStatus deprecation_status, const Version &maximum_version);
|
||||
void scan_mods();
|
||||
void close_mods();
|
||||
std::filesystem::path get_mods_directory();
|
||||
|
|
@ -622,8 +634,9 @@ namespace recomp {
|
|||
void enable_mod(const std::string& mod_id, bool enabled);
|
||||
bool is_mod_enabled(const std::string& mod_id);
|
||||
bool is_mod_auto_enabled(const std::string& mod_id);
|
||||
bool is_mod_deprecated(const std::string& mod_id);
|
||||
bool is_mod_deprecated(const std::string& mod_id, const Version& mod_version);
|
||||
DeprecationStatus get_mod_deprecation_status(const std::string& mod_id);
|
||||
Version get_mod_deprecation_version(const std::string& mod_id);
|
||||
std::string deprecation_status_to_message(DeprecationStatus deprecation_status);
|
||||
const config::ConfigSchema &get_mod_config_schema(const std::string &mod_id);
|
||||
config::Config *get_mod_config(const std::string &mod_id);
|
||||
|
|
|
|||
|
|
@ -636,8 +636,9 @@ void recomp::mods::ModContext::register_embedded_mod(const std::string &mod_id,
|
|||
embedded_mod_bytes.emplace(mod_id, mod_bytes);
|
||||
}
|
||||
|
||||
void recomp::mods::ModContext::register_deprecated_mod(const std::string& mod_id, DeprecationStatus deprecation_status) {
|
||||
deprecated_mods[mod_id] = deprecation_status;
|
||||
void recomp::mods::ModContext::register_deprecated_mod(const std::string& mod_id, DeprecationStatus deprecation_status, const Version &maximum_version) {
|
||||
deprecated_mods[mod_id].status = deprecation_status;
|
||||
deprecated_mods[mod_id].maximum_version = maximum_version;
|
||||
}
|
||||
|
||||
void recomp::mods::ModContext::close_mods() {
|
||||
|
|
@ -1042,7 +1043,7 @@ void recomp::mods::ModContext::enable_mod(const std::string& mod_id, bool enable
|
|||
}
|
||||
|
||||
// Do nothing if this mod was deprecated.
|
||||
if (is_mod_deprecated(mod_id)) {
|
||||
if (is_mod_deprecated(mod.manifest.mod_id, mod.manifest.version)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1070,7 +1071,7 @@ void recomp::mods::ModContext::enable_mod(const std::string& mod_id, bool enable
|
|||
if (mod_from_stack_it != opened_mods_by_id.end()) {
|
||||
const ModHandle &mod_from_stack_handle = opened_mods[mod_from_stack_it->second];
|
||||
for (const Dependency &dependency : mod_from_stack_handle.manifest.dependencies) {
|
||||
if (!dependency.optional && !auto_enabled_mods.contains(dependency.mod_id) && !is_mod_deprecated(dependency.mod_id)) {
|
||||
if (!dependency.optional && !auto_enabled_mods.contains(dependency.mod_id) && !is_mod_deprecated(dependency.mod_id, dependency.version)) {
|
||||
auto_enabled_mods.emplace(dependency.mod_id);
|
||||
mod_stack.emplace_back(dependency.mod_id);
|
||||
|
||||
|
|
@ -1115,7 +1116,7 @@ void recomp::mods::ModContext::enable_mod(const std::string& mod_id, bool enable
|
|||
if (mod_from_stack_it != opened_mods_by_id.end()) {
|
||||
const ModHandle &mod_from_stack_handle = opened_mods[mod_from_stack_it->second];
|
||||
for (const Dependency &dependency : mod_from_stack_handle.manifest.dependencies) {
|
||||
if (!dependency.optional && !new_auto_enabled_mods.contains(dependency.mod_id) && !is_mod_deprecated(dependency.mod_id)) {
|
||||
if (!dependency.optional && !new_auto_enabled_mods.contains(dependency.mod_id) && !is_mod_deprecated(dependency.mod_id, dependency.version)) {
|
||||
new_auto_enabled_mods.emplace(dependency.mod_id);
|
||||
mod_stack.emplace_back(dependency.mod_id);
|
||||
}
|
||||
|
|
@ -1159,20 +1160,36 @@ bool recomp::mods::ModContext::is_mod_auto_enabled(const std::string& mod_id) co
|
|||
return auto_enabled_mods.contains(mod_id);
|
||||
}
|
||||
|
||||
bool recomp::mods::ModContext::is_mod_deprecated(const std::string& mod_id) const {
|
||||
return get_mod_deprecation_status(mod_id) != DeprecationStatus::Unknown;
|
||||
bool recomp::mods::ModContext::is_mod_deprecated(const std::string& mod_id, const Version& mod_version) const {
|
||||
auto it = deprecated_mods.find(mod_id);
|
||||
if (it != deprecated_mods.end()) {
|
||||
return (it->second.status != recomp::mods::DeprecationStatus::Unknown) && (it->second.maximum_version.is_null() || (mod_version <= it->second.maximum_version));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
recomp::mods::DeprecationStatus recomp::mods::ModContext::get_mod_deprecation_status(const std::string& mod_id) const {
|
||||
auto it = deprecated_mods.find(mod_id);
|
||||
if (it != deprecated_mods.end()) {
|
||||
return it->second;
|
||||
return it->second.status;
|
||||
}
|
||||
else {
|
||||
return recomp::mods::DeprecationStatus::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
recomp::Version recomp::mods::ModContext::get_mod_deprecation_version(const std::string& mod_id) const {
|
||||
auto it = deprecated_mods.find(mod_id);
|
||||
if (it != deprecated_mods.end()) {
|
||||
return it->second.maximum_version;
|
||||
}
|
||||
else {
|
||||
return Version();
|
||||
}
|
||||
}
|
||||
|
||||
size_t recomp::mods::ModContext::num_opened_mods() {
|
||||
return opened_mods.size();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,9 +102,9 @@ void recomp::mods::register_embedded_mod(const std::string &mod_id, std::span<co
|
|||
mod_context->register_embedded_mod(mod_id, mod_bytes);
|
||||
}
|
||||
|
||||
void recomp::mods::register_deprecated_mod(const std::string& mod_id, recomp::mods::DeprecationStatus deprecation_status) {
|
||||
void recomp::mods::register_deprecated_mod(const std::string& mod_id, recomp::mods::DeprecationStatus deprecation_status, const Version& maximum_version) {
|
||||
std::lock_guard<std::mutex> lock(mod_context_mutex);
|
||||
mod_context->register_deprecated_mod(mod_id, deprecation_status);
|
||||
mod_context->register_deprecated_mod(mod_id, deprecation_status, maximum_version);
|
||||
}
|
||||
|
||||
void recomp::mods::scan_mods() {
|
||||
|
|
@ -575,9 +575,9 @@ bool recomp::mods::is_mod_auto_enabled(const std::string& mod_id) {
|
|||
return mod_context->is_mod_auto_enabled(mod_id);
|
||||
}
|
||||
|
||||
bool recomp::mods::is_mod_deprecated(const std::string& mod_id) {
|
||||
bool recomp::mods::is_mod_deprecated(const std::string& mod_id, const recomp::Version& mod_version) {
|
||||
std::lock_guard lock{ mod_context_mutex };
|
||||
return mod_context->is_mod_deprecated(mod_id);
|
||||
return mod_context->is_mod_deprecated(mod_id, mod_version);
|
||||
}
|
||||
|
||||
recomp::mods::DeprecationStatus recomp::mods::get_mod_deprecation_status(const std::string& mod_id) {
|
||||
|
|
@ -585,10 +585,19 @@ recomp::mods::DeprecationStatus recomp::mods::get_mod_deprecation_status(const s
|
|||
return mod_context->get_mod_deprecation_status(mod_id);
|
||||
}
|
||||
|
||||
recomp::Version recomp::mods::get_mod_deprecation_version(const std::string& mod_id) {
|
||||
std::lock_guard lock{ mod_context_mutex };
|
||||
return mod_context->get_mod_deprecation_version(mod_id);
|
||||
}
|
||||
|
||||
std::string recomp::mods::deprecation_status_to_message(DeprecationStatus deprecation_status) {
|
||||
switch (deprecation_status) {
|
||||
case DeprecationStatus::Integrated:
|
||||
return "This mod has already been integrated into the game";
|
||||
case DeprecationStatus::BrokenVersion:
|
||||
return "This version of the mod is known to cause issues. Please update it";
|
||||
case DeprecationStatus::BrokenPermanent:
|
||||
return "This mod is known to cause issues. Please uninstall it";
|
||||
default:
|
||||
return "Reason is unknown";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue