diff --git a/example_community_patch_settings_da.toml b/example_community_patch_settings_da.toml index 2069b388a..a66188376 100644 --- a/example_community_patch_settings_da.toml +++ b/example_community_patch_settings_da.toml @@ -737,34 +737,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Previews diff --git a/example_community_patch_settings_de.toml b/example_community_patch_settings_de.toml index dc626072b..74db40076 100644 --- a/example_community_patch_settings_de.toml +++ b/example_community_patch_settings_de.toml @@ -737,34 +737,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Vorschauen diff --git a/example_community_patch_settings_en-GB-x-cockney.toml b/example_community_patch_settings_en-GB-x-cockney.toml index e1aed8205..e2ddda4bb 100644 --- a/example_community_patch_settings_en-GB-x-cockney.toml +++ b/example_community_patch_settings_en-GB-x-cockney.toml @@ -737,34 +737,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Previews diff --git a/example_community_patch_settings_en-x-minionese.toml b/example_community_patch_settings_en-x-minionese.toml index 562af2608..84b05e4d7 100644 --- a/example_community_patch_settings_en-x-minionese.toml +++ b/example_community_patch_settings_en-x-minionese.toml @@ -737,34 +737,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Previews diff --git a/example_community_patch_settings_en.toml b/example_community_patch_settings_en.toml index 8dcc031a6..2f41d3288 100644 --- a/example_community_patch_settings_en.toml +++ b/example_community_patch_settings_en.toml @@ -757,34 +757,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Previews diff --git a/example_community_patch_settings_es.toml b/example_community_patch_settings_es.toml index 795c8f1c8..aa45774c8 100644 --- a/example_community_patch_settings_es.toml +++ b/example_community_patch_settings_es.toml @@ -737,34 +737,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Previews diff --git a/example_community_patch_settings_fr.toml b/example_community_patch_settings_fr.toml index 8bf856ea3..21f0fb3c7 100644 --- a/example_community_patch_settings_fr.toml +++ b/example_community_patch_settings_fr.toml @@ -737,34 +737,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Previews diff --git a/example_community_patch_settings_nl.toml b/example_community_patch_settings_nl.toml index 719b54a1d..9ff9d9a46 100644 --- a/example_community_patch_settings_nl.toml +++ b/example_community_patch_settings_nl.toml @@ -737,34 +737,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Previews diff --git a/example_community_patch_settings_ru.toml b/example_community_patch_settings_ru.toml index 6e1d0ca2a..b8217547a 100644 --- a/example_community_patch_settings_ru.toml +++ b/example_community_patch_settings_ru.toml @@ -737,34 +737,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Previews diff --git a/example_community_patch_settings_tlh.toml b/example_community_patch_settings_tlh.toml index ca88ac0b1..9b6ad77cf 100644 --- a/example_community_patch_settings_tlh.toml +++ b/example_community_patch_settings_tlh.toml @@ -737,34 +737,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Previews diff --git a/mods/src/config.cc b/mods/src/config.cc index b69377fbb..d39f325da 100644 --- a/mods/src/config.cc +++ b/mods/src/config.cc @@ -1109,9 +1109,6 @@ void Config::Load() write_config)); this->mission_hud_buttons.emplace( "outposts", get_mission_hud_visibility(config, parsed, "hud_outposts", DCU::hud_outposts, write_config)); - this->mission_hud_buttons.emplace( - "daily_goals", - get_mission_hud_visibility(config, parsed, "hud_daily_goals", DCU::hud_daily_goals, write_config)); this->mission_hud_buttons.emplace( "missions", get_mission_hud_visibility(config, parsed, "hud_missions", DCU::hud_missions, write_config)); spdlog::debug(""); diff --git a/mods/src/defaultconfig.h b/mods/src/defaultconfig.h index 10764b99f..b0f04a24b 100644 --- a/mods/src/defaultconfig.h +++ b/mods/src/defaultconfig.h @@ -264,7 +264,6 @@ namespace UI constexpr bool cargo_format = true; constexpr bool officer_sort = true; constexpr const char* disabled_banner_types = ""; - constexpr const char* hud_daily_goals = "auto"; constexpr const char* hud_field_training = "auto"; constexpr const char* hud_missions = "auto"; constexpr const char* hud_outposts = "auto"; diff --git a/mods/src/il2cpp/method_contract.h b/mods/src/il2cpp/method_contract.h new file mode 100644 index 000000000..d7d1ccdc5 --- /dev/null +++ b/mods/src/il2cpp/method_contract.h @@ -0,0 +1,44 @@ +#pragma once + +#include "il2cpp-functions.h" +#include +#include +#include + +namespace method_contract +{ +inline bool Type(const Il2CppType* type, const char* name) +{ + if (!type || type->byref) return false; + auto* actual = il2cpp_type_get_name(type); + const bool matches = actual && std::strcmp(actual, name) == 0; + il2cpp_free(actual); + return matches; +} + +// Resolve the entire managed signature, including static/instance dispatch. +// A renamed, ambiguous or generic method is not a compatible callback. +inline const MethodInfo* Resolve(Il2CppClass* cls, const char* name, bool is_static, + const char* result, std::initializer_list parameters) +{ + if (!cls) return nullptr; + const MethodInfo* found = nullptr; + void* iterator = nullptr; + while (auto* method = il2cpp_class_get_methods(cls, &iterator)) { + if (std::strcmp(method->name, name) != 0 || !method->methodPointer || method->is_generic || method->is_inflated + || bool(method->flags & METHOD_ATTRIBUTE_STATIC) != is_static + || method->parameters_count != parameters.size() || !Type(method->return_type, result)) continue; + bool matches = true; + unsigned i = 0; + for (auto* parameter : parameters) + matches = Type(method->parameters[i++], parameter) && matches; + if (!matches) continue; + if (found) return nullptr; + found = method; + } + return found; +} + +inline void* Pointer(const MethodInfo* method) +{ return method ? reinterpret_cast(method->methodPointer) : nullptr; } +} // namespace method_contract diff --git a/mods/src/patches/parts/mission_hud_tweaks.cc b/mods/src/patches/parts/mission_hud_tweaks.cc index 512890be8..8b703bb2b 100644 --- a/mods/src/patches/parts/mission_hud_tweaks.cc +++ b/mods/src/patches/parts/mission_hud_tweaks.cc @@ -2,6 +2,7 @@ #include "errormsg.h" #include +#include #include #include @@ -26,17 +27,17 @@ struct MissionHudButtonDefinition { using ComponentGetGameObjectFn = void* (*)(void*); using GameObjectSetActiveFn = void (*)(void*, bool); -std::array g_button_definitions{{ +std::array g_button_definitions{{ {"q_trials", "_challengesButton"}, {"field_training", "_achievementsButton"}, {"outposts", "_outpostsButton"}, - {"daily_goals", "_dailyGoalsButton"}, {"missions", "_missionsButton"}, }}; std::vector g_configured_buttons; ComponentGetGameObjectFn g_get_game_object = nullptr; GameObjectSetActiveFn g_set_active = nullptr; +bool g_ready = false; std::string_view to_string(MissionHudVisibility visibility) { @@ -78,12 +79,19 @@ std::string ConfiguredButtonModes() return modes; } -bool ResolveButtonFields(IL2CppClassHelper& controller_helper) +bool ResolveButtonFields(IL2CppClassHelper& controller_helper, Il2CppClass* component_class) { auto valid_count = 0; for (auto* button : g_configured_buttons) { auto field = controller_helper.GetField(button->field_name); - if (!field.isValidHelper()) { + auto* info = field.get_info(); + const auto* type = info ? info->type : nullptr; + auto* field_class = type ? il2cpp_class_from_type(type) : nullptr; + if (!info || !type || type->byref || (il2cpp_field_get_flags(info) & FIELD_ATTRIBUTE_STATIC) + || (type->type != IL2CPP_TYPE_CLASS && type->type != IL2CPP_TYPE_GENERICINST) + || !field_class || !il2cpp_class_is_assignable_from(component_class, field_class) + || info->offset < sizeof(Il2CppObject) + || info->offset + sizeof(void*) > il2cpp_class_instance_size(controller_helper.get_cls())) { spdlog::error("MissionHudTweaks: unable to find MissionsHudViewController field '{}'", button->field_name); continue; } @@ -114,18 +122,49 @@ void ApplyButtonVisibility(void* controller, const MissionHudButtonDefinition& b } } // namespace -int32_t MissionsHudViewController_UpdateButtons_Hook(auto original, void* controller) +// Visibility is now refreshed through several independent paths. Keep the game's +// setup/notification work, then apply only explicitly configured overrides. +void ApplyConfiguredButtonVisibility(void* controller) { - const auto result = original(controller); - + if (!g_ready) + return; for (auto* button : g_configured_buttons) { button->visibility = Config::Get().MissionHudButtonVisibility(button->canonical_name); - if (button->visibility != MissionHudVisibility::Auto) { + if (button->visibility != MissionHudVisibility::Auto) ApplyButtonVisibility(controller, *button); - } } +} + +void MissionsHudViewController_OnEnable_Hook(auto original, void* controller) +{ + original(controller); + ApplyConfiguredButtonVisibility(controller); +} + +void MissionsHudViewController_SetupAchievementsButton_Hook(auto original, void* controller) +{ + original(controller); + ApplyConfiguredButtonVisibility(controller); +} - return result; +void MissionsHudViewController_SetupChallengesButton_Hook(auto original, void* controller, bool replace_with_outposts) +{ + original(controller, replace_with_outposts); + ApplyConfiguredButtonVisibility(controller); +} + +void MissionsHudViewController_SetupOutpostsButton_Hook(auto original, void* controller, bool show_outposts) +{ + original(controller, show_outposts); + ApplyConfiguredButtonVisibility(controller); +} + +void MissionsHudViewController_HandleOutpostsAndChallengesHUD_Hook(auto original, void* controller) +{ + // In planetary view this method hides challenges directly, bypassing its setup + // method. Reapply after the whole operation, including the planetary branch. + original(controller); + ApplyConfiguredButtonVisibility(controller); } void InstallMissionHudTweaksHooks() @@ -138,17 +177,17 @@ void InstallMissionHudTweaksHooks() return; } - if (!ResolveButtonFields(controller_helper)) { - return; - } - auto component_helper = il2cpp_get_class_helper("UnityEngine.CoreModule", "UnityEngine", "Component"); if (!component_helper.isValidHelper()) { ErrorMsg::MissingHelper("UnityEngine", "Component"); return; } - g_get_game_object = reinterpret_cast(component_helper.GetMethod("get_gameObject")); + if (!ResolveButtonFields(controller_helper, component_helper.get_cls())) + return; + const auto* get_game_object = method_contract::Resolve( + component_helper.get_cls(), "get_gameObject", false, "UnityEngine.GameObject", {}); + g_get_game_object = reinterpret_cast(method_contract::Pointer(get_game_object)); if (!g_get_game_object) { ErrorMsg::MissingMethod("Component", "get_gameObject"); return; @@ -160,22 +199,58 @@ void InstallMissionHudTweaksHooks() return; } - g_set_active = reinterpret_cast(game_object_helper.GetMethod("SetActive", 1)); + const auto* set_active = method_contract::Resolve( + game_object_helper.get_cls(), "SetActive", false, "System.Void", {"System.Boolean"}); + g_set_active = reinterpret_cast(method_contract::Pointer(set_active)); if (!g_set_active) { ErrorMsg::MissingMethod("GameObject", "SetActive"); return; } - auto update_buttons = controller_helper.GetMethod("UpdateButtons", 0); - if (!update_buttons) { - ErrorMsg::MissingMethod("MissionsHudViewController", "UpdateButtons"); + // Resolve the complete surface before installing anything. Avoid the tiny + // planetary/outpost event wrappers: these substantive methods own the work. + const auto* on_enable = method_contract::Resolve( + controller_helper.get_cls(), "OnEnable", false, "System.Void", {}); + const auto* achievements = method_contract::Resolve( + controller_helper.get_cls(), "SetupAchievementsButton", false, "System.Void", {}); + const auto* challenges = method_contract::Resolve( + controller_helper.get_cls(), "SetupChallengesButton", false, "System.Void", {"System.Boolean"}); + const auto* outposts = method_contract::Resolve( + controller_helper.get_cls(), "SetupOutpostsButton", false, "System.Void", {"System.Boolean"}); + const auto* combined = method_contract::Resolve( + controller_helper.get_cls(), "HandleOutpostsAndChallengesHUD", false, "System.Void", {}); + if (!on_enable || !achievements || !challenges || !outposts || !combined) { + spdlog::error("MissionHudTweaks: current HUD lifecycle/setup methods are missing; overrides disabled"); return; } - const auto configured_modes = ConfiguredButtonModes(); - if (!configured_modes.empty()) { - spdlog::info("MissionHudTweaks: applying {}", configured_modes); + const std::array targets{on_enable, achievements, challenges, outposts, combined}; + for (std::size_t i = 0; i < targets.size(); ++i) { + if (targets[i]->has_full_generic_sharing_signature) + return; + for (std::size_t j = 0; j < i; ++j) + if (targets[i]->methodPointer == targets[j]->methodPointer) { + spdlog::error("MissionHudTweaks: lifecycle/setup targets overlap; overrides disabled"); + return; + } + } + if (get_game_object->has_full_generic_sharing_signature || set_active->has_full_generic_sharing_signature) + return; + const auto modes = ConfiguredButtonModes(); + if (!modes.empty()) + spdlog::info("MissionHudTweaks: applying {}", modes); + const bool enabled = SPUD_STATIC_DETOUR(on_enable->methodPointer, MissionsHudViewController_OnEnable_Hook); + const bool achievement_hook = SPUD_STATIC_DETOUR(achievements->methodPointer, MissionsHudViewController_SetupAchievementsButton_Hook); + const bool challenge_hook = SPUD_STATIC_DETOUR(challenges->methodPointer, MissionsHudViewController_SetupChallengesButton_Hook); + const bool outpost_hook = SPUD_STATIC_DETOUR(outposts->methodPointer, MissionsHudViewController_SetupOutpostsButton_Hook); + const bool combined_hook = SPUD_STATIC_DETOUR(combined->methodPointer, MissionsHudViewController_HandleOutpostsAndChallengesHUD_Hook); + g_ready = enabled && achievement_hook && challenge_hook && outpost_hook && combined_hook; + if (g_ready) { + spdlog::info("MissionHudTweaks: installed current HUD lifecycle/setup hooks"); + } else { + // Successfully installed detours still call through, but must not partially + // enforce preferences when another refresh path could undo them. + g_configured_buttons.clear(); + spdlog::error("MissionHudTweaks: hook installation incomplete; overrides disabled"); } - SPUD_STATIC_DETOUR(update_buttons, MissionsHudViewController_UpdateButtons_Hook); - spdlog::info("MissionHudTweaks: installed MissionsHudViewController.UpdateButtons hook"); }