client_runtime_lifecycle.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include "../../core/logging/log.h"
  2. #include "../../core/settings/settings.h"
  3. #include "../../server/bap/runtime.h"
  4. #include "../activity/mission_launch.h"
  5. #include "../content/activity/activity_sdk_generation_worker.h"
  6. #include "../content/activity/scriptable_catalog_worker.h"
  7. #include "../content/investment/worker.h"
  8. #include "../hooks/assert_handler/assert_handler_lifecycle.h"
  9. #include "../hooks/async_io/async_io_lifetime_guard.h"
  10. #include "../hooks/bitmap/bitmap_hook_lifecycle.h"
  11. #include "../hooks/bootflow/bootflow_hook_lifecycle.h"
  12. #include "../hooks/bootflow/bootflow_texture_override.h"
  13. #include "../hooks/cine_auth_probe/cine_auth_probe.h"
  14. #include "../hooks/cine_probe/cine_probe.h"
  15. #include "../hooks/config_getter/config_getter_lifecycle.h"
  16. #include "../hooks/cursor/runtime.h"
  17. #include "../hooks/graphics/graphics_hook_lifecycle.h"
  18. #include "../hooks/hitch_probe/hitch_probe.h"
  19. #include "../hooks/inactivity/inactivity_override.h"
  20. #include "../hooks/infinite_ammo/infinite_ammo.h"
  21. #include "../hooks/membership_probe/membership_probe.h"
  22. #include "../hooks/network/runtime.h"
  23. #include "../hooks/noclip/runtime.h"
  24. #include "../hooks/package_trust/package_trust_bypass.h"
  25. #include "../hooks/polled_input/runtime.h"
  26. #include "../hooks/queuez/queuez_hook_lifecycle.h"
  27. #include "../hooks/retail_log/retail_log_lifecycle.h"
  28. #include "../hooks/sense_chain_guard/sense_chain_guard.h"
  29. #include "../hooks/stall_probe/stall_probe.h"
  30. #include "../hooks/teleport/runtime.h"
  31. #include "../hooks/world_objects/world_object_registry.h"
  32. #include "../movement/movement_settings_store.h"
  33. #include "../player/player_settings_store.h"
  34. #include "../targets/game.h"
  35. #include "../targets/steam_targets.h"
  36. #include "../ui/activity/authored_placement_marker.h"
  37. #include "../ui/runtime/client_ui_module_runtime.h"
  38. #include "internal.h"
  39. #include "runtime.h"
  40. namespace sunrise::client {
  41. /** Initializes Client-owned process state without installing hooks. */
  42. bool initialize(void* module) noexcept {
  43. content::activity::sdk_generation::initialize(
  44. module, {core::settings::get().activitySdkGeneration.luaDeclarations});
  45. // Loaded before the pages register, so each page draws saved values on its first frame.
  46. movement::initialize(module);
  47. player::initialize(module);
  48. ui::activity::authored_placement_marker::initialize(module);
  49. return ui::runtime::initialize();
  50. }
  51. /** Detaches Client hooks before clearing their resolved target entries. */
  52. bool shutdown() noexcept {
  53. AcquireSRWLockExclusive(&runtime::g_lock);
  54. if (!hooks::graphics::uninstall()) {
  55. core::log::write(core::log::Channel::client,
  56. core::log::Level::error,
  57. "ev=shutdown stage=graphics_hooks result=fail");
  58. ReleaseSRWLockExclusive(&runtime::g_lock);
  59. return false;
  60. }
  61. // Detached after presentation, so no later frame can apply the cursor policy.
  62. hooks::cursor::uninstall();
  63. hooks::polled_input::uninstall();
  64. if (!hooks::world_objects::uninstall()) {
  65. core::log::write(core::log::Channel::client,
  66. core::log::Level::error,
  67. "ev=shutdown stage=world_objects result=fail");
  68. ReleaseSRWLockExclusive(&runtime::g_lock);
  69. return false;
  70. }
  71. if (!hooks::network::uninstall()) {
  72. core::log::write(core::log::Channel::client,
  73. core::log::Level::error,
  74. "ev=shutdown stage=network_hooks result=fail");
  75. ReleaseSRWLockExclusive(&runtime::g_lock);
  76. return false;
  77. }
  78. if (!hooks::bootflow::texture_override::uninstall()) {
  79. core::log::write(core::log::Channel::client,
  80. core::log::Level::error,
  81. "ev=shutdown stage=bootflow_texture result=fail");
  82. ReleaseSRWLockExclusive(&runtime::g_lock);
  83. return false;
  84. }
  85. if (!hooks::package_trust::uninstall()) {
  86. core::log::write(core::log::Channel::client,
  87. core::log::Level::error,
  88. "ev=shutdown stage=package_trust result=fail");
  89. ReleaseSRWLockExclusive(&runtime::g_lock);
  90. return false;
  91. }
  92. // Every probe below reads through a detour, so one left in place is a branch into code a
  93. // later unload unmaps.
  94. if (!hooks::cine_auth_probe::uninstall()) {
  95. core::log::write(core::log::Channel::client,
  96. core::log::Level::error,
  97. "ev=shutdown stage=cine_auth_probe result=fail");
  98. ReleaseSRWLockExclusive(&runtime::g_lock);
  99. return false;
  100. }
  101. if (!hooks::cine_probe::uninstall()) {
  102. core::log::write(core::log::Channel::client,
  103. core::log::Level::error,
  104. "ev=shutdown stage=cine_probe result=fail");
  105. ReleaseSRWLockExclusive(&runtime::g_lock);
  106. return false;
  107. }
  108. if (!hooks::membership_probe::uninstall()) {
  109. core::log::write(core::log::Channel::client,
  110. core::log::Level::error,
  111. "ev=shutdown stage=membership_probe result=fail");
  112. ReleaseSRWLockExclusive(&runtime::g_lock);
  113. return false;
  114. }
  115. if (!hooks::sense_chain_guard::uninstall()) {
  116. core::log::write(core::log::Channel::client,
  117. core::log::Level::error,
  118. "ev=shutdown stage=sense_chain_guard result=fail");
  119. ReleaseSRWLockExclusive(&runtime::g_lock);
  120. return false;
  121. }
  122. // The watcher runs on its own thread, so it stops before the targets it reads are cleared.
  123. if (!hooks::stall_probe::uninstall()) {
  124. core::log::write(core::log::Channel::client,
  125. core::log::Level::error,
  126. "ev=shutdown stage=stall_probe result=fail");
  127. ReleaseSRWLockExclusive(&runtime::g_lock);
  128. return false;
  129. }
  130. if (!hooks::hitch_probe::uninstall()) {
  131. core::log::write(core::log::Channel::client,
  132. core::log::Level::error,
  133. "ev=shutdown stage=hitch_probe result=fail");
  134. ReleaseSRWLockExclusive(&runtime::g_lock);
  135. return false;
  136. }
  137. hooks::bitmap::uninstall();
  138. activity::mission_launch::uninstall();
  139. hooks::bootflow::uninstall();
  140. hooks::infinite_ammo::uninstall();
  141. hooks::inactivity::uninstall();
  142. hooks::noclip::uninstall();
  143. hooks::teleport::uninstall();
  144. hooks::queuez::uninstall();
  145. if (!hooks::config_getter::uninstall()) {
  146. ReleaseSRWLockExclusive(&runtime::g_lock);
  147. return false;
  148. }
  149. if (!hooks::assert_handler::uninstall()) {
  150. ReleaseSRWLockExclusive(&runtime::g_lock);
  151. return false;
  152. }
  153. if (!hooks::retail_log::uninstall()) {
  154. core::log::write(core::log::Channel::client,
  155. core::log::Level::error,
  156. "ev=shutdown stage=retail_log result=fail");
  157. ReleaseSRWLockExclusive(&runtime::g_lock);
  158. return false;
  159. }
  160. content::activity::sdk_generation::reset();
  161. content::activity::scriptables::reset();
  162. server::bap::unregister_client_investment_consumers();
  163. content::investment::worker::reset();
  164. (void)hooks::async_io::uninstall();
  165. targets::steam::clear();
  166. if (runtime::g_platformModule != nullptr) {
  167. if (FreeLibrary(runtime::g_platformModule) == FALSE) {
  168. core::log::write(core::log::Channel::client,
  169. core::log::Level::error,
  170. "ev=shutdown stage=steam_module result=fail");
  171. ReleaseSRWLockExclusive(&runtime::g_lock);
  172. return false;
  173. }
  174. runtime::g_platformModule = nullptr;
  175. }
  176. targets::game::retail_log::clear();
  177. targets::game::content::clear();
  178. targets::game::network::clear();
  179. runtime::g_mainStage = runtime::StageState::pending;
  180. runtime::g_graphicsStage = runtime::StageState::pending;
  181. runtime::g_platformStage = runtime::StageState::pending;
  182. ui::runtime::shutdown();
  183. // The reverse of the order the stores initialize in.
  184. ui::activity::authored_placement_marker::shutdown();
  185. player::shutdown();
  186. movement::shutdown();
  187. core::log::write(core::log::Channel::client, core::log::Level::info, "ev=shutdown result=ok");
  188. ReleaseSRWLockExclusive(&runtime::g_lock);
  189. return true;
  190. }
  191. } // namespace sunrise::client