diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 574edae..7481fa7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,19 +1,23 @@ # Contributing +This project is entirely maintained in my own personal free time, and updated as and when that time +is available. Any help by submitting pull requests is greatly welcome and any donations or +sponsorships are greatly appreciated. + ## Building First clone and initialize the repository: ```bash -git clone https://github.com/tashcan/bob.git +git clone https://github.com/netniv/bob.git cd bob ``` ## Installing -Please note that when this project compiles, it will create a DLL called `stfc-community-patch.dll`. This -file must be either copied to the `C:\Games\Star Trek Fleet Command\Star Trek Fleet Command\default\game` -folder as `version.dll` or create a symbolic link to the file using an elevated (administrator) command +Please note that when this project compiles, it will create a DLL called `stfc-community-patch.dll`. This +file must be either copied to the `C:\Games\Star Trek Fleet Command\Star Trek Fleet Command\default\game` +folder as `version.dll` or create a symbolic link to the file using an elevated (administrator) command prompt: ```console @@ -33,18 +37,18 @@ You may see the following error, and this normally occurs if your SDK is below t The and headers are only supported with /await and implement pre-C++20 coroutine support. Use for standard C++20 coroutines ``` -If you have Visual Studio 2022, make sure to have the Windows 11 SDK selected as a minimum, even if you -are running the Visual Studio IDE on Windows 10. The Windows 11 SDK will also create targets that work +If you have Visual Studio 2022, make sure to have the Windows 11 SDK selected as a minimum, even if you +are running the Visual Studio IDE on Windows 10. The Windows 11 SDK will also create targets that work for Windows 10. -You can do this via the Visual Studio Installer. The Visual Studio Installer will show any other versions -of Visual Studio, so please make sure to use the `Modify` button on the correct one. You can launch the -Visual Studio Installer from within Visual Studio 2022 via the `Tools -> Get Tools and Features` menu -option, or through `Settings -> Apps -> Visual Studio -> Modify`. +You can do this via the Visual Studio Installer. The Visual Studio Installer will show any other versions +of Visual Studio, so please make sure to use the `Modify` button on the correct one. You can launch the +Visual Studio Installer from within Visual Studio 2022 via the `Tools -> Get Tools and Features` menu +option, or through `Settings -> Apps -> Visual Studio -> Modify`. -Once you are modifying the correct Visual Studio 2022 instance, select the `Individual Components` tab and -click into the Filter textbox. Enter the type `SDK` which should provided a minimal filtered list of SDK's -available. You should see Windows 11 SDK listed and has a tick. If not, please click the tick box and then +Once you are modifying the correct Visual Studio 2022 instance, select the `Individual Components` tab and +click into the Filter textbox. Enter the type `SDK` which should provided a minimal filtered list of SDK's +available. You should see Windows 11 SDK listed and has a tick. If not, please click the tick box and then apply the changes to have the SDK downloaded and installed. This will take around 2-3GB of space. #### Configure and building the project @@ -59,22 +63,22 @@ xmake project -k vsxmake -m "debug,release" You will now find a `bob.sln` file inside `vsxmake2022`(or similarly named). You can simply open that in `Visual Studio` and Build the solution. -**IMPORTANT**: To reset the build, you can remove the `build/` folder and all items beneath it. Visual +**IMPORTANT**: To reset the build, you can remove the `build/` folder and all items beneath it. Visual Studio will then rebuild the project. **IMPORTANT**: To fully reset the project, also remove the `.vs/` folder. ### Visual Studio Code -If you want to use Visual Studio Code, you may still need to make sure the various SDK's and MSVC runtimes +If you want to use Visual Studio Code, you may still need to make sure the various SDK's and MSVC runtimes are available. -Once they are installed, either standalone or via Visual Studio, you can open the `bob` folder inside -Visual Studio or by right clicking in a Windows Explorer via and selecting `Open with Visual Studio Code`. -When it first opens, it should ask you to install the XMake extension. Once the extensions are +Once they are installed, either standalone or via Visual Studio, you can open the `bob` folder inside +Visual Studio or by right clicking in a Windows Explorer via and selecting `Open with Visual Studio Code`. +When it first opens, it should ask you to install the XMake extension. Once the extensions are installed, you can build the project by navigating to the XMake section in the Activity Bar and clicking `Build All` at the top. -**IMPORTANT**: To reset the build, you can remove the `build/` folder and all items beneath it. Visual +**IMPORTANT**: To reset the build, you can remove the `build/` folder and all items beneath it. Visual Studio Code will then rebuild the project. ### Command Line diff --git a/README.md b/README.md index 5bbe791..4a92f2c 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@

License: GPLv3 + Sponsorship

