diff --git a/freedom/features/difficulty.cpp b/freedom/features/difficulty.cpp index 839d159..a7f8268 100644 --- a/freedom/features/difficulty.cpp +++ b/freedom/features/difficulty.cpp @@ -3,33 +3,39 @@ Parameter ar_parameter = { true, // lock 10.0f, // value + 10.0f, // calculated_value OSU_BEATMAP_AR_OFFSET, // offset "AR: %.1f", // slider_fmt "AR Offsets Not Found", // error_message enable_ar_hooks, // enable disable_ar_hooks, // disable + apply_mods_ar, // apply_mods // bool found = false }; Parameter cs_parameter = { false, // lock 4.0f, // value + 4.0f, // calculated_value OSU_BEATMAP_CS_OFFSET, // offset "CS: %.1f", // slider_fmt "CS Offsets Not Found", // error_message enable_cs_hooks, // enable disable_cs_hooks, // disable + apply_mods_cs, // apply_mods // bool found = false }; Parameter od_parameter = { false, // lock 8.0f, // value + 8.0f, // calculated_value OSU_BEATMAP_OD_OFFSET, // offset "OD: %.1f", // slider_fmt "OD Offsets Not Found", // error_message enable_od_hooks, // enable disable_od_hooks, // disable + apply_mods_od, // apply_mods // bool found = false }; @@ -55,6 +61,21 @@ Hook CircleSizeHook3; Hook OverallDifficultyHook1; Hook OverallDifficultyHook2; +static inline float ms_to_ar(float ms) +{ + return ms > 1200.f ? (1800.f - ms) / 120.f : (1200.f - ms) / 150.f + 5.f; +} + +static inline float ar_to_ms(float ar) +{ + return ar <= 5.f ? 1200.f + 600.f * (5.f - ar) / 5.f : 1200.f - 750.f * (ar - 5.f) / 5.f; +} + +static inline float compensate_double_time(float ar) +{ + return max(ms_to_ar(ar_to_ms(ar) * 1.5f), .0f); +} + void init_difficulty() { if (ar_parameter.found) @@ -63,7 +84,10 @@ void init_difficulty() ApproachRateHook2 = Hook(approach_rate_offsets[1], (BYTE *)set_approach_rate, 9); ApproachRateHook3 = Hook(approach_rate_offsets[2], (BYTE *)set_approach_rate_2, 12); if (ar_parameter.lock) + { enable_ar_hooks(); + ar_parameter.apply_mods(); + } } if (cs_parameter.found) @@ -72,7 +96,10 @@ void init_difficulty() CircleSizeHook2 = Hook(circle_size_offsets[1], (BYTE *)set_circle_size, 9); CircleSizeHook3 = Hook(circle_size_offsets[2], (BYTE *)set_circle_size, 9); if (cs_parameter.lock) + { enable_cs_hooks(); + cs_parameter.apply_mods(); + } } if (od_parameter.found) @@ -80,27 +107,35 @@ void init_difficulty() OverallDifficultyHook1 = Hook(overall_difficulty_offsets[0], (BYTE *)set_overall_difficulty, 9); OverallDifficultyHook2 = Hook(overall_difficulty_offsets[1], (BYTE *)set_overall_difficulty, 9); if (od_parameter.lock) + { enable_od_hooks(); + od_parameter.apply_mods(); + } } } void enable_od_hooks() { - enable_notify_hooks(); + enable_update_mods_hook(); OverallDifficultyHook1.Enable(); OverallDifficultyHook2.Enable(); } void disable_od_hooks() { - disable_notify_hooks(); + disable_update_mods_hook(); OverallDifficultyHook1.Disable(); OverallDifficultyHook2.Disable(); } +void apply_mods_od() +{ + od_parameter.calculated_value = od_parameter.value; +} + void enable_cs_hooks() { - enable_notify_hooks(); + enable_update_mods_hook(); CircleSizeHook1.Enable(); CircleSizeHook2.Enable(); CircleSizeHook3.Enable(); @@ -108,15 +143,20 @@ void enable_cs_hooks() void disable_cs_hooks() { - disable_notify_hooks(); + disable_update_mods_hook(); CircleSizeHook1.Disable(); CircleSizeHook2.Disable(); CircleSizeHook3.Disable(); } +void apply_mods_cs() +{ + cs_parameter.calculated_value = cs_parameter.value; +} + void enable_ar_hooks() { - enable_notify_hooks(); + enable_update_mods_hook(); ApproachRateHook1.Enable(); ApproachRateHook2.Enable(); ApproachRateHook3.Enable(); @@ -124,19 +164,35 @@ void enable_ar_hooks() void disable_ar_hooks() { - disable_notify_hooks(); + disable_update_mods_hook(); ApproachRateHook1.Disable(); ApproachRateHook2.Disable(); ApproachRateHook3.Disable(); } +void apply_mods_ar() +{ + if (selected_mods_ptr) + { + Mods mods = *selected_mods_ptr; + if ((mods & Mods::Nightcore) || (mods & Mods::DoubleTime)) + { + ar_parameter.calculated_value = compensate_double_time(ar_parameter.value); + FR_INFO_FMT("ar_parameter.calculated_value: %.2f", ar_parameter.calculated_value); + return; + } + } + ar_parameter.calculated_value = ar_parameter.value; + FR_INFO_FMT("ar_parameter.calculated_value: %.2f", ar_parameter.calculated_value); +} + __declspec(naked) void set_approach_rate() { __asm { mov eax, dword ptr [ebp-0x00000150] - fstp dword ptr [eax+0x2C] - mov ebx, ar_parameter.value - mov dword ptr [eax+0x2C], ebx + fstp dword ptr [eax+OSU_BEATMAP_AR_OFFSET] + mov ebx, ar_parameter.calculated_value + mov dword ptr [eax+OSU_BEATMAP_AR_OFFSET], ebx jmp [ar_hook_jump_back] } } @@ -146,9 +202,9 @@ __declspec(naked) void set_approach_rate_2() __asm { mov eax,[ebp-0x00000150] fld dword ptr [eax+0x38] - fstp dword ptr [eax+0x2C] - mov ebx, ar_parameter.value - mov dword ptr [eax+0x2C], ebx + fstp dword ptr [eax+OSU_BEATMAP_AR_OFFSET] + mov ebx, ar_parameter.calculated_value + mov dword ptr [eax+OSU_BEATMAP_AR_OFFSET], ebx jmp [ar_hook_jump_back] } } @@ -157,9 +213,9 @@ __declspec(naked) void set_circle_size() { __asm { mov eax, dword ptr [ebp-0x00000150] - fstp dword ptr [eax+0x30] - mov ebx, cs_parameter.value - mov dword ptr [eax+0x30], ebx + fstp dword ptr [eax+OSU_BEATMAP_CS_OFFSET] + mov ebx, cs_parameter.calculated_value + mov dword ptr [eax+OSU_BEATMAP_CS_OFFSET], ebx jmp [cs_hook_jump_back] } } @@ -168,9 +224,9 @@ __declspec(naked) void set_overall_difficulty() { __asm { mov eax, dword ptr [ebp-0x00000150] - fstp dword ptr [eax+0x38] - mov ebx, od_parameter.value - mov dword ptr [eax+0x38], ebx + fstp dword ptr [eax+OSU_BEATMAP_OD_OFFSET] + mov ebx, od_parameter.calculated_value + mov dword ptr [eax+OSU_BEATMAP_OD_OFFSET], ebx jmp [od_hook_jump_back] } } diff --git a/freedom/hitobject.cpp b/freedom/hitobject.cpp index c3345f9..5273d97 100644 --- a/freedom/hitobject.cpp +++ b/freedom/hitobject.cpp @@ -44,9 +44,9 @@ void process_hitobject() if (mods_updated) { - // TODO(Ciremun): calc AR value static char selected_mods[64] = "Unknown"; FR_INFO_FMT("mods updated: %s", selected_mods_ptr ? mods_to_string(*selected_mods_ptr, selected_mods) : "Unknown"); + ar_parameter.apply_mods(); mods_updated = false; } diff --git a/freedom/scan.cpp b/freedom/scan.cpp index 62a7c69..6e6f836 100644 --- a/freedom/scan.cpp +++ b/freedom/scan.cpp @@ -66,9 +66,14 @@ inline bool all_code_starts_found() && hom_update_vars_hidden_loc && selected_mods_code_start && update_mods_code_start; } +static inline bool some_feature_requires_update_mods_hook() +{ + return ar_parameter.lock || cs_parameter.lock || od_parameter.lock; +} + static inline bool some_feature_requires_notify_hooks() { - return cfg_relax_lock || cfg_aimbot_lock || cfg_replay_enabled || cfg_hidden_remover_enabled || cfg_flashlight_enabled || ar_parameter.lock || cs_parameter.lock || od_parameter.lock; + return cfg_relax_lock || cfg_aimbot_lock || cfg_replay_enabled || cfg_hidden_remover_enabled || cfg_flashlight_enabled; } static int filter(unsigned int code) @@ -388,15 +393,6 @@ static inline void init_hooks_wrapper() if (scene_is_game(current_scene_ptr)) enable_nt_user_send_input_patch(); - init_input(); - init_difficulty(); - init_timewarp(); - init_score_multiplier(); - init_discord_rpc(); - init_replay(); - init_unmod_flashlight(); - init_unmod_hidden(); - bool notify_hooks_required = some_feature_requires_notify_hooks(); if (beatmap_onload_offset) { @@ -413,9 +409,18 @@ static inline void init_hooks_wrapper() if (update_mods_offset) { UpdateModsHook = Hook(update_mods_offset, (BYTE *)notify_on_update_mods, (BYTE *)&o_update_mods_hook, 5); - if (notify_hooks_required) + if (some_feature_requires_update_mods_hook()) UpdateModsHook.Enable(); } + + init_input(); + init_difficulty(); + init_timewarp(); + init_score_multiplier(); + init_discord_rpc(); + init_replay(); + init_unmod_flashlight(); + init_unmod_hidden(); } void init_hooks() @@ -452,7 +457,6 @@ void enable_notify_hooks() { BeatmapOnLoadHook.Enable(); SceneHook.Enable(); - UpdateModsHook.Enable(); } void disable_notify_hooks() @@ -461,7 +465,6 @@ void disable_notify_hooks() { BeatmapOnLoadHook.Disable(); SceneHook.Disable(); - UpdateModsHook.Disable(); } } @@ -469,6 +472,21 @@ static inline void disable_notify_hooks_force() { BeatmapOnLoadHook.Disable(); SceneHook.Disable(); +} + +void enable_update_mods_hook() +{ + UpdateModsHook.Enable(); +} + +void disable_update_mods_hook() +{ + if (!some_feature_requires_update_mods_hook()) + UpdateModsHook.Disable(); +} + +static inline void disable_update_mods_hook_force() +{ UpdateModsHook.Disable(); } @@ -525,6 +543,7 @@ void destroy_hooks_except_swap() disable_cs_hooks(); disable_od_hooks(); disable_notify_hooks_force(); + disable_update_mods_hook_force(); disable_replay_hooks(); disable_flashlight_hooks(); disable_score_multiplier_hooks(); diff --git a/freedom/ui/ui.cpp b/freedom/ui/ui.cpp index 2aa3a2e..f19560c 100644 --- a/freedom/ui/ui.cpp +++ b/freedom/ui/ui.cpp @@ -635,7 +635,8 @@ void parameter_slider(uintptr_t selected_song_ptr, Parameter *p) else { ImGui::PushID(slider_fmt); - ImGui::SliderFloat("", &p->value, .0f, 11.0f, slider_fmt); + if (ImGui::SliderFloat("", &p->value, .0f, 11.0f, slider_fmt)) + p->apply_mods(); ImGui::PopID(); if (ImGui::IsItemDeactivatedAfterEdit()) ImGui::SaveIniSettingsToDisk(ImGui::GetIO().IniFilename); diff --git a/include/baked_utils_dll.h b/include/baked_utils_dll.h index 75cd32a..b7979b4 100644 --- a/include/baked_utils_dll.h +++ b/include/baked_utils_dll.h @@ -5,7 +5,7 @@ static const unsigned int utils_dll_data[9728/4] = { 0x00905a4d, 0x00000003, 0x00000004, 0x0000ffff, 0x000000b8, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x0eba1f0e, 0xcd09b400, 0x4c01b821, 0x685421cd, 0x70207369, 0x72676f72, 0x63206d61, 0x6f6e6e61, - 0x65622074, 0x6e757220, 0x206e6920, 0x20534f44, 0x65646f6d, 0x0a0d0d2e, 0x00000024, 0x00000000, 0x00004550, 0x0003014c, 0x65f4c27d, 0x00000000, + 0x65622074, 0x6e757220, 0x206e6920, 0x20534f44, 0x65646f6d, 0x0a0d0d2e, 0x00000024, 0x00000000, 0x00004550, 0x0003014c, 0x65ff5b5e, 0x00000000, 0x00000000, 0x202200e0, 0x0030010b, 0x00001e00, 0x00000600, 0x00000000, 0x00003c2a, 0x00002000, 0x00004000, 0x10000000, 0x00002000, 0x00000200, 0x00000004, 0x00000000, 0x00000004, 0x00000000, 0x00008000, 0x00000200, 0x00000000, 0x85400003, 0x00100000, 0x00001000, 0x00100000, 0x00001000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00003bd8, 0x0000004f, 0x00004000, 0x00000298, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -148,7 +148,7 @@ static const unsigned int utils_dll_data[9728/4] = 0x0035005f, 0x00300054, 0x003d006f, 0x00233f00, 0x007a003d, 0x00300045, 0x00440056, 0x0066005a, 0x004a0077, 0x00480045, 0x007a0033, 0x00440036, 0x00580033, 0x00710047, 0x0054006d, 0x0044006b, 0x00460052, 0x0077006b, 0x00470066, 0x3f000100, 0x003d0023, 0x004e007a, 0x00740044, 0x00300073, 0x00360067, 0x0058004a, 0x00240045, 0x005f0059, 0x00700059, 0x00650068, 0x00760053, 0x00670062, 0x007a007a, 0x007a0068, 0x006f0070, 0x17000051, - 0x003d0023, 0x004f007a, 0x00710035, 0x0062006d, 0x00550070, 0x0000003d, 0x5d1d72ad, 0x45d05450, 0x352c37a2, 0x70c9062d, 0x01200400, 0x20030801, + 0x003d0023, 0x004f007a, 0x00710035, 0x0062006d, 0x00550070, 0x0000003d, 0x23788f18, 0x4e9ea15d, 0x4a12e5b8, 0x17a1d3ba, 0x01200400, 0x20030801, 0x20050100, 0x11110101, 0x01012005, 0x07041d11, 0x04311101, 0x65120000, 0x12012005, 0x20050e35, 0x0e391201, 0x11002004, 0x00200331, 0x01000418, 0x07061808, 0x112d1102, 0x1215072d, 0x110e0229, 0x0120052d, 0x06001302, 0x01130120, 0x00050013, 0x08181802, 0x11020007, 0x71111c2d, 0x01022007, 0x01130013, 0x11010704, 0x0307082d, 0x0824111d, 0x20032411, 0x20030e00, 0x070e0800, 0x113d1106, 0x113d113d, 0x41121d3d, 0x00200408, 0x20043d11, diff --git a/include/features/difficulty.h b/include/features/difficulty.h index 4f78cd5..001937f 100644 --- a/include/features/difficulty.h +++ b/include/features/difficulty.h @@ -10,11 +10,13 @@ struct Parameter { bool lock; float value; + float calculated_value; uintptr_t offset; const char *slider_fmt; const char *error_message; void (*enable)(); void (*disable)(); + void (*apply_mods)(); bool found = false; }; @@ -37,12 +39,15 @@ void init_difficulty(); void enable_ar_hooks(); void disable_ar_hooks(); +void apply_mods_ar(); void enable_cs_hooks(); void disable_cs_hooks(); +void apply_mods_cs(); void enable_od_hooks(); void disable_od_hooks(); +void apply_mods_od(); void set_approach_rate(); void set_approach_rate_2(); diff --git a/include/scan.h b/include/scan.h index 7a0c086..2bfb7e2 100644 --- a/include/scan.h +++ b/include/scan.h @@ -83,6 +83,9 @@ void init_hooks(); void enable_notify_hooks(); void disable_notify_hooks(); +void enable_update_mods_hook(); +void disable_update_mods_hook(); + void enable_nt_user_send_input_patch(); void disable_nt_user_send_input_patch(); diff --git a/nobuild.exe b/nobuild.exe index 18ae078..0bd7ab9 100644 Binary files a/nobuild.exe and b/nobuild.exe differ