diff --git a/Source/Client/Application/Launcher.cpp b/Source/Client/Application/Launcher.cpp index 793c4e0b4..e7fc85306 100644 --- a/Source/Client/Application/Launcher.cpp +++ b/Source/Client/Application/Launcher.cpp @@ -2,11 +2,60 @@ #include "Utility/Cipher/XorBytes.h" #include "Utility/Text/FormatString.h" #include "Contents/Configuration/ServiceConfiguration.h" +#include "Client/Stove/StoveMgr.h" +#include "Contents/AdventureGuideMgr.h" +#include "Contents/Async/AsyncWorkMgr.h" +#include "Contents/CashEmotionMgr.h" +#include "Contents/ChampionMonsterMgr.h" +#include "Contents/ClanInfo.h" +#include "Contents/ConfigMgr.h" +#include "Contents/Configuration/GameSettingsMgr.h" +#include "Contents/EffectResourceSwitcher.h" +#include "Contents/Effects/EffectLists.h" +#include "Contents/Effects/EffectMemoryMgr.h" +#include "Contents/Emblems/EmblemDataMgr.h" +#include "Contents/EnchantMgr.h" +#include "Contents/EntryQueueMgr.h" +#include "Contents/EquipmentResourceMgr.h" +#include "Contents/GuildMgr.h" +#include "Contents/ItemDBToIDMgr.h" +#include "Contents/Items/ItemReformMgr.h" +#include "Contents/Items/NeoPackageItemMgr.h" +#include "Contents/Items/SelectPackageItemMgr.h" +#include "Contents/JobCodeForItem.h" +#include "Contents/MapPropertyMgr.h" +#include "Contents/MapSkyMgr.h" +#include "Contents/Messenger/ClientMessenger.h" +#include "Contents/Messenger/WhisperBlockMgr.h" +#include "Contents/Party/AdventurerAgencyMgr.h" +#include "Contents/PlayerNameDictionary.h" +#include "Contents/RenewQuestMgr.h" +#include "Contents/ReputeMgr.h" +#include "Contents/RodexMailStore.h" +#include "Contents/RouletteMgr.h" +#include "Contents/Schedule/TimeScheduler.h" +#include "Contents/SignBoard/SignBoard.h" +#include "Contents/SimpleStringMgr.h" +#include "Contents/Skills/SkillInfo.h" +#include "Contents/TownInfoMgr.h" +#include "Contents/UserData/AccountLinkedUserDataMgr.h" +#include "Contents/UserData/CharacterLinkedUserDataMgr.h" +#include "Network/Http/CURLMgr.h" +#include "Security/NProtectGameGuardMgr.h" +#include "Security/ReassemblyPacketMgr.h" +#include "Security/ThemidaMgr.h" +#include "UI/Cooldowns/CooldownOwner.h" +#include "UI/Party/UIRequestJoinPartyMgr.h" +#include "UI/Text/NavigationLink.h" +#include "UI/Window/UIRegisterMgr.h" +#include "Utility/Async/NMessageMgr.h" +#include "Utility/GGHashMgr.h" #include #include #include #include #include +#include #include #include #include @@ -802,3 +851,113 @@ bool ReplaceClientExecutable(char* executable, const char* update) { StartClientProcess(executable); return true; } + +namespace EquipmentProperties { +class CEquipmentPropertiesMgr { +public: + virtual ~CEquipmentPropertiesMgr(); +}; +} + +// INLINED +template +static void DestroyManager(T*& instance) { + if (instance == nullptr) { + instance = new (std::nothrow) T; + } + + if (instance != nullptr) { + delete instance; + instance = nullptr; + } +} + +// OFFSET: 0x00E574A0 +// FUNCTION: fn_24358 +void ShutdownManagers() { + DestroyManager(Singleton::s_instance); + DestroyManager(Singleton::s_instance); + DestroyManager(Singleton::s_instance); + + Singleton::GetInstance(); + if (Singleton::s_instance != nullptr) { + delete Singleton::s_instance; + Singleton::s_instance = nullptr; + } + + DestroyManager(Singleton::s_instance); + DestroyManager(g_skillActionMgr); + + Singleton::GetInstance(); + if (Singleton::s_instance != nullptr) { + delete Singleton::s_instance; + Singleton::s_instance = nullptr; + } + + DestroyManager(g_mapSkyMgr); + DestroyManager(Singleton::s_instance); + DestroyManager(g_itemReformMgr); + DestroyManager(g_itemDbToIdMgr); + DestroyManager(Singleton::s_instance); + + DestroySignBoardMgr(); + DestroyNavigationLinkParser(); + CEmblemDataMgr::Shutdown(); + CGuildMgr::Destroy(); + DestroyPlayerNameDictionary(); + + for (unsigned int attempt = 0; attempt < 30; ++attempt) { + if (g_accountLinkedUserDataMgr->unknown_0028 + g_adventurerAgencyMgr->pending == 0) { + break; + } + + Sleep(100); + g_asyncWorkMgr->Update(1000); + } + + g_asyncWorkMgr->Stop(); + CWhisperBlockMgr::Shutdown(); + CAsyncWorkMgr::Shutdown(); + NMessageMgr::Shutdown(); + CAccountLinkedUserDataMgr::Shutdown(); + CCharacterLinkedUserDataMgr::Shutdown(); + CCURLMgr::Shutdown(); + RouletteMgr::Destroy(); + RodexMailStore::Destroy(); + CMapPropertyMgr::Destroy(); + CChampionMonsterMgr::Destroy(); + CClanInfo::Destroy(); + CGGHashMgr::Destroy(); + CNProtectGameGuardMgr::Destroy(); + CCashEmotionMgr::Shutdown(); + CSimpleStringMgr::Destroy(); + CRenewQuestMgr::Destroy(); + DestroyCooldownOwner(); + CTownInfoMgr::Destroy(); + EquipmentResourceMgr::Destroy(); + CTimeScheduler::Destroy(); + DestroyEntryQueueMgr(); + DestroyEffectMemoryMgr(); + DestroyEffectMgr(); + CReassemblyPacketMgr::DestroyInstance(); + CThemidaMgr::Destroy(); + + if (g_launchPassCommandLine && g_stoveMgr != nullptr) { + typedef void(__thiscall * DeletingDestructor)(CStoveMgr*, unsigned char); + (*reinterpret_cast(g_stoveMgr))[0](g_stoveMgr, 1); + g_stoveMgr = nullptr; + } + + DestroyManager(Singleton::s_instance); + + CConfigMgr::Destroy(); + CAdventurerAgencyMgr::Shutdown(); + UIRequestJoinPartyMgr::Shutdown(); + + if (g_equipmentPropertiesMgr != nullptr) { + delete g_equipmentPropertiesMgr; + g_equipmentPropertiesMgr = nullptr; + } + + CAdventureGuideMgr::Destroy(); +} diff --git a/Source/Client/Application/Launcher.h b/Source/Client/Application/Launcher.h index 7cef8eba4..3465b71c7 100644 --- a/Source/Client/Application/Launcher.h +++ b/Source/Client/Application/Launcher.h @@ -11,6 +11,7 @@ bool RestartFromCommandLine(char* commandLine); void ExitForProtectionCheck(const char* commandLine); bool AcquireInstanceMutex(HANDLE* mutex); +void ShutdownManagers(); extern char* g_commandLine; extern bool g_launchAccountEnabled; diff --git a/Source/Contents/Messenger/WhisperBlockMgr.h b/Source/Contents/Messenger/WhisperBlockMgr.h index 4a9078934..6c1550b76 100644 --- a/Source/Contents/Messenger/WhisperBlockMgr.h +++ b/Source/Contents/Messenger/WhisperBlockMgr.h @@ -2,10 +2,17 @@ #define RAGNAROK_SOURCE_CONTENTS_MESSENGER_WHISPERBLOCKMGR_H #include -#include #include #include +#if __has_include() +#include +#else +namespace Json { +class Value; +} +#endif + class CWhisperBlockMgr { public: CWhisperBlockMgr(); diff --git a/Source/Contents/UserData/AccountLinkedUserDataMgr.h b/Source/Contents/UserData/AccountLinkedUserDataMgr.h index 43b0c7d29..935d00c55 100644 --- a/Source/Contents/UserData/AccountLinkedUserDataMgr.h +++ b/Source/Contents/UserData/AccountLinkedUserDataMgr.h @@ -13,6 +13,7 @@ class CAsyncWorkMgr; class CAccountLinkedUserDataMgr { friend class CGameMode; + friend void ShutdownManagers(); public: CAccountLinkedUserDataMgr(); diff --git a/Source/UI/Cooldowns/CooldownOwner.h b/Source/UI/Cooldowns/CooldownOwner.h index 9d6a79456..569b8dfd1 100644 --- a/Source/UI/Cooldowns/CooldownOwner.h +++ b/Source/UI/Cooldowns/CooldownOwner.h @@ -36,6 +36,8 @@ private: extern CooldownOwner* g_cooldownOwner; +void DestroyCooldownOwner(); + #if defined(_WIN32) && !defined(_WIN64) static_assert(sizeof(CooldownOwner) == 36); #endif