@@ -11,7 +12,7 @@ ## Features - Set system UI scale + adjustment factor -- Set viewer UI scale +- Set viewer UI scale - Set system zoom - default - maximum @@ -97,7 +98,7 @@ names: - community_patch_settings.toml - version.dll -The pre-compiled DLL can be downloaded from the official assets hosted on [GitHub Releases](https://github.com/tashcan/bob/releases) +The pre-compiled DLL can be downloaded from the official assets hosted on [GitHub Releases](https://github.com/netniv/bob/releases) ## Configuration @@ -142,10 +143,10 @@ The most common problems getting the DLL to work are: ## Support -Tashcan has now retired all things STFC from [Ripper's Corner](https://discord.gg/gPuQ5sPYM9) but still swing by to say hello to the wonderful man. - For STFC Community Mod items, please visit the [STFC Community Mod](https://discord.gg/PrpHgs7Vjs) discord server. +Tashcan has now retired all things STFC from [Ripper's Corner](https://discord.gg/gPuQ5sPYM9) but still swing by to say hello to the wonderful man. + ## Disclaimer This is intended to give people insight and possiblity to add new things for QoL improvements. diff --git a/example_community_patch_settings.toml b/example_community_patch_settings.toml index 5698373..bf6d7dd 100644 --- a/example_community_patch_settings.toml +++ b/example_community_patch_settings.toml @@ -13,9 +13,6 @@ hotkeys_extended = true use_scopely_hotkeys = false [graphics] -# This is an option that can be enabled to try and keep a more 'useable' UI scale size when resizing the Game Window, defaults to false -adjust_scale_res = false - # Allow borderless full screen mode, set to false to disable borderless_fullscreen_f11 = true diff --git a/macos-launcher/src/GitHubLib.swift b/macos-launcher/src/GitHubLib.swift index 3c15896..779de46 100644 --- a/macos-launcher/src/GitHubLib.swift +++ b/macos-launcher/src/GitHubLib.swift @@ -2,7 +2,7 @@ import Foundation struct GitHubUpdater { func latestPatchVersion() async -> Int { - let url = URL(string: "https://api.github.com/repos/tashcan/bob/releases/latest")! + let url = URL(string: "https://api.github.com/repos/netniv/bob/releases/latest")! do { let (data, _) = try await URLSession.shared.data(from: url) let json = try JSONSerialization.jsonObject(with: data) as! [String: Any] diff --git a/mods/src/config.cc b/mods/src/config.cc index aef7764..30c7a10 100644 --- a/mods/src/config.cc +++ b/mods/src/config.cc @@ -416,7 +416,6 @@ void Config::Load() this->ui_scale_viewer = get_config_or_default(config, parsed, "graphics", "ui_scale_viewer", 1.0f); this->zoom = get_config_or_default(config, parsed, "graphics", "zoom", 2500.f); this->free_resize = get_config_or_default(config, parsed, "graphics", "free_resize", true); - this->adjust_scale_res = get_config_or_default(config, parsed, "graphics", "adjust_scale_res", false); this->keyboard_zoom_speed = get_config_or_default(config, parsed, "graphics", "keyboard_zoom_speed", 350.0f); if (this->enable_experimental) { @@ -564,6 +563,7 @@ void Config::Load() parse_config_shortcut(config, parsed, "action_primary", GameFunction::ActionPrimary, "SPACE"); parse_config_shortcut(config, parsed, "action_secondary", GameFunction::ActionSecondary, "R"); + parse_config_shortcut(config, parsed, "action_queue", GameFunction::ActionQueue, "V"); parse_config_shortcut(config, parsed, "action_view", GameFunction::ActionView, "V"); parse_config_shortcut(config, parsed, "action_recall", GameFunction::ActionRecall, "R"); parse_config_shortcut(config, parsed, "action_recall_cancel", GameFunction::ActionRecallCancel, "SPACE"); @@ -668,6 +668,6 @@ void Config::Load() << "Loaded beta version " << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION << " (Release)" #endif - << "\n\nPlease see https://github.com/tashcan/bob for latest configuration help, examples and future releases\n" + << "\n\nPlease see https://github.com/netniv/bob for latest configuration help, examples and future releases\n" << "or visit the STFC Community Mod discord server at https://discord.gg/PrpHgs7Vjs\n\n"; } diff --git a/mods/src/errormsg.h b/mods/src/errormsg.h new file mode 100644 index 0000000..e2bbd42 --- /dev/null +++ b/mods/src/errormsg.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +class ErrorMsg +{ +public: + static void MissingMethod(const char* classname, const char* methodname) + { + spdlog::error("Unable to find method '{}->{}'", classname, methodname); + } + + static void MissingStaticMethod(const char* classname, const char* methodname) + { + spdlog::error("Unable to find method '{}::{}'", classname, methodname); + } + + static void MissingHelper(const char* namespacename, const char* classname) + { + spdlog::error("Unable to find helper '{}.{}'", namespacename, classname); + } +}; diff --git a/mods/src/il2cpp/il2cpp_helper.h b/mods/src/il2cpp/il2cpp_helper.h index e36e7dc..b8673de 100644 --- a/mods/src/il2cpp/il2cpp_helper.h +++ b/mods/src/il2cpp/il2cpp_helper.h @@ -136,6 +136,10 @@ class IL2CppClassHelper return obj; } + bool HasClass() { + return this->cls != nullptr; + } + template T* GetMethod(const char* name, int arg_count = -1) { if (!this->cls) { diff --git a/mods/src/patches/gamefunctions.h b/mods/src/patches/gamefunctions.h index 01bf784..a33afdb 100644 --- a/mods/src/patches/gamefunctions.h +++ b/mods/src/patches/gamefunctions.h @@ -59,6 +59,7 @@ enum GameFunction { UiViewerScaleDown, ActionPrimary, ActionSecondary, + ActionQueue, ActionView, ActionRecall, ActionRecallCancel, diff --git a/mods/src/patches/parts/buff_fixes.cc b/mods/src/patches/parts/buff_fixes.cc index d131833..adcb93b 100644 --- a/mods/src/patches/parts/buff_fixes.cc +++ b/mods/src/patches/parts/buff_fixes.cc @@ -1,4 +1,5 @@ #include "config.h" +#include "errormsg.h" #include "prime_types.h" #include @@ -101,37 +102,46 @@ bool FleetService_ResolveOfficerAbilityBuffs_Hook(auto original, int64_t _fleet) void InstallBuffFixHooks() { - auto screen_manager_helper = + auto buffhelper = il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Services", "BuffService"); - auto ptr = screen_manager_helper.GetMethod("IsBuffConditionMet"); - if (!ptr) { - return; - } - SPUD_STATIC_DETOUR(ptr, BuffService_IsBuffConditionMet_Hook); + if (!buffhelper.HasClass()) { + ErrorMsg::MissingHelper("Services", "BuffService"); + } else { + auto ptr = buffhelper.GetMethod("IsBuffConditionMet"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("BuffServices", "IsBuffConditionMet"); + } else { + SPUD_STATIC_DETOUR(ptr, BuffService_IsBuffConditionMet_Hook); + } - screen_manager_helper = - il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Services", "FleetService"); - ptr = screen_manager_helper.GetMethod("ResolveOfficerAbilityBuffs"); - if (!ptr) { - return; + ptr = buffhelper.GetMethodSpecial("ApplyBuffModifiersToCostVal", [](auto count, const Il2CppType **params) { + if (count != 2) { + return false; + } + auto p2 = params[1]->type; + if (p2 == IL2CPP_TYPE_VALUETYPE) { + return true; + } + return false; + }); + + if (ptr == nullptr) { + ErrorMsg::MissingMethod("BuffService", "ApplyBuffModifiersToCostVal"); + } else { + SPUD_STATIC_DETOUR(ptr, BuffService_ApplyBuffModifiersToCostVal_1_Hook); + } } - SPUD_STATIC_DETOUR(ptr, FleetService_ResolveOfficerAbilityBuffs_Hook); - screen_manager_helper = - il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Services", "BuffService"); - ptr = - screen_manager_helper.GetMethodSpecial("ApplyBuffModifiersToCostVal", [](auto count, const Il2CppType **params) { - if (count != 2) { - return false; - } - auto p2 = params[1]->type; - if (p2 == IL2CPP_TYPE_VALUETYPE) { - return true; - } - return false; - }); - if (!ptr) { - return; + auto fleethelper = + il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Services", "FleetService"); + if (!fleethelper.HasClass()) { + ErrorMsg::MissingHelper("Services", "FleetService"); + } else { + auto ptr = fleethelper.GetMethod("ResolveOfficerAbilityBuffs"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("FleetService", "IsBuffConditionMet"); + } else { + SPUD_STATIC_DETOUR(ptr, FleetService_ResolveOfficerAbilityBuffs_Hook); + } } - SPUD_STATIC_DETOUR(ptr, BuffService_ApplyBuffModifiersToCostVal_1_Hook); -} \ No newline at end of file +} diff --git a/mods/src/patches/parts/chat.cc b/mods/src/patches/parts/chat.cc index d30631b..f73ddaa 100644 --- a/mods/src/patches/parts/chat.cc +++ b/mods/src/patches/parts/chat.cc @@ -3,6 +3,7 @@ #include "prime/GenericButtonContext.h" #include "config.h" +#include "errormsg.h" #include @@ -73,25 +74,43 @@ void InstallChatPatches() { static auto fullscreen_controller = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Chat", "FullScreenChatViewController"); - auto ptr = fullscreen_controller.GetMethod("AboutToShow"); - if (ptr) { - SPUD_STATIC_DETOUR(ptr, FullScreenChatViewController_AboutToShow); + + if (!fullscreen_controller.HasClass()) { + ErrorMsg::MissingHelper("Chat", "FullScreenChatViewController"); + } else { + auto ptr = fullscreen_controller.GetMethod("AboutToShow"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("FullScreenChatViewController", "AboutToShow"); + } else { + SPUD_STATIC_DETOUR(ptr, FullScreenChatViewController_AboutToShow); + } } static auto preview_controller = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Chat", "ChatPreviewController"); - ptr = preview_controller.GetMethod("AboutToShow"); - if (ptr) { - SPUD_STATIC_DETOUR(ptr, ChatPreviewController_AboutToShow); - } - ptr = preview_controller.GetMethod("OnPanel_Focused"); - if (ptr) { - SPUD_STATIC_DETOUR(ptr, ChatPreviewController_OnPanel_Focused); - } + if (!preview_controller.HasClass()) { + ErrorMsg::MissingHelper("Chat", "ChatPreviewController"); + } else { + auto ptr = preview_controller.GetMethod("AboutToShow"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("ChatPreviewController", "AboutToShow"); + } else { + SPUD_STATIC_DETOUR(ptr, ChatPreviewController_AboutToShow); + } + + ptr = preview_controller.GetMethod("OnPanel_Focused"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("ChatPreviewController", "OnPanel_Focused"); + } else { + SPUD_STATIC_DETOUR(ptr, ChatPreviewController_OnPanel_Focused); + } - ptr = preview_controller.GetMethod("OnGlobalMessageReceived"); - if (ptr) { - SPUD_STATIC_DETOUR(ptr, ChatPreviewController_OnGlobalMessageReceived); + ptr = preview_controller.GetMethod("OnGlobalMessageReceived"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("ChatPreviewController", "OnGlobalMessageReceived"); + } else { + SPUD_STATIC_DETOUR(ptr, ChatPreviewController_OnGlobalMessageReceived); + } } -} \ No newline at end of file +} diff --git a/mods/src/patches/parts/disable_banners.cc b/mods/src/patches/parts/disable_banners.cc index 794ffe5..c18afe3 100644 --- a/mods/src/patches/parts/disable_banners.cc +++ b/mods/src/patches/parts/disable_banners.cc @@ -1,4 +1,5 @@ #include "config.h" +#include "errormsg.h" #include #include @@ -31,16 +32,21 @@ void ToastObserver_EnqueueOrCombineToast_Hook(auto original, ToastObserver *_thi void InstallToastBannerHooks() { auto helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.HUD", "ToastObserver"); - auto ptr = helper.GetMethod("EnqueueToast"); - if (!ptr) { - return; - } - SPUD_STATIC_DETOUR(ptr, ToastObserver_EnqueueToast_Hook); + if (!helper.HasClass()) { + ErrorMsg::MissingHelper("HUD", "ToastObserver"); + } else { + auto ptr = helper.GetMethod("EnqueueToast"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("ToastObserver", "EnqueueTosat"); + } else { + SPUD_STATIC_DETOUR(ptr, ToastObserver_EnqueueToast_Hook); + } - helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.HUD", "ToastObserver"); - ptr = helper.GetMethod("EnqueueOrCombineToast"); - if (!ptr) { - return; + ptr = helper.GetMethod("EnqueueOrCombineToast"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("ToastObserver", "EnqueueOrCombineToast"); + } else { + SPUD_STATIC_DETOUR(ptr, ToastObserver_EnqueueOrCombineToast_Hook); + } } - SPUD_STATIC_DETOUR(ptr, ToastObserver_EnqueueOrCombineToast_Hook); } diff --git a/mods/src/patches/parts/fix_pan.cc b/mods/src/patches/parts/fix_pan.cc index 128a9f7..5b42ccf 100644 --- a/mods/src/patches/parts/fix_pan.cc +++ b/mods/src/patches/parts/fix_pan.cc @@ -1,4 +1,5 @@ #include "config.h" +#include "errormsg.h" #include @@ -43,18 +44,27 @@ bool NavigationPan_LateUpdate_Hook(auto original, NavigationPan *_this) void InstallPanHooks() { - auto helper = il2cpp_get_class_helper("Assembly-CSharp-firstpass", "", "TKTouch"); - auto ptr = helper.GetMethod("populateWithPosition"); - if (!ptr) { - return; + auto touchhelper = il2cpp_get_class_helper("Assembly-CSharp-firstpass", "", "TKTouch"); + if (!touchhelper.HasClass()) { + ErrorMsg::MissingHelper("", "TKTouch"); + } else { + auto ptr = touchhelper.GetMethod("populateWithPosition"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("TKTouch", "populateWithPosition"); + } else { + SPUD_STATIC_DETOUR(ptr, TKTouch_populateWithPosition_Hook); + } } - SPUD_STATIC_DETOUR(ptr, TKTouch_populateWithPosition_Hook); - - auto h = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Navigation", "NavigationPan"); - ptr = h.GetMethod("LateUpdate"); - if (!ptr) { - return; + auto navhelper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Navigation", "NavigationPan"); + if (!navhelper.HasClass()) { + ErrorMsg::MissingHelper("Navgiation", "NavigationPan"); + } else { + auto ptr = navhelper.GetMethod("LateUpdate"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("NavigationPan", "LateUpdate"); + } else { + SPUD_STATIC_DETOUR(ptr, NavigationPan_LateUpdate_Hook); + } } - SPUD_STATIC_DETOUR(ptr, NavigationPan_LateUpdate_Hook); } diff --git a/mods/src/patches/parts/free_resize.cc b/mods/src/patches/parts/free_resize.cc index 9cd2889..0700d9d 100644 --- a/mods/src/patches/parts/free_resize.cc +++ b/mods/src/patches/parts/free_resize.cc @@ -2,6 +2,7 @@ #include #include "config.h" +#include "errormsg.h" #include @@ -147,14 +148,23 @@ void InstallFreeResizeHooks() { auto AspectRatioConstraintHandler_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Client.Utils", "AspectRatioConstraintHandler"); - auto ptr_update = AspectRatioConstraintHandler_helper.GetMethod("Update"); - auto ptr_wndproc = AspectRatioConstraintHandler_helper.GetMethod("WndProc"); + if (!AspectRatioConstraintHandler_helper.HasClass()) { + ErrorMsg::MissingHelper("Utils", "AspectRatioConstraintHandler"); + } else { + auto ptr_update = AspectRatioConstraintHandler_helper.GetMethod("Update"); + if (ptr_update == nullptr) { + ErrorMsg::MissingMethod("AspectRatioConstraintHandler", "Update"); + return; + } - if (!ptr_update || !ptr_wndproc) { - return; - } + auto ptr_wndproc = AspectRatioConstraintHandler_helper.GetMethod("WndProc"); + if (ptr_wndproc == nullptr) { + ErrorMsg::MissingMethod("AspectRatioConstraintHandler", "WndProc"); + return; + } - SPUD_STATIC_DETOUR(ptr_update, AspectRatioConstraintHandler_Update); - SPUD_STATIC_DETOUR(ptr_wndproc, AspectRatioConstraintHandler_WndProc); + SPUD_STATIC_DETOUR(ptr_update, AspectRatioConstraintHandler_Update); + SPUD_STATIC_DETOUR(ptr_wndproc, AspectRatioConstraintHandler_WndProc); + } } #endif diff --git a/mods/src/patches/parts/hotkeys.cc b/mods/src/patches/parts/hotkeys.cc index dba0576..0e996d5 100644 --- a/mods/src/patches/parts/hotkeys.cc +++ b/mods/src/patches/parts/hotkeys.cc @@ -13,6 +13,7 @@ #include "prime/MissionsObjectViewerWidget.h" #include "prime/StarNodeObjectViewerWidget.h" +#include "prime/ActionQueueManager.h" #include "prime/ActionRequirement.h" #include "prime/AnimatedRewardsScreenViewController.h" #include "prime/BookmarksManager.h" @@ -168,7 +169,9 @@ void ScreenManager_Update_Hook(auto original, ScreenManager* _this) chat_manager->OpenChannel(ChatChannelCategory::Alliance, ChatViewMode::Fullscreen); } } - } else if (MapKey::IsDown(GameFunction::ShowQTrials)) { + } + + if (MapKey::IsDown(GameFunction::ShowQTrials)) { return GotoSection(SectionID::ChallengeSelection); } else if (MapKey::IsDown(GameFunction::ShowBookmarks)) { auto bookmark_manager = BookmarksManager::Instance(); @@ -300,7 +303,7 @@ void ScreenManager_Update_Hook(auto original, ScreenManager* _this) if (MapKey::IsDown(GameFunction::ActionPrimary) || MapKey::IsDown(GameFunction::ActionSecondary) || MapKey::IsDown(GameFunction::ActionRecall) || MapKey::IsDown(GameFunction::ActionRepair) - || force_space_action_next_frame) { + || MapKey::IsDown(GameFunction::ActionQueue) || force_space_action_next_frame) { if (Hub::IsInSystemOrGalaxyOrStarbase() && !Hub::IsInChat() && !Key::IsInputFocused()) { auto fleet_bar = ObjectFinder::Get(); if (fleet_bar) { @@ -496,19 +499,30 @@ bool DidExecuteRepair(FleetBarViewController* fleet_bar) void ExecuteSpaceAction(FleetBarViewController* fleet_bar) { + auto fleet_controller = fleet_bar->_fleetPanelController; + auto fleet = fleet_controller->fleet; + + auto action_queue = ActionQueueManager::Instance(); + auto has_primary = MapKey::IsDown(GameFunction::ActionPrimary) || force_space_action_next_frame; auto has_repair = MapKey::IsDown(GameFunction::ActionRepair); auto has_recall_cancel = MapKey::IsDown(GameFunction::ActionRecallCancel); auto has_secondary = MapKey::IsDown(GameFunction::ActionSecondary); + auto has_queue = MapKey::IsDown(GameFunction::ActionQueue) && action_queue->CanAddToQueue(fleet); auto has_recall = MapKey::IsDown(GameFunction::ActionRecall) && (!Config::Get().disable_preview_recall || !CanHideViewers()); - auto fleet_controller = fleet_bar->_fleetPanelController; - auto fleet = fleet_controller->fleet; - if (has_recall_cancel && (fleet->CurrentState == FleetState::WarpCharging || fleet->CurrentState == FleetState::Warping)) { fleet_controller->CancelWarpClicked(); + } else if (has_queue) { + auto fleets_manager = FleetsManager::Instance(); + if (fleets_manager != nullptr) { + auto target = fleets_manager->targetFleetData; + if (target != nullptr) { + action_queue->AddToQueue(target->ID); + } + } } else { auto all_pre_scan_widgets = ObjectFinder::GetAll(); for (auto pre_scan_widget : all_pre_scan_widgets) { @@ -526,7 +540,9 @@ void ExecuteSpaceAction(FleetBarViewController* fleet_bar) return mine_object_viewer_widget->MineClicked(); } } else { - if (has_secondary) { + if (has_queue) { + + } else if (has_secondary) { return pre_scan_widget->_scanEngageButtonsWidget->OnScanButtonClicked(); } else if (has_primary) { auto armada_object_viewer_widget = ObjectFinder::Get(); @@ -681,30 +697,54 @@ void InstallHotkeyHooks() { auto shortcuts_manager_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.GameInput", "ShortcutsManager"); - auto ptr_can_user_shortcuts = shortcuts_manager_helper.GetMethod("InitializeActions"); - if (!ptr_can_user_shortcuts) { - return; + if (!shortcuts_manager_helper.HasClass()) { + ErrorMsg::MissingHelper("GameInput", "ShortcutsManager"); + } else { + auto ptr_can_user_shortcuts = shortcuts_manager_helper.GetMethod("InitializeActions"); + if (ptr_can_user_shortcuts == nullptr) { + ErrorMsg::MissingMethod("ShortcutsManager", "InitializeActions"); + } else { + SPUD_STATIC_DETOUR(ptr_can_user_shortcuts, InitializeActions_Hook); + } } - SPUD_STATIC_DETOUR(ptr_can_user_shortcuts, InitializeActions_Hook); auto screen_manager_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Client.UI", "ScreenManager"); - auto ptr_update = screen_manager_helper.GetMethod("Update"); - if (!ptr_update) { - return; + if (!screen_manager_helper.HasClass()) { + ErrorMsg::MissingHelper("UI", "ScreenManager"); + } else { + auto ptr_update = screen_manager_helper.GetMethod("Update"); + if (ptr_update == nullptr) { + ErrorMsg::MissingMethod("ScreenManager", "Update"); + } else { + SPUD_STATIC_DETOUR(ptr_update, ScreenManager_Update_Hook); + } } - SPUD_STATIC_DETOUR(ptr_update, ScreenManager_Update_Hook); static auto rewards_button_widget = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Combat", "RewardsButtonWidget"); - auto on_did_bind_context_ptr = rewards_button_widget.GetMethod("OnDidBindContext"); - - on_did_bind_context_ptr = on_did_bind_context_ptr; - - SPUD_STATIC_DETOUR(on_did_bind_context_ptr, OnDidBindContext_Hook); + if (!rewards_button_widget.HasClass()) { + ErrorMsg::MissingHelper("Combat", "RewardsButtonWidget"); + } else { + auto on_did_bind_context_ptr = rewards_button_widget.GetMethod("OnDidBindContext"); + on_did_bind_context_ptr = on_did_bind_context_ptr; + if (on_did_bind_context_ptr == nullptr) { + ErrorMsg::MissingMethod("RewardsButtonWidget", "OnDidBindContext"); + } else { + SPUD_STATIC_DETOUR(on_did_bind_context_ptr, OnDidBindContext_Hook); + } + } static auto pre_scan_target_widget = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Combat", "PreScanTargetWidget"); - auto show_with_fleet_ptr = pre_scan_target_widget.GetMethod("ShowWithFleet"); - show_with_fleet_ptr = show_with_fleet_ptr; - SPUD_STATIC_DETOUR(show_with_fleet_ptr, ShowWithFleet_Hook); + if (!pre_scan_target_widget.HasClass()) { + ErrorMsg::MissingHelper("Combat", "PreScanTargetWidget"); + } else { + auto show_with_fleet_ptr = pre_scan_target_widget.GetMethod("ShowWithFleet"); + show_with_fleet_ptr = show_with_fleet_ptr; + if (show_with_fleet_ptr == nullptr) { + ErrorMsg::MissingMethod("PreScanTargetWidget", "ShowWithFleet"); + } else { + SPUD_STATIC_DETOUR(show_with_fleet_ptr, ShowWithFleet_Hook); + } + } } diff --git a/mods/src/patches/parts/improve_responsiveness.cc b/mods/src/patches/parts/improve_responsiveness.cc index b10c4b4..476b286 100644 --- a/mods/src/patches/parts/improve_responsiveness.cc +++ b/mods/src/patches/parts/improve_responsiveness.cc @@ -1,4 +1,5 @@ #include "config.h" +#include "errormsg.h" #include "prime/TransitionManager.h" #include @@ -23,9 +24,14 @@ void InstallImproveResponsivenessHooks() { auto transition_manager_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.LoadingScreen", "TransitionManager"); - auto awake = transition_manager_helper.GetMethod("Awake"); - if (!awake) { - return; + if (!transition_manager_helper.HasClass()) { + ErrorMsg::MissingHelper("LoadingScreen", "TransitionManager"); + } else { + auto awake = transition_manager_helper.GetMethod("Awake"); + if (awake == nullptr) { + ErrorMsg::MissingMethod("TransitionManager", "Awake"); + } else { + SPUD_STATIC_DETOUR(awake, TransitionManager_Awake); + } } - SPUD_STATIC_DETOUR(awake, TransitionManager_Awake); -} \ No newline at end of file +} diff --git a/mods/src/patches/parts/misc.cc b/mods/src/patches/parts/misc.cc index 828c09e..4b18d1d 100644 --- a/mods/src/patches/parts/misc.cc +++ b/mods/src/patches/parts/misc.cc @@ -1,4 +1,5 @@ #include "config.h" +#include "errormsg.h" #include #include @@ -330,23 +331,58 @@ void InstallTempCrashFixes() { auto BuffService_helper = il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Services", "BuffService"); - - auto ptr_extract_buffs_of_type = BuffService_helper.GetMethod("ExtractBuffsOfType"); - SPUD_STATIC_DETOUR(ptr_extract_buffs_of_type, ExtractBuffsOfType_Hook); + if (!BuffService_helper.HasClass()) { + ErrorMsg::MissingHelper("Services", "BuffService"); + } else { + auto ptr_extract_buffs_of_type = BuffService_helper.GetMethod("ExtractBuffsOfType"); + if (ptr_extract_buffs_of_type == nullptr) { + ErrorMsg::MissingMethod("BuffService", "ExtractBuffsOfType"); + } else { + SPUD_STATIC_DETOUR(ptr_extract_buffs_of_type, ExtractBuffsOfType_Hook); + } + } auto shop_scene_manager = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Shop", "ShopSceneManager"); - - auto reveal_show = shop_scene_manager.GetMethod("ShouldShowRevealSequence"); - SPUD_STATIC_DETOUR(reveal_show, ShouldShowRevealHook); + if (!shop_scene_manager.HasClass()) { + ErrorMsg::MissingHelper("Shop", "ShopSceneManager"); + } else { + auto reveal_show = shop_scene_manager.GetMethod("ShouldShowRevealSequence"); + if (reveal_show == nullptr) { + ErrorMsg::MissingMethod("ShopSceneManager", "ShouldShowRevealSequence"); + } else { + SPUD_STATIC_DETOUR(reveal_show, ShouldShowRevealHook); + } + } auto shop_summary_director = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Shop", "ShopSummaryDirector"); - reveal_show = shop_summary_director.GetMethod("GoBackBehaviour"); - SPUD_STATIC_DETOUR(reveal_show, ShopSummaryDirectorGoBackBehavior); + if (!shop_summary_director.HasClass()) { + ErrorMsg::MissingHelper("Shop", "ShopSummaryDirector"); + } else { + auto shop_method = shop_summary_director.GetMethod("Start"); + if (shop_method == nullptr) { + ErrorMsg::MissingMethod("ShopSummaryDirectory", "Start"); + } else { + SPUD_STATIC_DETOUR(shop_method, ShopSummaryDirectorCtr); + } + + shop_method = shop_summary_director.GetMethod("GoBackBehaviour"); + if (shop_method == nullptr) { + ErrorMsg::MissingMethod("ShopSummaryDirectory", "GoBackBehaviour"); + } else { + SPUD_STATIC_DETOUR(shop_method, ShopSummaryDirectorGoBackBehavior); + } + } static auto interstitial_controller = - il2cpp_get_class_helper("Assembly-CSharp", "Digit.Client.UI", "InterstitialViewController"); - auto interstitial_show = interstitial_controller.GetMethod("AboutToShow"); - if (interstitial_show) { - SPUD_STATIC_DETOUR(interstitial_show, InterstitialViewController_AboutToShow); + il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Interstitial", "InterstitialViewController"); + if (!interstitial_controller.HasClass()) { + ErrorMsg::MissingHelper("Interstitial", "InterstitialViewController"); + } else { + auto interstitial_show = interstitial_controller.GetMethod("AboutToShow"); + if (interstitial_show == nullptr) { + ErrorMsg::MissingMethod("InterstitialViewController", "AboutToShow"); + } else { + SPUD_STATIC_DETOUR(interstitial_show, InterstitialViewController_AboutToShow); + } } } diff --git a/mods/src/patches/parts/sync.cc b/mods/src/patches/parts/sync.cc index 0f4faba..028348f 100644 --- a/mods/src/patches/parts/sync.cc +++ b/mods/src/patches/parts/sync.cc @@ -1,4 +1,5 @@ #include "config.h" +#include "errormsg.h" #include "il2cpp-api-types.h" #include @@ -67,7 +68,7 @@ struct CURLClient { static std::wstring instanceSessionId; static std::wstring gameServerUrl; -static int32_t instanceId; +static int32_t instanceId; static std::string newUUID() { @@ -616,8 +617,11 @@ void HandleEntityGroup(EntityGroup* entity_group) auto amount = resource.second["current_amount"].get(); const auto prevResourceAmountIter = resource_states.find(id); - const auto hadResource = (prevResourceAmountIter != resource_states.end() && prevResourceAmountIter->second != 0); - const auto amountChanged = amount > 0 && (prevResourceAmountIter == resource_states.end() || prevResourceAmountIter->second != amount); + const auto hadResource = + (prevResourceAmountIter != resource_states.end() && prevResourceAmountIter->second != 0); + const auto amountChanged = + amount > 0 + && (prevResourceAmountIter == resource_states.end() || prevResourceAmountIter->second != amount); const auto resourceDepleted = hadResource && amount == 0; if (resourceDepleted || amountChanged) { @@ -812,43 +816,112 @@ void InstallSyncPatches() auto missions_data_container = il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Models", "MissionsDataContainer"); - auto ptr = missions_data_container.GetMethod("ParseBinaryObject"); - SPUD_STATIC_DETOUR(ptr, MissionsDataContainer_ParseBinaryObject); + if (!missions_data_container.HasClass()) { + ErrorMsg::MissingHelper("Models", "MissionsDataContainer"); + } else { + auto ptr = missions_data_container.GetMethod("ParseBinaryObject"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("MissionsDataContainer", "ParseBinaryObject"); + } else { + SPUD_STATIC_DETOUR(ptr, MissionsDataContainer_ParseBinaryObject); + } + } auto inventory_data_container = il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Services", "InventoryDataContainer"); - ptr = inventory_data_container.GetMethod("ParseBinaryObject"); - SPUD_STATIC_DETOUR(ptr, MissionsDataContainer_ParseBinaryObject); + if (!inventory_data_container.HasClass()) { + ErrorMsg::MissingHelper("Services", "InventoryDataContainer"); + } else { + auto ptr = inventory_data_container.GetMethod("ParseBinaryObject"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("InventoryDataContainer", "ParseBinaryObject"); + } else { + SPUD_STATIC_DETOUR(ptr, MissionsDataContainer_ParseBinaryObject); + } + } auto research_data_container = il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Services", "ResearchDataContainer"); - ptr = research_data_container.GetMethod("ParseBinaryObject"); - SPUD_STATIC_DETOUR(ptr, MissionsDataContainer_ParseBinaryObject); + if (!research_data_container.HasClass()) { + ErrorMsg::MissingHelper("Services", "ResearchDataContainer"); + } else { + auto ptr = research_data_container.GetMethod("ParseBinaryObject"); + if (ptr == nullptr) { + ErrorMsg::MissingHelper("ResearchDataContainer", "ParseBinaryObject"); + } else { + SPUD_STATIC_DETOUR(ptr, MissionsDataContainer_ParseBinaryObject); + } + } auto research_service = il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Services", "ResearchService"); - ptr = research_service.GetMethod("ParseBinaryObject"); - SPUD_STATIC_DETOUR(ptr, MissionsDataContainer_ParseBinaryObject); + if (!research_service.HasClass()) { + ErrorMsg::MissingHelper("Services", "ResearchService"); + } else { + auto ptr = research_service.GetMethod("ParseBinaryObject"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("ResearchService", "ParseBinaryObject"); + } else { + SPUD_STATIC_DETOUR(ptr, MissionsDataContainer_ParseBinaryObject); + } + } auto game_server_model_registry = il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Core", "GameServerModelRegistry"); - ptr = game_server_model_registry.GetMethod("ProcessResultInternal"); - SPUD_STATIC_DETOUR(ptr, GameServerModelRegistry_ProcessResultInternal); - ptr = game_server_model_registry.GetMethod("HandleBinaryObjects"); - SPUD_STATIC_DETOUR(ptr, GameServerModelRegistry_HandleBinaryObjects); + if (!game_server_model_registry.HasClass()) { + ErrorMsg::MissingHelper("Core", "GameServerModelRegistry"); + } else { + auto ptr = game_server_model_registry.GetMethod("ProcessResultInternal"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("GameServerModelRegistry", "ProcessResultInterval"); + } else { + SPUD_STATIC_DETOUR(ptr, GameServerModelRegistry_ProcessResultInternal); + } + + ptr = game_server_model_registry.GetMethod("HandleBinaryObjects"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("GameServerModelRegsitry", "HandleBinaryObjects"); + } else { + SPUD_STATIC_DETOUR(ptr, GameServerModelRegistry_HandleBinaryObjects); + } + } auto platform_model_registry = il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimePlatform.Core", "PlatformModelRegistry"); - ptr = platform_model_registry.GetMethod("ProcessResultInternal"); - SPUD_STATIC_DETOUR(ptr, GameServerModelRegistry_ProcessResultInternal); + if (!platform_model_registry.HasClass()) { + ErrorMsg::MissingHelper("Core", "PlatformModelRegistry"); + } else { + auto ptr = platform_model_registry.GetMethod("ProcessResultInternal"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("PlatformModelRegistry", "ProcessResultInterval"); + } else { + SPUD_STATIC_DETOUR(ptr, GameServerModelRegistry_ProcessResultInternal); + } + } auto authentication_service = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Client.Core", "PrimeApp"); - ptr = authentication_service.GetMethod("InitPrimeServer"); - SPUD_STATIC_DETOUR(ptr, PrimeApp_InitPrimeServer); + if (!authentication_service.HasClass()) { + ErrorMsg::MissingHelper("Core", "PrimeApp"); + } else { + auto ptr = authentication_service.GetMethod("InitPrimeServer"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("PrimeApp", "InitPrimeServer"); + } else { + SPUD_STATIC_DETOUR(ptr, PrimeApp_InitPrimeServer); + } + } auto game_server = il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Core", "GameServer"); - ptr = game_server.GetMethod("SetInstanceIdHeader"); - SPUD_STATIC_DETOUR(ptr, GameServer_SetInstanceIdHeader); + if (!game_server.HasClass()) { + ErrorMsg::MissingHelper("Core", "GameServer"); + } else { + auto ptr = game_server.GetMethod("SetInstanceIdHeader"); + if (ptr == nullptr) { + ErrorMsg::MissingMethod("GameServer", "SetInstanceIdHeader"); + } else { + SPUD_STATIC_DETOUR(ptr, GameServer_SetInstanceIdHeader); + } + } std::thread(ship_sync_data).detach(); std::thread(ship_combat_log_data).detach(); diff --git a/mods/src/patches/parts/testing.cc b/mods/src/patches/parts/testing.cc index 06f61fd..25e146e 100644 --- a/mods/src/patches/parts/testing.cc +++ b/mods/src/patches/parts/testing.cc @@ -1,4 +1,5 @@ #include "config.h" +#include "errormsg.h" #include "prime/ActionRequirement.h" #include "prime/BlurController.h" @@ -10,6 +11,7 @@ #include "prime/DeploymentManager.h" #include "prime/FleetLocalViewController.h" #include "prime/FleetsManager.h" +#include "prime/FullScreenChatViewController.h" #include "prime/Hub.h" #include "prime/InventoryForPopup.h" #include "prime/KeyCode.h" @@ -18,7 +20,6 @@ #include "prime/SceneManager.h" #include "prime/ScreenManager.h" #include -#include "prime/FullScreenChatViewController.h" #include #include @@ -128,15 +129,31 @@ void SetActive_hook(auto original, void* _this, bool active) void InstallTestPatches() { - auto model = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Client.Core", "Model"); - auto load_configs_ptr = model.GetMethod("LoadConfigs"); - SPUD_STATIC_DETOUR(load_configs_ptr, Model_LoadConfigs); + auto model = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Client.Core", "Model"); + if (!model.HasClass()) { + ErrorMsg::MissingHelper("Core", "Model"); + } else { + auto load_configs_ptr = model.GetMethod("LoadConfigs"); + if (load_configs_ptr == nullptr) { + ErrorMsg::MissingMethod("Model", "LoadConfigs"); + } else { + SPUD_STATIC_DETOUR(load_configs_ptr, Model_LoadConfigs); + } + } auto battle_target_data = il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Models", "BattleTargetData"); - battle_target_data = battle_target_data; - - static auto SetActive = - il2cpp_resolve_icall_typed("UnityEngine.GameObject::SetActive(System.Boolean)"); - SPUD_STATIC_DETOUR(SetActive, SetActive_hook); + if (!battle_target_data.HasClass()) { + ErrorMsg::MissingHelper("Models", "BattleTargetData"); + } else { + battle_target_data = battle_target_data; + + static auto SetActive = + il2cpp_resolve_icall_typed("UnityEngine.GameObject::SetActive(System.Boolean)"); + if (SetActive == nullptr) { + ErrorMsg::MissingStaticMethod("GameObject", "SetActive"); + } else { + SPUD_STATIC_DETOUR(SetActive, SetActive_hook); + } + } } diff --git a/mods/src/patches/parts/ui_scale.cc b/mods/src/patches/parts/ui_scale.cc index a8b5bb6..851e22c 100644 --- a/mods/src/patches/parts/ui_scale.cc +++ b/mods/src/patches/parts/ui_scale.cc @@ -1,3 +1,4 @@ +#include "errormsg.h" #include #include @@ -60,26 +61,40 @@ void CanvasController_Show(auto original, CanvasController* _this, int desiredEn void InstallUiScaleHooks() { auto screen_manager_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Client.UI", "ScreenManager"); - auto ptr_update_scale = screen_manager_helper.GetMethod("UpdateCanvasRootScaleFactor"); - SPUD_STATIC_DETOUR(ptr_update_scale, ScreenManager_UpdateCanvasRootScaleFactor_Hook); + if (!screen_manager_helper.HasClass()) { + ErrorMsg::MissingHelper("UI", "ScreenManager"); + } else { + auto ptr_update_scale = screen_manager_helper.GetMethod("UpdateCanvasRootScaleFactor"); + if (ptr_update_scale == nullptr) { + ErrorMsg::MissingMethod("ScreenManager", "UpdateCanvasRootScaleFactor"); + } else { + SPUD_STATIC_DETOUR(ptr_update_scale, ScreenManager_UpdateCanvasRootScaleFactor_Hook); + } + } auto canvas_controller_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Client.UI", "CanvasController"); - - auto ptr_canvas_show = canvas_controller_helper.GetMethodSpecial("Show", [](auto count, const Il2CppType** params) { - if (count != 2) { + if (!canvas_controller_helper.HasClass()) { + ErrorMsg::MissingHelper("UI", "CanvasController"); + } else { + auto ptr_canvas_show = canvas_controller_helper.GetMethodSpecial("Show", [](auto count, const Il2CppType** params) { + if (count != 2) { + return false; + } + + auto p1 = params[0]->type; + auto p2 = params[1]->type; + + if (p1 == IL2CPP_TYPE_I4 && p2 == IL2CPP_TYPE_BOOLEAN) { + return true; + } return false; - } - - auto p1 = params[0]->type; - auto p2 = params[1]->type; + }); - if (p1 == IL2CPP_TYPE_I4 && p2 == IL2CPP_TYPE_BOOLEAN) { - return true; + if (ptr_canvas_show == nullptr) { + ErrorMsg::MissingMethod("CanvasContrller", "Show"); + } else { + SPUD_STATIC_DETOUR(ptr_canvas_show, CanvasController_Show); } - return false; - }); - if (ptr_canvas_show) { - SPUD_STATIC_DETOUR(ptr_canvas_show, CanvasController_Show); } Config::RefreshDPI(); diff --git a/mods/src/patches/parts/zoom.cc b/mods/src/patches/parts/zoom.cc index 068b560..d0f08c3 100644 --- a/mods/src/patches/parts/zoom.cc +++ b/mods/src/patches/parts/zoom.cc @@ -1,4 +1,5 @@ #include "config.h" +#include "errormsg.h" #include @@ -80,9 +81,9 @@ void NavigationZoom_Update_Hook(auto original, NavigationZoom *_this) do_absolute_zoom = false; do_default_zoom = true; } else if (MapKey::IsDown(GameFunction::ZoomMin)) { - zoomDelta = config->zoom; + zoomDelta = config->zoom; } else if (MapKey::IsDown(GameFunction::ZoomMax)) { - zoomDelta = 100; + zoomDelta = 100; } } @@ -192,20 +193,42 @@ void NavigationCamera_SetSystemViewSizeData_Hook(auto original, uint8_t *_this_c void InstallZoomHooks() { - auto screen_manager_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Navigation", "NavigationZoom"); - auto ptr_set_view_parameters = screen_manager_helper.GetMethod("SetViewParameters"); - auto ptr_update = screen_manager_helper.GetMethod("Update"); - auto ptr_apply_range_changes = screen_manager_helper.GetMethod("ApplyRangeChanges"); - auto ptr_set_depth = screen_manager_helper.GetMethod("SetDepth"); - SPUD_STATIC_DETOUR(ptr_update, NavigationZoom_Update_Hook); - SPUD_STATIC_DETOUR(ptr_set_depth, NavigationZoom_SetDepth_Hook); + auto screen_manager_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Navigation", "NavigationZoom"); + if (!screen_manager_helper.HasClass()) { + ErrorMsg::MissingHelper("Navigation", "NavigationZoom"); + } else { + auto ptr_update = screen_manager_helper.GetMethod("Update"); + if (ptr_update == nullptr) { + ErrorMsg::MissingMethod("NavigationZoom", "Update"); + } else { + SPUD_STATIC_DETOUR(ptr_update, NavigationZoom_Update_Hook); + } + + auto ptr_set_depth = screen_manager_helper.GetMethod("SetDepth"); + if (ptr_set_depth == nullptr) { + ErrorMsg::MissingMethod("NavigationZoom", "SetDepth"); + } else { + SPUD_STATIC_DETOUR(ptr_set_depth, NavigationZoom_SetDepth_Hook); + } #if _WIN32 - SPUD_STATIC_DETOUR(ptr_set_view_parameters, NavigationZoom_SetViewParameters_Hook); - // SPUD_STATIC_DETOUR(ptr_apply_range_changes, NavigationZoom_ApplyRangeChanges_Hook); + auto ptr_set_view_parameters = screen_manager_helper.GetMethod("SetViewParameters"); + if (ptr_set_view_parameters == nullptr) { + ErrorMsg::MissingMethod("NavigationZoom", "SetViewParameters"); + } else { + SPUD_STATIC_DETOUR(ptr_set_view_parameters, NavigationZoom_SetViewParameters_Hook); + } + + // auto ptr_apply_range_changes = screen_manager_helper.GetMethod("ApplyRangeChanges"); + // if (ptr_apply_range_changes == nullptr) { + // ErrorMsg::MissingMethod("NavigationZoom", "ApplyRangeChanges"); + // } else { + // SPUD_STATIC_DETOUR(ptr_apply_range_changes, NavigationZoom_ApplyRangeChanges_Hook); + // } #endif - // auto navigation_camera = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Navigation", "NavigationCamera"); - // auto ptr_set_system_view_size_data = navigation_camera.GetMethod("SetSystemViewSizeData"); - // SPUD_STATIC_DETOUR(ptr_set_system_view_size_data, NavigationCamera_SetSystemViewSizeData_Hook); + // auto navigation_camera = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Navigation", + // "NavigationCamera"); auto ptr_set_system_view_size_data = navigation_camera.GetMethod("SetSystemViewSizeData"); + // SPUD_STATIC_DETOUR(ptr_set_system_view_size_data, NavigationCamera_SetSystemViewSizeData_Hook); + } } diff --git a/mods/src/patches/patches.cc b/mods/src/patches/patches.cc index c11000c..220bd1f 100644 --- a/mods/src/patches/patches.cc +++ b/mods/src/patches/patches.cc @@ -97,7 +97,7 @@ __int64 il2cpp_init_hook(auto original, const char* domain_name) #endif spdlog::info(""); - spdlog::info("Please see https://github.com/tashcan/bob for latest configuration help, examples and future releases"); + spdlog::info("Please see https://github.com/netniv/bob for latest configuration help, examples and future releases"); spdlog::info("or visit the STFC Community Mod discord server at https://discord.gg/PrpHgs7Vjs"); spdlog::info(""); diff --git a/mods/src/prime/ActionQueueManager.h b/mods/src/prime/ActionQueueManager.h new file mode 100644 index 0000000..b13ab9c --- /dev/null +++ b/mods/src/prime/ActionQueueManager.h @@ -0,0 +1,92 @@ +#pragma once + +#include + +#include "FleetPlayerData.h" +#include "MonoSingleton.h" +#include "errormsg.h" + +struct ActionQueueManager : MonoSingleton { + friend struct MonoSingleton; + +public: + bool IsQueueFull(FleetPlayerData* playerData) + { + static auto IsQueueFullMethod = + get_class_helper().GetMethod("IsQueueFull"); + static auto IsQueueFullWarn = true; + + if (IsQueueFullMethod) { + return IsQueueFullMethod(this, playerData); + } else if (IsQueueFullWarn) { + IsQueueFullWarn = false; + ErrorMsg::MissingMethod("ActionQueueManager", "IsQueueFull"); + } + + return false; + } + + bool IsFleetInQueue(FleetPlayerData* playerData) + { + static auto IsFleetInQueueMethod = + get_class_helper().GetMethod("IsFleetInQueue"); + static auto IsFleetInQueueWarn = true; + + if (IsFleetInQueueMethod) { + return IsFleetInQueueMethod(this, playerData); + } else if (IsFleetInQueueWarn) { + IsFleetInQueueWarn = false; + ErrorMsg::MissingMethod("ActionQueueManager", "IFleetInQueue"); + } + + return false; + } + + bool IsQueueUnlocked() + { + static auto IsQueueUnlockedMethod = get_class_helper().GetMethod("IsQueueUnlocked"); + static auto IsQueueUnlockedWarn = true; + if (IsQueueUnlockedMethod) { + return IsQueueUnlockedMethod(this); + } else if (IsQueueUnlockedWarn) { + IsQueueUnlockedWarn = false; + ErrorMsg::MissingMethod("ActionQueueManager", "IsQueueUnlocked"); + } + + return false; + } + + bool CanAddToQueue(FleetPlayerData* playerData) + { + if (IsQueueUnlocked()) { + if (!IsQueueFull(playerData)) { + if (!IsFleetInQueue(playerData)) { + return true; + } + } + } + + return false; + } + + void AddToQueue(long targetId) + { + static auto AddToQueueMethod = get_class_helper().GetMethod("AddActionToQueue"); + static auto AddToQueueWarn = true; + + if (AddToQueueMethod != nullptr) { + spdlog::warn("AddToQueue({})", targetId); + AddToQueueMethod(this, targetId); + } else if (AddToQueueWarn) { + AddToQueueWarn = false; + ErrorMsg::MissingMethod("ActionQueueManager", "AddActionToQueue"); + } + } + +private: + static IL2CppClassHelper& get_class_helper() + { + static auto class_helper = il2cpp_get_class_helper("Assembly-CSharp", "Prime.ActionQueue", "ActionQueueManager"); + return class_helper; + } +}; diff --git a/mods/src/prime/AnimatedRewardsScreenViewController.h b/mods/src/prime/AnimatedRewardsScreenViewController.h index 2cdea11..d252e71 100644 --- a/mods/src/prime/AnimatedRewardsScreenViewController.h +++ b/mods/src/prime/AnimatedRewardsScreenViewController.h @@ -1,30 +1,57 @@ #pragma once +#include "errormsg.h" + #include struct AnimatedRewardsScreenViewController { public: static IL2CppClassHelper& get_class_helper() { - static auto class_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Missions.UI", "AnimatedRewardsScreenViewController"); + static auto class_helper = + il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Missions.UI", "AnimatedRewardsScreenViewController"); return class_helper; } void GoBackToLastSection() { - static auto GoBackToLastSectionMethod = get_class_helper().GetMethod("GoBackToLastSection"); - GoBackToLastSectionMethod(this); + static auto GoBackToLastSectionMethod = + get_class_helper().GetMethod("GoBackToLastSection"); + static auto GoBackToLastSectionWarn = true; + if (GoBackToLastSectionMethod) { + GoBackToLastSectionMethod(this); + } else if (GoBackToLastSectionWarn) { + GoBackToLastSectionWarn == false; + ErrorMsg::MissingMethod("AnimatedRewardsScreenViewController", "GoBackToLastSection"); + } } void OnCollectClicked() { - static auto OnCollectClickedMethod = get_class_helper().GetMethod("OnCollectClicked"); - OnCollectClickedMethod(this); + static auto OnCollectClickedMethod = + get_class_helper().GetMethod("OnCollectClicked"); + static auto OnCollectClickedWarn = true; + + if (OnCollectClickedMethod) { + OnCollectClickedMethod(this); + } else if (OnCollectClickedWarn) { + OnCollectClickedWarn = false; + ErrorMsg::MissingMethod("AnimatedRewardsScreenViewController", "OnCollectClicked"); + } } bool IsActive() { - auto IsActive = get_class_helper().GetMethod("IsActive"); - return IsActive(this); + auto IsActiveMethod = get_class_helper().GetMethod("IsActive"); + auto IsActiveWarn = true; + + if (IsActiveMethod) { + return IsActiveMethod(this); + } else if (IsActiveWarn) { + IsActiveWarn == false; + ErrorMsg::MissingMethod("AnimatedRewardsScreenViewController", "IsActive"); + } + + return false; } -}; \ No newline at end of file +}; diff --git a/mods/src/prime/ArmadaObjectViewerWidget.h b/mods/src/prime/ArmadaObjectViewerWidget.h index 5b91648..60c29de 100644 --- a/mods/src/prime/ArmadaObjectViewerWidget.h +++ b/mods/src/prime/ArmadaObjectViewerWidget.h @@ -1,5 +1,6 @@ #pragma once +#include "errormsg.h" #include #include "GenericButtonContext.h" @@ -10,21 +11,43 @@ struct ArmadaObjectViewerWidget : public ObjectViewerBaseWidget("SetCourseToArmada"); - SetCourseToArmada(this); + static auto SetCourseToAramdaWarn = true; + + if (SetCourseToArmadaMethod) { + SetCourseToArmadaMethod(this); + } else if (SetCourseToAramdaWarn) { + SetCourseToAramdaWarn = false; + ErrorMsg::MissingMethod("ArmadaObjectViewerWidget", "SetCourseToArmada"); + } } + void ValidateThenJoinArmada() { - static auto ValidateThenJoinArmada = + static auto ValidateThenJoinArmadaMethod = get_class_helper().GetMethod("ValidateThenJoinArmada"); - ValidateThenJoinArmada(this); + static auto ValidateThenJoinArmadaWarn = true; + + if (ValidateThenJoinArmadaMethod) { + ValidateThenJoinArmadaMethod(this); + } else if (ValidateThenJoinArmadaWarn) { + ValidateThenJoinArmadaWarn = false; + ErrorMsg::MissingMethod("ArmadaObjectViewerWidget", "ValidateThenJoinArmada"); + } } void JoinArmada() { - static auto JoinArmada = get_class_helper().GetMethod("JoinArmada"); - JoinArmada(this); + static auto JoinArmadaMethod = get_class_helper().GetMethod("JoinArmada"); + static auto JoinArmadaWarn = true; + + if (JoinArmadaMethod) { + JoinArmadaMethod(this); + } else if (JoinArmadaWarn) { + JoinArmadaWarn = false; + ErrorMsg::MissingMethod("ArmadaObjectViewerWidget", "JoinArmada"); + } } bool HasJoinButton() diff --git a/mods/src/prime/BattleTargetData.h b/mods/src/prime/BattleTargetData.h index 55f382f..5d8ef50 100644 --- a/mods/src/prime/BattleTargetData.h +++ b/mods/src/prime/BattleTargetData.h @@ -1,79 +1,7 @@ #pragma once #include - -enum class HullType { - Any = -1, - Destroyer = 0, - Survey = 1, - Explorer = 2, - Battleship = 3, - Defense = 4, - ArmadaTarget = 5 -}; - -enum class DeployedFleetType { - Nonexistent, - Player, - Marauder, - NpcInstantiated, - Sentinel, - Alliance, -}; - -struct HullSpec { -public: - __declspec(property(get = __get_Id)) long Id; - __declspec(property(get = __get_Type)) HullType Type; - -private: - static IL2CppClassHelper& get_class_helper() - { - static auto class_helper = - il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Models", "HullSpec"); - return class_helper; - } - -public: - long __get_Id() - { - static auto field = get_class_helper().GetField("id_").offset(); - return *(long*)((char*)this + field); - } - - HullType __get_Type() - { - static auto field = get_class_helper().GetProperty("Type"); - return *field.Get(this); - } -}; - -struct FleetDeployedData { -public: - __declspec(property(get = __get_Hull)) HullSpec* Hull; - __declspec(property(get = __get_FleetType)) DeployedFleetType FleetType; - -private: - static IL2CppClassHelper& get_class_helper() - { - static auto class_helper = - il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Models", "FleetDeployedData"); - return class_helper; - } - -public: - HullSpec* __get_Hull() - { - static auto field = get_class_helper().GetProperty("Hull"); - return field.GetRaw(this); - } - - DeployedFleetType __get_FleetType() - { - static auto field = get_class_helper().GetProperty("FleetType"); - return *field.Get(this); - } -}; +#include "FleetDeployedData.h" struct BattleTargetData { public: @@ -93,4 +21,4 @@ struct BattleTargetData { static auto field = get_class_helper().GetField("TargetFleetDeployedData").offset(); return *(FleetDeployedData**)((char*)this + field); } -}; \ No newline at end of file +}; diff --git a/mods/src/prime/BookmarksManager.h b/mods/src/prime/BookmarksManager.h index 80bac93..8846c5e 100644 --- a/mods/src/prime/BookmarksManager.h +++ b/mods/src/prime/BookmarksManager.h @@ -1,5 +1,6 @@ #pragma once +#include "errormsg.h" #include #include "MonoSingleton.h" @@ -11,7 +12,14 @@ struct BookmarksManager : MonoSingleton { void ViewBookmarks() { static auto ViewBookmarksMethod = get_class_helper().GetMethod("ViewBookmarks"); - ViewBookmarksMethod(this); + static auto ViewBookmarksWarn = true; + + if (ViewBookmarksMethod) { + ViewBookmarksMethod(this); + } else if (ViewBookmarksWarn) { + ViewBookmarksWarn = false; + ErrorMsg::MissingMethod("BookmarksManager", "ViewBookmarks"); + } } private: @@ -20,4 +28,4 @@ struct BookmarksManager : MonoSingleton { static auto class_helper = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Bookmarks", "BookmarksManager"); return class_helper; } -}; \ No newline at end of file +}; diff --git a/mods/src/prime/BundleDataWidget.h b/mods/src/prime/BundleDataWidget.h index dc1bfae..71d7989 100644 --- a/mods/src/prime/BundleDataWidget.h +++ b/mods/src/prime/BundleDataWidget.h @@ -46,7 +46,14 @@ class BundleDataWidget : public Widget { static auto AuxViewButtonPressedHandler = get_class_helper().GetMethod("AuxViewButtonPressedHandler"); - AuxViewButtonPressedHandler(this); + static auto AuxViewButtonPressedWarn = true; + + if (AuxViewButtonPressedHandler) { + AuxViewButtonPressedHandler(this); + } else if (AuxViewButtonPressedWarn) { + AuxViewButtonPressedWarn = false; + ErrorMsg::MissingMethod("BundleDataWidget", "AuxViewButtonPressedHandelr"); + } } private: @@ -63,4 +70,4 @@ class BundleDataWidget : public Widget static auto field = get_class_helper().GetField("_currentState"); return *(ItemState*)((ptrdiff_t)this + field.offset()); } -}; \ No newline at end of file +}; diff --git a/mods/src/prime/CanvasController.h b/mods/src/prime/CanvasController.h index 463fd84..f4cd925 100644 --- a/mods/src/prime/CanvasController.h +++ b/mods/src/prime/CanvasController.h @@ -13,8 +13,15 @@ struct CanvasController { void ResetFocus() { - static auto ResetFocus = get_class_helper().GetMethod("ResetFocus"); - ResetFocus(this); + static auto ResetFocusMethod = get_class_helper().GetMethod("ResetFocus"); + static auto ResetFocusWarn = true; + + if (ResetFocusMethod) { + ResetFocusMethod(this); + } else if (ResetFocusWarn) { + ResetFocusWarn = false; + ErrorMsg::MissingMethod("CanvasController", "ResetFocus"); + } } bool Visible() diff --git a/mods/src/prime/CanvasScaler.h b/mods/src/prime/CanvasScaler.h index a0c7c42..37d3627 100644 --- a/mods/src/prime/CanvasScaler.h +++ b/mods/src/prime/CanvasScaler.h @@ -9,8 +9,15 @@ struct CanvasScaler { void SetScaleFactor(float v) { - static auto SetScaleFactor = get_class_helper().GetMethod("SetScaleFactor"); - SetScaleFactor(this, v); + static auto SetScaleFactorMethod = get_class_helper().GetMethod("SetScaleFactor"); + static auto SetScaleFactorWarn = true; + + if (SetScaleFactorMethod) { + SetScaleFactorMethod(this, v); + } else if (SetScaleFactorWarn) { + SetScaleFactorWarn = false; + ErrorMsg::MissingMethod("CanvasScalar", "SetScaleFactor"); + } } private: @@ -42,4 +49,4 @@ struct CanvasScaler { static auto field = get_class_helper().GetProperty("referenceResolution"); field.SetRaw(this, v); } -}; \ No newline at end of file +}; diff --git a/mods/src/prime/ChatManager.h b/mods/src/prime/ChatManager.h index 820ba7d..017a239 100644 --- a/mods/src/prime/ChatManager.h +++ b/mods/src/prime/ChatManager.h @@ -1,5 +1,7 @@ #pragma once +#include "errormsg.h" + #include #include "MonoSingleton.h" @@ -28,19 +30,22 @@ struct ChatManager : MonoSingleton { void OpenChannel(ChatChannelCategory category = ChatChannelCategory::Alliance) { - static auto OpenChannel = + static auto OpenChannelMethod = get_class_helper().GetMethod("OpenChannel", 2); + static auto OpenChannelWarn = true; static void* params = il2cpp_string_new(""); - OpenChannel(this, category, params, nullptr); + if (OpenChannelMethod) { + OpenChannelMethod(this, category, params, nullptr); + } else if (OpenChannelWarn) { + OpenChannelWarn = false; + ErrorMsg::MissingMethod("ChatManager", "OpenChannel"); + } } void OpenChannel(ChatChannelCategory category, ChatViewMode viewMode) { - static auto OpenChannel = - get_class_helper().GetMethod("OpenChannel", 2); - static void* params = il2cpp_string_new(""); this->__set_ViewMode(viewMode); - OpenChannel(this, category, params, nullptr); + this->OpenChannel(category); } public: @@ -73,4 +78,4 @@ struct ChatManager : MonoSingleton { static auto field = get_class_helper().GetProperty("ViewMode"); field.SetRaw(this, v); } -}; \ No newline at end of file +}; diff --git a/mods/src/prime/ChatPreviewController.h b/mods/src/prime/ChatPreviewController.h index a285439..e3aa568 100644 --- a/mods/src/prime/ChatPreviewController.h +++ b/mods/src/prime/ChatPreviewController.h @@ -1,5 +1,7 @@ #pragma once +#include "errormsg.h" + #include enum PanelState { Global = 0, Alliance = 1 }; @@ -11,8 +13,14 @@ class SwipeScroller void FocusOnInstantly(int32_t index) { - static auto FocusOnInstantly = get_class_helper().GetMethod("FocusOnInstantly"); - FocusOnInstantly(this, index); + static auto FocusOnInstantlyMethod = get_class_helper().GetMethod("FocusOnInstantly"); + static auto FocusOnInstantlyWarn = true; + if (FocusOnInstantlyMethod) { + FocusOnInstantlyMethod(this, index); + } else if (FocusOnInstantlyWarn) { + FocusOnInstantlyWarn = false; + ErrorMsg::MissingMethod("SwipeSCroller", "FocusOnInstantly"); + } } public: @@ -68,4 +76,4 @@ class ChatPreviewController static auto field = get_class_helper().GetField("_focusedPanel"); *(PanelState*)((ptrdiff_t)this + field.offset()) = v; } -}; \ No newline at end of file +}; diff --git a/mods/src/prime/DeploymentManager.h b/mods/src/prime/DeploymentManager.h index bb3957f..5cd7d22 100644 --- a/mods/src/prime/DeploymentManager.h +++ b/mods/src/prime/DeploymentManager.h @@ -3,11 +3,11 @@ #include "CallbackContainer.h" #include "MonoSingleton.h" #include "Vector3.h" +#include "FleetPlayerData.h" +#include "FleetDeployedData.h" #include -struct FleetPlayerData; -struct FleetDeployedData; class DeploymentService { public: @@ -17,7 +17,16 @@ class DeploymentService bool MoveNext() { static auto MoveNext = get_class_helper().GetMethodSpecial("MoveNext"); - return MoveNext(this); + static auto MoveWarn = true; + + if (MoveNext) { + return MoveNext(this); + } else if (MoveWarn) { + MoveWarn = false; + ErrorMsg::MissingMethod("IEnumerator_PlanCourse", "MoveNext"); + } + + return false; } private: @@ -45,23 +54,39 @@ struct DeploymentManger : MonoSingleton { public: void SetTowRequest(uint64_t towedFleetId, uint64_t towingFleetId) { - static auto SetTowRequest = + static auto SetTowRequestMethod = get_class_helper().GetMethod("SetTowRequest"); - auto ptr = CallbackContainer::Create(); - SetTowRequest(this, towedFleetId, towingFleetId, ptr); + static auto SetTowRequestWarn = true; + + if (SetTowRequestMethod) { + auto ptr = CallbackContainer::Create(); + SetTowRequestMethod(this, towedFleetId, towingFleetId, ptr); + } else if (SetTowRequestWarn) { + SetTowRequestWarn = false; + ErrorMsg::MissingMethod("DeploymentManager", "SetTowRequest"); + } } DeploymentService::IEnumerator_PlanCourse* PlanCourse(FleetPlayerData* selectedFleet, void* targetAddress, Vector3 targetPosition, FleetDeployedData* targetDeployedFleet, void* starbaseData, void* allianceStarbaseData) { - static auto PlanCourse = + static auto PlanCourseMethod = get_class_helper() .GetMethod("PlanCourse"); - return PlanCourse(this, selectedFleet, targetAddress, &targetPosition, targetDeployedFleet, starbaseData, - allianceStarbaseData); + static auto PlanCourseWarn = true; + + if (PlanCourseMethod) { + return PlanCourseMethod(this, selectedFleet, targetAddress, &targetPosition, targetDeployedFleet, starbaseData, + allianceStarbaseData); + } else if (PlanCourseWarn) { + PlanCourseWarn = false; + ErrorMsg::MissingMethod("DeploymentService", "PlanCourse"); + } + + return nullptr; } private: @@ -70,4 +95,4 @@ struct DeploymentManger : MonoSingleton { static auto class_helper = il2cpp_get_class_helper("Assembly-CSharp", "", "DeploymentManager"); return class_helper; } -}; \ No newline at end of file +}; diff --git a/mods/src/prime/FleetBarViewController.h b/mods/src/prime/FleetBarViewController.h index 0f2ceb8..ec05172 100644 --- a/mods/src/prime/FleetBarViewController.h +++ b/mods/src/prime/FleetBarViewController.h @@ -29,7 +29,8 @@ struct FleetBarViewController { void RequestSelect(int32_t index, bool simulated = false) { - static auto RequestSelect = get_class_helper().GetMethodSpecial( + static auto RequestSelectWarn = true; + static auto RequestSelectMethod = get_class_helper().GetMethodSpecial( "RequestSelect", [](auto count, auto params) { if (count != 2) { return false; @@ -40,14 +41,26 @@ struct FleetBarViewController { } return false; }); - RequestSelect(this, index, simulated); + if (RequestSelectMethod) { + RequestSelectMethod(this, index, simulated); + } else if (RequestSelectWarn) { + RequestSelectWarn = false; + ErrorMsg::MissingMethod("FleetBarViewController", "RequestSelect"); + } } bool IsIndexSelected(int32_t index) { - static auto IsIndexSelected = + static auto IsIndexSelectedWarn = true; + static auto IsIndexSelectedMethod = get_class_helper().GetMethod("IsIndexSelected"); - return IsIndexSelected(this, index); + + if (IsIndexSelectedMethod) { + return IsIndexSelectedMethod(this, index); + } else if (IsIndexSelectedWarn) { + IsIndexSelectedWarn = false; + ErrorMsg::MissingMethod("FleetBarViewController", "IsIndexSelected"); + } } FleetBarContext* CanvasContext() diff --git a/mods/src/prime/FleetDeployedData.h b/mods/src/prime/FleetDeployedData.h new file mode 100644 index 0000000..0f7bf2e --- /dev/null +++ b/mods/src/prime/FleetDeployedData.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include "HullSpec.h" + +enum class DeployedFleetType { + Nonexistent, + Player, + Marauder, + NpcInstantiated, + Sentinel, + Alliance, +}; + +struct FleetDeployedData { +public: + __declspec(property(get = __get_ID)) long ID; + __declspec(property(get = __get_Hull)) HullSpec* Hull; + __declspec(property(get = __get_FleetType)) DeployedFleetType FleetType; + +private: + static IL2CppClassHelper& get_class_helper() + { + static auto class_helper = + il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Models", "FleetDeployedData"); + return class_helper; + } + +public: + long __get_ID() + { + static auto field = get_class_helper().GetProperty("ID"); + return *field.Get(this); + } + + HullSpec* __get_Hull() + { + static auto field = get_class_helper().GetProperty("Hull"); + return field.GetRaw(this); + } + + DeployedFleetType __get_FleetType() + { + static auto field = get_class_helper().GetProperty("FleetType"); + return *field.Get(this); + } +}; diff --git a/mods/src/prime/FleetLocalViewController.h b/mods/src/prime/FleetLocalViewController.h index ec39b00..3d8c20f 100644 --- a/mods/src/prime/FleetLocalViewController.h +++ b/mods/src/prime/FleetLocalViewController.h @@ -14,25 +14,36 @@ struct FleetLocalViewController { void CancelWarpClicked() { - static auto CancelWarpClicked = get_class_helper().GetMethod("CancelWarpClicked"); - if (CancelWarpClicked != nullptr) { - CancelWarpClicked(this); + static auto CancelWarpWarn = true; + static auto CancelWarpMethod = get_class_helper().GetMethod("CancelWarpClicked"); + if (CancelWarpMethod) { + CancelWarpMethod(this); + } else if (CancelWarpWarn) { + CancelWarpWarn = false; + ErrorMsg::MissingMethod("FLeetLocalViewController", "CancelWarpClicked"); } } bool RequestAction(IActionData target, ActionType type, int index, ActionBehaviour behaviourMask, void* callback = nullptr) { - static auto RequestAction = + static auto RequestActionMethod = get_class_helper() .GetMethodSpecial( - "RequestAction", [](int param_count, const Il2CppType **) { + "RequestAction", [](int param_count, const Il2CppType**) { if (param_count == 5) { return true; } return false; }); - return RequestAction(this, target, type, index, behaviourMask, callback); + static auto RequestActionWarn = true; + + if (RequestActionMethod) { + return RequestActionMethod(this, target, type, index, behaviourMask, callback); + } else if (!RequestActionWarn) { + RequestActionWarn = false; + ErrorMsg::MissingMethod("FleetLocalViewController", "RequestAction"); + } } private: diff --git a/mods/src/prime/FleetPlayerData.h b/mods/src/prime/FleetPlayerData.h index c7a7be0..83cdd26 100644 --- a/mods/src/prime/FleetPlayerData.h +++ b/mods/src/prime/FleetPlayerData.h @@ -1,6 +1,7 @@ #pragma once #include "BattleTargetData.h" +#include "HullSpec.h" #include "RecallRequirement.h" #include "CanRepairRequirement.h" @@ -87,4 +88,4 @@ struct FleetPlayerData { static auto field = get_class_helper().GetProperty("Id"); return *field.Get(this); } -}; \ No newline at end of file +}; diff --git a/mods/src/prime/FleetsManager.h b/mods/src/prime/FleetsManager.h index 86681a7..45199be 100644 --- a/mods/src/prime/FleetsManager.h +++ b/mods/src/prime/FleetsManager.h @@ -1,7 +1,9 @@ #pragma once #include "CallbackContainer.h" +#include "FleetDeployedData.h" #include "FleetPlayerData.h" +#include "HullSpec.h" #include "IEnumerator.h" #include "MonoSingleton.h" #include "Vector3.h" @@ -11,6 +13,9 @@ struct FleetsManager : MonoSingleton { friend struct MonoSingleton; +public: + __declspec(property(get = __get_TargetFleetData)) FleetDeployedData* targetFleetData; + public: class IEnumerator_Tow { @@ -18,7 +23,16 @@ struct FleetsManager : MonoSingleton { bool MoveNext() { static auto MoveNext = get_class_helper().GetMethodSpecial("MoveNext"); - return MoveNext(this); + static auto MoveWarn = true; + + if (MoveNext) { + return MoveNext(this); + } else if (MoveWarn) { + MoveWarn = false; + ErrorMsg::MissingMethod("IEnumerator_Tow", "MoveNext"); + } + + return false; } private: @@ -33,28 +47,66 @@ struct FleetsManager : MonoSingleton { { static auto RequestViewFleet = get_class_helper().GetMethod("RequestViewFleet"); - RequestViewFleet(this, fleetData, showSystemInfo); + static auto RequestViewWarn = true; + if (RequestViewFleet) { + RequestViewFleet(this, fleetData, showSystemInfo); + } else if (RequestViewWarn) { + RequestViewWarn = false; + ErrorMsg::MissingMethod("FleetsManager", "RequestViewFleet"); + } } + void RecallFleet(long fleetId) { static auto RecallFleet = get_class_helper().GetMethod("RecallFleet"); - auto ptr = CallbackContainer::Create(); - RecallFleet(this, fleetId, ptr); + static auto RecallWarn = true; + + if (RecallFleet) { + auto ptr = CallbackContainer::Create(); + RecallFleet(this, fleetId, ptr); + } else if (RecallWarn) { + RecallWarn = true; + ErrorMsg::MissingMethod("FleetsManager", "RecallFleet"); + } } IEnumerator_Tow* Tow(long towedFleetId, long towingFleetId, Vector3* targetPosition) { - static auto Tow = + static auto TowMethod = get_class_helper().GetMethod("Tow"); - auto ptr = CallbackContainer::Create(); - return Tow(this, towedFleetId, towingFleetId, nullptr, targetPosition, ptr); + static auto TowWarn = true; + + if (TowMethod) { + auto ptr = CallbackContainer::Create(); + return TowMethod(this, towedFleetId, towingFleetId, nullptr, targetPosition, ptr); + } else if (TowWarn) { + TowWarn = false; + ErrorMsg::MissingMethod("FleetsManager", "Tow"); + } + + return nullptr; } FleetPlayerData* GetFleetPlayerData(int idx) { - static auto GetFleetPlayerData = + static auto GetFleetPlayerDataMethod = get_class_helper().GetMethod("GetFleetPlayerData"); - return GetFleetPlayerData(this, idx); + static auto GetFleetPlayerDataWarn = true; + + if (GetFleetPlayerDataMethod) { + return GetFleetPlayerDataMethod(this, idx); + } else if (GetFleetPlayerDataWarn) { + GetFleetPlayerDataWarn = false; + ErrorMsg::MissingMethod("FleetPlayerData", "GetFleetPlayerData"); + } + + return nullptr; + } + + FleetDeployedData* __get_TargetFleetData() + { + static auto field = get_class_helper().GetField("_targetFleetData").offset(); + return *(FleetDeployedData**)((char*)this + field); } private: diff --git a/mods/src/prime/GenericButtonWidget.h b/mods/src/prime/GenericButtonWidget.h new file mode 100644 index 0000000..2c659c9 --- /dev/null +++ b/mods/src/prime/GenericButtonWidget.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +#include "BattleTargetData.h" +#include "Widget.h" + +struct GenericButtonWidget : public Widget { +public: + __declspec(property(get = __get__armadaButton)) void* _armadaButton; + + void OnEngageButtonClicked() + { + static auto OnEngageButtonClicked = + get_class_helper().GetMethod("OnEngageButtonClicked"); + OnEngageButtonClicked(this); + } + void OnScanButtonClicked() + { + static auto OnScanButtonClicked = + get_class_helper().GetMethod("OnScanButtonClicked"); + OnScanButtonClicked(this); + } + +private: + friend class ObjectFinder; + friend struct Widget; + static IL2CppClassHelper& get_class_helper() + { + static auto class_helper = + il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Combat", "ScanEngageButtonsWidget"); + return class_helper; + } + +public: + void* __get__armadaButton() + { + static auto field = get_class_helper().GetProperty("_armadaButton"); + return field.GetRaw(this); + } +}; diff --git a/mods/src/prime/GenericRewardsScreenViewController.h b/mods/src/prime/GenericRewardsScreenViewController.h index b80700e..1c62bc3 100644 --- a/mods/src/prime/GenericRewardsScreenViewController.h +++ b/mods/src/prime/GenericRewardsScreenViewController.h @@ -1,5 +1,6 @@ #pragma once +#include "errormsg.h" #include struct GenericRewardsScreenViewController { @@ -12,13 +13,28 @@ struct GenericRewardsScreenViewController { void OnCollectClicked() { - static auto OnCollectClickedMethod = get_class_helper().GetMethod("OnCollectClicked"); - OnCollectClickedMethod(this); + static auto OnCollectClickedWarn = true; + static auto OnCollectClickedMethod = + get_class_helper().GetMethod("OnCollectClicked"); + + if (OnCollectClickedMethod) { + OnCollectClickedMethod(this); + } else if (OnCollectClickedWarn) { + OnCollectClickedWarn = false; + ErrorMsg::MissingMethod("GenericRewardsScreenViewController", "OnCollectClicked"); + } } bool IsActive() { - auto IsActive = get_class_helper().GetMethod("IsActive"); - return IsActive(this); + auto IsActiveMethod = get_class_helper().GetMethod("IsActive"); + auto IsActiveWarn = true; + + if (IsActiveMethod) { + return IsActiveMethod(this); + } else if (IsActiveWarn) { + IsActiveWarn = false; + ErrorMsg::MissingMethod("GenericRewardsSCreenViewController", "IsActive"); + } } -}; \ No newline at end of file +}; diff --git a/mods/src/prime/Hub.h b/mods/src/prime/Hub.h index 10197ae..05c82c9 100644 --- a/mods/src/prime/Hub.h +++ b/mods/src/prime/Hub.h @@ -146,8 +146,15 @@ struct SectionStorage { public: void* GetState(SectionID section) { - static auto GetState = get_class_helper().GetMethod("GetState"); - return GetState(this, section); + static auto GetStateMethod = get_class_helper().GetMethod("GetState"); + static auto GetStateWarn = true; + + if (GetStateMethod) { + return GetStateMethod(this, section); + } else if (GetStateWarn) { + GetStateWarn = false; + ErrorMsg::MissingMethod("SectionStorage", "GetState"); + } } private: @@ -162,8 +169,15 @@ struct SectionNavHistory { public: bool Contains(SectionID section) { - static auto Contains = get_class_helper().GetMethod("Contains"); - return Contains(this, section); + static auto ContainsMethod = get_class_helper().GetMethod("Contains"); + static auto ContainsWarn = true; + + if (ContainsMethod) { + return ContainsMethod(this, section); + } else if (ContainsWarn) { + ContainsWarn = false; + ErrorMsg::MissingMethod("SectionNavHistory", "Contains"); + } } private: @@ -183,10 +197,17 @@ struct SectionManager { void TriggerSectionChange(SectionID nextSectionID, void* args, bool forcedSectionChange = false, bool isGoBackStep = false, bool allowSameSection = false) { - static auto trigger = + static auto triggerWarn = true; + static auto triggerMethod = get_class_helper().GetMethod( "TriggerSectionChange"); - trigger(this, nextSectionID, args, forcedSectionChange, isGoBackStep, allowSameSection); + + if (triggerMethod) { + triggerMethod(this, nextSectionID, args, forcedSectionChange, isGoBackStep, allowSameSection); + } else if (triggerWarn) { + triggerWarn = false; + ErrorMsg::MissingMethod("SectionManager", "TriggerSectionChange"); + } } private: @@ -275,4 +296,4 @@ struct Hub { } public: -}; \ No newline at end of file +}; diff --git a/mods/src/prime/HullSpec.h b/mods/src/prime/HullSpec.h new file mode 100644 index 0000000..a24221c --- /dev/null +++ b/mods/src/prime/HullSpec.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +enum class HullType { + Any = -1, + Destroyer = 0, + Survey = 1, + Explorer = 2, + Battleship = 3, + Defense = 4, + ArmadaTarget = 5 +}; + +struct HullSpec { +public: + __declspec(property(get = __get_Id)) long Id; + __declspec(property(get = __get_Type)) HullType Type; + +private: + static IL2CppClassHelper& get_class_helper() + { + static auto class_helper = + il2cpp_get_class_helper("Digit.Client.PrimeLib.Runtime", "Digit.PrimeServer.Models", "HullSpec"); + return class_helper; + } + +public: + long __get_Id() + { + static auto field = get_class_helper().GetField("id_").offset(); + return *(long*)((char*)this + field); + } + + HullType __get_Type() + { + static auto field = get_class_helper().GetProperty("Type"); + return *field.Get(this); + } +};