Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions example_community_patch_settings_en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ galacticanomalytimerhooks = true
game_version = true
giftsbulkclaimhooks = true
hotkeyhooks = true
havenhistoryhooks = true

# Show cargo totals immediately instead of counting up
instantcargocounterhooks = true
Expand Down Expand Up @@ -652,6 +653,9 @@ zoom_reset = "="
# <[===================================================================]>

[ui]
# Show the newest Haven help-history entries first
reverse_haven_history = true

# Skip the reveal box animation, and just open the boxes
always_skip_reveal_sequence = true
auto_confirm_discovery = true
Expand Down
4 changes: 4 additions & 0 deletions mods/src/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,8 @@ void Config::Load()
get_config_or_default(config, parsed, "patches", "officersorthooks", DCP::officersorthooks, write_config);
this->installPinnedShipSortHooks =
get_config_or_default(config, parsed, "patches", "pinnedshiphooks", DCP::pinnedshiphooks, write_config);
this->installHavenHistoryHooks =
get_config_or_default(config, parsed, "patches", "havenhistoryhooks", DCP::havenhistoryhooks, write_config);
spdlog::debug("");
this->queue_enabled =
get_config_or_default(config, parsed, "control", "queue_enabled", DCC::queue_enabled, write_config);
Expand Down Expand Up @@ -1082,6 +1084,8 @@ void Config::Load()
this->format_cargo_values = get_config_or_default_with_alias(
config, parsed, "ui", "format_cargo_values", "cargo_format", DCU::format_cargo_values, write_config);
this->officer_sort = get_config_or_default(config, parsed, "ui", "officer_sort", DCU::officer_sort, write_config);
this->reverse_haven_history = get_config_or_default(config, parsed, "ui", "reverse_haven_history",
DCU::reverse_haven_history, write_config);

this->arrow_keys_to_select_ship = get_config_or_default(config, parsed, "ui", "arrow_keys_to_select_ship",
DCU::arrow_keys_to_select_ship, write_config);
Expand Down
4 changes: 4 additions & 0 deletions mods/src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ class Config final
bool focus_search;
bool format_cargo_values;
bool officer_sort;
bool reverse_haven_history;
bool arrow_keys_to_select_ship;

bool show_cargo_default;
Expand Down Expand Up @@ -310,4 +311,7 @@ class Config final

// Fleet management dock ship sort: pin configured ships to the front
bool installPinnedShipSortHooks;

// Haven help-history list ordering
bool installHavenHistoryHooks;
};
2 changes: 2 additions & 0 deletions mods/src/defaultconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ namespace Patches
constexpr bool cargoformathooks = true; // on by default: cargo number precision override
constexpr bool officersorthooks = true; // restore Below Deck Ability sort option
constexpr bool pinnedshiphooks = true; // pin configured ships to front of fleet dock sort
constexpr bool havenhistoryhooks = true; // reverse Haven help history into newest-first order
} // namespace Patches

namespace Shortcuts
Expand Down Expand Up @@ -266,6 +267,7 @@ namespace UI
constexpr bool focus_search = true;
constexpr bool format_cargo_values = true;
constexpr bool officer_sort = true;
constexpr bool reverse_haven_history = true;
constexpr const char* disabled_banner_types = "";
constexpr const char* hud_daily_goals = "auto";
constexpr const char* hud_field_training = "auto";
Expand Down
86 changes: 86 additions & 0 deletions mods/src/patches/parts/haven_history.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include "config.h"
#include "errormsg.h"

#include <il2cpp/il2cpp-functions.h>
#include <il2cpp/il2cpp_helper.h>

#include <spdlog/spdlog.h>
#include <spud/detour.h>

#include <cstdint>
#include <vector>

namespace
{

void ReverseRecords(void* records)
{
if (!records)
return;

auto* listClass = il2cpp_object_get_class(reinterpret_cast<Il2CppObject*>(records));
if (!listClass)
return;

auto* getCount = il2cpp_class_get_method_from_name(listClass, "get_Count", 0);
auto* getItem = il2cpp_class_get_method_from_name(listClass, "get_Item", 1);
auto* setItem = il2cpp_class_get_method_from_name(listClass, "set_Item", 2);
if (!getCount || !getItem || !setItem) {
spdlog::warn("[HavenHistory] Record list is missing expected IList<T> methods");
return;
}

Il2CppException* exception = nullptr;
auto* countObj = il2cpp_runtime_invoke(getCount, records, nullptr, &exception);
if (exception || !countObj)
return;

const auto count = *reinterpret_cast<int32_t*>(il2cpp_object_unbox(countObj));
if (count <= 1)
return;
if (count > 2000) {
spdlog::warn("[HavenHistory] Record list reported an implausible count ({}); skipping", count);
return;
}

std::vector<void*> items;
items.reserve(count);
for (int32_t index = 0; index < count; ++index) {
void* getArgs[1] = {&index};
exception = nullptr;
auto* item = il2cpp_runtime_invoke(getItem, records, getArgs, &exception);
if (exception)
return;
items.push_back(item);
}

for (int32_t index = 0; index < count; ++index) {
void* setArgs[2] = {&index, items[count - index - 1]};
exception = nullptr;
il2cpp_runtime_invoke(setItem, records, setArgs, &exception);
if (exception)
return;
}
}

void PlanetaryHelpHistoryContext_ApplyRecords_Hook(auto original, void* _this, void* records)
{
if (Config::Get().reverse_haven_history)
ReverseRecords(records);
original(_this, records);
}

} // namespace

void InstallHavenHistoryHooks()
{
auto context = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.PlanetaryBase", "PlanetaryHelpHistoryContext");
auto applyRecords = context.GetMethod("ApplyRecords", 1);
if (!applyRecords) {
ErrorMsg::MissingMethod("PlanetaryHelpHistoryContext", "ApplyRecords");
return;
}

SPUD_STATIC_DETOUR(applyRecords, PlanetaryHelpHistoryContext_ApplyRecords_Hook);
spdlog::info("Haven history: hooks installed");
}
2 changes: 2 additions & 0 deletions mods/src/patches/patches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ void InstallDoubleClickAssignShipHooks();
void InstallInstantWarpConfirmationHooks();
void InstallForbiddenTechConfirmationHooks();
void InstallAudioEventHooks();
void InstallHavenHistoryHooks();

__int64 il2cpp_init_hook(auto original, const char* domain_name)
{
Expand Down Expand Up @@ -154,6 +155,7 @@ __int64 il2cpp_init_hook(auto original, const char* domain_name)
{"InstantWarpConfirm", {InstallInstantWarpConfirmationHooks, &cfg.installInstantWarpConfirmationHooks}},
{"ForbiddenTechConfirm", {InstallForbiddenTechConfirmationHooks, &cfg.installForbiddenTechConfirmationHooks}},
{"AudioEvents", {InstallAudioEventHooks, &cfg.installAudioEventHooks}},
{"HavenHistory", {InstallHavenHistoryHooks, &cfg.installHavenHistoryHooks}},
};
printf("il2cpp_init_hook(%s)\n", domain_name);

Expand Down
Loading