From fec919b88e47cf35f932b2978059a2db25fd22ff Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Fri, 6 Nov 2026 10:56:48 +0000 Subject: [PATCH] Maintenance: Link-completeness fixes so the whole client links into one executable (all units in data/compile.json plus exe-only thir Batch #13186 by ragnarok-clanker: forced by an admin (40 lower score(s), 206 changed function(s)); checked with 620 compiled unit(s), including every includer of Source/Archive/GPak.h, Source/Client/Mode/CGameMode.h, Source/Client/Mode/CLoginMode.h, Source/Client/Session.h, Source/Client/Stove/StoveMgr.h, Source/Client/Stove/StovePCSDK.h, Source/Client/Timer.h, Source/Contents/Actors/GameActor.h, Source/Contents/Actors/RenderObject.h, Source/Contents/CashEmotionMgr.h, Source/Contents/Configuration/ServiceOptions.h, Source/Contents/Skills/SkillTreeScript.h, Source/Render/DX9/D3DX9Runtime.h, Source/Resource/GifResource.h, Source/UI/AdventureGuide/UIAdventureGuide.h, Source/UI/Cooldowns/CooldownOwner.h, Source/UI/Edit/UIEditBoxEx.h, Source/UI/Lists/UIListBoxTemplate.h, Source/UI/Quest/UIRenewQuestUI.h, Source/UI/Rodex/UIRodexComposeWnd.h, Source/UI/Text/UITextViewerControl.h, Source/UI/UIBroadcastBalloon.h, Source/UI/UICaptchaRegisterWnd.h, Source/UI/UIMacroDetectorWnd.h, Source/UI/UIReputeWnd.h, Source/UI/Window/UIRegisterMgr.h, Source/UI/Window/UISecondCostumeWnd.h, Source/UI/Window/UISelCharForUServerWnd.h, Source/UI/Window/UIWindow.h, Source/UI/Window/UIWindowMgr.h, Source/Utility/EncryptedName.h. --- Source/Archive/GPak.cpp | 86 ++---- Source/Archive/GPak.h | 10 + .../Client/Application/ApplicationWindow.cpp | 4 +- Source/Client/Application/Launcher.cpp | 46 +-- Source/Client/Mode/CGameMode.h | 29 +- Source/Client/Mode/CLoginMode.h | 15 +- Source/Client/Mode/GameMode.cpp | 60 ++-- Source/Client/Mode/GameModeHandlers.cpp | 6 +- Source/Client/Mode/GameModeMiniMap.cpp | 8 - Source/Client/Mode/GameModeNotices.cpp | 2 +- Source/Client/Mode/GameModePackets.cpp | 118 ++++---- Source/Client/Mode/LoginMode.cpp | 43 +-- Source/Client/Session.cpp | 30 +- Source/Client/Session.h | 2 - Source/Client/Stove/StoveMgr.cpp | 115 +++++--- Source/Client/Stove/StoveMgr.h | 5 - Source/Client/Stove/StovePCSDK.h | 6 +- Source/Client/Timer.cpp | 6 + Source/Client/Timer.h | 1 + Source/Contents/Actors/GameActor.h | 1 - Source/Contents/Actors/MercenaryAI.cpp | 4 +- Source/Contents/Actors/Player.cpp | 2 +- Source/Contents/Actors/RenderObject.cpp | 81 +----- Source/Contents/Actors/RenderObject.h | 1 - Source/Contents/BodyResources.cpp | 30 +- Source/Contents/CashEmotionMgr.cpp | 12 +- Source/Contents/CashEmotionMgr.h | 2 +- Source/Contents/ClientItemLists.cpp | 19 -- Source/Contents/ClientState.cpp | 5 +- .../Contents/Configuration/ServiceOptions.cpp | 36 +-- .../Contents/Configuration/ServiceOptions.h | 2 +- .../Effects/EffectPrimitiveRendering.cpp | 4 +- Source/Contents/Effects/Particle.cpp | 5 + Source/Contents/Effects/SpriteEffect.cpp | 14 +- .../Contents/Effects/TalismanMarkEffect.cpp | 18 +- Source/Contents/Effects/TriangleShotArrow.cpp | 8 +- Source/Contents/EnchantMgr.cpp | 5 + Source/Contents/Items/ItemNaming.cpp | 11 +- Source/Contents/Messenger/ClientMessenger.cpp | 30 +- Source/Contents/Messenger/MessengerMember.cpp | 8 +- Source/Contents/RenewQuestMgr.cpp | 4 +- Source/Contents/ReputeMgr.cpp | 168 ++++++++++- Source/Contents/Skills/SkillActionDruid.cpp | 2 +- Source/Contents/Skills/SkillTreeScript.cpp | 78 +++-- Source/Contents/Skills/SkillTreeScript.h | 2 + Source/Contents/SpecialPopupMgr.cpp | 5 +- Source/Contents/SpriteRidingOffset.cpp | 2 +- Source/Network/Connection/Connection.cpp | 5 + Source/Render/DX9/D3DX9Runtime.h | 2 + Source/Render/ScreenGeometry.cpp | 18 +- Source/Resource/GifResource.cpp | 3 +- Source/Resource/GifResource.h | 1 - Source/Script/LuaScript.cpp | 3 +- Source/Script/NLuaState.cpp | 11 +- Source/Security/NProtectGameGuardMgr.cpp | 4 +- Source/Security/ThemidaMgr.cpp | 20 +- Source/UI/Acceptance/UIChooseSellBuyWnd.cpp | 37 ++- Source/UI/AdventureGuide/UIAdventureGuide.cpp | 4 - Source/UI/AdventureGuide/UIAdventureGuide.h | 9 + Source/UI/CashShop/UICashShopWnd.cpp | 30 +- Source/UI/Chat/UINewChatWnd.cpp | 6 +- Source/UI/Cooldowns/CooldownOwner.cpp | 7 + Source/UI/Cooldowns/CooldownOwner.h | 4 +- Source/UI/Edit/UIEditBoxEx.cpp | 2 +- Source/UI/Edit/UIEditBoxEx.h | 1 - Source/UI/Edit/UIEditCtrl.cpp | 60 +--- Source/UI/EntryQueue/UIEntryQueueWnd.cpp | 20 ++ Source/UI/FrameSkin.cpp | 4 - Source/UI/GameSettings/GameSettingsUI.cpp | 35 ++- Source/UI/Guild/UIGuildHelperWnd.cpp | 4 +- Source/UI/Item/UIEquipmentPropertiesWnd.cpp | 10 - Source/UI/Items/MergeItemWnd.cpp | 5 + Source/UI/Items/UISwapEquipmentWnd.cpp | 6 +- Source/UI/Lists/UIListBoxTemplate.h | 2 + Source/UI/Lists/UITagListBox.cpp | 4 + .../ProbabilityTable/UIProbabilityTable.cpp | 14 +- Source/UI/Quest/UIOngoingQuestInfo.cpp | 27 ++ Source/UI/Quest/UIRenewQuestUI.cpp | 33 +-- Source/UI/Quest/UIRenewQuestUI.h | 1 - Source/UI/Rodex/UIRodexComposeWnd.cpp | 4 +- Source/UI/Rodex/UIRodexComposeWnd.h | 1 - .../UISelectPackageItemBox.cpp | 54 ++++ Source/UI/Shortcuts/UIShortCutWnd.cpp | 2 +- Source/UI/Text/UIAchWnd.cpp | 10 +- Source/UI/Text/UITextViewerControl.h | 1 - Source/UI/Text/UITextViewerMessages.cpp | 8 +- Source/UI/UIBroadcastBalloon.cpp | 2 +- Source/UI/UIBroadcastBalloon.h | 4 - Source/UI/UICaptchaPreviewWnd.cpp | 14 +- Source/UI/UICaptchaRegisterWnd.cpp | 4 +- Source/UI/UICaptchaRegisterWnd.h | 2 - Source/UI/UICheckAttendanceWnd.cpp | 10 + Source/UI/UIGradeEnchantWnd.cpp | 7 +- Source/UI/UIHotkeyGuideWnd.cpp | 2 +- Source/UI/UIMacroDetectorWnd.h | 3 - Source/UI/UIReputeWnd.cpp | 1 + Source/UI/UIReputeWnd.h | 2 - Source/UI/Window/UIFrameWnd.cpp | 4 +- Source/UI/Window/UIRegisterMgr.h | 1 - Source/UI/Window/UIRoMapWnd.cpp | 2 +- Source/UI/Window/UISecondCostumeWnd.cpp | 2 +- Source/UI/Window/UISecondCostumeWnd.h | 1 - Source/UI/Window/UISelCharForUServerWnd.cpp | 2 +- Source/UI/Window/UISelCharForUServerWnd.h | 1 - Source/UI/Window/UIWindow.h | 1 - Source/UI/Window/UIWindowMgr.cpp | 102 +++---- Source/UI/Window/UIWindowMgr.h | 1 - Source/Utility/EncryptedName.h | 56 ++++ Source/Utility/GGHash.cpp | 2 +- Source/Utility/Hash/MD5.cpp | 275 +++++++++++++++++- 110 files changed, 1184 insertions(+), 940 deletions(-) create mode 100644 Source/Utility/EncryptedName.h diff --git a/Source/Archive/GPak.cpp b/Source/Archive/GPak.cpp index d80bd284..45417339 100644 --- a/Source/Archive/GPak.cpp +++ b/Source/Archive/GPak.cpp @@ -524,7 +524,6 @@ unsigned int Triple32Hash(unsigned int value) { void sub_6468C0(void* first, void* last, const void* val); void sub_646930(void* first, void* last, const void* val); -[[noreturn]] void sub_4F9440(); struct VectorUint32_654D10 { unsigned int* first; @@ -543,7 +542,7 @@ __declspec(noinline) void VectorUint32_654D10::AssignFill(unsigned int count, un return; } if (count > 0x3fffffff) { - sub_4F9440(); + std::_Throw_bad_array_new_length(); } unsigned int bytes = count * sizeof(unsigned int); unsigned int* new_ptr; @@ -555,7 +554,7 @@ __declspec(noinline) void VectorUint32_654D10::AssignFill(unsigned int count, un } } else { if (bytes + 0x23 <= bytes) { - sub_4F9440(); + std::_Throw_bad_array_new_length(); } void* raw = ::operator new(bytes + 0x23); if (!raw) { @@ -601,7 +600,7 @@ __declspec(noinline) void VectorInt32_654E00::AssignFill(unsigned int count, int return; } if (count > 0x3fffffff) { - sub_4F9440(); + std::_Throw_bad_array_new_length(); } unsigned int bytes = count * sizeof(int); int* new_ptr; @@ -613,7 +612,7 @@ __declspec(noinline) void VectorInt32_654E00::AssignFill(unsigned int count, int } } else { if (bytes + 0x23 <= bytes) { - sub_4F9440(); + std::_Throw_bad_array_new_length(); } void* raw = ::operator new(bytes + 0x23); if (!raw) { @@ -997,19 +996,19 @@ HashNode_655340* HashTable_655340::EraseRange(HashNode_655340* first, HashNode_6 return last; } -void sub_6563E0(void*, void*, void*); - -struct PakUniformRandom { - /* 0000 */ std::mt19937 m_engine; - /* 1388 */ std::uniform_int_distribution m_distribution; - - PakUniformRandom(int minimum, int maximum, unsigned int seed); -}; #if defined(_WIN32) && !defined(_WIN64) static_assert(offsetof(PakUniformRandom, m_distribution) == 0x1388); #endif +// OFFSET: 0x006563E0 +// FUNCTION: fn_05073 +__declspec(noinline) void FillRandomBytes(char* first, char* last, PakUniformRandom& random) { + for (; first != last; ++first) { + *first = static_cast(random.m_distribution(random.m_engine)); + } +} + struct PakKeyBlock48 { /* 0000 */ std::uint8_t bytes[48]; }; @@ -1039,7 +1038,7 @@ short* PakCipherBlock_655900::Encode(const short* in, const int* src) { unsigned int seed = std::_Random_device(); PakUniformRandom rng(1, 0xfe, seed); - sub_6563E0(key_ptr, payload, &rng); + FillRandomBytes(reinterpret_cast(key_ptr), payload, rng); const unsigned char* in_bytes = reinterpret_cast(src); unsigned char* out_bytes = reinterpret_cast(out); @@ -1139,9 +1138,16 @@ HashSearchResult_655D70 HashTable_655340::FindLast(const short* key, unsigned in struct SeedGen_657C30 { unsigned int seed; - unsigned int sub_657C30(); + __declspec(noinline) unsigned int sub_657C30(); }; +// OFFSET: 0x00657C30 +// FUNCTION: fn_05095 +__declspec(noinline) unsigned int SeedGen_657C30::sub_657C30() { + this->seed = static_cast(static_cast(this->seed) * 40014u % 0x7fffffabu); + return this->seed; +} + struct RanluxEngine_655F00 { void Seed(const unsigned int* seed_ptr, char flag, int unused); }; @@ -1844,33 +1850,6 @@ namespace GPakEx { return this; } - class BlockCipherStub { - public: - /* 0000 */ void* m_vftable; - - void sub_642A60(); - }; - - class CipherModeStub { - public: - /* 0000 */ void* m_vftable; - /* 0004 */ BlockCipherStub* m_cipher; - /* 0008 */ std::uint8_t* m_register[3]; - /* 0014 */ std::uint8_t* m_buffer[3]; - - void sub_642A70(); - std::size_t CiphertextLength(std::size_t length, bool padding) const; - std::size_t Process(std::span input, std::span output, bool final); - void SetKeyWithIV(std::span key, std::span iv); - }; - - template - class FixedStateBlockCipher : public BlockCipherStub { - public: - /* 0004 */ std::uint8_t m_state[StateSize]; - - }; - // OFFSET: 0x006434B0 // FUNCTION: fn_04838 __declspec(noinline) void XorBuffers(std::uint8_t* output, const std::uint8_t* input, const std::uint8_t* mask, std::size_t length) { @@ -3314,25 +3293,6 @@ namespace GPakEx { static_assert(offsetof(GostCfbDecryption, m_blockCipher) == 0x2C); - class CipherModeFinal_6470D0 : public CipherModeStub { - public: - /* 0020 */ FixedStateBlockCipher<0xD0> m_blockCipher; - - // INLINED - CipherModeFinal_6470D0() { - this->sub_6470D0(); - } - - // INLINED - ~CipherModeFinal_6470D0() { - SecureWipe(this->m_blockCipher.m_state, sizeof(this->m_blockCipher.m_state)); - this->m_blockCipher.sub_642A60(); - this->sub_642A70(); - } - - void sub_6470D0(); - }; - } using PakBlockTransform = void (*)(std::span, std::span, std::span, std::span); @@ -3342,7 +3302,7 @@ __forceinline void EncryptBlockWithDataHash(std::span data, std::span input, std::span output) { const auto iv = keyData.subspan(Deobfuscate<0x53F9360C, 0x4CC36824>(ivOffset), Deobfuscate<0x53F9360C, 0x4CC36824>(8)); XXH128_hash_t key = XXH3_128bits(data.data(), data.size()); - GPakEx::CipherModeFinal_6470D0 cipher; + GPakEx::IdeaCbcEncryption cipher; cipher.SetKeyWithIV(std::span(reinterpret_cast(&key), sizeof(key)), iv); cipher.Process(input, output, false); SecureWipe(&key, sizeof(key)); @@ -3353,7 +3313,7 @@ __forceinline void EncryptDataHash(std::span data, std::span std::span key, std::span output) { const auto iv = keyData.subspan(Deobfuscate<0x53F9360C, 0x4CC36824>(ivOffset), Deobfuscate<0x53F9360C, 0x4CC36824>(8)); XXH128_hash_t hash = XXH3_128bits(data.data(), data.size()); - GPakEx::CipherModeFinal_6470D0 cipher; + GPakEx::IdeaCbcEncryption cipher; cipher.SetKeyWithIV(key, iv); cipher.Process(std::span(reinterpret_cast(&hash), sizeof(hash)), output, false); SecureWipe(&hash, sizeof(hash)); diff --git a/Source/Archive/GPak.h b/Source/Archive/GPak.h index b206f38f..3d6aff60 100644 --- a/Source/Archive/GPak.h +++ b/Source/Archive/GPak.h @@ -8,8 +8,18 @@ #include #include #include +#include #include +struct PakUniformRandom { + /* 0000 */ std::mt19937 m_engine; + /* 1388 */ std::uniform_int_distribution m_distribution; + + PakUniformRandom(int minimum, int maximum, unsigned int seed); +}; + +void FillRandomBytes(char* first, char* last, PakUniformRandom& random); + namespace myGPack { struct PakEntry { diff --git a/Source/Client/Application/ApplicationWindow.cpp b/Source/Client/Application/ApplicationWindow.cpp index 4841e320..40feb18f 100644 --- a/Source/Client/Application/ApplicationWindow.cpp +++ b/Source/Client/Application/ApplicationWindow.cpp @@ -78,11 +78,11 @@ LRESULT CALLBACK sub_E5C430(HWND window, UINT message, WPARAM wParam, LPARAM lPa for (int i = 0; i < count; ++i) { candidates[i] = g_serverLanguage->Candidate(first + i); } - g_windowMgr.sub_A978D0(0x33)->SendMsg(nullptr, 0x41, reinterpret_cast(candidates), reinterpret_cast(info), 0, 0); + g_windowMgr.EnsureWindow(0x33)->SendMsg(nullptr, 0x41, reinterpret_cast(candidates), reinterpret_cast(info), 0, 0); } if (g_serverLanguage->DisplayLength()) { - g_windowMgr.sub_A978D0(0x55)->Invalidate(); + g_windowMgr.EnsureWindow(0x55)->Invalidate(); } else { g_windowMgr.CloseWindow(0x55); } diff --git a/Source/Client/Application/Launcher.cpp b/Source/Client/Application/Launcher.cpp index 8bc59f64..ef818f9e 100644 --- a/Source/Client/Application/Launcher.cpp +++ b/Source/Client/Application/Launcher.cpp @@ -1,4 +1,5 @@ #include "Client/Application/Launcher.h" +#include "Utility/EncryptedName.h" #include "Utility/Cipher/XorBytes.h" #include "Utility/Text/FormatString.h" #include "Contents/Configuration/ServiceConfiguration.h" @@ -109,41 +110,6 @@ HINSTANCE g_instance; // GLOBAL: gl_24584 char g_applicationDirectory[0x80]; -template -class EncryptedName { -public: - // INLINED - template - explicit EncryptedName(const Source (&source)[Length]) : m_encrypted(true) { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = source[index]; - } - } - - ~EncryptedName() { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = 0; - } - } - - bool Encrypted() const { - return this->m_encrypted; - } - - const char* Text() { - if (this->m_encrypted) { - utility::XorBytes(this->m_text, Length, Key); - this->m_encrypted = false; - } - - return reinterpret_cast(this->m_text); - } - -private: - /* 0000 */ std::uint8_t m_text[Length]; - bool m_encrypted; -}; - // INLINED template EncryptedName& ThreadLocalName(const Source (&source)[Length]) { @@ -931,7 +897,7 @@ public: virtual ~CEquipmentPropertiesMgr(); static CEquipmentPropertiesMgr* GetInstance(); - void sub_6AD910(); + bool InitializeLua(); }; } @@ -941,7 +907,7 @@ void sub_E198F0(); void __fastcall sub_81FE50(CSignBoardMgr* manager); LRESULT CALLBACK sub_E5C430(HWND window, UINT message, WPARAM wParam, LPARAM lParam); int sub_E59030(); -void sub_AEA780(); +int RemoveProtectionTools(); void sub_3DE90E0(char* buffer); void IgnoreNull(); LSTATUS SaveDisplayDeviceSettings(); @@ -1403,9 +1369,9 @@ std::pair InitializeManagers() { Singleton::GetInstance()->Init(); GetMapSkyMgr()->LoadData(); Singleton::GetInstance()->LoadScript(); - Singleton::GetInstance()->sub_9EB920(); + Singleton::GetInstance()->Load(); Singleton::GetInstance()->Init(); - EquipmentProperties::CEquipmentPropertiesMgr::GetInstance()->sub_6AD910(); + EquipmentProperties::CEquipmentPropertiesMgr::GetInstance()->InitializeLua(); if (!CAdventureGuideMgr::Create()) { return std::make_pair(false, std::string(AdventureGuideCreateInstanceName()().Text())); } @@ -1838,7 +1804,7 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE previous, LPSTR commandLine, in CoUninitialize(); DestroyWindow(hWnd); - sub_AEA780(); + RemoveProtectionTools(); ShutdownManagers(); CSoundMgr::Destroy(); CoUninitialize(); diff --git a/Source/Client/Mode/CGameMode.h b/Source/Client/Mode/CGameMode.h index cd18403a..c977785a 100644 --- a/Source/Client/Mode/CGameMode.h +++ b/Source/Client/Mode/CGameMode.h @@ -264,7 +264,6 @@ public: bool HasResurrectionItem(); void SendMousePointerState(int value); void ShowSpecialPopup(int popupId); - void ReceiveNpcAckMapmove(const unsigned char* packet); void ReceiveZoneServerChange(const unsigned char* packet); void ReceiveZoneServerChange(const char* mapName, std::int16_t x, std::int16_t y, int ip, std::int16_t port); void RequestLocalMapMove(const char* mapName, std::uint16_t x, std::uint16_t y); @@ -465,7 +464,6 @@ public: void ReceiveEnchantSimulation(const unsigned char* packet); void ReceivePackageSimulation(const unsigned char* packet); void ReceiveSimulationResult(const unsigned char* packet); - void sub_D606B0(const unsigned char* packet); void ReceiveWindow154Result(std::int16_t value); void ReceivePlayerDuration(const unsigned char* packet); void ReceiveFailureNotice(const unsigned char* packet); @@ -574,12 +572,6 @@ public: __declspec(noinline) unsigned sub_CEBF30(const std::vector& data); unsigned sub_CEC100(const std::vector& data); unsigned sub_CEC6A0(const std::vector& data); - void sub_D2DB80(const unsigned char* record); - void sub_D3D2F0(const unsigned char* record); - void sub_D3F130(const unsigned char* record); - void sub_D24430(const unsigned char* record); - void sub_D350A0(const unsigned char* record); - void sub_D37A10(const unsigned char* record); void sub_D40730(const unsigned char* record); void ReceiveGroundSkill8(const unsigned char* record); void ReceiveGroundSkill32(const unsigned char* record); @@ -600,25 +592,13 @@ public: void sub_D1A330(const unsigned char* data); void sub_D1A520(int unknown_0004, std::string name, std::string text, bool flag); void SpawnGroundSkill(std::uint32_t aid, std::uint32_t owner, int value, std::int16_t x, std::int16_t y, int type, signed char level, unsigned char visible, unsigned char flags); - void sub_D60D70(std::uint32_t aid, std::uint32_t owner, std::int16_t x, std::int16_t y); - void sub_D41250(const unsigned char* record); - void sub_D51A90(const unsigned char* record); - void sub_D61390(const unsigned char* record); - void sub_D616B0(const unsigned char* record); - void sub_D619E0(const unsigned char* record); - void sub_D63720(const unsigned char* record); - void sub_D63A40(const unsigned char* record); - void sub_D63D70(const unsigned char* record); + void sub_D41250(const unsigned char* record); void sub_D65FC0(const unsigned char* record); void ReceiveBroadcastBalloonNotice(const unsigned char* packet); void ReceiveUnknownD65870(const unsigned char* packet); void ReceiveStatusChangeEffect2(const unsigned char* packet); void ReceiveActorStatusValuePacket2(const unsigned char* packet); void ReceiveWindow95Data(const unsigned char* packet); - void sub_D7B170( - int first, int second, int third, int fourth, int fifth, int sixth, int seventh, int eighth, int ninth, int tenth, - int eleventh, int twelfth, int thirteenth, int fourteenth, std::string text, int fifteenth - ); int Run() override; void Initialize(const char* name) override; void End() override; @@ -1031,6 +1011,13 @@ void SendPacketHeader2(std::uint16_t packetType); void sub_D73A10(const unsigned char* packet); void sub_D6E440(); +struct MiniMapEffectMarker { + /* 0000 */ int count; + /* 0004 */ int x; + /* 0008 */ int y; +}; + +extern std::map g_miniMapEffectMarkers; extern char g_pendingWhisperCount; extern int g_whisperRecord; extern int g_timeAttackStart; diff --git a/Source/Client/Mode/CLoginMode.h b/Source/Client/Mode/CLoginMode.h index ab122c33..1cbed70a 100644 --- a/Source/Client/Mode/CLoginMode.h +++ b/Source/Client/Mode/CLoginMode.h @@ -72,6 +72,19 @@ struct CharacterSlotExtension { }; #pragma pack(pop) +struct LoginStringRecord { + /* 0000 */ std::string unknown_0000; + /* 0018 */ std::string unknown_0018; + /* 0030 */ std::string unknown_0030; + /* 0048 */ std::string unknown_0048; + /* 0060 */ std::string unknown_0060; + /* 0078 */ unsigned char unknown_0078[8]; +}; + +#if defined(_WIN32) && !defined(_WIN64) +static_assert(sizeof(LoginStringRecord) == 0x80); +#endif + struct MapStateData { /* 0000 */ std::uint32_t values[4]; }; @@ -111,7 +124,7 @@ public: /* 6F1C */ std::vector unknown_6F1C; /* 6F28 */ int unknown_6F28; /* 6F2C */ std::vector unknown_6F2C; - /* 6F38 */ std::vector unknown_6F38; + /* 6F38 */ std::vector unknown_6F38; /* 6F44 */ unsigned char savedInlineCharset; /* 6F45 */ unsigned char unknown_6F45[0x3]; /* 6F48 */ int unknown_6F48; diff --git a/Source/Client/Mode/GameMode.cpp b/Source/Client/Mode/GameMode.cpp index 568bc823..3afda732 100644 --- a/Source/Client/Mode/GameMode.cpp +++ b/Source/Client/Mode/GameMode.cpp @@ -1364,10 +1364,10 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i return 0; } case 0x105: - g_windowMgr.sub_A978D0(0xA8); + g_windowMgr.EnsureWindow(0xA8); return 0; case 0x10D: - g_windowMgr.sub_A978D0(0xA9); + g_windowMgr.EnsureWindow(0xA9); return 0; case 0x103: { const GameModePacketDwordByteByte packet{ @@ -2423,7 +2423,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i if (argument2 == 0) { g_session.unknown_54C4.clear(); } else { - g_windowMgr.sub_A978D0(0x22); + g_windowMgr.EnsureWindow(0x22); } const GameModePacketDwordByte packet{0x2C7, static_cast(argument1), static_cast(argument2 != 0)}; GetRagConnection().Send(g_packetLengths.FixedLength(packet.packetId), &packet); @@ -2589,7 +2589,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i if (actor != nullptr && actor->unknown_0314 == 0) { return 0; } - g_windowMgr.sub_A978D0(0x5B)->SendMsg(nullptr, 0x50, 0, argument2, 0, 0); + g_windowMgr.EnsureWindow(0x5B)->SendMsg(nullptr, 0x50, 0, argument2, 0, 0); return 0; } if (argument1 == 20000) { @@ -2607,7 +2607,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i } if (argument1 == 40000) { if (static_cast(argument2) != g_session.unknown_1010) { - g_windowMgr.sub_A978D0(0xC4)->SendMsg(nullptr, 0x50, 0, argument2, 0, 0); + g_windowMgr.EnsureWindow(0xC4)->SendMsg(nullptr, 0x50, 0, argument2, 0, 0); } return 0; } @@ -2650,7 +2650,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i return 0; } if (argument1 == 154) { - g_windowMgr.sub_A978D0(0x5F); + g_windowMgr.EnsureWindow(0x5F); } } const std::uint16_t id = static_cast(argument1); @@ -2962,7 +2962,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i } const ITEM_INFO item = LookupClientItemByIdentity(g_session.m_inventoryItems, static_cast(argument1)); if (item.unknown_0064 == 1) { - UIWindow* window = g_windowMgr.sub_A978D0(0x8A); + UIWindow* window = g_windowMgr.EnsureWindow(0x8A); *reinterpret_cast(&this->unknown_0100[4]) = timeGetTime(); window->SendMsg(nullptr, 0x5B, argument1, argument2, 0, 0); } else { @@ -3257,7 +3257,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i } case 0xAF: { if (argument3 != 0) { - g_windowMgr.sub_A978D0(0x22)->SendMsg(nullptr, 6, 0xD7, 1, 0, 0); + g_windowMgr.EnsureWindow(0x22)->SendMsg(nullptr, 6, 0xD7, 1, 0, 0); } const GameModePacketDwordDwordDword packet{ 0x208, static_cast(argument1), static_cast(argument2), @@ -3410,7 +3410,7 @@ int CGameMode::SendMsg(int event, int argument1, int argument2, int argument3, i return 0; } g_windowMgr.CloseWindow(0x35); - g_windowMgr.sub_A978D0(0x35); + g_windowMgr.EnsureWindow(0x35); g_session.unknown_54AC = name; return 0; } @@ -5023,7 +5023,7 @@ unsigned CGameMode::sub_CEBF30(const std::vector& data) { std::vector record(0x13); std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D2DB80(record.data()); + this->ReceiveItemFallEntry(record.data()); } else if (header.type == 15001) { break; } else { @@ -5066,68 +5066,68 @@ unsigned CGameMode::sub_CEC100(const std::vector& data) { case 0xC9: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D3F130(record.data()); + this->ReceiveActorMessage32(record.data()); break; case 0xCA: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D51A90(record.data()); + this->ReceiveActorTitle(record.data()); break; case 0xCB: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D3D2F0(record.data()); + this->ReceivePlayerMessage82(record.data()); break; case 0xCC: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D24430(record.data()); + this->ReceiveActorText(record.data()); break; case 0xD0: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D350A0(record.data()); + this->ReceiveActorMoveEntryNamed(record.data()); break; case 0xD2: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D37A10(record.data()); + this->ReceiveActorStateEntryNamedOld(record.data()); break; case 0xD4: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D619E0(record.data()); + this->ReceiveActorMoveEntryLegacy(record.data()); break; case 0xD5: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D61390(record.data()); + this->ReceiveActorMoveEntry(record.data()); break; case 0xD6: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D616B0(record.data()); + this->ReceiveActorMoveEntryBody(record.data()); break; case 0xD7: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D63D70(record.data()); + this->ReceiveActorStateEntryLegacy(record.data()); break; case 0xD8: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D63720(record.data()); + this->ReceiveActorStateEntryNamed(record.data()); break; case 0xD9: std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; - this->sub_D63A40(record.data()); + this->ReceiveActorStateEntryNamedBody(record.data()); break; case 0xDA: { std::memcpy(record.data(), data.data() + offset, header.size); offset += header.size; const auto* stored = reinterpret_cast(record.data()); - this->sub_D7B170( + this->SpawnStandingPc2( stored->value0002, stored->value0006, stored->value000A, stored->value000C, stored->value000E, stored->value000F, stored->value0011, stored->value0015, stored->value0019, stored->value001B, stored->value001D, stored->value001F, stored->value0021, stored->value0023, stored->text, stored->value003D @@ -7905,7 +7905,7 @@ void CGameMode::Initialize(const char* name) { this->noticeBalloon = nullptr; g_windowMgr.HideWindow01C8(); g_windowMgr.ShowWindowsWithId(0x43, 0); - g_windowMgr.sub_A978D0(7); + g_windowMgr.EnsureWindow(7); g_windowMgr.SendNotice(4, 0, 0, 0, 0, 0); g_windowMgr.CenterSurface0478(); g_windowMgr.DrawWindows(); @@ -8805,8 +8805,6 @@ struct StatusPointRequestPacket { static_assert(sizeof(StatusPointRequestPacket) == 5); -int sub_C7F5A0(); - // GLOBAL: gl_25463 std::uint32_t g_spriteAtlasClearTick; @@ -8932,7 +8930,7 @@ void CGameMode::Update() { return; } - if (sub_C7F5A0()) { + if (ShouldRenderFrame()) { g_renderer->ClearWorld(); g_actorPickNode.Clear(); this->camera->Render(); @@ -9482,7 +9480,7 @@ void CGameMode::ExecuteTalkType(int talkType, std::string* arguments) { g_windowToggleFlag = !g_windowToggleFlag; g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0); if (g_windowToggleFlag) { - g_windowMgr.sub_A978D0(0x74); + g_windowMgr.EnsureWindow(0x74); } else { g_windowMgr.SendNotice(1, reinterpret_cast(LookupMessage(0x3AF)), 0x64FFFF, 0, 0, 0); } @@ -9579,7 +9577,7 @@ void CGameMode::ExecuteTalkType(int talkType, std::string* arguments) { } case 42: if (!g_windowMgr.CloseWindow(0x13B)) { - g_windowMgr.sub_A978D0(0x13B); + g_windowMgr.EnsureWindow(0x13B); } break; case 29: @@ -9983,7 +9981,7 @@ void CGameMode::ExecuteTalkType(int talkType, std::string* arguments) { break; } case 217: - g_windowMgr.sub_A978D0(0xCB); + g_windowMgr.EnsureWindow(0xCB); break; case 207: { char text[1024]; @@ -10084,7 +10082,7 @@ void CGameMode::ExecuteTalkType(int talkType, std::string* arguments) { } case 237: if (!g_windowMgr.CloseWindow(0x144)) { - g_windowMgr.sub_A978D0(0x144); + g_windowMgr.EnsureWindow(0x144); } break; case 254: diff --git a/Source/Client/Mode/GameModeHandlers.cpp b/Source/Client/Mode/GameModeHandlers.cpp index 7404b2e3..68d0e2c6 100644 --- a/Source/Client/Mode/GameModeHandlers.cpp +++ b/Source/Client/Mode/GameModeHandlers.cpp @@ -395,7 +395,7 @@ void CGameMode::ReceiveGroundSkillExtended(const unsigned char* record) { return; } case 0x126: - this->sub_D60D70(packet.aid, packet.owner, packet.x, packet.y); + this->SpawnMirrorActor(packet.aid, packet.owner, packet.x, packet.y); return; } @@ -441,7 +441,7 @@ void CGameMode::ReceiveGroundSkillExtended(const unsigned char* record) { // FUNCTION: fn_21824 void CGameMode::SpawnGroundSkill(std::uint32_t aid, std::uint32_t owner, int value, std::int16_t x, std::int16_t y, int type, signed char level, unsigned char visible, unsigned char flags) { if (type == 0x126) { - this->sub_D60D70(aid, owner, x, y); + this->SpawnMirrorActor(aid, owner, x, y); return; } GroundSkillArgumentData data; @@ -2560,7 +2560,7 @@ void CGameMode::ReceiveSimulationResult(const unsigned char* packet) { this->ReceivePackageSimulation(packet); break; case 2: - this->sub_D606B0(packet); + this->ReceiveRandomOptionSimulation(packet); break; case 3: this->ReceiveEnchantSimulation(packet); diff --git a/Source/Client/Mode/GameModeMiniMap.cpp b/Source/Client/Mode/GameModeMiniMap.cpp index bbefe7db..9ba4ff7a 100644 --- a/Source/Client/Mode/GameModeMiniMap.cpp +++ b/Source/Client/Mode/GameModeMiniMap.cpp @@ -84,14 +84,6 @@ __forceinline const char* TimeFontSpriteName() { // GLOBAL: gl_25107 CFile g_whisperFile; -struct MiniMapEffectMarker { - /* 0000 */ int count; - /* 0004 */ int x; - /* 0008 */ int y; -}; - -// GLOBAL: gl_25132 -std::map g_miniMapEffectMarkers; // OFFSET: 0x00CCFCE0 // FUNCTION: fn_21246 diff --git a/Source/Client/Mode/GameModeNotices.cpp b/Source/Client/Mode/GameModeNotices.cpp index a14200fe..f13c1350 100644 --- a/Source/Client/Mode/GameModeNotices.cpp +++ b/Source/Client/Mode/GameModeNotices.cpp @@ -5225,7 +5225,7 @@ void CGameMode::RequestLocalMapMove(const char* mapName, std::uint16_t x, std::u strcpy_s(packet.mapName, sizeof(packet.mapName), mapName); packet.x = x; packet.y = y; - this->ReceiveNpcAckMapmove(reinterpret_cast(&packet)); + this->ReceiveMapMove(reinterpret_cast(&packet)); } #pragma pack(push, 1) diff --git a/Source/Client/Mode/GameModePackets.cpp b/Source/Client/Mode/GameModePackets.cpp index 7c6feb50..21a967bc 100644 --- a/Source/Client/Mode/GameModePackets.cpp +++ b/Source/Client/Mode/GameModePackets.cpp @@ -2511,7 +2511,7 @@ __declspec(noinline) void CGameMode::ReceiveLapineBoxIngredient(const unsigned c return; } - if (UIWindow* window = g_windowMgr.sub_A978D0(0x122)) { + if (UIWindow* window = g_windowMgr.EnsureWindow(0x122)) { static_cast(window)->SetIngredient(static_cast(reinterpret_cast(packet))); } } @@ -7502,12 +7502,6 @@ struct MiniMapEffectMarkerPacket { }; #pragma pack(pop) -struct MiniMapEffectMarker { - /* 0000 */ int unknown_0000; - /* 0004 */ int x; - /* 0008 */ int y; -}; - // GLOBAL: gl_25132 std::map g_miniMapEffectMarkers; @@ -7519,7 +7513,7 @@ __declspec(noinline) void CGameMode::AddMiniMapEffectMarker(const unsigned char* if (found != g_miniMapEffectMarkers.end()) { found->second.x = marker->x; found->second.y = marker->y; - found->second.unknown_0000 = 0x78; + found->second.count = 0x78; return; } @@ -20100,7 +20094,7 @@ void CGameMode::HandleCameraInfo(const unsigned char* data) { if (packet->action == 1) { UIWindow* window = g_windowMgr.LookupWindow(289); if (window == nullptr) { - window = g_windowMgr.sub_A978D0(289); + window = g_windowMgr.EnsureWindow(289); } g_session.unknown_61B1 = g_session.unknown_61B1 == 0; g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0); @@ -21739,7 +21733,7 @@ void CGameMode::sub_D08910() { break; } case 0xA5: { - g_windowMgr.sub_A978D0(33); + g_windowMgr.EnsureWindow(33); const int count = static_cast(*reinterpret_cast(g_gameModePacketBuffer + 2) - 4) / sizeof(NormalItemRecord); const NormalItemRecord *record = reinterpret_cast(g_gameModePacketBuffer + 4); for (int i = 0; i < count; ++i, ++record) { @@ -21760,7 +21754,7 @@ void CGameMode::sub_D08910() { break; } case 0xA6: { - g_windowMgr.sub_A978D0(33); + g_windowMgr.EnsureWindow(33); const int count = static_cast(*reinterpret_cast(g_gameModePacketBuffer + 2) - 4) / sizeof(EquipItemRecord); const EquipItemRecord *record = reinterpret_cast(g_gameModePacketBuffer + 4); for (int i = 0; i < count; ++i, ++record) { @@ -21864,7 +21858,7 @@ void CGameMode::sub_D08910() { this->unknown_024C = 1; this->unknown_02DC = *reinterpret_cast(packet + 4); unsigned int length = *reinterpret_cast(packet + 2) - 8; - UIWindow *window = g_windowMgr.sub_A978D0(16); + UIWindow *window = g_windowMgr.EnsureWindow(16); char text[0x803]; if (g_serviceType == 10) { sprintf(text, "|%02x", LanguageCharset(31)); @@ -21880,7 +21874,7 @@ void CGameMode::sub_D08910() { case 0xB5: this->unknown_024C = 1; this->unknown_02DC = *reinterpret_cast(g_gameModePacketBuffer + 2); - g_windowMgr.sub_A978D0(16)->SendMsg(nullptr, 25, 0, 0, 0, 0); + g_windowMgr.EnsureWindow(16)->SendMsg(nullptr, 25, 0, 0, 0, 0); break; case 0xC0: { const std::uint32_t aid = *reinterpret_cast(g_gameModePacketBuffer + 2); @@ -21910,7 +21904,7 @@ void CGameMode::sub_D08910() { } case 0xC4: this->unknown_024C = 1; - g_windowMgr.sub_A978D0(25)->SendMsg(nullptr, 28, *reinterpret_cast(g_gameModePacketBuffer + 2), 0, 0, 0); + g_windowMgr.EnsureWindow(25)->SendMsg(nullptr, 28, *reinterpret_cast(g_gameModePacketBuffer + 2), 0, 0, 0); g_windowMgr.CloseWindow(22); g_windowMgr.CloseWindow(23); g_windowMgr.CloseWindow(24); @@ -21931,10 +21925,10 @@ void CGameMode::sub_D08910() { g_session.AddItem1718(item, 0); } - UIWindow *buyWindow = g_windowMgr.sub_A978D0(22); + UIWindow *buyWindow = g_windowMgr.EnsureWindow(22); buyWindow->SendMsg(nullptr, 36, 0, 0, 0, 0); buyWindow->SendMsg(nullptr, 23, 0, 0, 0, 0); - UIWindow *sellWindow = g_windowMgr.sub_A978D0(23); + UIWindow *sellWindow = g_windowMgr.EnsureWindow(23); sellWindow->SendMsg(nullptr, 36, 0, 0, 0, 0); sellWindow->SendMsg(nullptr, 23, 0, 0, 0, 0); break; @@ -22008,7 +22002,7 @@ void CGameMode::sub_D08910() { case 0: { g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0); g_windowMgr.SendNotice(1, reinterpret_cast(LookupMessage(64)), 0xFFFF00, 0, 0, 0); - UIWindow *window = g_windowMgr.sub_A978D0(28); + UIWindow *window = g_windowMgr.EnsureWindow(28); this->unknown_03FC = 1; window->SendMsg(nullptr, 34, reinterpret_cast(&this->unknown_03C8), 0, 0, 0); window->SendMsg(nullptr, 43, 0, 0, 0, 0); @@ -22041,7 +22035,7 @@ void CGameMode::sub_D08910() { std::memcpy(name, g_gameModePacketBuffer + 4, 24); name[24] = '\0'; g_session.DecodePlayerName(); - UIChatRoomWnd *window = static_cast(g_windowMgr.sub_A978D0(28)); + UIChatRoomWnd *window = static_cast(g_windowMgr.EnsureWindow(28)); ChatRoomMemberUpdateInfo info{window->title, window->unknown_00CC, window->roomStatus.roomType, window->roomStatus.memberCount, window->roomStatus.memberLimit, window->roomStatus.roomId}; info.memberCount = *reinterpret_cast(g_gameModePacketBuffer + 2); @@ -22062,7 +22056,7 @@ void CGameMode::sub_D08910() { break; } - UIChatRoomWnd *window = static_cast(g_windowMgr.sub_A978D0(28)); + UIChatRoomWnd *window = static_cast(g_windowMgr.EnsureWindow(28)); ChatRoomMemberUpdateInfo info{window->title, window->unknown_00CC, window->roomStatus.roomType, window->roomStatus.memberCount, window->roomStatus.memberLimit, window->roomStatus.roomId}; info.memberCount = *reinterpret_cast(g_gameModePacketBuffer + 2); @@ -22082,7 +22076,7 @@ void CGameMode::sub_D08910() { break; } case 0xE1: { - UIWindow *window = g_windowMgr.sub_A978D0(28); + UIWindow *window = g_windowMgr.EnsureWindow(28); char name[25]; std::memcpy(name, g_gameModePacketBuffer + 6, 24); name[24] = '\0'; @@ -22098,7 +22092,7 @@ void CGameMode::sub_D08910() { char name[25]; std::memcpy(name, g_gameModePacketBuffer + 2, 24); name[24] = '\0'; - g_windowMgr.sub_A978D0(32)->SendMsg(nullptr, 50, reinterpret_cast(name), 0, 0, 0); + g_windowMgr.EnsureWindow(32)->SendMsg(nullptr, 50, reinterpret_cast(name), 0, 0, 0); this->exchangeName.assign(name, strlen(name)); break; } @@ -22144,7 +22138,7 @@ void CGameMode::sub_D08910() { g_session.ResetSlots(); break; case 0xF2: - g_windowMgr.sub_A978D0(33)->SendMsg(nullptr, 55, *reinterpret_cast(g_gameModePacketBuffer + 2), + g_windowMgr.EnsureWindow(33)->SendMsg(nullptr, 55, *reinterpret_cast(g_gameModePacketBuffer + 2), *reinterpret_cast(g_gameModePacketBuffer + 4), 0, 0); break; case 0xF6: { @@ -22164,7 +22158,7 @@ void CGameMode::sub_D08910() { switch (g_gameModePacketBuffer[2]) { case 0: g_windowMgr.SendNotice(1, reinterpret_cast(LookupMessage(77)), 0xFFFF00, 0, 0, 0); - g_windowMgr.sub_A978D0(34); + g_windowMgr.EnsureWindow(34); break; case 1: g_windowMgr.SendNotice(1, reinterpret_cast(LookupMessage(78)), 0xFF, 0, 0, 0); @@ -22187,7 +22181,7 @@ void CGameMode::sub_D08910() { g_forbiddenWords.Mask(name, &masked); } g_session.unknown_54C4.assign(name, strlen(name)); - g_windowMgr.sub_A978D0(35)->SendMsg(nullptr, 56, *reinterpret_cast(g_gameModePacketBuffer + 2), reinterpret_cast(name), 0, 0); + g_windowMgr.EnsureWindow(35)->SendMsg(nullptr, 56, *reinterpret_cast(g_gameModePacketBuffer + 2), reinterpret_cast(name), 0, 0); break; } case 0x101: { @@ -22332,7 +22326,7 @@ void CGameMode::sub_D08910() { } case 0x11C: { g_windowMgr.CloseWindow(39); - UIWindow *window = g_windowMgr.sub_A978D0(39); + UIWindow *window = g_windowMgr.EnsureWindow(39); window->SendMsg(nullptr, 59, *reinterpret_cast(g_gameModePacketBuffer + 2), 0, 0, 0); const char *name = reinterpret_cast(g_gameModePacketBuffer + 4); for (unsigned int i = 0; i < 4; ++i, name += 16) { @@ -22482,7 +22476,7 @@ void CGameMode::sub_D08910() { if (g_windowMgr.window_027C || g_windowMgr.window_0274) { g_windowMgr.Confirm(LookupMessage(587), 0, true, false, 0, "Message", 280, 120, 0); this->SendMsg(81, 0, 0, 0, 0); - } else if (UIMerchantShopMakeWnd *window = static_cast(g_windowMgr.sub_A978D0(41))) { + } else if (UIMerchantShopMakeWnd *window = static_cast(g_windowMgr.EnsureWindow(41))) { window->AddActionButton(); } break; @@ -22546,7 +22540,7 @@ void CGameMode::sub_D08910() { case 0x142: { const std::uint32_t aid = *reinterpret_cast(g_gameModePacketBuffer + 2); if (this->scene->GetGameActorByAID(aid)) { - g_windowMgr.sub_A978D0(56)->SendMsg(nullptr, 28, aid, 0, 0, 0); + g_windowMgr.EnsureWindow(56)->SendMsg(nullptr, 28, aid, 0, 0, 0); } break; } @@ -22741,7 +22735,7 @@ void CGameMode::sub_D08910() { std::string masked(""); g_forbiddenWords.Mask(name, &masked); } - g_windowMgr.sub_A978D0(70)->SendMsg(nullptr, 73, *reinterpret_cast(g_gameModePacketBuffer + 2), reinterpret_cast(name), 0, 0); + g_windowMgr.EnsureWindow(70)->SendMsg(nullptr, 73, *reinterpret_cast(g_gameModePacketBuffer + 2), reinterpret_cast(name), 0, 0); break; } case 0x16C: { @@ -22784,7 +22778,7 @@ void CGameMode::sub_D08910() { std::string masked(""); g_forbiddenWords.Mask(name, &masked); } - g_windowMgr.sub_A978D0(72)->SendMsg(nullptr, 74, *reinterpret_cast(g_gameModePacketBuffer + 2), reinterpret_cast(name), 0, 0); + g_windowMgr.EnsureWindow(72)->SendMsg(nullptr, 74, *reinterpret_cast(g_gameModePacketBuffer + 2), reinterpret_cast(name), 0, 0); break; } case 0x173: @@ -22811,7 +22805,7 @@ void CGameMode::sub_D08910() { break; case 0x177: { unsigned int count = (*reinterpret_cast(g_gameModePacketBuffer + 2) - 4u) >> 1; - UIWindow *window = g_windowMgr.sub_A978D0(73); + UIWindow *window = g_windowMgr.EnsureWindow(73); window->SendMsg(nullptr, 75, 0, 0, 0, 0); const std::int16_t *index = reinterpret_cast(g_gameModePacketBuffer + 4); for (; count != 0; --count, ++index) { @@ -22839,7 +22833,7 @@ void CGameMode::sub_D08910() { break; case 0x17B: { unsigned int count = (*reinterpret_cast(g_gameModePacketBuffer + 2) - 4u) >> 1; - UIWindow *window = g_windowMgr.sub_A978D0(74); + UIWindow *window = g_windowMgr.EnsureWindow(74); window->SendMsg(nullptr, 75, 0, 0, 0, 0); window->SendMsg(nullptr, 77, *reinterpret_cast(this->unknown_045C), 0, 0, 0); const std::int16_t *index = reinterpret_cast(g_gameModePacketBuffer + 4); @@ -22908,7 +22902,7 @@ void CGameMode::sub_D08910() { case 0x18C: { const std::uint16_t id = *reinterpret_cast(g_gameModePacketBuffer + 2); if (id != 1285 && id != 1286 && id != 1287 && id != 1829 && id != 1830) { - g_windowMgr.sub_A978D0(77)->SendMsg(nullptr, 79, reinterpret_cast(g_gameModePacketBuffer), 0, 0, 0); + g_windowMgr.EnsureWindow(77)->SendMsg(nullptr, 79, reinterpret_cast(g_gameModePacketBuffer), 0, 0, 0); } break; } @@ -22919,7 +22913,7 @@ void CGameMode::sub_D08910() { break; } g_windowMgr.CloseWindow(79); - UIWindow *window = g_windowMgr.sub_A978D0(79); + UIWindow *window = g_windowMgr.EnsureWindow(79); const int *record = reinterpret_cast(g_gameModePacketBuffer + 4); for (; count != 0; --count, record += 4) { window->SendMsg(nullptr, 31, *record, 0, 0, 0); @@ -22975,7 +22969,7 @@ void CGameMode::sub_D08910() { std::int16_t &value = *reinterpret_cast(packet + 0x1B); if (value >= 10000) { value -= 10000; - if (UIItemCollectionWnd *window = static_cast(g_windowMgr.sub_A978D0(12))) { + if (UIItemCollectionWnd *window = static_cast(g_windowMgr.EnsureWindow(12))) { window->unknown_0218 = value; window->unknown_021A = *reinterpret_cast(packet + 0x1D); window->unknown_021C = *reinterpret_cast(packet + 0x1F); @@ -23003,7 +22997,7 @@ void CGameMode::sub_D08910() { } case 0x1A6: { const int count = static_cast(*reinterpret_cast(g_gameModePacketBuffer + 2) - 4) >> 1; - UIWindow *window = g_windowMgr.sub_A978D0(90); + UIWindow *window = g_windowMgr.EnsureWindow(90); window->SendMsg(nullptr, 75, 0, 0, 0, 0); const std::int16_t *index = reinterpret_cast(g_gameModePacketBuffer + 4); for (int i = 0; i < count; ++i, ++index) { @@ -23039,7 +23033,7 @@ void CGameMode::sub_D08910() { break; case 0x1AD: { const unsigned int count = static_cast(*reinterpret_cast(g_gameModePacketBuffer + 2) - 4) >> 2; - UIWindow *window = g_windowMgr.sub_A978D0(94); + UIWindow *window = g_windowMgr.EnsureWindow(94); window->SendMsg(nullptr, 75, 0, 0, 0, 0); const unsigned char *entry = g_gameModePacketBuffer + 4; for (unsigned int i = count; i != 0; --i, entry += 4) { @@ -23165,7 +23159,7 @@ void CGameMode::sub_D08910() { if (count <= 0) { break; } - if (UIWindow *window = g_windowMgr.sub_A978D0(99)) { + if (UIWindow *window = g_windowMgr.EnsureWindow(99)) { for (const int *skill = reinterpret_cast(g_gameModePacketBuffer + 2); skill < reinterpret_cast(g_gameModePacketBuffer + 0x1E); ++skill) { if (*skill) { @@ -23182,7 +23176,7 @@ void CGameMode::sub_D08910() { case 0x1D4: if (this->scene->GetGameActorByAID(*reinterpret_cast(g_gameModePacketBuffer + 2)) || *reinterpret_cast(g_gameModePacketBuffer + 2) == 0) { - g_windowMgr.sub_A978D0(100)->SendMsg(nullptr, 28, *reinterpret_cast(g_gameModePacketBuffer + 2), 0, 0, 0); + g_windowMgr.EnsureWindow(100)->SendMsg(nullptr, 28, *reinterpret_cast(g_gameModePacketBuffer + 2), 0, 0, 0); } break; case 0x1D6: { @@ -23233,7 +23227,7 @@ void CGameMode::sub_D08910() { name[24] = 0; *reinterpret_cast(this->unknown_028C) = *reinterpret_cast(g_gameModePacketBuffer + 2); *reinterpret_cast(this->unknown_028C + 4) = *reinterpret_cast(g_gameModePacketBuffer + 6); - g_windowMgr.sub_A978D0(104)->SendMsg(nullptr, 90, *reinterpret_cast(g_gameModePacketBuffer + 6), reinterpret_cast(name), 0, + g_windowMgr.EnsureWindow(104)->SendMsg(nullptr, 90, *reinterpret_cast(g_gameModePacketBuffer + 6), reinterpret_cast(name), 0, 0); break; } @@ -23301,7 +23295,7 @@ void CGameMode::sub_D08910() { break; } case 0x1F0: { - g_windowMgr.sub_A978D0(33); + g_windowMgr.EnsureWindow(33); const int count = static_cast(*reinterpret_cast(g_gameModePacketBuffer + 2) - 4) / sizeof(CardItemRecord); const CardItemRecord *record = reinterpret_cast(g_gameModePacketBuffer + 4); for (int i = 0; i < count; ++i, ++record) { @@ -23346,7 +23340,7 @@ void CGameMode::sub_D08910() { char name[25]; std::memcpy(name, g_gameModePacketBuffer + 2, 24); name[24] = '\0'; - g_windowMgr.sub_A978D0(32)->SendMsg(nullptr, 50, reinterpret_cast(name), *reinterpret_cast(g_gameModePacketBuffer + 0x1A), + g_windowMgr.EnsureWindow(32)->SendMsg(nullptr, 50, reinterpret_cast(name), *reinterpret_cast(g_gameModePacketBuffer + 0x1A), *reinterpret_cast(g_gameModePacketBuffer + 0x1E), 0); this->exchangeName.assign(name, strlen(name)); break; @@ -23357,7 +23351,7 @@ void CGameMode::sub_D08910() { name[24] = 0; *reinterpret_cast(this->unknown_028C) = *reinterpret_cast(g_gameModePacketBuffer + 2); *reinterpret_cast(this->unknown_028C + 4) = *reinterpret_cast(g_gameModePacketBuffer + 6); - g_windowMgr.sub_A978D0(105)->SendMsg(nullptr, 91, *reinterpret_cast(g_gameModePacketBuffer + 6), reinterpret_cast(name), 0, + g_windowMgr.EnsureWindow(105)->SendMsg(nullptr, 91, *reinterpret_cast(g_gameModePacketBuffer + 6), reinterpret_cast(name), 0, 0); break; } @@ -23368,7 +23362,7 @@ void CGameMode::sub_D08910() { break; } g_windowMgr.CloseWindow(107); - UIWindow *window = g_windowMgr.sub_A978D0(107); + UIWindow *window = g_windowMgr.EnsureWindow(107); const unsigned char *record = g_gameModePacketBuffer + 4; for (int i = 0; i < count; ++i, record += 23) { window->SendMsg(nullptr, 31, reinterpret_cast(record), 0, 0, 0); @@ -23427,7 +23421,7 @@ void CGameMode::sub_D08910() { g_modeMgr.gameMode->SendMsg(175, *reinterpret_cast(g_gameModePacketBuffer + 2), *reinterpret_cast(g_gameModePacketBuffer + 6), 0, 0); } else { - g_windowMgr.sub_A978D0(109)->SendMsg(nullptr, 95, *reinterpret_cast(g_gameModePacketBuffer + 2), + g_windowMgr.EnsureWindow(109)->SendMsg(nullptr, 95, *reinterpret_cast(g_gameModePacketBuffer + 2), *reinterpret_cast(g_gameModePacketBuffer + 6), reinterpret_cast(name), 0); } break; @@ -23462,7 +23456,7 @@ void CGameMode::sub_D08910() { if (g_windowMgr.LookupWindow(111)) { g_windowMgr.CloseWindow(111); } - UIWindow *window = g_windowMgr.sub_A978D0(111); + UIWindow *window = g_windowMgr.EnsureWindow(111); const unsigned char *record = g_gameModePacketBuffer + 4; for (int i = 0; i < count; ++i, record += 23) { window->SendMsg(nullptr, 31, *reinterpret_cast(record + 2), *reinterpret_cast(record), 0, 0); @@ -23499,11 +23493,11 @@ void CGameMode::sub_D08910() { break; } case 0x253: - g_windowMgr.sub_A978D0(119)->SendMsg(nullptr, 91, static_cast(g_gameModePacketBuffer[2]), 0, 0, 0); + g_windowMgr.EnsureWindow(119)->SendMsg(nullptr, 91, static_cast(g_gameModePacketBuffer[2]), 0, 0, 0); break; case 0x25A: { const unsigned int count = static_cast(*reinterpret_cast(g_gameModePacketBuffer + 2) - 6) >> 2; - UIWindow *window = g_windowMgr.sub_A978D0(94); + UIWindow *window = g_windowMgr.EnsureWindow(94); if (!window) { break; } @@ -23632,7 +23626,7 @@ void CGameMode::sub_D08910() { break; } case 0x2EA: { - g_windowMgr.sub_A978D0(33); + g_windowMgr.EnsureWindow(33); const int count = static_cast(*reinterpret_cast(g_gameModePacketBuffer + 2) - 4) / sizeof(CardItemExpiryRecord); const CardItemExpiryRecord *entry = reinterpret_cast(g_gameModePacketBuffer + 4); for (int i = 0; i < count; ++i, ++entry) { @@ -23703,7 +23697,7 @@ void CGameMode::sub_D08910() { if (count == 0) { break; } - if (UIWindow *window = g_windowMgr.sub_A978D0(99)) { + if (UIWindow *window = g_windowMgr.EnsureWindow(99)) { window->SendMsg(nullptr, 27, *reinterpret_cast(g_gameModePacketBuffer + 4), 0, 0, 0); const std::uint16_t *skills = reinterpret_cast(g_gameModePacketBuffer + 8); for (int i = 0; i < count; ++i) { @@ -24159,7 +24153,7 @@ void CGameMode::sub_D08910() { case 0x845: case 0xA2B: if (!g_windowMgr.CloseWindow(318)) { - if (UIWindow *window = g_windowMgr.sub_A978D0(318)) { + if (UIWindow *window = g_windowMgr.EnsureWindow(318)) { window->SendMsg(nullptr, 120, *reinterpret_cast(g_gameModePacketBuffer + 2), *reinterpret_cast(g_gameModePacketBuffer + 6), 0, 0); } else { @@ -24389,7 +24383,7 @@ void CGameMode::sub_D08910() { this->ReceiveFeedConfig(g_gameModePacketBuffer[0x2], g_gameModePacketBuffer[0x3]); break; case 0xAA0: - g_windowMgr.sub_A978D0(295); + g_windowMgr.EnsureWindow(295); break; case 0xAB4: this->ReceiveLapineUpgradeBoxValue(*reinterpret_cast(g_gameModePacketBuffer + 0x2)); @@ -24698,7 +24692,7 @@ void CGameMode::sub_D08910() { case 0x973: this->unknown_024C = 1; this->unknown_02DC = *reinterpret_cast(g_gameModePacketBuffer + 2); - g_windowMgr.sub_A978D0(226)->SendMsg(nullptr, 25, 0, 0, 0, 0); + g_windowMgr.EnsureWindow(226)->SendMsg(nullptr, 25, 0, 0, 0, 0); break; case 0xBEE: switch (g_gameModePacketBuffer[4]) { @@ -24881,7 +24875,7 @@ void CGameMode::sub_D08910() { memcpy(text, packet + 9, length); } text[length] = 0; - g_windowMgr.sub_A978D0(226)->SendMsg(nullptr, 26, reinterpret_cast(text), *reinterpret_cast(packet + 4), 0, 0); + g_windowMgr.EnsureWindow(226)->SendMsg(nullptr, 26, reinterpret_cast(text), *reinterpret_cast(packet + 4), 0, 0); break; } case 0xBF6: { @@ -24936,7 +24930,7 @@ void CGameMode::sub_D08910() { if (g_gameModePacketBuffer[2] == 1) { UIWindow *window = g_windowMgr.LookupWindow(289); if (!window) { - window = g_windowMgr.sub_A978D0(289); + window = g_windowMgr.EnsureWindow(289); } g_session.unknown_61B1 = !g_session.unknown_61B1; g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0); @@ -24977,10 +24971,10 @@ void CGameMode::sub_D08910() { case 0xA28: switch (g_gameModePacketBuffer[2]) { case 0: - if (UIWindow *window = g_windowMgr.sub_A978D0(45)) { + if (UIWindow *window = g_windowMgr.EnsureWindow(45)) { window->SendMsg(nullptr, 23, 0, 0, 0, 0); } - if (UIMerchantShopMakeWnd *window = static_cast(g_windowMgr.sub_A978D0(41))) { + if (UIMerchantShopMakeWnd *window = static_cast(g_windowMgr.EnsureWindow(41))) { window->PrintSellList(); } g_windowMgr.CloseWindow(41); @@ -25088,7 +25082,7 @@ void CGameMode::sub_D08910() { break; } case 0x904: { - g_windowMgr.sub_A978D0(33); + g_windowMgr.EnsureWindow(33); const int count = static_cast(*reinterpret_cast(g_gameModePacketBuffer + 2) - 4) / sizeof(FlaggedItemRecord); for (int i = 0; i < count; ++i) { const FlaggedItemRecord *record = reinterpret_cast(g_gameModePacketBuffer + 4) + i; @@ -25139,7 +25133,7 @@ void CGameMode::sub_D08910() { break; } case 0x905: { - g_windowMgr.sub_A978D0(33); + g_windowMgr.EnsureWindow(33); const int count = static_cast(*reinterpret_cast(g_gameModePacketBuffer + 2) - 4) / sizeof(FlaggedEquipRecord); for (int i = 0; i < count; ++i) { const FlaggedEquipRecord *record = reinterpret_cast(g_gameModePacketBuffer + 4) + i; @@ -25229,8 +25223,8 @@ void CGameMode::sub_D08910() { item.id = *reinterpret_cast(record + 0x15); g_barterMarketItemMgr->items.push_back(item); } - g_windowMgr.sub_A978D0(334)->SendMsg(nullptr, 23, 0, 0, 0, 0); - g_windowMgr.sub_A978D0(335)->SendMsg(nullptr, 23, 0, 0, 0, 0); + g_windowMgr.EnsureWindow(334)->SendMsg(nullptr, 23, 0, 0, 0, 0); + g_windowMgr.EnsureWindow(335)->SendMsg(nullptr, 23, 0, 0, 0, 0); break; } case 0x9D5: { @@ -25250,10 +25244,10 @@ void CGameMode::sub_D08910() { g_session.AddItem1718(item, *reinterpret_cast(entry + 9), static_cast(*reinterpret_cast(entry + 0xD) / 10)); } - UIWindow *window = g_windowMgr.sub_A978D0(254); + UIWindow *window = g_windowMgr.EnsureWindow(254); window->SendMsg(nullptr, 36, 0, 0, 0, 0); window->SendMsg(nullptr, 23, 0, 0, 0, 0); - window = g_windowMgr.sub_A978D0(255); + window = g_windowMgr.EnsureWindow(255); window->SendMsg(nullptr, 36, 0, 0, 0, 0); window->SendMsg(nullptr, 23, 0, 0, 0, 0); break; diff --git a/Source/Client/Mode/LoginMode.cpp b/Source/Client/Mode/LoginMode.cpp index f8aef391..775b633f 100644 --- a/Source/Client/Mode/LoginMode.cpp +++ b/Source/Client/Mode/LoginMode.cpp @@ -1,4 +1,5 @@ #include "Client/Mode/CLoginMode.h" +#include "Utility/EncryptedName.h" #include "Client/Mode/CGameMode.h" #include "Client/Application/ApplicationMessages.h" #include "Client/Application/ApplicationWindow.h" @@ -11,6 +12,7 @@ #include "Client/Mode/ModeMgr.h" #include "Client/Session.h" #include "Client/Replay.h" +#include "Client/Timer.h" #include "Client/Input/InputCharset.h" #include "Client/Stove/StovePCSDK.h" #include "Contents/Async/AsyncWorkMgr.h" @@ -90,7 +92,6 @@ #include #include -void sub_D8C390(const int* first, const int* last); void TraceSelection(int selection); void TraceSelectionRange(int first, int last); @@ -335,8 +336,6 @@ int g_restoreSurfaces; // GLOBAL: gl_25384 int g_isAppActive; -int sub_C7F5A0(); - static_assert(sizeof(CharacterSlotsPacket) == 0x1D); static_assert(offsetof(AcceptLoginPacket, body) == 0x2F); static_assert(sizeof(ServerAddress) == 0x20); @@ -346,37 +345,6 @@ static_assert(offsetof(CharacterSlotCountsPacket, extension) == 0xA); static_assert(sizeof(BlockedCharacter) == 0x18); static_assert(offsetof(AcceptEnterPacket, characters) == 0x1B); -template -class EncryptedName { -public: - // INLINED - template - explicit EncryptedName(const Byte (&source)[Length]) : m_encrypted(true) { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = source[index]; - } - } - - ~EncryptedName() { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = 0; - } - } - - const char* Text() { - if (this->m_encrypted) { - utility::XorBytes(this->m_text, Length, Key); - this->m_encrypted = false; - } - - return reinterpret_cast(this->m_text); - } - -private: - /* 0000 */ std::uint8_t m_text[Length]; - bool m_encrypted; -}; - // INLINED template const char* DecryptName(const char (&source)[Length]) { @@ -1028,7 +996,7 @@ void CLoginMode::Slot5(int value) { return; } - if (sub_C7F5A0()) { + if (ShouldRenderFrame()) { g_renderer->ClearDepth(1); g_windowMgr.UpdateFrameWindows(); if (g_serviceType == 0 || g_serviceType == 4 || g_serviceType == 8 || g_serviceType == 9 || g_serviceType == 3 || g_serviceType == 10 || @@ -1178,7 +1146,7 @@ void CLoginMode::Update() { return; } - if (sub_C7F5A0()) { + if (ShouldRenderFrame()) { g_renderer->ClearDepth(1); g_windowMgr.UpdateFrameWindows(); if (g_serviceType == 0 || g_serviceType == 4 || g_serviceType == 8 || g_serviceType == 9 || g_serviceType == 3 || g_serviceType == 10 || @@ -1213,7 +1181,7 @@ void CLoginMode::SubD97F00(int) { // OFFSET: 0x00D97F10 // FUNCTION: fn_22308 -void OpenAccountRegistration() { +void CLoginMode::OpenAccountRegistration() { switch (g_serviceType) { case 0: if (*reinterpret_cast(&g_session.unknown_59DC[0x198]) == 1) { @@ -3348,7 +3316,6 @@ int CLoginMode::SendMsg(int event, int argument1, int argument2, int argument3, return 0; case 10022: this->unknown_6F4C = argument1; - sub_D8C390(this->unknown_6F38.data(), this->unknown_6F38.data() + this->unknown_6F38.size()); this->unknown_6F38.clear(); TraceSelectionRange(this->unknown_6F48, this->unknown_6F4C); this->pendingCursorType = 3; diff --git a/Source/Client/Session.cpp b/Source/Client/Session.cpp index 8a03016f..df7f4c30 100644 --- a/Source/Client/Session.cpp +++ b/Source/Client/Session.cpp @@ -1,4 +1,5 @@ #include "Client/Session.h" +#include "Utility/EncryptedName.h" #include "Client/Mode/CGameMode.h" #include "Contents/Actors/RenderObject.h" #include "Contents/Effects/EffectActor.h" @@ -2740,35 +2741,6 @@ void CSession::LoadMiniPartyInfo() { delete[] data; } -template -class EncryptedName { -public: - explicit EncryptedName(const std::uint8_t (&source)[Length]) : m_encrypted(true) { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = source[index]; - } - } - - ~EncryptedName() { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = 0; - } - } - - const char* Text() { - if (this->m_encrypted) { - utility::XorBytes(this->m_text, Length, Key); - this->m_encrypted = false; - } - - return reinterpret_cast(this->m_text); - } - -private: - /* 0000 */ std::uint8_t m_text[Length]; - bool m_encrypted; -}; - // OFFSET: 0x00DFD060 // FUNCTION: fn_23603 void CSession::LoadExternalSettings() { diff --git a/Source/Client/Session.h b/Source/Client/Session.h index f391749b..c51f9da3 100644 --- a/Source/Client/Session.h +++ b/Source/Client/Session.h @@ -713,7 +713,6 @@ public: int GetMapProperty13() const; bool HasUnknown6178Records() const; bool HasUnknown6178Record(int id) const; - bool sub_E06580(int id); int IsBerserkActive() const; int IsTrickDeadActive() const; int HasActiveSkillEffect(int id) const; @@ -900,7 +899,6 @@ public: int SkillLevel(int id) const; CRenderObject* FindGameActor(std::uint32_t aid) const; int GetPetTargetAid() const; - bool sub_E1DE30(std::uint32_t aid); int sub_DDD2C0(const ITEM_INFO& item); const char* GetJobName(unsigned job, int sex); void InitJobNameTable(); diff --git a/Source/Client/Stove/StoveMgr.cpp b/Source/Client/Stove/StoveMgr.cpp index 5c986e24..7dc5a608 100644 --- a/Source/Client/Stove/StoveMgr.cpp +++ b/Source/Client/Stove/StoveMgr.cpp @@ -1,4 +1,5 @@ #include "Client/Application/ApplicationWindow.h" +#include "Utility/EncryptedName.h" #include "Client/Application/Launcher.h" #include "Client/Mode/CGameMode.h" #include "Client/Mode/CMode.h" @@ -26,14 +27,14 @@ // GLOBAL: gl_24904 bool g_stoveWaitingCallback; -void sub_63A7F0(Stove::PCSDK::CallbackResult callbackResult); -void sub_63A8D0(Stove::PCSDK::CallbackResult callbackResult); -void sub_63A860(Stove::PCSDK::CallbackResult callbackResult); +void OnStoveTermsAgreementFetched(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url); +void OnStoveCategoryProductsFetched(Stove::PCSDK::CallbackResult callbackResult, const Stove::PCSDK::IAP::StovePCProduct* products, unsigned int count); +void OnStoveAllProductsFetched(Stove::PCSDK::CallbackResult callbackResult, const Stove::PCSDK::IAP::StovePCProduct* products, unsigned int count); void sub_DD8A20(int value); -void sub_63A780(Stove::PCSDK::CallbackResult callbackResult); -void sub_63AA50(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::Base::StovePCShutdown shutdown); -void sub_63A940(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::IAP::StovePCPurchaseResult purchaseResult); -void sub_63A9D0(Stove::PCSDK::CallbackResult callbackResult, bool purchased, int unknown1, unsigned int count, int unknown2, int unknown3); +void OnStoveInitialized(Stove::PCSDK::CallbackResult callbackResult); +void OnStoveShutdown(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::Base::StovePCShutdown shutdown); +void OnStovePurchaseStarted(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::IAP::StovePCPurchaseResult purchaseResult); +void OnStovePurchaseConfirmed(Stove::PCSDK::CallbackResult callbackResult, bool purchased, int unknown1, unsigned int count, int unknown2, int unknown3); // STRING: st_01259 const wchar_t g_stoveCategoryIdA[] = L"44C71118750747D"; @@ -49,7 +50,7 @@ void CStoveMgr::FetchAllProducts() { allParam.SetCategoryId(L""); allParam.SetPageNumber(1); allParam.SetPageSize(0x7FFFFFFF); - IAP_FetchProducts(&allParam, sub_63A860); + IAP_FetchProducts(&allParam, OnStoveAllProductsFetched); g_stoveWaitingCallback = true; do { Base_RunCallback(); @@ -61,7 +62,7 @@ void CStoveMgr::FetchAllProducts() { categoryParam.SetCategoryId(this->m_environment == 2 ? g_stoveCategoryIdA : g_stoveCategoryIdB); categoryParam.SetPageNumber(1); categoryParam.SetPageSize(0x7FFFFFFF); - IAP_FetchProducts(&categoryParam, sub_63A8D0); + IAP_FetchProducts(&categoryParam, OnStoveCategoryProductsFetched); g_stoveWaitingCallback = true; do { Base_RunCallback(); @@ -74,7 +75,7 @@ void CStoveMgr::FetchAllProducts() { void FetchStoveTermsAgreement() { Stove::PCSDK::IAP::StovePCTermsOption option; option.SetOperation(Stove::PCSDK::IAP::StovePCPaymentOperation::DEFAULT); - IAP_FetchTermsAgreement(&option, sub_63A7F0); + IAP_FetchTermsAgreement(&option, OnStoveTermsAgreementFetched); g_stoveWaitingCallback = true; do { Base_RunCallback(); @@ -90,7 +91,7 @@ void CStoveMgr::FetchCategoryProducts() { param.SetCategoryId(this->m_environment == 2 ? g_stoveCategoryIdA : g_stoveCategoryIdB); param.SetPageNumber(1); param.SetPageSize(0x7FFFFFFF); - IAP_FetchProducts(¶m, sub_63A8D0); + IAP_FetchProducts(¶m, OnStoveCategoryProductsFetched); g_stoveWaitingCallback = true; do { Base_RunCallback(); @@ -98,36 +99,6 @@ void CStoveMgr::FetchCategoryProducts() { } while (g_stoveWaitingCallback); } -template -class EncryptedName { -public: - // INLINED - explicit EncryptedName(const char (&source)[Length]) : m_encrypted(true) { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = source[index]; - } - } - - ~EncryptedName() { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = 0; - } - } - - const char* Text() { - if (this->m_encrypted) { - utility::XorBytes(this->m_text, Length, Key); - this->m_encrypted = false; - } - - return reinterpret_cast(this->m_text); - } - -private: - /* 0000 */ std::uint8_t m_text[Length]; - bool m_encrypted; -}; - // INLINED template const char* DecryptName(const char (&source)[Length]) { @@ -151,6 +122,14 @@ struct PurchaseCheckingMessage { EncryptedName<129, 0x2D3B15774149D5DDULL>& operator()() const; }; +struct InitializeCallback { + void operator()(Stove::PCSDK::CallbackResult callbackResult) const; +}; + +struct TermsAgreementCallback { + void operator()(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url) const; +}; + struct FetchProductsCallback { void operator()(Stove::PCSDK::CallbackResult callbackResult, const Stove::PCSDK::IAP::StovePCProduct* products, unsigned int count) const; }; @@ -171,6 +150,48 @@ struct ConfirmPurchaseCallback { void operator()(Stove::PCSDK::CallbackResult callbackResult, bool purchased, int unknown1, unsigned int count, int unknown2, int unknown3) const; }; +// OFFSET: 0x0063A780 +// FUNCTION: fn_04771 +void OnStoveInitialized(Stove::PCSDK::CallbackResult callbackResult) { + InitializeCallback()(callbackResult); +} + +// OFFSET: 0x0063A7F0 +// FUNCTION: fn_04772 +void OnStoveTermsAgreementFetched(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url) { + TermsAgreementCallback()(callbackResult, unused, url); +} + +// OFFSET: 0x0063A860 +// FUNCTION: fn_04773 +void OnStoveAllProductsFetched(Stove::PCSDK::CallbackResult callbackResult, const Stove::PCSDK::IAP::StovePCProduct* products, unsigned int count) { + CategoryProductsCallback()(callbackResult, products, count); +} + +// OFFSET: 0x0063A8D0 +// FUNCTION: fn_04774 +void OnStoveCategoryProductsFetched(Stove::PCSDK::CallbackResult callbackResult, const Stove::PCSDK::IAP::StovePCProduct* products, unsigned int count) { + FetchProductsCallback()(callbackResult, products, count); +} + +// OFFSET: 0x0063A940 +// FUNCTION: fn_04775 +void OnStovePurchaseStarted(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::IAP::StovePCPurchaseResult purchaseResult) { + PurchaseResultCallback()(callbackResult, purchaseResult); +} + +// OFFSET: 0x0063A9D0 +// FUNCTION: fn_04776 +void OnStovePurchaseConfirmed(Stove::PCSDK::CallbackResult callbackResult, bool purchased, int unknown1, unsigned int count, int unknown2, int unknown3) { + ConfirmPurchaseCallback()(callbackResult, purchased, unknown1, count, unknown2, unknown3); +} + +// OFFSET: 0x0063AA50 +// FUNCTION: fn_04777 +void OnStoveShutdown(Stove::PCSDK::CallbackResult callbackResult, Stove::PCSDK::Base::StovePCShutdown shutdown) { + ShutdownCallback()(callbackResult, shutdown); +} + // OFFSET: 0x0063AAE0 // FUNCTION: fn_04778 @@ -425,7 +446,7 @@ EncryptedName<100, 0x4F1791FB1503C713ULL>& TokenCallbackFailureMessage::operator // OFFSET: 0x0063D260 // FUNCTION: fn_04789 -void CStoveMgr::OnInitializeCallback(Stove::PCSDK::CallbackResult callbackResult) { +void InitializeCallback::operator()(Stove::PCSDK::CallbackResult callbackResult) const { g_stoveWaitingCallback = false; if (!callbackResult.GetResult().IsSuccessful()) { const char captionSource[] = {'\xD5', '\x3D', '\xF8', '\x60', '\x2C', '\x37', '\xD7'}; @@ -521,12 +542,12 @@ bool CStoveMgr::Initialize() { return false; } - Base_Initialize(¶m, sub_63A780); + Base_Initialize(¶m, OnStoveInitialized); this->WaitForCallback(); Stove::PCSDK::Result result = IAP_Initialize(this->unknown_02B8.c_str()); if (result.IsSuccessful()) { this->FetchUser(); - Base_GetShutdown(sub_63AA50); + Base_GetShutdown(OnStoveShutdown); this->m_initialized = true; return true; } @@ -592,7 +613,7 @@ void CStoveMgr::StartPurchase(const std::vector& items) { Stove::PCSDK::IAP::StovePCPaymentOption option; option.SetOperation(Stove::PCSDK::IAP::StovePCPaymentOperation::DEFAULT); param.SetPurchaseOption(option); - IAP_StartPurchase(¶m, sub_63A940); + IAP_StartPurchase(¶m, OnStovePurchaseStarted); g_stoveWaitingCallback = true; do { Base_RunCallback(); @@ -613,7 +634,7 @@ void CStoveMgr::StartPurchase(const std::vector& items) { const char* verb = DecryptName<0x9B17C9EFDBB39F2FULL>(verbSource); ShellExecuteA(nullptr, verb, url, url, nullptr, SW_SHOWNORMAL); if (g_windowMgr.Confirm(PurchaseCheckingMessage()().Text(), 2, true, false, 0, "Message", 250, 170, 0) == 187) { - IAP_ConfirmPurchase((static_cast(this->unknown_0014) << 32) | static_cast(this->unknown_0010), sub_63A9D0); + IAP_ConfirmPurchase((static_cast(this->unknown_0014) << 32) | static_cast(this->unknown_0010), OnStovePurchaseConfirmed); g_stoveWaitingCallback = true; do { Base_RunCallback(); @@ -635,7 +656,7 @@ void CStoveMgr::WaitForCallback() { // OFFSET: 0x0063CD20 // FUNCTION: fn_04785 -void CStoveMgr::OnOpenUrlCallback(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url) { +void TermsAgreementCallback::operator()(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url) const { g_stoveWaitingCallback = false; if (callbackResult.GetResult().IsSuccessful()) { g_modeMgr.GetGameMode()->SendMsg(323, 0, 0, 0, 0); diff --git a/Source/Client/Stove/StoveMgr.h b/Source/Client/Stove/StoveMgr.h index 84feeda0..cf8a0bcf 100644 --- a/Source/Client/Stove/StoveMgr.h +++ b/Source/Client/Stove/StoveMgr.h @@ -7,9 +7,6 @@ struct ITEM_INFO; -namespace Stove::PCSDK { - struct CallbackResult; -} // VTABLE: vt_00291 template class Singleton2 { @@ -40,8 +37,6 @@ public: __declspec(noinline) void WaitForCallback(); void FetchCategoryProducts(); void FetchAllProducts(); - void OnInitializeCallback(Stove::PCSDK::CallbackResult callbackResult); - void OnOpenUrlCallback(Stove::PCSDK::CallbackResult callbackResult, int unused, const wchar_t* url); bool Initialize(); void StartPurchase(const std::vector& items); }; diff --git a/Source/Client/Stove/StovePCSDK.h b/Source/Client/Stove/StovePCSDK.h index 451465e8..77dfa83c 100644 --- a/Source/Client/Stove/StovePCSDK.h +++ b/Source/Client/Stove/StovePCSDK.h @@ -156,8 +156,10 @@ Stove::PCSDK::Result IAP_UnInitialize(); Stove::PCSDK::Result Base_UnInitialize(); void IAP_StartPurchase(const Stove::PCSDK::IAP::StovePCStartPurchaseParam* param, void (*callback)(Stove::PCSDK::CallbackResult, Stove::PCSDK::IAP::StovePCPurchaseResult)); -void IAP_FetchTermsAgreement(Stove::PCSDK::IAP::StovePCTermsOption* option, void (*callback)(Stove::PCSDK::CallbackResult)); -void IAP_FetchProducts(Stove::PCSDK::IAP::StovePCFetchProductParam* param, void (*callback)(Stove::PCSDK::CallbackResult)); +void IAP_FetchTermsAgreement(Stove::PCSDK::IAP::StovePCTermsOption* option, + void (*callback)(Stove::PCSDK::CallbackResult, int, const wchar_t*)); +void IAP_FetchProducts(Stove::PCSDK::IAP::StovePCFetchProductParam* param, + void (*callback)(Stove::PCSDK::CallbackResult, const Stove::PCSDK::IAP::StovePCProduct*, unsigned int)); void IAP_ConfirmPurchase(std::int64_t transactionNumber, void (*callback)(Stove::PCSDK::CallbackResult, bool, int, unsigned int, int, int)); } diff --git a/Source/Client/Timer.cpp b/Source/Client/Timer.cpp index a4ebbe15..af19418a 100644 --- a/Source/Client/Timer.cpp +++ b/Source/Client/Timer.cpp @@ -37,3 +37,9 @@ void InitTimer(unsigned long freq) { void ResetTimer() { frameTime = timeGetTime(); } + +// OFFSET: 0x00C7F5A0 +// FUNCTION: fn_20434 +int ShouldRenderFrame() { + return 1; +} diff --git a/Source/Client/Timer.h b/Source/Client/Timer.h index ba70fe19..166ca823 100644 --- a/Source/Client/Timer.h +++ b/Source/Client/Timer.h @@ -6,5 +6,6 @@ extern int g_frameskip; void ResetTimer(); void InitTimer(unsigned long freq); int GetSkipFrameCount(); +int ShouldRenderFrame(); #endif diff --git a/Source/Contents/Actors/GameActor.h b/Source/Contents/Actors/GameActor.h index 0278530d..398624bd 100644 --- a/Source/Contents/Actors/GameActor.h +++ b/Source/Contents/Actors/GameActor.h @@ -264,7 +264,6 @@ public: __declspec(noinline) int WeaponActionBase(int weaponType); int GetUnknown0404(); int MountHeightOffset(); - float sub_CAD4B0(); void ResetState(); void UpdateGaugePositions(); void UpdateHpGauge(); diff --git a/Source/Contents/Actors/MercenaryAI.cpp b/Source/Contents/Actors/MercenaryAI.cpp index f4bb24d2..865944f6 100644 --- a/Source/Contents/Actors/MercenaryAI.cpp +++ b/Source/Contents/Actors/MercenaryAI.cpp @@ -408,7 +408,7 @@ int AiHomunGetV(lua_State* state) { } std::uint32_t homunAid = *reinterpret_cast(&g_session.unknown_5570[8]); - if (actor->render.accountId != g_session.m_aid && !g_session.sub_E1DE30(actor->render.accountId)) { + if (actor->render.accountId != g_session.m_aid && !g_session.IsCompanionAid(actor->render.accountId)) { CGameActor* targetActor = static_cast(static_cast(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(homunAid)); if (targetActor) { int targetX, targetY; @@ -592,7 +592,7 @@ int AiMercenaryGetV(lua_State* state) { } std::uint32_t mercAid = *reinterpret_cast(&g_session.unknown_5620[8]); - if (actor->render.accountId != g_session.m_aid && !g_session.sub_E1DE30(actor->render.accountId)) { + if (actor->render.accountId != g_session.m_aid && !g_session.IsCompanionAid(actor->render.accountId)) { CGameActor* targetActor = static_cast(static_cast(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(mercAid)); if (targetActor) { int targetX, targetY; diff --git a/Source/Contents/Actors/Player.cpp b/Source/Contents/Actors/Player.cpp index 1ea74520..aa045079 100644 --- a/Source/Contents/Actors/Player.cpp +++ b/Source/Contents/Actors/Player.cpp @@ -553,7 +553,7 @@ void CPc::Slot39(int value) { // OFFSET: 0x00DDD190 // FUNCTION: fn_23381 -static __declspec(noinline) std::string GetBodyImfName(int job, int sex, int head, int costumeJob) { +__declspec(noinline) std::string GetBodyImfName(int job, int sex, int head, int costumeJob) { return g_equipmentResourceMgr->GetBodyImfName(job, sex, head, costumeJob); } diff --git a/Source/Contents/Actors/RenderObject.cpp b/Source/Contents/Actors/RenderObject.cpp index 32901314..1bc72cd2 100644 --- a/Source/Contents/Actors/RenderObject.cpp +++ b/Source/Contents/Actors/RenderObject.cpp @@ -86,7 +86,6 @@ struct CharacterRenderDrawItem { RenderCommand* command; }; -std::list sub_8105A0(unsigned char kind, char* useBounds); // GLOBAL: gl_24798 int g_multiHitInterval = 200; @@ -2640,7 +2639,7 @@ void CCharacterNpc::Render(int) { characterRender->unknown_0044 = this->render.curMotion; char useBounds = 0; - std::list drawList = sub_8105A0(this->render.unknown_00A4Bytes[1], &useBounds); + std::list drawList = characterRender->BuildDrawList(this->render.unknown_00A4Bytes[1], &useBounds); float bounds[5]; std::memcpy(bounds, characterRender->unknown_0094, sizeof(bounds)); @@ -4536,75 +4535,6 @@ void CGameActor::SetActorJob(int job) { this->sub_CAA4D0(); } -__declspec(noinline) void CWorld::PlayerMove(const float& x, const float& z) { - const float position[2] = { x, z }; - UpdateWorldProximityNotification( - reinterpret_cast(this->unknown_00F4), - [this, position]() { - return this->FindActorInCell(position, [](std::uint32_t id) { - return id == g_guildInfo.unknown_00D0; - }); - }, - GetRagConnection(), - g_packetLengths, - g_guildInfo.unknown_00D0 - ); -} - -__declspec(noinline) void CWorld::PcApproachToPlayer(std::uint32_t accountId, const CellFloatPos& pos) { - if (this->player == nullptr) { - return; - } - - if (this->player->Slot50() < 1) { - return; - } - - bool found = false; - for (std::list::iterator it = this->actors.begin(); it != this->actors.end(); ++it) { - CGameActor* actor = static_cast(*it); - if (actor == nullptr) { - continue; - } - if (actor->render.accountId != accountId) { - continue; - } - if (actor->Slot42() == static_cast(g_guildInfo.unknown_00D0)) { - found = true; - break; - } - } - if (!found) { - return; - } - - const float playerX = this->player->render.position.x; - const float playerZ = this->player->render.position.z; - const float cellX = pos.x; - const float cellZ = pos.z; - const int range = this->nearbyRange; - UpdateWorldProximityNotification( - reinterpret_cast(this->unknown_00F4), - [playerX, playerZ, cellX, cellZ, range]() { - const float dx = playerX - cellX; - const float dz = playerZ - cellZ; - return dx * dx + dz * dz <= static_cast(range) * static_cast(range); - }, - GetRagConnection(), - g_packetLengths, - g_guildInfo.unknown_00D0 - ); -} - -__declspec(noinline) void CGameMode::RemoveUnknown0604(int window) { - for (std::list::iterator it = this->unknown_0604.begin(); it != this->unknown_0604.end(); ++it) { - if (*it == reinterpret_cast(window)) { - this->unknown_0604.erase(it); - return; - } - } -} - // OFFSET: 0x00CAAFD0 // FUNCTION: fn_21023 void CGameActor::ClearUnknown0188() { @@ -4859,6 +4789,15 @@ CCharacterNpc::CCharacterNpc() : CNpc() { this->unknown_0440 = 0; } +// INLINED +CCharacterNpc::~CCharacterNpc() { + if (this->unknown_0440) { + delete this->unknown_0440; + this->unknown_0440 = nullptr; + } +} + + // OFFSET: 0x00CBFC40 // FUNCTION: fn_21120 void CGameActor::SetStatusStates(int bodyState, std::uint32_t stateFlags, int effectState, bool notify) { diff --git a/Source/Contents/Actors/RenderObject.h b/Source/Contents/Actors/RenderObject.h index 1a965bcc..76e3c34f 100644 --- a/Source/Contents/Actors/RenderObject.h +++ b/Source/Contents/Actors/RenderObject.h @@ -98,7 +98,6 @@ public: unsigned char animation, unsigned char firstFrame, unsigned char lastFrame, unsigned char finishAnimation, unsigned char finishFrame, int timed, std::uint32_t duration, int loop ); - void ClearLevelEffects(); void PlayFrameSounds(); /* 0010 */ RenderObjectState render; diff --git a/Source/Contents/BodyResources.cpp b/Source/Contents/BodyResources.cpp index 90c99fb7..59af0a2d 100644 --- a/Source/Contents/BodyResources.cpp +++ b/Source/Contents/BodyResources.cpp @@ -1,4 +1,5 @@ #include "Client/Session.h" +#include "Utility/EncryptedName.h" #include "Contents/EquipmentResourceMgr.h" #include "Contents/Jobs/JobId.h" #include "Utility/Cipher/XorBytes.h" @@ -8,35 +9,6 @@ #include #include -template -class EncryptedName { -public: - // INLINED - explicit EncryptedName(const char (&source)[Length]) : m_encrypted(true) { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = source[index]; - } - } - - ~EncryptedName() { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = 0; - } - } - - const char* Text() { - if (this->m_encrypted) { - utility::XorBytes(this->m_text, Length, Key); - this->m_encrypted = false; - } - - return reinterpret_cast(this->m_text); - } - -private: - /* 0000 */ std::uint8_t m_text[Length]; - bool m_encrypted; -}; // OFFSET: 0x00DC7440 // FUNCTION: fn_22794 diff --git a/Source/Contents/CashEmotionMgr.cpp b/Source/Contents/CashEmotionMgr.cpp index e5252caf..2501602d 100644 --- a/Source/Contents/CashEmotionMgr.cpp +++ b/Source/Contents/CashEmotionMgr.cpp @@ -318,8 +318,7 @@ public: void Paint() override; int SendMsg(UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4) override; - unsigned int Select(int actionId); - void Select(CashEmotionCommand* command); + __declspec(noinline) void Select(CashEmotionCommand* command); void Previous(); void Refresh(int first); void Next(); @@ -640,14 +639,14 @@ void CCashEmotionMgr::RefreshCommands() { // OFFSET: 0x00599730 // FUNCTION: fn_02942 -int CCashEmotionMgr::ProcessChatCommand(const char* command) { +void CCashEmotionMgr::ProcessChatCommand(const char* command) { if (!ChatWindow() || !ChatWindow()->m_suggestions) { - return 0; + return; } if (!command || std::strlen(command) < 1 || command[0] != '/') { ChatWindow()->ShowSuggestions(0); - return 0; + return; } const char* key = command + 1; @@ -661,10 +660,9 @@ int CCashEmotionMgr::ProcessChatCommand(const char* command) { if (actionId != 0) { ChatWindow()->ShowSuggestions(1); auto* miniWnd = reinterpret_cast(ChatWindow()->m_suggestions); - return static_cast(miniWnd->Select(actionId)); + miniWnd->Select(reinterpret_cast(actionId)); } else { this->HideSuggestions(); - return 0; } } diff --git a/Source/Contents/CashEmotionMgr.h b/Source/Contents/CashEmotionMgr.h index 9c6c2aad..befdb57c 100644 --- a/Source/Contents/CashEmotionMgr.h +++ b/Source/Contents/CashEmotionMgr.h @@ -130,7 +130,7 @@ public: void ClearCommands(); __declspec(noinline) void HideSuggestions(); __declspec(noinline) int FindEmotionId(const char* name); - int ProcessChatCommand(const char* command); + void ProcessChatCommand(const char* command); __declspec(noinline) const char* GetPackName(int packId); std::vector FindBaseEmotions(const char* filter); __declspec(noinline) CashEmotionTable* GetBasePackEmotions(); diff --git a/Source/Contents/ClientItemLists.cpp b/Source/Contents/ClientItemLists.cpp index 4bdfa4c8..aa2648fe 100644 --- a/Source/Contents/ClientItemLists.cpp +++ b/Source/Contents/ClientItemLists.cpp @@ -1117,25 +1117,6 @@ bool CSession::OnItemEquipped(ITEM_INFO& item) { return true; } -void EquipmentProperties::CEquipmentPropertiesMgr::UnequipWearable(const int& location) { - this->m_dirty = true; - auto found = this->properties1.find(GetEquipLocationIndex(location)); - if (found != this->properties1.end()) { - CEquipmentWearable*& wearable = found->second; - for (CEquipmentAttachable& attachable : wearable->GetAttachables()) { - this->UnequipItem(attachable.GetId(), true); - } - this->UnequipItem(wearable->GetId(), true); - wearable->Clear(); - delete wearable; - this->properties1.erase(found); - } - - if (this->unknown_0020 != nullptr) { - this->unknown_0020->SendMsg(nullptr, 0x3C, 0, 0, 0, 0); - } -} - // OFFSET: 0x00DFC620 // FUNCTION: fn_23598 bool CSession::UnequipItem(int location, std::uint32_t identity) { diff --git a/Source/Contents/ClientState.cpp b/Source/Contents/ClientState.cpp index 99d7ea6e..9a9b0dee 100644 --- a/Source/Contents/ClientState.cpp +++ b/Source/Contents/ClientState.cpp @@ -1,6 +1,7 @@ #include "Contents/ClientState.h" #include "Client/Mode/CGameMode.h" +#include "Contents/Configuration/ServiceOptions.h" #include "Client/Mode/ModeMgr.h" #include "Client/Session.h" #include "Contents/Actors/Pc.h" @@ -981,14 +982,12 @@ void CSession::SetPetAutoFeed(bool enabled) { g_windowMgr.SendNotice(1, reinterpret_cast(text), 0x64FFFF, 0, 0, 0); } -extern "C" void __cdecl sub_6C2A80(int id, bool value); - // OFFSET: 0x00E489C0 // FUNCTION: fn_24224 void __stdcall sub_E489C0(bool enabled) { std::string notice = LookupMessage(enabled ? 4357 : 4379); g_windowMgr.SendNotice(1, reinterpret_cast(notice.c_str()), 0x64FFFF, 0, 0, 0); - sub_6C2A80(0x128, enabled); + g_serviceOptions.Set(0x128, enabled); g_windowMgr.sub_AAB070(0x128); } diff --git a/Source/Contents/Configuration/ServiceOptions.cpp b/Source/Contents/Configuration/ServiceOptions.cpp index 0ac336b0..e6d92179 100644 --- a/Source/Contents/Configuration/ServiceOptions.cpp +++ b/Source/Contents/Configuration/ServiceOptions.cpp @@ -1,4 +1,5 @@ #include "Contents/Configuration/ServiceOptions.h" +#include "Utility/EncryptedName.h" #include "Contents/Actors/Pc.h" #include "Contents/Camera/Camera.h" #include "Contents/Configuration/ServiceConfiguration.h" @@ -410,35 +411,6 @@ const char* const g_serviceOptionNames[300] = { "TT_3D_SOUND_ON_OFF" }; -template -class EncryptedName { -public: - explicit EncryptedName(const std::uint8_t (&source)[Length]) : m_encrypted(true) { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = source[index]; - } - } - - ~EncryptedName() { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = 0; - } - } - - const char* Text() { - if (this->m_encrypted) { - utility::XorBytes(this->m_text, Length, Key); - this->m_encrypted = false; - } - - return reinterpret_cast(this->m_text); - } - -private: - std::uint8_t m_text[Length]; - bool m_encrypted; -}; - __declspec(noinline) void NotifyServiceOption(unsigned char enabled, int enabledMessage, int disabledMessage, int color); __declspec(noinline) void ApplyServiceOption(int id, unsigned char value, bool notify, int enabledMessage, int disabledMessage); @@ -706,8 +678,6 @@ bool GameSettings::ReadOptionTable() { return lua_gettop(state) == 0; } -void sub_AAB070(int id); - // OFFSET: 0x006C2610 // FUNCTION: fn_06322 void GameSettings::ResetToDefaults() { @@ -729,7 +699,7 @@ void GameSettings::ToggleOption(int id) { if (option.type == 0) { const unsigned char current = g_serviceOptions.Get(id); this->sub_6C0C40(id, current == 0, true); - sub_AAB070(id); + g_windowMgr.sub_AAB070(id); } else if (option.type == 1) { const auto entry = this->functions.find(id); if (entry != this->functions.end() && entry->second) { @@ -1112,7 +1082,7 @@ void ApplyServiceOptionAskOnDisable(int id, unsigned char value, bool notify, in if (!value && g_windowMgr.Confirm(LookupMessage(0x1104), 2, true, false, 0, "Message", 0x118, 0x78, 0) == 0xBC) { g_serviceOptions.Set(0x128, 1); - sub_AAB070(0x128); + g_windowMgr.sub_AAB070(0x128); return; } diff --git a/Source/Contents/Configuration/ServiceOptions.h b/Source/Contents/Configuration/ServiceOptions.h index f7740231..882b987f 100644 --- a/Source/Contents/Configuration/ServiceOptions.h +++ b/Source/Contents/Configuration/ServiceOptions.h @@ -19,7 +19,7 @@ struct ServiceOptions { /* 0000 */ std::unordered_map values; unsigned char Get(int id) const; - bool Set(int id, unsigned char value); + static bool Set(int id, unsigned char value); }; extern ServiceOptions g_serviceOptions; diff --git a/Source/Contents/Effects/EffectPrimitiveRendering.cpp b/Source/Contents/Effects/EffectPrimitiveRendering.cpp index a9e0523a..db2e03be 100644 --- a/Source/Contents/Effects/EffectPrimitiveRendering.cpp +++ b/Source/Contents/Effects/EffectPrimitiveRendering.cpp @@ -6640,7 +6640,7 @@ void CEffectPrim::Render2DPrimitive() { if (cdState) { cdState->x = static_cast(this->render.position.x); cdState->y = static_cast(this->render.position.y); - g_cooldownOwner->Draw(0, 0, 16, 16, *cdState, 0, 0, 0); + g_cooldownOwner->Drawing().Draw(0, 0, 16, 16, *cdState, 0, 0, 0); } } } @@ -6648,7 +6648,7 @@ void CEffectPrim::Render2DPrimitive() { if (g_overrideColor == 1) { g_cooldownOwner->ClearReverseCommands(); } else { - g_cooldownOwner->SubmitReverse(); + g_cooldownOwner->Drawing().SubmitReverse(g_renderer->queues, g_renderer->fog.supported != 0, g_depthStart, g_depthEnd); } } } diff --git a/Source/Contents/Effects/Particle.cpp b/Source/Contents/Effects/Particle.cpp index 9fa333a2..4cd6af37 100644 --- a/Source/Contents/Effects/Particle.cpp +++ b/Source/Contents/Effects/Particle.cpp @@ -132,6 +132,11 @@ CEZ2STRParticle::CEZ2STRParticle(vector3d position, int flags) : CParticle(posit this->Clear(); } +// INLINED +CEZ2STRParticle::~CEZ2STRParticle() { +} + + // OFFSET: 0x00B3CFC0 // FUNCTION: fn_18815 void CEZ2STRParticle::Slot01() { diff --git a/Source/Contents/Effects/SpriteEffect.cpp b/Source/Contents/Effects/SpriteEffect.cpp index 67e75c1a..1c75557e 100644 --- a/Source/Contents/Effects/SpriteEffect.cpp +++ b/Source/Contents/Effects/SpriteEffect.cpp @@ -470,7 +470,7 @@ void CSpriteEffect::Slot03() { case 0x46A: { int height = 8; if (CGameActor* actor = static_cast(FindRenderObject(this->actor))) { - height = static_cast(actor->sub_CAD4B0() + 8.0f); + height = static_cast(actor->GetNameOffset() + 8.0f); } particle->position.x = this->position[0]; @@ -496,7 +496,7 @@ void CSpriteEffect::Slot03() { case 0x488: { int height = 25; if (CGameActor* actor = static_cast(FindRenderObject(this->actor))) { - height = static_cast(actor->sub_CAD4B0() + 25.0f); + height = static_cast(actor->GetNameOffset() + 25.0f); } particle->position.x = this->position[0]; @@ -512,7 +512,7 @@ void CSpriteEffect::Slot03() { break; } - const int height = static_cast(actor->sub_CAD4B0() + 8.0f); + const int height = static_cast(actor->GetNameOffset() + 8.0f); particle->position.x = this->position[0]; particle->position.y = this->position[1] - static_cast(height); particle->position.z = this->position[2]; @@ -524,7 +524,7 @@ void CSpriteEffect::Slot03() { break; } - const int height = static_cast(actor->sub_CAD4B0() + 3.0f); + const int height = static_cast(actor->GetNameOffset() + 3.0f); particle->position.x = this->position[0]; particle->position.y = this->position[1] - static_cast(height); particle->position.z = this->position[2]; @@ -537,7 +537,7 @@ void CSpriteEffect::Slot03() { break; } - const int height = static_cast(actor->sub_CAD4B0()); + const int height = static_cast(actor->GetNameOffset()); particle->position.x = this->position[0]; particle->position.y = this->position[1] - static_cast(height); particle->position.z = this->position[2]; @@ -549,7 +549,7 @@ void CSpriteEffect::Slot03() { break; } - const float height = actor->sub_CAD4B0(); + const float height = actor->GetNameOffset(); const float offset = g_session.IsDoramJob(actor->GetEffectiveJob(-1)) ? height + 13.7f : height + 17.0f; particle->position.x = this->position[0]; particle->position.y = this->position[1] - offset; @@ -575,7 +575,7 @@ void CSpriteEffect::Slot03() { break; } - const float height = actor->sub_CAD4B0(); + const float height = actor->GetNameOffset(); particle->position.x = this->position[0]; particle->position.y = this->position[1] - height; particle->position.z = this->position[2]; diff --git a/Source/Contents/Effects/TalismanMarkEffect.cpp b/Source/Contents/Effects/TalismanMarkEffect.cpp index 89e5c646..49350251 100644 --- a/Source/Contents/Effects/TalismanMarkEffect.cpp +++ b/Source/Contents/Effects/TalismanMarkEffect.cpp @@ -11,8 +11,8 @@ #include #include -CParticle* sub_B82ED0(const vector3d* position, int flags); -void sub_B82FD0(CParticle* particle); +CParticle* CreateEZ2STRParticle(const vector3d* position, int flags); +void FreeParticle(CParticle* particle); // GLOBAL: gl_24871 static const std::array s_talismanStartEffects = { @@ -48,7 +48,7 @@ CTalismanMarkEffect::CTalismanMarkEffect() : CEffect(-1) { void CTalismanMarkEffect::Close() { for (auto it = this->particles.begin(); it != this->particles.end(); ++it) { if (*it) { - sub_B82FD0(*it); + FreeParticle(*it); } } this->particles.clear(); @@ -65,9 +65,9 @@ void CTalismanMarkEffect::PlayEnd() { const int index = particle->unknown_000C; const int angle = particle->unknown_004C; - sub_B82FD0(particle); + FreeParticle(particle); - particle = static_cast(sub_B82ED0(reinterpret_cast(this->position), 13)); + particle = static_cast(CreateEZ2STRParticle(reinterpret_cast(this->position), 13)); if (!particle) { *it = nullptr; continue; @@ -92,7 +92,7 @@ void CTalismanMarkEffect::Slot01() { this->retained = 1; for (int i = 0; i < std::min(this->unknown_00B0, 4); ++i) { - CEZ2STRParticle* particle = static_cast(sub_B82ED0(reinterpret_cast(this->position), 13)); + CEZ2STRParticle* particle = static_cast(CreateEZ2STRParticle(reinterpret_cast(this->position), 13)); if (!particle) { continue; } @@ -128,9 +128,9 @@ void CTalismanMarkEffect::Slot03() { { const int index = particle->unknown_000C; const int angle = particle->unknown_004C; - sub_B82FD0(particle); + FreeParticle(particle); - particle = static_cast(sub_B82ED0(reinterpret_cast(this->position), 13)); + particle = static_cast(CreateEZ2STRParticle(reinterpret_cast(this->position), 13)); if (!particle) { *it = nullptr; continue; @@ -156,7 +156,7 @@ void CTalismanMarkEffect::Slot03() { break; } - sub_B82FD0(particle); + FreeParticle(particle); it = this->particles.erase(it); continue; default: diff --git a/Source/Contents/Effects/TriangleShotArrow.cpp b/Source/Contents/Effects/TriangleShotArrow.cpp index ba1ec112..b84e7c80 100644 --- a/Source/Contents/Effects/TriangleShotArrow.cpp +++ b/Source/Contents/Effects/TriangleShotArrow.cpp @@ -9,8 +9,8 @@ #include -CParticle* sub_B82ED0(const vector3d* position, int flags); -void sub_B82FD0(CParticle* particle); +CParticle* CreateEZ2STRParticle(const vector3d* position, int flags); +void FreeParticle(CParticle* particle); // OFFSET: 0x0072ED00 // FUNCTION: fn_07521 @@ -21,7 +21,7 @@ CTriangleShotArrow::CTriangleShotArrow() : CEffect(-1), current{}, direction{}, // OFFSET: 0x0072EE80 // FUNCTION: fn_07523 void CTriangleShotArrow::Close() { - sub_B82FD0(this->arrow); + FreeParticle(this->arrow); } // OFFSET: 0x0072EE90 @@ -31,7 +31,7 @@ void CTriangleShotArrow::Slot01() { this->current.y = this->position[1]; this->current.z = this->position[2]; - CEZ2STRParticle* arrow = static_cast(sub_B82ED0(&this->current, 5)); + CEZ2STRParticle* arrow = static_cast(CreateEZ2STRParticle(&this->current, 5)); if (g_serviceOptions.Get(229)) { arrow->Open("mineffect\\new_triangleshot\\new_triangleshot_arrow\\new_triangleshot_arrow.str"); } else { diff --git a/Source/Contents/EnchantMgr.cpp b/Source/Contents/EnchantMgr.cpp index e11354a3..225bb56c 100644 --- a/Source/Contents/EnchantMgr.cpp +++ b/Source/Contents/EnchantMgr.cpp @@ -58,6 +58,11 @@ CEnchantMgr::CEnchantMgr() { m_unknown_0030 = true; } +// INLINED +CEnchantMgr::~CEnchantMgr() { +} + + // OFFSET: 0x00682960 // FUNCTION: fn_05540 void CEnchantMgr::SendCloseEnchant() { diff --git a/Source/Contents/Items/ItemNaming.cpp b/Source/Contents/Items/ItemNaming.cpp index b14e6d0b..77ca754e 100644 --- a/Source/Contents/Items/ItemNaming.cpp +++ b/Source/Contents/Items/ItemNaming.cpp @@ -420,18 +420,11 @@ std::string ITEM_INFO::DisplayName(unsigned char detailed) const { #include "File/File.h" #include "File/ResourcePath.h" #include "Resource/Bitmap/BitmapResource.h" - -class CItemInfoMgr { -public: - void Apply(std::map& values); -}; +#include "Contents/Items/ItemInfoMgr.h" // GLOBAL: gl_24730 CCommonObject g_tableStorage; -// GLOBAL: gl_24729 -CItemInfoMgr* g_itemInfoMgr; - // OFFSET: 0x005E11E0 // FUNCTION: fn_03873 std::string ItemDisplayName(int id) { @@ -751,7 +744,7 @@ __declspec(noinline) void LoadItemNameTables() { } } - g_itemInfoMgr->Apply(g_itemDescriptions); + g_itemInfoMgr->SetItemInfo(g_itemDescriptions); } if (ResourceExists("EventNum2ItemResNameTable.txt", 0)) { diff --git a/Source/Contents/Messenger/ClientMessenger.cpp b/Source/Contents/Messenger/ClientMessenger.cpp index 2839f7e5..7ab1c059 100644 --- a/Source/Contents/Messenger/ClientMessenger.cpp +++ b/Source/Contents/Messenger/ClientMessenger.cpp @@ -1,4 +1,5 @@ #include "Contents/Messenger/ClientMessenger.h" +#include "Utility/EncryptedName.h" #include "Contents/Effects/PartyMemberEffects.h" #include "Client/Mode/ModeMgr.h" #include "Client/Mode/CGameMode.h" @@ -6243,35 +6244,6 @@ void CGameMode::Zc_Mer_Par_Change(const unsigned char* data) { g_session.RefreshMercenaryInfo(); } -template -class EncryptedName { -public: - explicit EncryptedName(const std::uint8_t (&source)[Length]) : m_encrypted(true) { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = source[index]; - } - } - - ~EncryptedName() { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = 0; - } - } - - const char* Text() { - if (this->m_encrypted) { - utility::XorBytes(this->m_text, Length, Key); - this->m_encrypted = false; - } - - return reinterpret_cast(this->m_text); - } - -private: - /* 0000 */ std::uint8_t m_text[Length]; - bool m_encrypted; -}; - template void ShowEncryptedFailure(const std::uint8_t (&captionBytes)[CaptionLength], const std::uint8_t (&messageBytes)[MessageLength]) { thread_local EncryptedName caption(captionBytes); diff --git a/Source/Contents/Messenger/MessengerMember.cpp b/Source/Contents/Messenger/MessengerMember.cpp index 04edeff9..7bcf4687 100644 --- a/Source/Contents/Messenger/MessengerMember.cpp +++ b/Source/Contents/Messenger/MessengerMember.cpp @@ -87,8 +87,6 @@ public: void RemoveGauge(); void SetUnknown010C(int first, int second); void SetGaugeValues(int current, int maximum); - std::string sub_A80880(int width, const char* text, int font, int height, int bold); - void sub_A84360(int x, int y, const char* text, int length, int font, int height, unsigned int color, int bold, int shadow); /* 00B4 */ MessengerMember member; /* 0104 */ UIPcGage* gauge; @@ -396,8 +394,8 @@ void UIDragMiniPartyWnd::Paint() { const char* mapName = g_session.GetMapDisplayName(this->member.map.c_str()); char text[256]; sprintf(text, "%d %s(%s)", this->member.level, this->member.name.c_str(), mapName); - std::string clipped = this->sub_A80880(this->geometry.width - 0x43, text, 0, 12, 1); - this->sub_A84360( + std::string clipped = this->FitDisplayText(this->geometry.width - 0x43, text, 0, 12, 1); + this->DrawTextAt( this->iconPositions[this->iconIndex].x + 0x1C, this->iconPositions[this->iconIndex].y + 3, clipped.c_str(), @@ -413,7 +411,7 @@ void UIDragMiniPartyWnd::Paint() { char hpText[128]; sprintf(hpText, "%d/%d", this->gauge->current, this->gauge->maximum); int len = static_cast(strlen(hpText)); - this->sub_A84360( + this->DrawTextAt( this->gauge->geometry.x + 0x42, this->gauge->geometry.y - 4, hpText, diff --git a/Source/Contents/RenewQuestMgr.cpp b/Source/Contents/RenewQuestMgr.cpp index c0453db9..072b992f 100644 --- a/Source/Contents/RenewQuestMgr.cpp +++ b/Source/Contents/RenewQuestMgr.cpp @@ -632,8 +632,8 @@ int CRenewQuestMgr::L_AddQuestIconTooltip(lua_State* state) { // OFFSET: 0x0067B620 // FUNCTION: fn_05457 void CRenewQuestMgr::sub_67B620(unsigned int questId) { - if (auto* window = static_cast(g_windowMgr.EnsureWindow(0x2719))) { - window->sub_A56050(questId); + if (auto* window = static_cast(g_windowMgr.EnsureWindow(0x2719))) { + window->SetQuest(questId); } } diff --git a/Source/Contents/ReputeMgr.cpp b/Source/Contents/ReputeMgr.cpp index 76de8d68..7bec8d36 100644 --- a/Source/Contents/ReputeMgr.cpp +++ b/Source/Contents/ReputeMgr.cpp @@ -1,13 +1,177 @@ #include "Contents/ReputeMgr.h" +#include "Client/Application/ErrorDialog.h" +#include "Render/DeviceContext/DCSurface.h" #include "Contents/MessageTable.h" +#include "File/File.h" #include "Network/TextEncoding.h" #include "UI/Window/UIWindow.h" #include "UI/Window/UIWindowMgr.h" +#include "Utility/JsonCppLoader.h" #include +#include #include -int sub_AD6360(const char* text, unsigned int type); +// OFFSET: 0x0050AE30 +// FUNCTION: fn_00894 +bool JsonCppLoader::sub_50AE30(std::map* out) { + if (!this->loaded) { + this->Fail("초기화가 되어야 합니다."); + return false; + } + + JsonValue groups; + this->GetValue(groups, "ReputeGroup", this->document, JsonValue::OBJECT_VALUE); + if (groups.IsNull()) { + this->Fail("키에 해당하는 데이터가 없습니다. (key : %s)", "ReputeGroup"); + return false; + } + + const JsonObject& members = groups.GetObject(); + for (JsonObject::const_iterator member = members.begin(); member != members.end(); ++member) { + JsonValue idValue; + JsonValue nameValue; + JsonValue listValue; + this->GetValue(idValue, "ID", member->second, JsonValue::STRING_VALUE); + if (idValue.IsNull()) { + this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", "ID"); + } + this->GetValue(nameValue, "Name", member->second, JsonValue::STRING_VALUE); + if (nameValue.IsNull()) { + this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", "Name"); + } + this->GetValue(listValue, "ReputeList", member->second, JsonValue::ARRAY_VALUE); + if (listValue.IsNull()) { + this->Fail("key 에 해당하는 데이터를 찾지 못했습니다. (keyName : %s)", "ReputeList"); + } + + ReputeGroupRecord record; + if (!idValue.IsNull()) { + record.id = idValue.AsString(); + } + if (!nameValue.IsNull()) { + record.name = nameValue.AsString(); + } + if (!listValue.IsNull()) { + const JsonArray& ids = listValue.GetArray(); + for (JsonArray::const_iterator id = ids.begin(); id != ids.end(); ++id) { + if (id->GetType() != JsonValue::INT64_VALUE) { + this->Fail("잘못된 데이터가 입력되었습니다. intValue 가 입력되어야 합니다. (keyName : %s)", "ReputeList"); + break; + } + record.reputes.push_back(id->AsInt()); + } + } + + if (!out->insert(std::make_pair(std::stoi(member->first), record)).second) { + this->Fail("중복키가 입력되었습니다. (name : %s)", member->first.c_str()); + return false; + } + } + + return this->succeeded; +} + +// OFFSET: 0x0050B830 +// FUNCTION: fn_00895 +bool JsonCppLoader::sub_50B830(std::map* out) { + if (!this->loaded) { + this->Fail("초기화가 되어야 합니다."); + return false; + } + + const JsonValue* infos = nullptr; + if (const JsonObject* root = this->document.ObjectRange()) { + for (const JsonMember& entry : *root) { + if (entry.first == "reputeInfo") { + infos = &entry.second; + break; + } + } + } + + if (infos == nullptr) { + this->Fail("키에 해당하는 데이터가 없습니다. (key : %s)", "reputeInfo"); + return false; + } + + const JsonObject* members = infos->ObjectRange(); + const JsonObject none; + for (const JsonMember& member : members ? *members : none) { + const std::string name = member.first; + const JsonValue node = member.second; + ReputeInfoRecord record; + this->GetStringValue(node, "Name", &record.name); + this->GetIntValue(node, "MaxPoint_Positive", &record.maxPointPositive); + this->GetIntValue(node, "MaxPoint_Negative", &record.maxPointNegative); + this->GetStringValue(node, "Invisible", &record.invisible); + + if (!out->insert(std::make_pair(std::stoi(name), record)).second) { + this->Fail("중복키가 입력되었습니다. (key : %s)", name.c_str()); + return false; + } + } + + return this->succeeded; +} + +// OFFSET: 0x0060DC70 +// FUNCTION: fn_04294 +bool CReputeMgr::sub_60DC70(std::map& groups) { + std::string path = "ContentData\\Repute\\ReputeGroupData.bson"; + CFile file; + if (!file.Open(path.c_str(), 0, true, false)) { + return false; + } + + const auto* data = static_cast(file.GetData()); + std::vector buffer(data, data + file.GetSize()); + + JsonCppLoader loader; + if (!loader.sub_4F3C70(buffer, true)) { + return false; + } + + std::map records; + if (!loader.sub_50AE30(&records)) { + return false; + } + + groups.clear(); + for (std::pair record : records) { + GroupInserter{this, &groups}(record); + } + return true; +} + +// OFFSET: 0x0060E090 +// FUNCTION: fn_04295 +bool CReputeMgr::sub_60E090(std::map& infos) { + std::string path = "ContentData\\Repute\\ReputeInfoData.bson"; + CFile file; + if (!file.Open(path.c_str(), 0, true, false)) { + return false; + } + + const auto* data = static_cast(file.GetData()); + std::vector buffer(data, data + file.GetSize()); + + JsonCppLoader loader; + if (!loader.sub_4F3C70(buffer, true)) { + return false; + } + + std::map records; + if (!loader.sub_50B830(&records)) { + return false; + } + + infos.clear(); + for (std::pair record : records) { + InfoInserter{this, &infos}(record); + } + return true; +} // OFFSET: 0x0060C5D0 // FUNCTION: fn_04283 @@ -76,7 +240,7 @@ bool CReputeMgr::sub_60DBF0() { return true; } - sub_AD6360("Failed : LoadReputeInfoData", 0); + ShowErrorDialog(GetRenderSystemHolder()->system, "Failed : LoadReputeInfoData", 0); return false; } diff --git a/Source/Contents/Skills/SkillActionDruid.cpp b/Source/Contents/Skills/SkillActionDruid.cpp index 22ccfe24..5a3e2571 100644 --- a/Source/Contents/Skills/SkillActionDruid.cpp +++ b/Source/Contents/Skills/SkillActionDruid.cpp @@ -68,6 +68,7 @@ public: class CSkillAction_DamageWereRaptorForm : public CSkillAction_AnimalForm, public CSkillAction_Direction { public: + void sub_5A4760(int sourceActor, CGameActor* target); void Slot16(int level, CGameActor* source, CGameActor* target) override; bool Slot17(CGameActor* actor) override; void Slot18(CGameActor* actor) override; @@ -189,7 +190,6 @@ public: int Slot02() override; void Slot11(int level, CGameActor* source, CGameActor* target) override; void Slot15(int level, CGameActor* source, CGameActor* target) override; - void sub_5A4760(int level, CGameActor* source); }; class CSkillAction_DR_FLICKING_TONADO : public CSkillAction_DamageWereRaptorForm { diff --git a/Source/Contents/Skills/SkillTreeScript.cpp b/Source/Contents/Skills/SkillTreeScript.cpp index 19842636..b1ddff91 100644 --- a/Source/Contents/Skills/SkillTreeScript.cpp +++ b/Source/Contents/Skills/SkillTreeScript.cpp @@ -11,52 +11,50 @@ extern "C" { CSkillInfo* FindGroupedSkill(CSession& session, std::uint32_t id); -namespace { - // OFFSET: 0x00AFEE00 - // FUNCTION: fn_18349 - int AddSkill(lua_State* state) { - CSkillInfo skill(0); - const double group = luaL_checknumber(state, 1); - const double id = luaL_checknumber(state, 2); - const char* name = luaL_checkstring(state, 3); - const int position = static_cast(luaL_checknumber(state, 4)); - const int value = static_cast(luaL_checknumber(state, 5)); - const double last = luaL_checknumber(state, 6); +// OFFSET: 0x00AFEE00 +// FUNCTION: fn_18349 +int AddSkill(lua_State* state) { + CSkillInfo skill(0); + const double group = luaL_checknumber(state, 1); + const double id = luaL_checknumber(state, 2); + const char* name = luaL_checkstring(state, 3); + const int position = static_cast(luaL_checknumber(state, 4)); + const int value = static_cast(luaL_checknumber(state, 5)); + const double last = luaL_checknumber(state, 6); - if (std::strcmp(name, "") != 0 && position != -1 && value != -1) { - skill.level = 0; - skill.unknown_0014 = 0; - skill.unknown_001C = 0; - skill.unknown_0018 = 0; - skill.available = 1; - skill.name = name; - skill.unknown_0024 = position; - skill.unknown_0028 = value; - skill.id = static_cast(static_cast(id)); - skill.unknown_0034 = 0; - skill.unknown_002C = static_cast(last); - g_session.m_skillBundle.AddGrouped(static_cast(group), skill); - } - - return 1; + if (std::strcmp(name, "") != 0 && position != -1 && value != -1) { + skill.level = 0; + skill.unknown_0014 = 0; + skill.unknown_001C = 0; + skill.unknown_0018 = 0; + skill.available = 1; + skill.name = name; + skill.unknown_0024 = position; + skill.unknown_0028 = value; + skill.id = static_cast(static_cast(id)); + skill.unknown_0034 = 0; + skill.unknown_002C = static_cast(last); + g_session.m_skillBundle.AddGrouped(static_cast(group), skill); } - // OFFSET: 0x00AFED50 - // FUNCTION: fn_18348 - int AddNeededSkill(lua_State* state) { - const int id = static_cast(luaL_checknumber(state, 1)); - const int needed = static_cast(luaL_checknumber(state, 2)); - const int level = static_cast(luaL_checknumber(state, 3)); + return 1; +} - if (id != -1 && needed != -1 && level != -1) { - CSkillInfo* skill = FindGroupedSkill(g_session, static_cast(id)); - if (skill && skill->available) { - skill->entries.push_back({static_cast(needed), static_cast(level)}); - } +// OFFSET: 0x00AFED50 +// FUNCTION: fn_18348 +int AddNeededSkill(lua_State* state) { + const int id = static_cast(luaL_checknumber(state, 1)); + const int needed = static_cast(luaL_checknumber(state, 2)); + const int level = static_cast(luaL_checknumber(state, 3)); + + if (id != -1 && needed != -1 && level != -1) { + CSkillInfo* skill = FindGroupedSkill(g_session, static_cast(id)); + if (skill && skill->available) { + skill->entries.push_back({static_cast(needed), static_cast(level)}); } - - return 1; } + + return 1; } // INLINED diff --git a/Source/Contents/Skills/SkillTreeScript.h b/Source/Contents/Skills/SkillTreeScript.h index 55a56a2c..d19ba72e 100644 --- a/Source/Contents/Skills/SkillTreeScript.h +++ b/Source/Contents/Skills/SkillTreeScript.h @@ -4,6 +4,8 @@ struct lua_State; class CPlayerSkillBundle; +int AddSkill(lua_State* state); +int AddNeededSkill(lua_State* state); void RegisterSkillTreeCallbacks(lua_State* state, CPlayerSkillBundle& bundle); #endif diff --git a/Source/Contents/SpecialPopupMgr.cpp b/Source/Contents/SpecialPopupMgr.cpp index 33d73a81..8b53056f 100644 --- a/Source/Contents/SpecialPopupMgr.cpp +++ b/Source/Contents/SpecialPopupMgr.cpp @@ -1,4 +1,5 @@ #include "Contents/SpecialPopupMgr.h" +#include "Script/LuaFileOperations.h" #include "Script/NLuaState.h" extern "C" { @@ -12,8 +13,6 @@ extern "C" { #include #include -bool sub_AF6580(lua_State* state, const std::string& path, bool flag); - // GLOBAL: gl_24839 CSpecialPopupMgr* g_specialPopupMgr = nullptr; @@ -72,7 +71,7 @@ bool CSpecialPopupMgr::Init() { lua_pushcclosure(luaState.GetState(), CSpecialPopupMgr::LuaAddDesc, 0); lua_setfield(luaState.GetState(), LUA_GLOBALSINDEX, "AddDesc"); - if (!sub_AF6580(luaState.GetState(), "System\\spopup.lub", false)) { + if (!LoadLuaResource(luaState.GetState(), "System\\spopup.lub", false)) { MessageBoxA(NULL, lua_tostring(luaState.GetState(), -1), "CSpecialPopupMgr LuaLoadFile X", 0); return false; } diff --git a/Source/Contents/SpriteRidingOffset.cpp b/Source/Contents/SpriteRidingOffset.cpp index 77f0469f..4c5e0574 100644 --- a/Source/Contents/SpriteRidingOffset.cpp +++ b/Source/Contents/SpriteRidingOffset.cpp @@ -6,7 +6,7 @@ // OFFSET: 0x00DDE340 // FUNCTION: fn_23394 -static std::string GetBodyActionResourceName(int job, int sex, int costumeJob, int costume) { +std::string GetBodyActionResourceName(int job, int sex, int costumeJob, int costume) { return g_equipmentResourceMgr->GetBodyResourceName(0, job, sex, costumeJob, costume); } diff --git a/Source/Network/Connection/Connection.cpp b/Source/Network/Connection/Connection.cpp index 0a61a268..afcebffa 100644 --- a/Source/Network/Connection/Connection.cpp +++ b/Source/Network/Connection/Connection.cpp @@ -30,6 +30,11 @@ CConnection::~CConnection() = default; CRagConnection::CRagConnection() : unknown_006C(0) { } +// INLINED +CRagConnection::~CRagConnection() { +} + + // OFFSET: 0x00C7C4D0 // FUNCTION: fn_20389 bool CConnection::Connect(const ConnectionEndpoint& endpoint) { diff --git a/Source/Render/DX9/D3DX9Runtime.h b/Source/Render/DX9/D3DX9Runtime.h index 2262eb39..47fa5382 100644 --- a/Source/Render/DX9/D3DX9Runtime.h +++ b/Source/Render/DX9/D3DX9Runtime.h @@ -3,6 +3,7 @@ #include +extern "C" { HRESULT WINAPI D3DXFilterTexture(IDirect3DBaseTexture9* texture, const PALETTEENTRY* palette, UINT level, DWORD filter); HRESULT WINAPI D3DXLoadSurfaceFromMemory( IDirect3DSurface9* destination, const PALETTEENTRY* destinationPalette, const RECT* destinationRect, const void* source, D3DFORMAT format, @@ -14,5 +15,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface( ); D3DMATRIX* WINAPI D3DXMatrixPerspectiveFovLH(D3DMATRIX* output, float fovy, float aspect, float nearPlane, float farPlane); HRESULT WINAPI D3DXSaveSurfaceToFileA(const char* filename, int format, IDirect3DSurface9* surface, const PALETTEENTRY* palette, const RECT* rectangle); +} #endif diff --git a/Source/Render/ScreenGeometry.cpp b/Source/Render/ScreenGeometry.cpp index e303c7d8..0b9851ef 100644 --- a/Source/Render/ScreenGeometry.cpp +++ b/Source/Render/ScreenGeometry.cpp @@ -79,32 +79,32 @@ void DrawScreenQuad( // OFFSET: 0x00915F60 // FUNCTION: fn_12581 -void DrawScreenQuad(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, CTexture* texture, std::uint32_t color) { +void DrawScreenQuad(ScreenPoint p0, ScreenPoint p1, ScreenPoint p2, ScreenPoint p3, CTexture* texture, std::uint32_t color) { RenderPrimitive* primitive = g_renderer->primitives.Acquire(); RenderVertex* vertices = primitive->vertices; - vertices[0].x = x0; - vertices[0].y = y0; + vertices[0].x = p0.x; + vertices[0].y = p0.y; vertices[0].z = 0.8f; vertices[0].rhw = 1.0f; vertices[0].diffuse = color; vertices[0].u = 0.0f; vertices[0].v = 0.0f; - vertices[1].x = x1; - vertices[1].y = y1; + vertices[1].x = p1.x; + vertices[1].y = p1.y; vertices[1].z = 0.8f; vertices[1].rhw = 1.0f; vertices[1].diffuse = color; vertices[1].u = 1.0f; vertices[1].v = 0.0f; - vertices[2].x = x2; - vertices[2].y = y2; + vertices[2].x = p2.x; + vertices[2].y = p2.y; vertices[2].z = 0.8f; vertices[2].rhw = 1.0f; vertices[2].diffuse = color; vertices[2].u = 0.0f; vertices[2].v = 1.0f; - vertices[3].x = x3; - vertices[3].y = y3; + vertices[3].x = p3.x; + vertices[3].y = p3.y; vertices[3].z = 0.8f; vertices[3].rhw = 1.0f; vertices[3].diffuse = color; diff --git a/Source/Resource/GifResource.cpp b/Source/Resource/GifResource.cpp index 09e03942..c6de23f4 100644 --- a/Source/Resource/GifResource.cpp +++ b/Source/Resource/GifResource.cpp @@ -1,6 +1,7 @@ #include "Resource/GifResource.h" #include "File/File.h" +#include "Resource/GifLzw.h" #include #include @@ -294,7 +295,7 @@ bool CGifRes::DecodeGif(const void* data, int bytes, bool iconOnly) { ++cursor; unsigned char* indices = new unsigned char[descriptor.width * descriptor.height]; - if (this->DecodeGifLzw(minimumCodeSize, compressed, compressedBytes, indices) > 0) { + if (DecodeGifLzw(minimumCodeSize, compressed, compressedBytes, indices) > 0) { const unsigned int pixelCount = screenHeight * screenWidth; std::uint32_t* pixels = new std::uint32_t[pixelCount]; diff --git a/Source/Resource/GifResource.h b/Source/Resource/GifResource.h index abf3d027..1630de71 100644 --- a/Source/Resource/GifResource.h +++ b/Source/Resource/GifResource.h @@ -23,7 +23,6 @@ public: void CreateBlank(int width, int height); bool DecodeGif(const void* data, int bytes, bool iconOnly); - int DecodeGifLzw(int minimumCodeSize, const unsigned char* input, int inputBytes, unsigned char* output); /* 0124 */ std::vector frames; /* 0130 */ std::uint16_t loopCount; diff --git a/Source/Script/LuaScript.cpp b/Source/Script/LuaScript.cpp index 0bfa144f..67208923 100644 --- a/Source/Script/LuaScript.cpp +++ b/Source/Script/LuaScript.cpp @@ -9,6 +9,7 @@ #include "Contents/Effects/EvilsPawEffect.h" #include "Contents/Effects/WindEffect.h" #include "Contents/Hotkeys/HotkeyInfo.h" +#include "Contents/Skills/SkillTreeScript.h" #include "File/File.h" #include "File/ResourcePath.h" #include "Script/LuaFileOperations.h" @@ -88,8 +89,6 @@ static void AddAttendanceBanner(UICheckAttendanceWnd* window, std::string image, window->m_banner->AddBanner(image, url, action, argument); } -int AddSkill(lua_State* state); -int AddNeededSkill(lua_State* state); // OFFSET: 0x00AFF7E0 // FUNCTION: fn_18354 diff --git a/Source/Script/NLuaState.cpp b/Source/Script/NLuaState.cpp index faaf1d36..6b8f8ece 100644 --- a/Source/Script/NLuaState.cpp +++ b/Source/Script/NLuaState.cpp @@ -22,9 +22,18 @@ struct TreeSubMap { unsigned int size; void Clear() noexcept; - void EraseSubtree(TreeSubMap& al, TreeSubNode* node); + __declspec(noinline) void EraseSubtree(TreeSubMap& al, TreeSubNode* node); }; +// OFFSET: 0x00BA1A20 +// FUNCTION: fn_19656 +void TreeSubMap::EraseSubtree(TreeSubMap& al, TreeSubNode* node) { + while (node->isnil == 0) { + this->EraseSubtree(al, node->right); + ::operator delete(std::exchange(node, node->left), 0x18); + } +} + // OFFSET: 0x00CA4AE0 // FUNCTION: fn_20939 void TreeSubMap::Clear() noexcept { diff --git a/Source/Security/NProtectGameGuardMgr.cpp b/Source/Security/NProtectGameGuardMgr.cpp index c0f48e30..50280fc9 100644 --- a/Source/Security/NProtectGameGuardMgr.cpp +++ b/Source/Security/NProtectGameGuardMgr.cpp @@ -28,7 +28,7 @@ void sub_E929B0(const char* name); int sub_E92820(); int __stdcall sub_76D910(int code, const int* packet); void sub_E92E90(int(__stdcall* callback)(int, const int*)); -void sub_CF0BA0(const char* file, int line, const char* message); +void WriteMyLog(const char* file, int line, const char* format, ...); void __fastcall sub_76C320(void* tokens); namespace { @@ -257,7 +257,7 @@ int CNProtectGameGuardMgr::sub_76C9D0() { MessageBoxA(hWnd, message, title, 0); return 0; } - sub_CF0BA0(g_nprotectSource, 0x284, title); + WriteMyLog(g_nprotectSource, 0x284, title); } sub_E92E90(sub_76D910); diff --git a/Source/Security/ThemidaMgr.cpp b/Source/Security/ThemidaMgr.cpp index 6434297c..63e3c123 100644 --- a/Source/Security/ThemidaMgr.cpp +++ b/Source/Security/ThemidaMgr.cpp @@ -1,21 +1,13 @@ #include "Security/ThemidaMgr.h" +#include "Archive/GPak.h" + #include #include // GLOBAL: gl_24891 CThemidaMgr* g_themidaMgr; -void sub_6563E0(char* first, char* last, void* distribution); - -struct ThemidaKeyRandom { - std::mt19937 engine; - std::uniform_int_distribution distribution; - - ThemidaKeyRandom(unsigned int seed) : engine(seed), distribution(1, 0xfe) { - } -}; - struct ThemidaKeyEncoderA { unsigned char* Generate(const unsigned char* input); }; @@ -38,8 +30,8 @@ CThemidaMgr::~CThemidaMgr() { // FUNCTION: fn_08237 unsigned char* ThemidaKeyEncoderA::Generate(const unsigned char* input) { auto* output = reinterpret_cast(this); - ThemidaKeyRandom random(std::random_device{}()); - sub_6563E0(reinterpret_cast(output), reinterpret_cast(output) + 5, &random); + PakUniformRandom random(1, 0xfe, std::random_device{}()); + FillRandomBytes(reinterpret_cast(output), reinterpret_cast(output) + 5, random); output[5] = input[0] ^ output[1] ^ output[0]; output[6] = input[1] ^ output[2] ^ output[1]; output[7] = input[2] ^ output[3] ^ output[2]; @@ -51,8 +43,8 @@ unsigned char* ThemidaKeyEncoderA::Generate(const unsigned char* input) { // FUNCTION: fn_08238 unsigned char* ThemidaKeyEncoderB::Generate(const unsigned char* input) { auto* output = reinterpret_cast(this); - ThemidaKeyRandom random(std::random_device{}()); - sub_6563E0(reinterpret_cast(output), reinterpret_cast(output) + 5, &random); + PakUniformRandom random(1, 0xfe, std::random_device{}()); + FillRandomBytes(reinterpret_cast(output), reinterpret_cast(output) + 5, random); output[5] = input[0] ^ output[1] ^ output[0]; output[6] = input[1] ^ output[2] ^ output[1]; output[7] = input[2] ^ output[3] ^ output[2]; diff --git a/Source/UI/Acceptance/UIChooseSellBuyWnd.cpp b/Source/UI/Acceptance/UIChooseSellBuyWnd.cpp index 5ea49c76..cdd94a70 100644 --- a/Source/UI/Acceptance/UIChooseSellBuyWnd.cpp +++ b/Source/UI/Acceptance/UIChooseSellBuyWnd.cpp @@ -195,9 +195,6 @@ static const char bookmarkKeySuffixText[] = "\\BookMark"; // GLOBAL: gl_24751 const char* g_bookmarkKeySuffix = bookmarkKeySuffixText; -// GLOBAL: gl_25332 -int g_window315Enabled = 1; - // GLOBAL: gl_25391 bool g_randomLoadingScreen; @@ -611,7 +608,7 @@ void UIEquipWnd::Paint() { if (this->m_page == 0) { ITEM_INFO dragItem = LookupClientItemByIdentity(g_session.m_inventoryItems, g_session.unknown_16EC); if (dragItem.unknown_0000[1] != 0) { - this->sub_8A8EE0(this->geometry.width / 2 - 25, this->m_contentTop + 44, &dragItem, 0); + DrawItemIcon(*this, ResourceMgr::Instance(), this->geometry.width / 2 - 25, this->m_contentTop + 44, dragItem, 0); this->DrawItemName(this->geometry.width / 2 - 25, this->m_contentTop + 68, 40, &dragItem, 0, 0, 12); } this->m_otherButton->Enable(1); @@ -792,7 +789,7 @@ int UIMinimapZoomWnd::SendMsg(UIWindow* sender, int message, std::intptr_t argum if (!g_session.IsNavigationAllowed()) { g_windowMgr.Confirm(LookupMessage(2767), 0, true, false, 0, "Message", 280, 120, 0); } else if (!g_windowMgr.CloseWindow(273)) { - g_windowMgr.sub_A978D0(273); + g_windowMgr.EnsureWindow(273); } return 0; case 216: @@ -825,7 +822,7 @@ int UIMinimapZoomWnd::SendMsg(UIWindow* sender, int message, std::intptr_t argum } case 454: if (!g_windowMgr.CloseWindow(140)) { - g_windowMgr.sub_A978D0(140); + g_windowMgr.EnsureWindow(140); } return 0; case 455: { @@ -3122,7 +3119,7 @@ int UIEquipWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::int if (g_windowMgr.unknown_0210 != nullptr) { g_windowMgr.CloseWindow(18); } - UIWindow* menu = g_windowMgr.sub_A978D0(18); + UIWindow* menu = g_windowMgr.EnsureWindow(18); if (!menu) { return 0; } @@ -3163,7 +3160,7 @@ int UIEquipWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::int case 249: if ((g_replayAnimationScaling == 0 || Replay::Instance().header.options.Get(ReplayRecordOption::Item) != 0) && !g_windowMgr.LookupWindow(227) && !g_windowMgr.CloseWindow(40) && g_session.unknown_5C1C > 0) { - g_windowMgr.sub_A978D0(40); + g_windowMgr.EnsureWindow(40); } return 0; case 271: { @@ -3235,7 +3232,7 @@ int UIEquipWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::int } case 582: if (!g_windowMgr.CloseWindow(10001)) { - g_windowMgr.sub_A978D0(10001); + g_windowMgr.EnsureWindow(10001); } return 0; } @@ -4287,7 +4284,7 @@ void UIItemIdentifyWnd::Paint() { this->FillRegion(5, top + 31, this->geometry.width - 24, 30, RGB(red, green, blue)); } - this->sub_8A8EE0(8, y, &*it, 0); + DrawItemIcon(*this, ResourceMgr::Instance(), 8, y, *it, 0); this->DrawFittedItemName(40, y, &*it, 0, 0, 12, 0); if (it->unknown_0088 > 0) { this->DrawBitmap( @@ -5840,7 +5837,7 @@ int UIChatRoomMakeWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, s if (g_windowMgr.unknown_0214) { g_windowMgr.CloseWindow(26); } - UIWindow* list = g_windowMgr.sub_A978D0(26); + UIWindow* list = g_windowMgr.EnsureWindow(26); int count = 1; if (a == 228) { this->m_listKind = 0; @@ -5923,7 +5920,7 @@ int UIChatRoomChangeWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, if (g_windowMgr.unknown_0214) { g_windowMgr.CloseWindow(26); } - UIWindow* list = g_windowMgr.sub_A978D0(26); + UIWindow* list = g_windowMgr.EnsureWindow(26); int count = 1; if (a == 228) { this->m_listKind = 0; @@ -9963,7 +9960,7 @@ void UIItemCollectionWnd::Slot32(int x, int y) { card.unknown_0000[0] = 6; card.unknown_0060 = 0; card.SetItemId(cardId); - UIWindow* window = g_windowMgr.sub_A978D0(82); + UIWindow* window = g_windowMgr.EnsureWindow(82); window->SendMsg(nullptr, 76, card.identified, 0, 0, 0); window->SendMsg(nullptr, 24, reinterpret_cast(&card), index >= ItemSlotsCount(this->m_item), 0, 0); @@ -9976,7 +9973,7 @@ void UIItemCollectionWnd::Slot32(int x, int y) { compareCard.unknown_0000[0] = 6; compareCard.unknown_0060 = 0; compareCard.SetItemId(compareId); - UIWindow* compareWindow = g_windowMgr.sub_A978D0(250); + UIWindow* compareWindow = g_windowMgr.EnsureWindow(250); compareWindow->SendMsg(nullptr, 76, compareCard.identified, 0, 0, 0); compareWindow->SendMsg(nullptr, 24, reinterpret_cast(&compareCard), 1, 0, 0); } @@ -10000,7 +9997,7 @@ void UIItemCollection_ComparisonWnd::Slot32(int x, int y) { card.unknown_0000[0] = 6; card.unknown_0060 = 0; card.SetItemId(cardId); - UIWindow* window = g_windowMgr.sub_A978D0(82); + UIWindow* window = g_windowMgr.EnsureWindow(82); window->SendMsg(nullptr, 76, card.identified, 0, 0, 0); window->SendMsg(nullptr, 24, reinterpret_cast(&card), index >= ItemSlotsCount(this->m_item), 0, 0); } @@ -12427,7 +12424,7 @@ int UIItemCollectionWnd::SendMsg(UIWindow* sender, int message, std::intptr_t ar g_windowMgr.CloseWindow(this->m_kind); return 0; case 250: { - UIWindow* window = g_windowMgr.sub_A978D0(47); + UIWindow* window = g_windowMgr.EnsureWindow(47); window->SendMsg(nullptr, 62, reinterpret_cast(this->m_item.itemId.c_str()), this->m_item.identified, 0, 0); return 0; } @@ -12445,13 +12442,13 @@ int UIItemCollectionWnd::SendMsg(UIWindow* sender, int message, std::intptr_t ar g_windowMgr.SendNotice(1, reinterpret_cast("책이 없습니다"), 0xFF, 0, 0, 0); return 0; } - UIWindow* window = g_windowMgr.sub_A978D0(106); + UIWindow* window = g_windowMgr.EnsureWindow(106); window->SendMsg(nullptr, 94, reinterpret_cast(this->m_item.itemId.c_str()), argument1, 0, 0); file.Close(); return 0; } case 343: { - UIWindow* window = g_windowMgr.sub_A978D0(10012); + UIWindow* window = g_windowMgr.EnsureWindow(10012); if (window) { static_cast(window)->SetItem(this->m_item.GetItemId()); window->PlaceBeside(this); @@ -12460,7 +12457,7 @@ int UIItemCollectionWnd::SendMsg(UIWindow* sender, int message, std::intptr_t ar break; } case 354: { - UIWindow* window = g_windowMgr.sub_A978D0(294); + UIWindow* window = g_windowMgr.EnsureWindow(294); if (window) { window->SendMsg(this, 23, reinterpret_cast(&this->m_item), 0, 0, 0); return 0; @@ -12613,7 +12610,7 @@ int UIItemCollectionWnd::SendMsg(UIWindow* sender, int message, std::intptr_t ar if (this->m_kind == 12) { ITEM_INFO* equipped = g_session.GetEquippedItem(&this->m_item); if (g_serviceOptions.Get(264) && equipped && argument4 == 0) { - UIWindow* window = g_windowMgr.sub_A978D0(234); + UIWindow* window = g_windowMgr.EnsureWindow(234); if (window) { window->SendMsg(nullptr, 24, reinterpret_cast(equipped), 1, 0, 0); } diff --git a/Source/UI/AdventureGuide/UIAdventureGuide.cpp b/Source/UI/AdventureGuide/UIAdventureGuide.cpp index f6ec63ed..17a349c9 100644 --- a/Source/UI/AdventureGuide/UIAdventureGuide.cpp +++ b/Source/UI/AdventureGuide/UIAdventureGuide.cpp @@ -1980,10 +1980,6 @@ CUIListBox* CUITab::CreateSubTabList() { } -CUIAdventureGuide::CUIAdventureGuide() - : background(nullptr), titleBar(nullptr), characterInfo(nullptr), titleText(nullptr), intro(nullptr), quest(nullptr), monster(nullptr), item(nullptr), tabs(nullptr) { -} - // OFFSET: 0x009C1230 // FUNCTION: fn_13986 CUIAdventureGuide* CreateAdventureGuide() { diff --git a/Source/UI/AdventureGuide/UIAdventureGuide.h b/Source/UI/AdventureGuide/UIAdventureGuide.h index 7d734172..a5add99d 100644 --- a/Source/UI/AdventureGuide/UIAdventureGuide.h +++ b/Source/UI/AdventureGuide/UIAdventureGuide.h @@ -155,6 +155,15 @@ public: } +template <> +void CUIListBoxEx::AddNewItem(); +template <> +void CUIListBoxEx::AddNewItem(); +template <> +void CUIListBoxEx::AddNewItem(); +template <> +void CUIListBoxEx::AddNewItem(); + #if defined(_WIN32) && !defined(_WIN64) static_assert(sizeof(AdventureGuide::CUIIntro) == 0x8C); static_assert(sizeof(AdventureGuide::CUIMonster) == 0xA0); diff --git a/Source/UI/CashShop/UICashShopWnd.cpp b/Source/UI/CashShop/UICashShopWnd.cpp index 75f4e14f..507ac234 100644 --- a/Source/UI/CashShop/UICashShopWnd.cpp +++ b/Source/UI/CashShop/UICashShopWnd.cpp @@ -1,4 +1,5 @@ #include "UI/CashShop/UICashShopWnd.h" +#include "Utility/EncryptedName.h" #include "Client/Mode/CGameMode.h" #include "Client/Mode/CMode.h" @@ -43,35 +44,6 @@ #include #include -template -class EncryptedName { -public: - // INLINED - explicit EncryptedName(const char (&source)[Length]) : m_encrypted(true) { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = source[index]; - } - } - - ~EncryptedName() { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = 0; - } - } - - const char* Text() { - if (this->m_encrypted) { - utility::XorBytes(this->m_text, Length, Key); - this->m_encrypted = false; - } - - return reinterpret_cast(this->m_text); - } - -private: - /* 0000 */ std::uint8_t m_text[Length]; - bool m_encrypted; -}; #pragma pack(push, 1) struct CashItemPurchase { diff --git a/Source/UI/Chat/UINewChatWnd.cpp b/Source/UI/Chat/UINewChatWnd.cpp index ef12ccae..c27f5d83 100644 --- a/Source/UI/Chat/UINewChatWnd.cpp +++ b/Source/UI/Chat/UINewChatWnd.cpp @@ -351,7 +351,7 @@ int UINewChatWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::i case 6: switch (a) { case 0xC1: - if (UIWindow* window = g_windowMgr.sub_A978D0(0x84)) { + if (UIWindow* window = g_windowMgr.EnsureWindow(0x84)) { window->SendMsg(this, 6, 0xC1, this->m_currentTab, 1, 0); } return 0; @@ -375,7 +375,7 @@ int UINewChatWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::i if (g_windowMgr.unknown_0214 != nullptr) { g_windowMgr.CloseWindow(0x1A); } - UIWindow* menu = g_windowMgr.sub_A978D0(0x1A); + UIWindow* menu = g_windowMgr.EnsureWindow(0x1A); menu->SendMsg(nullptr, 0x1F, reinterpret_cast(LookupMessage(0x55)), 0, 0, 0); menu->SendMsg(nullptr, 0x1F, reinterpret_cast(LookupMessage(0x56)), 0, 0, 0); menu->SendMsg(nullptr, 0x1F, reinterpret_cast(LookupMessage(0x1B5)), 0, 0, 0); @@ -402,7 +402,7 @@ int UINewChatWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::i return 0; } - UIWindow* menu = g_windowMgr.sub_A978D0(0x1A); + UIWindow* menu = g_windowMgr.EnsureWindow(0x1A); for (int i = 0; i < count; ++i) { menu->SendMsg(nullptr, 0x1F, reinterpret_cast(static_cast(this->unknown_00C0)->history[i].c_str()), 0, 0, 0); } diff --git a/Source/UI/Cooldowns/CooldownOwner.cpp b/Source/UI/Cooldowns/CooldownOwner.cpp index 32241943..cb73dd37 100644 --- a/Source/UI/Cooldowns/CooldownOwner.cpp +++ b/Source/UI/Cooldowns/CooldownOwner.cpp @@ -8,6 +8,13 @@ CooldownOwner::CooldownOwner() : m_initialized(false) { this->m_initialized = true; } +// INLINED +CooldownOwner::~CooldownOwner() { + this->m_drawing.normal.clear(); + this->m_drawing.reverse.clear(); + this->m_values.clear(); +} + // OFFSET: 0x00CA61A0 // FUNCTION: fn_20957 void CooldownOwner::Register(unsigned id, std::uint32_t duration, std::uint32_t start, std::uint32_t elapsed) { diff --git a/Source/UI/Cooldowns/CooldownOwner.h b/Source/UI/Cooldowns/CooldownOwner.h index 569b8dfd..8f253f52 100644 --- a/Source/UI/Cooldowns/CooldownOwner.h +++ b/Source/UI/Cooldowns/CooldownOwner.h @@ -8,11 +8,9 @@ class CooldownOwner { public: CooldownOwner(); - ~CooldownOwner(); + __declspec(noinline) ~CooldownOwner(); void Register(unsigned id, std::uint32_t duration, std::uint32_t start, std::uint32_t elapsed); void ClearReverseCommands(); - void SubmitReverse(); - void Draw(int centerX, int centerY, int radiusX, int radiusY, CooldownState& value, int limit, int offsetX, int offsetY); CooldownState* Find(unsigned id); void Erase(unsigned id); diff --git a/Source/UI/Edit/UIEditBoxEx.cpp b/Source/UI/Edit/UIEditBoxEx.cpp index 90a09570..451820ec 100644 --- a/Source/UI/Edit/UIEditBoxEx.cpp +++ b/Source/UI/Edit/UIEditBoxEx.cpp @@ -195,7 +195,7 @@ void CUIEditCtrlEx::Synchronize() { if (reinterpret_cast(&this->unknown_0184)[1] != 0) { int wrapWidth = this->geometry.width - this->unknown_0130->geometry.width - this->unknown_01B4; this->WrapTextWithBreaks(fullText.c_str(), &lines, &breaks, wrapWidth); - this->sub_860C60(&lines); + this->WrapLines(lines); } else { lines.push_back(fullText); breaks.push_back(false); diff --git a/Source/UI/Edit/UIEditBoxEx.h b/Source/UI/Edit/UIEditBoxEx.h index dffe46d1..02feb8eb 100644 --- a/Source/UI/Edit/UIEditBoxEx.h +++ b/Source/UI/Edit/UIEditBoxEx.h @@ -29,7 +29,6 @@ public: void UpdateScrollBar() override; int SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) override; - void sub_860C60(std::vector* lines); __declspec(noinline) void RefreshPlaceholder(); void HandleKeyDown(int key, std::intptr_t lparam); diff --git a/Source/UI/Edit/UIEditCtrl.cpp b/Source/UI/Edit/UIEditCtrl.cpp index 30e8f00f..672d8fb8 100644 --- a/Source/UI/Edit/UIEditCtrl.cpp +++ b/Source/UI/Edit/UIEditCtrl.cpp @@ -1369,7 +1369,7 @@ int UIMerchantItemMyShopWnd::SendMsg(UIWindow* sender, int message, std::intptr_ } { - UIWindow* window = g_windowMgr.sub_A978D0(windowId); + UIWindow* window = g_windowMgr.EnsureWindow(windowId); if (window) { window->Show(1); window->Move(this->geometry.x, this->geometry.y); @@ -3770,20 +3770,13 @@ bool ItemTypeNameLess::operator()(const ITEM_INFO& left, const ITEM_INFO& right) return leftRank < rightRank; } -extern "C" void sub_96E320(void* head, size_t size, ...); - // OFFSET: 0x00996870 // FUNCTION: fn_13470 bool UIItemStoreSubWnd::Sort1() { if (!this->sub_996950()) { return false; } - struct Flag { - char val; - } flag{0}; - void* head = *reinterpret_cast(reinterpret_cast(this) + 0xe8); - size_t size = *reinterpret_cast(reinterpret_cast(this) + 0xec); - sub_96E320(head, size, flag); + this->items.sort(); return true; } @@ -3793,12 +3786,7 @@ bool UIItemStoreSubWnd::Sort2() { if (!this->sub_996AF0()) { return false; } - struct Flag { - char val; - } flag{0}; - void* head = *reinterpret_cast(reinterpret_cast(this) + 0xe8); - size_t size = *reinterpret_cast(reinterpret_cast(this) + 0xec); - sub_96E320(head, size, flag); + this->items.sort(); return true; } @@ -3808,12 +3796,7 @@ bool UIItemStoreSubWnd::Sort3() { if (!this->sub_996C90()) { return false; } - struct Flag { - char val; - } flag{0}; - void* head = *reinterpret_cast(reinterpret_cast(this) + 0xe8); - size_t size = *reinterpret_cast(reinterpret_cast(this) + 0xec); - sub_96E320(head, size, flag); + this->items.sort(); return true; } @@ -3823,12 +3806,7 @@ bool UIItemStoreSubWnd::SortReversed1() { if (!this->sub_996950()) { return false; } - struct Flag { - char val; - } flag{0}; - void* head = *reinterpret_cast(reinterpret_cast(this) + 0xe8); - size_t size = *reinterpret_cast(reinterpret_cast(this) + 0xec); - sub_96E320(head, size, flag); + this->items.sort(); this->items.reverse(); return true; } @@ -3839,12 +3817,7 @@ bool UIItemStoreSubWnd::SortReversed2() { if (!this->sub_996AF0()) { return false; } - struct Flag { - char val; - } flag{0}; - void* head = *reinterpret_cast(reinterpret_cast(this) + 0xe8); - size_t size = *reinterpret_cast(reinterpret_cast(this) + 0xec); - sub_96E320(head, size, flag); + this->items.sort(); this->items.reverse(); return true; } @@ -3855,12 +3828,7 @@ bool UIItemStoreSubWnd::SortReversed3() { if (!this->sub_996C90()) { return false; } - struct Flag { - char val; - } flag{0}; - void* head = *reinterpret_cast(reinterpret_cast(this) + 0xe8); - size_t size = *reinterpret_cast(reinterpret_cast(this) + 0xec); - sub_96E320(head, size, flag); + this->items.sort(); this->items.reverse(); return true; } @@ -6567,7 +6535,7 @@ int UIMerchantItemPurchaseWnd::SendMsg(UIWindow* sender, int message, std::intpt } mode->SendMsg(273, this->unknown_00F8, this->unknown_0104, 0, 0); } else { - static_cast(g_windowMgr.sub_A978D0(230))->SetPurchase(this->unknown_00F8, this->unknown_0104); + static_cast(g_windowMgr.EnsureWindow(230))->SetPurchase(this->unknown_00F8, this->unknown_0104); } mode->SendMsg(40, 0, 0, 0, 0); @@ -8582,7 +8550,7 @@ int UIItemStoreWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std: case 365: { std::string text(this->searchEdit->Text()); if (!text.empty()) { - UIItemStoreFindWnd* window = static_cast(g_windowMgr.sub_A978D0(153)); + UIItemStoreFindWnd* window = static_cast(g_windowMgr.EnsureWindow(153)); this->unknown_0140 = window; window->SetSearchText(std::string(text.c_str(), text.size())); this->unknown_0140->SendMsg(nullptr, 23, 365, 0, 0, 0); @@ -8606,7 +8574,7 @@ int UIItemStoreWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std: if (tab->geometry.unknown_0030 != 0) { this->unknown_0120[index] = nullptr; - this->unknown_0120[index] = g_windowMgr.sub_A978D0(a); + this->unknown_0120[index] = g_windowMgr.EnsureWindow(a); if (this->unknown_0120[index]) { this->unknown_0120[index]->SendMsg(nullptr, 23, 0, 0, 0, 0); } @@ -8628,7 +8596,7 @@ int UIItemStoreWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std: if (this->tabs[7]->geometry.unknown_0030 != 0) { this->unknown_0120[7] = nullptr; - this->unknown_0120[7] = g_windowMgr.sub_A978D0(309); + this->unknown_0120[7] = g_windowMgr.EnsureWindow(309); if (this->unknown_0120[7]) { this->unknown_0120[7]->SendMsg(nullptr, 23, 0, 0, 0, 0); } @@ -8644,7 +8612,7 @@ int UIItemStoreWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std: break; case 133: if (!this->unknown_0140) { - this->unknown_0140 = g_windowMgr.sub_A978D0(153); + this->unknown_0140 = g_windowMgr.EnsureWindow(153); std::string text(this->searchEdit->Text()); if (!text.empty() && reinterpret_cast(this)->FilterByName3(std::string(text.c_str(), text.size()))) { static_cast(this->unknown_0140)->SetSearchText(std::string(text.c_str(), text.size())); @@ -11516,7 +11484,7 @@ int UIMerchantShopMakeWnd::SendMsg(UIWindow* sender, int message, std::intptr_t std::memcpy(&header, data + offset, sizeof(header)); offset += 6; if (header.type == 21301 || header.type == 21351) { - UIWindow* window = g_windowMgr.sub_A978D0(header.type == 21301 ? 42 : 175); + UIWindow* window = g_windowMgr.EnsureWindow(header.type == 21301 ? 42 : 175); if (window) { window->SendMsg(nullptr, 23, 0, 0, 0, 0); } @@ -11532,7 +11500,7 @@ int UIMerchantShopMakeWnd::SendMsg(UIWindow* sender, int message, std::intptr_t g_session.m_skipPriceWarning = !g_session.m_skipPriceWarning; } else if (a == 343) { if (!g_windowMgr.LookupWindow(333)) { - g_windowMgr.sub_A978D0(333); + g_windowMgr.EnsureWindow(333); } } else if (a == 560) { this->unknown_0168->SetDisabled(1); diff --git a/Source/UI/EntryQueue/UIEntryQueueWnd.cpp b/Source/UI/EntryQueue/UIEntryQueueWnd.cpp index 89ba1e7c..363b9864 100644 --- a/Source/UI/EntryQueue/UIEntryQueueWnd.cpp +++ b/Source/UI/EntryQueue/UIEntryQueueWnd.cpp @@ -65,6 +65,11 @@ int UIEntryQueueHelpWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, __declspec(noinline) UIEntryQueueListBox::UIEntryQueueListBox() : UIListBox() { } +// INLINED +UIEntryQueueListBox::~UIEntryQueueListBox() { +} + + // OFFSET: 0x00BA4490 // FUNCTION: fn_19686 void UIEntryQueueListBox::AddEntry(const char* name, int value) { @@ -99,6 +104,11 @@ UIEntryQueueRequestWnd::UIEntryQueueRequestWnd() : UIFrameWnd(0), m_interval(1000), m_elapsed(0), m_delta(0), m_lastTick(0) { } +// INLINED +UIEntryQueueRequestWnd::~UIEntryQueueRequestWnd() { +} + + // OFFSET: 0x00BA48E0 // FUNCTION: fn_19691 bool UIEntryQueueRequestWnd::Create() { @@ -225,6 +235,11 @@ UIEntryQueueStandByWnd::UIEntryQueueStandByWnd() m_rankingText() { } +// INLINED +UIEntryQueueStandByWnd::~UIEntryQueueStandByWnd() { +} + + // OFFSET: 0x00BA5700 // FUNCTION: fn_19698 bool UIEntryQueueStandByWnd::Create() { @@ -329,6 +344,11 @@ UIEntryQueueWnd::UIEntryQueueWnd() : UIFrameWnd(0) { std::memset(this->m_values, 0, sizeof(this->m_values)); } +// INLINED +UIEntryQueueWnd::~UIEntryQueueWnd() { +} + + // OFFSET: 0x00BA6410 // FUNCTION: fn_19706 int UIEntryQueueWnd::SelectedIndex() { diff --git a/Source/UI/FrameSkin.cpp b/Source/UI/FrameSkin.cpp index 013b3592..d8e6f27b 100644 --- a/Source/UI/FrameSkin.cpp +++ b/Source/UI/FrameSkin.cpp @@ -11,10 +11,6 @@ template <> CUIRegisterMgr* Singleton::s_instance = nullptr; -__declspec(noinline) CUIRegisterMgr::CUIRegisterMgr() { - InitializeCriticalSection(&this->lock); -} - // OFFSET: 0x009E69D0 // FUNCTION: fn_14469 CUIFrameWnd::~CUIFrameWnd() { diff --git a/Source/UI/GameSettings/GameSettingsUI.cpp b/Source/UI/GameSettings/GameSettingsUI.cpp index 1463c3bd..2470886a 100644 --- a/Source/UI/GameSettings/GameSettingsUI.cpp +++ b/Source/UI/GameSettings/GameSettingsUI.cpp @@ -98,8 +98,6 @@ std::map g_optionHotkeys; // GLOBAL: gl_25229 bool g_restartClient; -RenderAdapter sub_56A0F0(); - // OFFSET: 0x00A3D0A0 // FUNCTION: fn_15905 RenderAdapter::RenderAdapter() : backend(0), ordinal(0), drawGuid{}, renderGuid{}, deviceGuid{} { @@ -795,6 +793,33 @@ void CUIListBoxEx::AddNewItem() { this->scrollBar->SetVisible(this->geometry.height); } +// INLINED +template <> +void CUIListBoxEx::SelectItem(CUIListItem* item) { + if (this->unknown_00C4) { + return; + } + for (GameSettingsUI::CUIOptionItem* other : this->items) { + if (item != other) { + other->SetSelected(0); + } + } + item->SetSelected(1); + if (item->index == static_cast(this->selected) && this->unknown_00E0) { + return; + } + GameSettingsUI::CUIOptionItem* selectedItem = dynamic_cast(item); + if (!selectedItem) { + return; + } + this->selected = selectedItem->index; + if (this->onSelect && static_cast(this->selected) >= 0 && this->selected < this->data.size()) { + auto node = this->data.begin(); + std::advance(node, static_cast(this->selected)); + this->onSelect(selectedItem, *node); + } +} + // OFFSET: 0x00A35170 // FUNCTION: fn_15425 template <> @@ -2063,7 +2088,7 @@ void GameSettingsUI::CUIGroupTextureDetailLevel::Slot16() { void ToggleGameSettingsTab4() { UIWindow* window = g_windowMgr.LookupWindow(0x271E); if (!window) { - window = g_windowMgr.sub_A978D0(0x271E); + window = g_windowMgr.EnsureWindow(0x271E); } CUIGameSettingsUI* settings = static_cast(window); @@ -2223,7 +2248,7 @@ void GameSettingsUI::CUIGroupGraphics::Slot16() { const char* modeText = LookupMessage(0xc6e); this->m_modeText->SetText(modeText, std::strlen(modeText)); GetRenderSystemHolder(); - this->m_pendingAdapter = sub_56A0F0(); + this->m_pendingAdapter = SelectedRenderAdapter(); this->m_adapter = this->m_pendingAdapter; DisplayMode mode{}; mode.width = g_configuredScreenWidth; @@ -2425,7 +2450,7 @@ void GameSettingsUI::CUIGroupSound::Apply() { // OFFSET: 0x00A19C60 // FUNCTION: fn_15346 -CUIButton::CUIButton() : CUIControl(), state(0), disabled(0), tooltip(), unknown_00C4(nullptr), unknown_00EC(nullptr) { +inline CUIButton::CUIButton() : CUIControl(), state(0), disabled(0), tooltip(), unknown_00C4(nullptr), unknown_00EC(nullptr) { } // OFFSET: 0x00A19D30 diff --git a/Source/UI/Guild/UIGuildHelperWnd.cpp b/Source/UI/Guild/UIGuildHelperWnd.cpp index 3311af8d..ccb671c4 100644 --- a/Source/UI/Guild/UIGuildHelperWnd.cpp +++ b/Source/UI/Guild/UIGuildHelperWnd.cpp @@ -237,12 +237,12 @@ int UIGuildHelperWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a1, s break; case 343: if (!g_windowMgr.CloseWindow(214)) { - g_windowMgr.sub_A978D0(214); + g_windowMgr.EnsureWindow(214); } break; case 448: if (!g_windowMgr.CloseWindow(213)) { - g_windowMgr.sub_A978D0(213); + g_windowMgr.EnsureWindow(213); if (g_windowMgr.unknown_0438) { int x = 0; int y = 0; diff --git a/Source/UI/Item/UIEquipmentPropertiesWnd.cpp b/Source/UI/Item/UIEquipmentPropertiesWnd.cpp index cc958789..53906ee7 100644 --- a/Source/UI/Item/UIEquipmentPropertiesWnd.cpp +++ b/Source/UI/Item/UIEquipmentPropertiesWnd.cpp @@ -43,16 +43,6 @@ template void CUIListBoxEx::Slot35(int); template void CUIListBoxEx::ClearItems(); -void CUIListItem::SetImageResources(CBitmapRes* normal, CBitmapRes* hover, CBitmapRes* pressed, CBitmapRes* disabled) { - auto& images = *reinterpret_cast*>(reinterpret_cast(this) + 0x80); - images.clear(); - images[0] = normal; - images[1] = hover; - images[2] = pressed; - this->disabledImage = disabled; - this->Invalidate(); -} - // OFFSET: 0x00A0EBF0 // FUNCTION: fn_15152 EquipmentPropertiesWnd::CUIItemEquipmentPropertiesLine::CUIItemEquipmentPropertiesLine() diff --git a/Source/UI/Items/MergeItemWnd.cpp b/Source/UI/Items/MergeItemWnd.cpp index 465b28a7..4cd261fb 100644 --- a/Source/UI/Items/MergeItemWnd.cpp +++ b/Source/UI/Items/MergeItemWnd.cpp @@ -75,6 +75,11 @@ void CMergeItemWnd::SelectSameItems(int id) { } } +// INLINED +CMergeItemWnd::~CMergeItemWnd() { +} + + // OFFSET: 0x007DF3D0 // FUNCTION: fn_09663 int CMergeItemWnd::ItemIdOf(int id) { diff --git a/Source/UI/Items/UISwapEquipmentWnd.cpp b/Source/UI/Items/UISwapEquipmentWnd.cpp index cffba5e1..b6db0634 100644 --- a/Source/UI/Items/UISwapEquipmentWnd.cpp +++ b/Source/UI/Items/UISwapEquipmentWnd.cpp @@ -122,7 +122,7 @@ void UISwapEquipmentWnd::sub_82FD90() { const int row = slot & 3; if (slot < 8) { const int iconY = row * 26 + 48; - this->sub_8A8EE0(xCoords[slot / 4 + 2], iconY, &item, 0); + DrawItemIcon(*this, ResourceMgr::Instance(), xCoords[slot / 4 + 2], iconY, item, 0); this->DrawItemName(xCoords[slot / 4], yCoords[row], 70, &item, 0, 0, 12); if (item.unknown_0088 > 0) { CBitmapRes* gradeBitmap = static_cast( @@ -131,7 +131,7 @@ void UISwapEquipmentWnd::sub_82FD90() { this->DrawBitmap(xCoords[slot / 4 + 2], iconY + 12, gradeBitmap ? &gradeBitmap->image : nullptr, true); } } else { - this->sub_8A8EE0(xCoords[row + 2], 22, &item, 0); + DrawItemIcon(*this, ResourceMgr::Instance(), xCoords[row + 2], 22, item, 0); this->DrawItemName(xCoords[slot - 8], 30, 70, &item, 0, 0, 12); } } else { @@ -367,7 +367,7 @@ void UISwapEquipmentWnd::Paint() { if (g_session.unknown_7EC8 != 0) { ITEM_INFO dragItem = LookupClientItemByIdentity(g_session.m_inventoryItems, g_session.unknown_7EC8); if (dragItem.unknown_0000[1] > 0) { - this->sub_8A8EE0(this->geometry.width / 2 - 24, 27, &dragItem, 0); + DrawItemIcon(*this, ResourceMgr::Instance(), this->geometry.width / 2 - 24, 27, dragItem, 0); this->DrawFittedItemName(this->geometry.width / 2 - 24, 51, &dragItem, 0, 0, 12, 0); } } diff --git a/Source/UI/Lists/UIListBoxTemplate.h b/Source/UI/Lists/UIListBoxTemplate.h index 564da81f..763a746f 100644 --- a/Source/UI/Lists/UIListBoxTemplate.h +++ b/Source/UI/Lists/UIListBoxTemplate.h @@ -392,6 +392,8 @@ public: // FUNCTION: fn_14344 // OFFSET: 0x00A06300 // FUNCTION: fn_15001 + // OFFSET: 0x00A4E360 + // FUNCTION: fn_16205 void UpdateScrollBar() { this->scrollBar->SetTotal(this->data.size() * this->rowHeight + this->itemY); this->scrollBar->SetVisible(this->geometry.height); diff --git a/Source/UI/Lists/UITagListBox.cpp b/Source/UI/Lists/UITagListBox.cpp index ba15bf46..8a0448f0 100644 --- a/Source/UI/Lists/UITagListBox.cpp +++ b/Source/UI/Lists/UITagListBox.cpp @@ -19,6 +19,10 @@ #include #include +// INLINED +UITagListBox::STagInfoV2::~STagInfoV2() { +} + // OFFSET: 0x009B7A10 // FUNCTION: fn_13869 void UITagListBox::AddLine(const char* text) { diff --git a/Source/UI/ProbabilityTable/UIProbabilityTable.cpp b/Source/UI/ProbabilityTable/UIProbabilityTable.cpp index dc46daf5..b11398e2 100644 --- a/Source/UI/ProbabilityTable/UIProbabilityTable.cpp +++ b/Source/UI/ProbabilityTable/UIProbabilityTable.cpp @@ -543,10 +543,10 @@ void CUIProbabilityTable::OnPrepareItem(ProbabilityTable::CUIItem*, const Probab void BindItem(ProbabilityTable::CUIItem* item, const ProbabilityTable::CItemData& data) { item->nameText->Clear(); item->probabilityText->Clear(); - item->nameText->SetText(data.name); + item->nameText->AddLine(data.name); item->nameText->SetBackgroundColor(data.color); item->probabilityText->SetBackgroundColor(data.color); - item->probabilityText->SetText(FormatOwnedString("%.4lf%%", data.probability)); + item->probabilityText->AddLine(FormatOwnedString("%.4lf%%", data.probability)); } // OFFSET: 0x00A493D0 @@ -852,13 +852,3 @@ void CUIItem::Slot25(int, int) { } } - -// OFFSET: 0x00A4E360 -// FUNCTION: fn_16205 -template <> -void CUIListBoxEx::UpdateScrollBar() { - this->scrollBar->SetTotal(this->data.size() * this->rowHeight + this->itemY); - this->scrollBar->SetVisible(this->geometry.height); - this->scrollBar->SetPosition(this->scrollBar->position); - this->rebind = 1; -} diff --git a/Source/UI/Quest/UIOngoingQuestInfo.cpp b/Source/UI/Quest/UIOngoingQuestInfo.cpp index c95f5865..60996a49 100644 --- a/Source/UI/Quest/UIOngoingQuestInfo.cpp +++ b/Source/UI/Quest/UIOngoingQuestInfo.cpp @@ -701,6 +701,33 @@ CUIScrollWindow::CUIScrollWindow() } } +// INLINED +template <> +void CUIListBoxEx::SelectItem(CUIListItem* item) { + if (this->unknown_00C4) { + return; + } + for (OngoingQuestInfo::CUIRewardItem* other : this->items) { + if (item != other) { + other->SetSelected(0); + } + } + item->SetSelected(1); + if (item->index == static_cast(this->selected) && this->unknown_00E0) { + return; + } + OngoingQuestInfo::CUIRewardItem* selectedItem = dynamic_cast(item); + if (!selectedItem) { + return; + } + this->selected = selectedItem->index; + if (this->onSelect && static_cast(this->selected) >= 0 && this->selected < this->data.size()) { + auto node = this->data.begin(); + std::advance(node, static_cast(this->selected)); + this->onSelect(selectedItem, *node); + } +} + // OFFSET: 0x00A53A90 // FUNCTION: fn_16233 template <> diff --git a/Source/UI/Quest/UIRenewQuestUI.cpp b/Source/UI/Quest/UIRenewQuestUI.cpp index 2f8a11fd..1d435c91 100644 --- a/Source/UI/Quest/UIRenewQuestUI.cpp +++ b/Source/UI/Quest/UIRenewQuestUI.cpp @@ -1,4 +1,5 @@ #include "UI/Quest/UIRenewQuestUI.h" +#include "Utility/EncryptedName.h" #include "Client/Replay.h" #include "Contents/MessageTable.h" #include "Contents/RenewQuestMgr.h" @@ -25,36 +26,6 @@ // GLOBAL: gl_25249 static bool s_recommendedTabFirstSelect = true; -template -class EncryptedName { -public: - // INLINED - template - explicit EncryptedName(const Byte (&source)[Length]) : m_encrypted(true) { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = source[index]; - } - } - - ~EncryptedName() { - for (std::uint64_t index = 0; index < Length; ++index) { - this->m_text[index] = 0; - } - } - - const char* Text() { - if (this->m_encrypted) { - utility::XorBytes(this->m_text, Length, Key); - this->m_encrypted = false; - } - - return reinterpret_cast(this->m_text); - } - -private: - /* 0000 */ std::uint8_t m_text[Length]; - bool m_encrypted; -}; // INLINED template @@ -78,7 +49,7 @@ const char* EncryptedName<6, 0xE33F2FF779878559ULL>::Text() { // OFFSET: 0x00A5A010 // FUNCTION: fn_16372 template <> -const char* EncryptedName<6, 0xC70319B5EB61598FULL>::Text() { +inline const char* EncryptedName<6, 0xC70319B5EB61598FULL>::Text() { if (this->m_encrypted) { utility::XorBytes(this->m_text, 6, 0xC70319B5EB61598FULL); this->m_encrypted = false; diff --git a/Source/UI/Quest/UIRenewQuestUI.h b/Source/UI/Quest/UIRenewQuestUI.h index ad111c54..26ad2bcc 100644 --- a/Source/UI/Quest/UIRenewQuestUI.h +++ b/Source/UI/Quest/UIRenewQuestUI.h @@ -85,7 +85,6 @@ public: void OnCallback56(); void OnCallback74(); void OnCallback80(); - void sub_A56050(unsigned int questId); void sub_A67290(unsigned int flags); void sub_A66FF0(unsigned int questId); diff --git a/Source/UI/Rodex/UIRodexComposeWnd.cpp b/Source/UI/Rodex/UIRodexComposeWnd.cpp index 23813885..d697f51c 100644 --- a/Source/UI/Rodex/UIRodexComposeWnd.cpp +++ b/Source/UI/Rodex/UIRodexComposeWnd.cpp @@ -107,7 +107,7 @@ void UIRodexComposeWnd::sub_7FF710(const ITEM_INFO& item) { tagCtrl->taggedText = this->m_contents->Text(); std::string appendResult = tagCtrl->AppendTag(item.DisplayName(0)); this->m_contents->SetText(appendResult.c_str()); - this->m_contents->sub_855150(); + this->m_contents->MoveCursorToEnd(); tagCtrl->sub_89CFE0(item, 0xd630a9); } @@ -135,7 +135,7 @@ void UIRodexComposeWnd::sub_7FF940(int tagId) { std::string fullText = std::string(this->m_contents->Text()) + tagText; this->m_contents->SetText(fullText.c_str()); - this->m_contents->sub_855150(); + this->m_contents->MoveCursorToEnd(); } // OFFSET: 0x00800480 diff --git a/Source/UI/Rodex/UIRodexComposeWnd.h b/Source/UI/Rodex/UIRodexComposeWnd.h index 82ef03e6..25895a84 100644 --- a/Source/UI/Rodex/UIRodexComposeWnd.h +++ b/Source/UI/Rodex/UIRodexComposeWnd.h @@ -27,7 +27,6 @@ class UIRodexEditCtrl3 : public UIEditCtrl3 { public: UIRodexEditCtrl3(); void Slot15(int width, int height) override; - void sub_855150(); }; class UIRodexComposeWnd : public UIFrameWnd { diff --git a/Source/UI/SelectPackageItemBox/UISelectPackageItemBox.cpp b/Source/UI/SelectPackageItemBox/UISelectPackageItemBox.cpp index 7618d476..675f3d48 100644 --- a/Source/UI/SelectPackageItemBox/UISelectPackageItemBox.cpp +++ b/Source/UI/SelectPackageItemBox/UISelectPackageItemBox.cpp @@ -161,6 +161,60 @@ void CUIListBoxEx +void CUIListBoxEx::SelectItem(CUIListItem* item) { + if (this->unknown_00C4) { + return; + } + for (SelectPackageItemBox::CUIItemInfo* other : this->items) { + if (item != other) { + other->SetSelected(0); + } + } + item->SetSelected(1); + if (item->index == static_cast(this->selected) && this->unknown_00E0) { + return; + } + SelectPackageItemBox::CUIItemInfo* selectedItem = dynamic_cast(item); + if (!selectedItem) { + return; + } + this->selected = selectedItem->index; + if (this->onSelect && static_cast(this->selected) >= 0 && this->selected < this->data.size()) { + auto node = this->data.begin(); + std::advance(node, static_cast(this->selected)); + this->onSelect(selectedItem, *node); + } +} + +// INLINED +template <> +void CUIListBoxEx::SelectItem(CUIListItem* item) { + if (this->unknown_00C4) { + return; + } + for (SelectPackageItemBox::CUITabInfo* other : this->items) { + if (item != other) { + other->SetSelected(0); + } + } + item->SetSelected(1); + if (item->index == static_cast(this->selected) && this->unknown_00E0) { + return; + } + SelectPackageItemBox::CUITabInfo* selectedTab = dynamic_cast(item); + if (!selectedTab) { + return; + } + this->selected = selectedTab->index; + if (this->onSelect && static_cast(this->selected) >= 0 && this->selected < this->data.size()) { + auto node = this->data.begin(); + std::advance(node, static_cast(this->selected)); + this->onSelect(selectedTab, *node); + } +} + // OFFSET: 0x00A6D1A0 // FUNCTION: fn_16670 template <> diff --git a/Source/UI/Shortcuts/UIShortCutWnd.cpp b/Source/UI/Shortcuts/UIShortCutWnd.cpp index d0af68a4..a42c599b 100644 --- a/Source/UI/Shortcuts/UIShortCutWnd.cpp +++ b/Source/UI/Shortcuts/UIShortCutWnd.cpp @@ -1247,7 +1247,7 @@ int UISubChatHisWnd::SendMsg(UIWindow* sender, int message, std::intptr_t argume case 6: switch (argument1) { case 0xC1: - if (UIWindow* window = g_windowMgr.sub_A978D0(0x84)) { + if (UIWindow* window = g_windowMgr.EnsureWindow(0x84)) { window->SendMsg(this, 6, 0xC1, this->m_index, 0, 0); return 0; } diff --git a/Source/UI/Text/UIAchWnd.cpp b/Source/UI/Text/UIAchWnd.cpp index d8f8ad92..56702534 100644 --- a/Source/UI/Text/UIAchWnd.cpp +++ b/Source/UI/Text/UIAchWnd.cpp @@ -1230,7 +1230,7 @@ void UIAchSummaryWnd::Slot15(int, int) { int UIAchListWnd::SendMsg(UIWindow*, int message, std::intptr_t argument1, std::intptr_t, std::intptr_t, std::intptr_t) { switch (message) { case 6: - if (g_session.sub_E06580(this->ids[this->unknown_008C + argument1])) { + if (g_session.ToggleTrackedAchievement(this->ids[this->unknown_008C + argument1])) { UIWindow* window = g_windowMgr.EnsureWindow(271); if (window) { window->Invalidate(); @@ -1486,6 +1486,14 @@ UIAchListWnd::UIAchListWnd() unknown_009C(0), unknown_00AC(nullptr), scrollBar(nullptr) { } +// INLINED +UIAchListWnd::~UIAchListWnd() { + if (this->buttons) { + delete[] this->buttons; + } +} + + // OFFSET: 0x007B1F40 // FUNCTION: fn_09182 UIAchScrollBar::UIAchScrollBar() : UIScrollBar() { diff --git a/Source/UI/Text/UITextViewerControl.h b/Source/UI/Text/UITextViewerControl.h index 99e6deb7..6b6ce05d 100644 --- a/Source/UI/Text/UITextViewerControl.h +++ b/Source/UI/Text/UITextViewerControl.h @@ -37,7 +37,6 @@ public: void SetScrollBarThumbImages(const std::string& top, const std::string& middle, const std::string& bottom); void SetScrollBarThumbImage(const std::string& name); void SetScrollBarBackground(const std::string& name); - void SetText(const std::string& text); void Clear(); void AddLine(const std::string& text); void Relayout(); diff --git a/Source/UI/Text/UITextViewerMessages.cpp b/Source/UI/Text/UITextViewerMessages.cpp index 8a5b06e0..5cc690a6 100644 --- a/Source/UI/Text/UITextViewerMessages.cpp +++ b/Source/UI/Text/UITextViewerMessages.cpp @@ -109,7 +109,7 @@ __forceinline void UITextViewer::Activate(UITextButton* button, int id) { item.unknown_0060 = 0; item.itemId = button->GetLine(0); - if (UIWindow* window = g_windowMgr.sub_A978D0(12)) { + if (UIWindow* window = g_windowMgr.EnsureWindow(12)) { window->SendMsg(nullptr, 24, reinterpret_cast(&item), 0, 0, 0); } @@ -119,7 +119,7 @@ __forceinline void UITextViewer::Activate(UITextButton* button, int id) { if (button && button->GetLinesCount() != 0) { const std::string& tip = button->GetLine(0); - if (UIWindow* window = g_windowMgr.sub_A978D0(315)) { + if (UIWindow* window = g_windowMgr.EnsureWindow(315)) { static_cast(window)->ShowTip(std::atoi(tip.c_str())); } } @@ -362,7 +362,7 @@ int UITextViewer::SendMsg(UIWindow* sender, int message, std::intptr_t argument1 item.unknown_0000[0] = static_cast(idValue); item.unknown_0060 = 0; item.itemId = button->GetLine(0); - if (UIWindow* window = g_windowMgr.sub_A978D0(12)) { + if (UIWindow* window = g_windowMgr.EnsureWindow(12)) { window->SendMsg(nullptr, 24, reinterpret_cast(&item), 0, 0, 0); } } @@ -370,7 +370,7 @@ int UITextViewer::SendMsg(UIWindow* sender, int message, std::intptr_t argument1 case 517: if (button && button->GetLinesCount() != 0) { const std::string& tip = button->GetLine(0); - if (UIWindow* window = g_windowMgr.sub_A978D0(315)) { + if (UIWindow* window = g_windowMgr.EnsureWindow(315)) { static_cast(window)->ShowTip(std::atoi(tip.c_str())); } } diff --git a/Source/UI/UIBroadcastBalloon.cpp b/Source/UI/UIBroadcastBalloon.cpp index 70f10fc7..11d36599 100644 --- a/Source/UI/UIBroadcastBalloon.cpp +++ b/Source/UI/UIBroadcastBalloon.cpp @@ -95,7 +95,7 @@ void UIBroadcastBalloon::Paint() { DrawRoundedBorder(*this, x, y, message.width, message.height, 0xFF5C5C5C); y += 4; for (const BroadcastBalloonLine& line : message.lines) { - this->sub_A86510(x + 6, y, line.text.c_str(), 0, line.color, line.outlineColor, 0, message.fontHeight, 0); + this->DrawShadowedText(x + 6, y, line.text.c_str(), 0, line.color, line.outlineColor, 0, message.fontHeight, 0); int lineHeight = this->TextHeight(line.text.c_str(), 0, 0, message.fontHeight, 0, 0); y += 4 + lineHeight; } diff --git a/Source/UI/UIBroadcastBalloon.h b/Source/UI/UIBroadcastBalloon.h index cf92070e..294bf9ab 100644 --- a/Source/UI/UIBroadcastBalloon.h +++ b/Source/UI/UIBroadcastBalloon.h @@ -36,10 +36,6 @@ public: void Slot43() override; void AddMessage(int category, const BroadcastBalloonMessage& message); - void sub_A86510( - int x, int y, const char* text, int bytes, std::uint32_t color, std::uint32_t outline, int family, int height, - unsigned char bold - ); protected: /* 007C */ std::map> m_messages; diff --git a/Source/UI/UICaptchaPreviewWnd.cpp b/Source/UI/UICaptchaPreviewWnd.cpp index 8ce48b31..28485780 100644 --- a/Source/UI/UICaptchaPreviewWnd.cpp +++ b/Source/UI/UICaptchaPreviewWnd.cpp @@ -115,16 +115,16 @@ void UICaptchaPreviewWnd::Paint() { // OFFSET: 0x007ED960 // FUNCTION: fn_09813 void UIMacroDetectorWnd::Paint() { - this->sub_8D2CE0(false, "", 0); + this->DrawTitleBar(false, "", 0); this->DrawButtonBar(0, 0, 1); this->FillRegion(0, 16, this->geometry.width, this->geometry.height - 36, 0xFFFFFFFF); DrawRectangleBorder(*this, 0, 16, this->geometry.width, this->geometry.height - 36, 0xC6C6C6); - this->sub_A84360(25, 28, LookupMessage(2883), 0, 0, 12, 0, 1, 0); - this->sub_A84360(25, 45, LookupMessage(2884), 0, 0, 12, 0, 1, 0); - this->sub_A84360(25, 62, LookupMessage(2885), 0, 0, 12, 0, 1, 0); + this->DrawTextAt(25, 28, LookupMessage(2883), 0, 0, 12, 0, 1, 0); + this->DrawTextAt(25, 45, LookupMessage(2884), 0, 0, 12, 0, 1, 0); + this->DrawTextAt(25, 62, LookupMessage(2885), 0, 0, 12, 0, 1, 0); - this->sub_A84360(25, 82, this->message.c_str(), 0, 0, 12, 0x2323FF, 1, 0); + this->DrawTextAt(25, 82, this->message.c_str(), 0, 0, 12, 0x2323FF, 1, 0); this->FillRegion(59, 158, 222, 92, 0xC6C6C6); this->FillRegion(60, 97, 220, 30, 0xC6C6C6); @@ -138,11 +138,11 @@ void UIMacroDetectorWnd::Paint() { unsigned int seconds = remaining / 1000; { std::string str = FormatOwnedString("%2d : %2d", seconds / 60, seconds); - this->sub_A86440(280, 138, str.c_str(), 0, 0, 13, 0xFF2323, 1); + this->DrawRightAlignedText(280, 138, str.c_str(), 0, 0, 13, 0xFF2323, 1); } { std::string str = FormatOwnedString(LookupMessage(2886), this->unknown_00D0); - this->sub_A84360(60, 138, str.c_str(), 0, 0, 13, 0x2323FF, 1, 0); + this->DrawTextAt(60, 138, str.c_str(), 0, 0, 13, 0x2323FF, 1, 0); } } } diff --git a/Source/UI/UICaptchaRegisterWnd.cpp b/Source/UI/UICaptchaRegisterWnd.cpp index 30e3a241..fe0c4501 100644 --- a/Source/UI/UICaptchaRegisterWnd.cpp +++ b/Source/UI/UICaptchaRegisterWnd.cpp @@ -43,8 +43,8 @@ UICaptchaRegisterWnd::UICaptchaRegisterWnd() // OFFSET: 0x007EA3B0 // FUNCTION: fn_09788 void UICaptchaRegisterWnd::Slot15(int width, int height) { - this->sub_8CEF10(); - this->sub_8CF0C0("", 0); + this->AddBaseButton(); + this->AddCloseButton("", 0); std::string directory = FormatOwnedString("%s\\captcha\\", g_applicationDirectory); diff --git a/Source/UI/UICaptchaRegisterWnd.h b/Source/UI/UICaptchaRegisterWnd.h index 1e4f0d1e..a9f6061c 100644 --- a/Source/UI/UICaptchaRegisterWnd.h +++ b/Source/UI/UICaptchaRegisterWnd.h @@ -19,8 +19,6 @@ public: int SendMsg(UIWindow* sender, int message, std::intptr_t a1, std::intptr_t a2, std::intptr_t a3, std::intptr_t a4) override; void SetRegisterDisabled(unsigned char disabled); - void sub_8CEF10(); - void sub_8CF0C0(const char* tooltip, int width); /* 00B4 */ UIStaticText* m_pathText; /* 00B8 */ UIComboBoxDefWnd* m_fileComboBox; diff --git a/Source/UI/UICheckAttendanceWnd.cpp b/Source/UI/UICheckAttendanceWnd.cpp index abdd02b5..ed6c94f6 100644 --- a/Source/UI/UICheckAttendanceWnd.cpp +++ b/Source/UI/UICheckAttendanceWnd.cpp @@ -48,6 +48,11 @@ UICheckAttendanceWnd::UICheckAttendanceWnd() this->m_rewardCount = static_cast(g_checkAttendanceMgr->m_rewards.size()); } +// INLINED +UICheckAttendanceWnd::~UICheckAttendanceWnd() { +} + + // OFFSET: 0x007DCBD0 // FUNCTION: fn_09636 void UICheckAttendanceWnd_Banner::AddBanner(std::string image, std::string url, int action, int argument) { @@ -95,6 +100,11 @@ UICheckAttendanceWnd_Banner::UICheckAttendanceWnd_Banner() : UIWindow(0), m_current(0), m_lastSwitch(timeGetTime()) { } +// INLINED +UICheckAttendanceWnd_Banner::~UICheckAttendanceWnd_Banner() { +} + + // OFFSET: 0x007DCF50 // FUNCTION: fn_09639 void UICheckAttendanceWnd::Slot15(int, int) { diff --git a/Source/UI/UIGradeEnchantWnd.cpp b/Source/UI/UIGradeEnchantWnd.cpp index 8ff2efde..3dd81ee5 100644 --- a/Source/UI/UIGradeEnchantWnd.cpp +++ b/Source/UI/UIGradeEnchantWnd.cpp @@ -1,4 +1,5 @@ #include "UI/Window/UINewSelectCharWnd.h" +#include "UI/Shop/ItemDrawing.h" #include "UI/UIGradeEnchantWnd.h" #include "Client/Mode/CMode.h" @@ -250,7 +251,7 @@ void UIGradeEnchantWnd::Paint() { ITEM_INFO itemInfo; itemInfo.SetItemId(material.itemId); itemInfo.sub_6D5810(description, capacity, 0); - this->sub_8A8EE0(170, y - 9, &itemInfo, 0); + DrawItemIcon(*this, ResourceMgr::Instance(), 170, y - 9, itemInfo, 0); std::string text = FormatOwnedString(LookupMessage(3553), description, material.amount); this->sub_A85850(203, y, text, 180, 0, 0, 0, 0, 11, 0, 0); y += 40; @@ -260,7 +261,7 @@ void UIGradeEnchantWnd::Paint() { ITEM_INFO itemInfo; itemInfo.SetItemId(this->info.unknown_0000); itemInfo.sub_6D5810(description, capacity, 0); - this->sub_8A8EE0(195, 228, &itemInfo, 0); + DrawItemIcon(*this, ResourceMgr::Instance(), 195, 228, itemInfo, 0); std::string text = FormatOwnedString(LookupMessage(3553), description, this->unknown_0114); this->sub_A85850(228, 237, text, 160, 0, 0xFFFFFF, 0, 0, 11, 1, 1); } @@ -292,7 +293,7 @@ void UIGradeEnchantWnd::Paint() { } if (this->item.unknown_0000[1] > 0) { - this->sub_8A8EE0(64, 125, &this->item, 0); + DrawItemIcon(*this, ResourceMgr::Instance(), 64, 125, this->item, 0); if (this->item.unknown_0088 > 0) { this->DrawBitmap(64, 137, reinterpret_cast(ResourceMgr::Instance().Load(Resolve(FormatOwnedString("유저인터페이스\\grade_enchant\\grade_icon%d.bmp", this->item.unknown_0088).c_str()))), true); } diff --git a/Source/UI/UIHotkeyGuideWnd.cpp b/Source/UI/UIHotkeyGuideWnd.cpp index 6d810cff..9fcd421b 100644 --- a/Source/UI/UIHotkeyGuideWnd.cpp +++ b/Source/UI/UIHotkeyGuideWnd.cpp @@ -283,7 +283,7 @@ int UIHotkeyGuideWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, st if (message == 6) { switch (a) { case 342: { - UIWindow* window = g_windowMgr.sub_A978D0(156); + UIWindow* window = g_windowMgr.EnsureWindow(156); if (window) { window->SendMsg(this, 22, 1, 0, 0, 0); } diff --git a/Source/UI/UIMacroDetectorWnd.h b/Source/UI/UIMacroDetectorWnd.h index bf507e93..e0d9f413 100644 --- a/Source/UI/UIMacroDetectorWnd.h +++ b/Source/UI/UIMacroDetectorWnd.h @@ -21,9 +21,6 @@ public: void Slot31(int x, int y) override; int SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) override; - void sub_8D2CE0(bool closeButton, const char* title, int width); - void sub_A84360(int x, int y, const char* text, int bytes, int family, int height, std::uint32_t color, unsigned char bold, unsigned char italic); - void sub_A86440(int right, int y, const char* text, int bytes, int family, int height, std::uint32_t color, unsigned char bold); void AddImageData(const void* data, int size); void ClearImageData(); void SetCountdown(unsigned char count, std::uint32_t duration); diff --git a/Source/UI/UIReputeWnd.cpp b/Source/UI/UIReputeWnd.cpp index 55b33ac3..992b3ae6 100644 --- a/Source/UI/UIReputeWnd.cpp +++ b/Source/UI/UIReputeWnd.cpp @@ -12,6 +12,7 @@ #include "UI/Lists/UIComboBoxEx.h" #include "UI/Window/WindowBorder.h" #include "UI/Window/WindowManagerWindows.h" +#include "Utility/JsonCppLoader.h" #include "Utility/Text/FormatString.h" #include diff --git a/Source/UI/UIReputeWnd.h b/Source/UI/UIReputeWnd.h index a46ed290..f7e13f0a 100644 --- a/Source/UI/UIReputeWnd.h +++ b/Source/UI/UIReputeWnd.h @@ -36,7 +36,5 @@ public: std::vector m_reputes; }; -#include "Contents/ReputeMgrLoad.inl" - #endif diff --git a/Source/UI/Window/UIFrameWnd.cpp b/Source/UI/Window/UIFrameWnd.cpp index 8c926947..e682b452 100644 --- a/Source/UI/Window/UIFrameWnd.cpp +++ b/Source/UI/Window/UIFrameWnd.cpp @@ -891,7 +891,7 @@ int UIChatRoomWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std:: return 0; } case 2: - g_windowMgr.sub_A978D0(30)->SendMsg(nullptr, 34, reinterpret_cast(&mode->unknown_03C8), 0, 0, 0); + g_windowMgr.EnsureWindow(30)->SendMsg(nullptr, 34, reinterpret_cast(&mode->unknown_03C8), 0, 0, 0); return 0; case 3: g_windowMgr.Confirm(LookupMessage(191), 0, true, false, 0, "Message", 280, 120, 0); @@ -962,7 +962,7 @@ int UIChatRoomWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std:: } if (!this->unknown_0114.empty()) { - UIWindow* menu = g_windowMgr.sub_A978D0(18); + UIWindow* menu = g_windowMgr.EnsureWindow(18); for (unsigned index = 0; index < this->unknown_0114.size(); ++index) { menu->SendMsg(nullptr, 31, reinterpret_cast(this->unknown_0114[index].first.c_str()), 0, 0, 0); } diff --git a/Source/UI/Window/UIRegisterMgr.h b/Source/UI/Window/UIRegisterMgr.h index a5022a98..7eaaac25 100644 --- a/Source/UI/Window/UIRegisterMgr.h +++ b/Source/UI/Window/UIRegisterMgr.h @@ -19,7 +19,6 @@ public: CUIFrameWnd* Create(int key); void Load(); bool SaveTemporary(); - void sub_9EB920(); /* 0004 */ std::map> entries; /* 000C */ std::map> unknown_000C; diff --git a/Source/UI/Window/UIRoMapWnd.cpp b/Source/UI/Window/UIRoMapWnd.cpp index a05026a5..3d5d6d12 100644 --- a/Source/UI/Window/UIRoMapWnd.cpp +++ b/Source/UI/Window/UIRoMapWnd.cpp @@ -756,7 +756,7 @@ int UIRoMapWnd::SendMsg(UIWindow* sender, int message, std::intptr_t argument1, this->Invalidate(); return 0; case 200: - g_windowMgr.sub_A978D0(203); + g_windowMgr.EnsureWindow(203); if (g_windowMgr.window_4F174) { g_windowMgr.window_4F174->SendMsg(nullptr, 6, 200, 0, 0, 0); } diff --git a/Source/UI/Window/UISecondCostumeWnd.cpp b/Source/UI/Window/UISecondCostumeWnd.cpp index c78ce7b2..0129e085 100644 --- a/Source/UI/Window/UISecondCostumeWnd.cpp +++ b/Source/UI/Window/UISecondCostumeWnd.cpp @@ -209,7 +209,7 @@ void UISecondCostumeWnd::Slot15(int width, int height) { // OFFSET: 0x0094EC60 // FUNCTION: fn_12913 void UISecondCostumeWnd::Paint() { - int titleHeight = this->sub_8D2CE0(true, "Dress Room", 0); + int titleHeight = this->DrawTitleBar(true, "Dress Room", 0); this->DrawPanelBackground(17, 0, ""); int x = this->geometry.width - 204; const BitmapImage* bitmap = reinterpret_cast(ResourceMgr::Instance().Load(Resolve("유저인터페이스\\basic_interface\\dressroomback.bmp"))); diff --git a/Source/UI/Window/UISecondCostumeWnd.h b/Source/UI/Window/UISecondCostumeWnd.h index c7d778aa..d0f7d83a 100644 --- a/Source/UI/Window/UISecondCostumeWnd.h +++ b/Source/UI/Window/UISecondCostumeWnd.h @@ -24,7 +24,6 @@ public: void Paint() override; int SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) override; __declspec(noinline) void RefreshList(int tab); - int sub_8D2CE0(bool closeButton, const char* title, int width); void sub_948D20(int x, int y); void LoadLists(); void SelectSavedEntries(); diff --git a/Source/UI/Window/UISelCharForUServerWnd.cpp b/Source/UI/Window/UISelCharForUServerWnd.cpp index f66b5dcd..fc4e514b 100644 --- a/Source/UI/Window/UISelCharForUServerWnd.cpp +++ b/Source/UI/Window/UISelCharForUServerWnd.cpp @@ -183,7 +183,7 @@ int UISelCharForUServerWnd::SendMsg(UIWindow* sender, int message, std::intptr_t // OFFSET: 0x00932B40 // FUNCTION: fn_12714 void UISelCharForUServerWnd::Slot27(int x, int y) { - this->sub_93F1F0(x, y, -1); + this->UpdateCharInfoBalloon(x, y, static_cast(-1)); UIFrameWnd::Slot27(x, y); } diff --git a/Source/UI/Window/UISelCharForUServerWnd.h b/Source/UI/Window/UISelCharForUServerWnd.h index 5453e8c8..636623e1 100644 --- a/Source/UI/Window/UISelCharForUServerWnd.h +++ b/Source/UI/Window/UISelCharForUServerWnd.h @@ -20,7 +20,6 @@ public: void Slot27(int x, int y) override; void Paint() override; void UpdateCharInfoBalloon(int x, int y, std::uint32_t color); - void sub_93F1F0(int x, int y, int slot); protected: /* 00B4 */ CharSlotInfo m_slots[18]; diff --git a/Source/UI/Window/UIWindow.h b/Source/UI/Window/UIWindow.h index ca61ce61..07b91b87 100644 --- a/Source/UI/Window/UIWindow.h +++ b/Source/UI/Window/UIWindow.h @@ -120,7 +120,6 @@ public: void ClearSurface(std::uint32_t color); void SetSize(int width, int height); void DrawBitmap(int x, int y, const BitmapImage* image, bool transparent); - void sub_8A8EE0(int x, int y, const ITEM_INFO* item, unsigned char identified); void sub_A85850(int x, int y, std::string text, int width, int align, std::uint32_t color, int arg7, int arg8, int arg9, int arg10, unsigned char bold); void FillRegion(int x, int y, int width, int height, std::uint32_t color); int TextWidth(const char* text, unsigned bytes, int family, int height, unsigned char bold, unsigned char italic); diff --git a/Source/UI/Window/UIWindowMgr.cpp b/Source/UI/Window/UIWindowMgr.cpp index 9c1d662d..ad03ade6 100644 --- a/Source/UI/Window/UIWindowMgr.cpp +++ b/Source/UI/Window/UIWindowMgr.cpp @@ -241,6 +241,7 @@ #include "UI/Window/UITransMenuWnd.h" #include "UI/Window/UIVideoWnd.h" #include "UI/Window/UIViewCameraInfoWnd.h" +#include "Utility/JsonCppLoader.h" #include namespace { @@ -1925,7 +1926,7 @@ int UIWindowMgr::SendNotice(int selector, std::intptr_t a, std::intptr_t b, std: break; case 8: case 9: - this->sub_A978D0(51)->SendMsg(nullptr, 65, a, b, 0, 0); + this->EnsureWindow(51)->SendMsg(nullptr, 65, a, b, 0, 0); break; case 10: this->CloseWindow(51); @@ -4260,7 +4261,7 @@ bool UIWindowMgr::sub_AA35F0(int action) { const bool closed = g_windowMgr.CloseWindow(0x45); std::memcpy(&partyTab, this->unknown_0740, sizeof(partyTab)); if (!closed || previous != partyTab) { - g_windowMgr.sub_A978D0(0x45); + g_windowMgr.EnsureWindow(0x45); } } break; @@ -4276,7 +4277,7 @@ bool UIWindowMgr::sub_AA35F0(int action) { break; case 0x6C: if (this->unknown_01DC && !g_windowMgr.CloseWindow(0x8C)) { - g_windowMgr.sub_A978D0(0x8C); + g_windowMgr.EnsureWindow(0x8C); } break; case 0x6D: @@ -4288,21 +4289,21 @@ bool UIWindowMgr::sub_AA35F0(int action) { if (this->unknown_01DC) { if (g_guildInfo.m_guildId != 0) { if (!g_windowMgr.CloseWindow(0x3B)) { - g_windowMgr.sub_A978D0(0x3B); + g_windowMgr.EnsureWindow(0x3B); } } else if (!g_windowMgr.CloseWindow(0xD4)) { - g_windowMgr.sub_A978D0(0xD4); + g_windowMgr.EnsureWindow(0xD4); } } break; case 0x90: if (this->unknown_01DC && !g_windowMgr.CloseWindow(0xED)) { - g_windowMgr.sub_A978D0(0xED); + g_windowMgr.EnsureWindow(0xED); } break; case 0x6F: if (this->unknown_01DC && !g_windowMgr.CloseWindow(0x57)) { - g_windowMgr.sub_A978D0(0x57); + g_windowMgr.EnsureWindow(0x57); } break; case 0x70: @@ -4317,14 +4318,14 @@ bool UIWindowMgr::sub_AA35F0(int action) { return true; } if (!this->CloseWindow(14)) { - this->sub_A978D0(14); + this->EnsureWindow(14); this->unknown_005C = 0xFFFFFFFF; } } break; case 0x72: if (this->unknown_01DC && !g_windowMgr.CloseWindow(0x56)) { - g_windowMgr.sub_A978D0(0x56); + g_windowMgr.EnsureWindow(0x56); } break; case 0x73: @@ -4370,22 +4371,22 @@ bool UIWindowMgr::sub_AA35F0(int action) { if (UIWindow* window = this->unknown_03F8) { window->Show(window->geometry.visible == 0); } else { - g_windowMgr.sub_A978D0(0x89); + g_windowMgr.EnsureWindow(0x89); } break; case 0x7B: if (this->unknown_01DC && !g_windowMgr.CloseWindow(0x58)) { - g_windowMgr.sub_A978D0(0x58); + g_windowMgr.EnsureWindow(0x58); } break; case 0x7C: if (this->unknown_01DC && g_session.unknown_5614 != 0 && !g_windowMgr.CloseWindow(0x71)) { - g_windowMgr.sub_A978D0(0x71); + g_windowMgr.EnsureWindow(0x71); } break; case 0x7D: if (this->unknown_01DC && g_session.unknown_56B0 != 0 && !g_windowMgr.CloseWindow(0x7D)) { - g_windowMgr.sub_A978D0(0x7D); + g_windowMgr.EnsureWindow(0x7D); } break; case 0x7E: @@ -4422,12 +4423,12 @@ bool UIWindowMgr::sub_AA35F0(int action) { break; case 0x80: if (this->unknown_01DC && !g_windowMgr.CloseWindow(0x44)) { - g_windowMgr.sub_A978D0(0x44); + g_windowMgr.EnsureWindow(0x44); } break; case 0x81: if (this->unknown_01DC && !g_windowMgr.CloseWindow(0x35) && g_session.PartyCount()) { - g_windowMgr.sub_A978D0(0x35); + g_windowMgr.EnsureWindow(0x35); } break; case 0x87: { @@ -4486,9 +4487,10 @@ bool UIWindowMgr::sub_AA35F0(int action) { } else if (g_windowMgr.modal) { g_windowMgr.modal->SendMsg(nullptr, 6, 0xC8, 0, 0, 0); } else { - g_windowMgr.sub_A978D0(0xCB); + g_windowMgr.EnsureWindow(0xCB); } break; + case 0x92: if (g_windowMgr.window_0448) { g_windowMgr.CloseWindow(0x113); @@ -4525,7 +4527,7 @@ bool UIWindowMgr::sub_AA35F0(int action) { } case 0x95: if (!g_windowMgr.CloseWindow(0x10E)) { - g_windowMgr.sub_A978D0(0x10E); + g_windowMgr.EnsureWindow(0x10E); } break; case 0x96: @@ -4533,7 +4535,7 @@ bool UIWindowMgr::sub_AA35F0(int action) { if (!g_session.IsNavigationAllowed()) { g_windowMgr.Confirm(LookupMessage(0xACF), 0, true, false, 0, "Message", 280, 120, 0); } else if (!g_windowMgr.CloseWindow(0x111)) { - g_windowMgr.sub_A978D0(0x111); + g_windowMgr.EnsureWindow(0x111); } } break; @@ -4547,7 +4549,7 @@ bool UIWindowMgr::sub_AA35F0(int action) { break; case 0x9A: if (!g_windowMgr.CloseWindow(0x13B)) { - g_windowMgr.sub_A978D0(0x13B); + g_windowMgr.EnsureWindow(0x13B); } break; case 0x9B: @@ -4562,7 +4564,7 @@ bool UIWindowMgr::sub_AA35F0(int action) { break; case 0x9D: if (!g_windowMgr.CloseWindow(0x144)) { - g_windowMgr.sub_A978D0(0x144); + g_windowMgr.EnsureWindow(0x144); } break; case 0x9F: @@ -4570,12 +4572,12 @@ bool UIWindowMgr::sub_AA35F0(int action) { break; case 0xA0: if (!g_windowMgr.CloseWindow(0x15A)) { - g_windowMgr.sub_A978D0(0x15A); + g_windowMgr.EnsureWindow(0x15A); } break; case 0xA1: if (!g_windowMgr.CloseWindow(0x2711)) { - g_windowMgr.sub_A978D0(0x2711); + g_windowMgr.EnsureWindow(0x2711); } break; case 0xA3: @@ -4615,7 +4617,7 @@ bool UIWindowMgr::sub_AA35F0(int action) { } // OFFSET: 0x00A978D0 // FUNCTION: fn_17207 -UIWindow* UIWindowMgr::sub_A978D0(int id) { +UIWindow* UIWindowMgr::EnsureWindow(int id) { UIWindow* transient = this->window_4F250; if (transient && static_cast(transient)->member.valid && transient->geometry.unknown_0030 == 0) { bool behavior = false; @@ -4667,7 +4669,7 @@ UIWindow* UIWindowMgr::sub_A978D0(int id) { this->AddRendered(window); this->unknown_01DC->SendMsg(this->unknown_01DC, 0x22, reinterpret_cast(this->unknown_0514), 0, 0, 0); g_snapMgr.SetRoot(window); - if (UIWindow* navigation = g_windowMgr.sub_A978D0(307)) { + if (UIWindow* navigation = g_windowMgr.EnsureWindow(307)) { int x = 0; int y = 0; window->ToScreen(x, y); @@ -4680,44 +4682,44 @@ UIWindow* UIWindowMgr::sub_A978D0(int id) { if (savedId == 301) { this->RebuildMiniPartyWindows(); } else { - this->sub_A978D0(savedId); + this->EnsureWindow(savedId); } } } else { if (this->unknown_054C) { - this->sub_A978D0(8); + this->EnsureWindow(8); } if (this->unknown_05A4) { - this->sub_A978D0(10); + this->EnsureWindow(10); } if (this->unknown_0588) { - this->sub_A978D0(11); + this->EnsureWindow(11); } if (this->unknown_05BC) { - this->sub_A978D0(13); + this->EnsureWindow(13); } if (this->unknown_077C) { - this->sub_A978D0(37); + this->EnsureWindow(37); } if (this->unknown_0568) { - this->sub_A978D0(321); + this->EnsureWindow(321); } if (this->unknown_073C) { - this->sub_A978D0(69); + this->EnsureWindow(69); } if (g_session.unknown_5470 == 1 && g_session.unknown_5474 == 1 && g_effectDetailLevel == 2 && g_textureDetailLevel == 2) { - this->sub_A978D0(10014); + this->EnsureWindow(10014); } if (g_session.HasUnknown6178Records() == true) { - this->sub_A978D0(271); + this->EnsureWindow(271); } if (this->unknown_4F210 == true) { - this->sub_A978D0(286); + this->EnsureWindow(286); } this->RebuildMiniPartyWindows(); } if (static_cast(g_modeMgr.GetGameMode())->unknown_0254) { - this->sub_A978D0(14); + this->EnsureWindow(14); } this->ShowWindowById(1, this->unknown_003C); this->ShowWindowById(36, this->m_normalItemSlotWindow.show); @@ -5077,9 +5079,9 @@ UIWindow* UIWindowMgr::sub_A978D0(int id) { break; case 69: if (*reinterpret_cast(this->unknown_0740)) { - this->sub_A978D0(34)->SendMsg(nullptr, 6, 0xD7, 2, 0, 0); + this->EnsureWindow(34)->SendMsg(nullptr, 6, 0xD7, 2, 0, 0); } else { - this->sub_A978D0(34)->SendMsg(nullptr, 6, 0xD7, 1, 0, 0); + this->EnsureWindow(34)->SendMsg(nullptr, 6, 0xD7, 1, 0, 0); } break; case 34: @@ -5110,7 +5112,7 @@ UIWindow* UIWindowMgr::sub_A978D0(int id) { window->SendMsg(nullptr, 0x22, reinterpret_cast(base + 0x7A4), 0, 0, 0); } window->Show(1); - this->sub_A978D0(42); + this->EnsureWindow(42); break; case 42: window = reinterpret_cast(this->unknown_02F8); @@ -5237,25 +5239,25 @@ UIWindow* UIWindowMgr::sub_A978D0(int id) { } switch (guildInfo->unknown_0010) { case 0: - window = g_windowMgr.sub_A978D0(60); + window = g_windowMgr.EnsureWindow(60); break; case 1: - window = g_windowMgr.sub_A978D0(61); + window = g_windowMgr.EnsureWindow(61); break; case 2: - window = g_windowMgr.sub_A978D0(62); + window = g_windowMgr.EnsureWindow(62); break; case 3: - window = g_windowMgr.sub_A978D0(63); + window = g_windowMgr.EnsureWindow(63); break; case 4: - window = g_windowMgr.sub_A978D0(64); + window = g_windowMgr.EnsureWindow(64); break; case 5: - window = g_windowMgr.sub_A978D0(65); + window = g_windowMgr.EnsureWindow(65); break; case 6: - window = g_windowMgr.sub_A978D0(66); + window = g_windowMgr.EnsureWindow(66); break; } break; @@ -5823,7 +5825,7 @@ UIWindow* UIWindowMgr::sub_A978D0(int id) { window->SendMsg(nullptr, 0x22, reinterpret_cast(base + 0x71C), 0, 0, 0); } window->Show(1); - this->sub_A978D0(50); + this->EnsureWindow(50); break; case 45: window = this->unknown_0304; @@ -6643,7 +6645,7 @@ UIWindow* UIWindowMgr::sub_A978D0(int id) { window->SendMsg(nullptr, 0x22, reinterpret_cast(base + 0x954), 0, 0, 0); } window->Show(1); - this->sub_A978D0(175); + this->EnsureWindow(175); break; case 175: window = reinterpret_cast(this->unknown_0410); @@ -7153,7 +7155,7 @@ UIWindow* UIWindowMgr::sub_A978D0(int id) { case 295: { const int x = static_cast((g_renderer->viewport.width - 264) * g_depthAverageHalf); const int y = static_cast((g_renderer->viewport.height - 346) * g_depthAverageHalf); - this->sub_A978D0(8); + this->EnsureWindow(8); if (this->unknown_01D4) { this->unknown_01D4->Move(x + 264, y - this->unknown_01D4->geometry.height + 346); } @@ -7375,7 +7377,7 @@ UIWindow* UIWindowMgr::sub_A978D0(int id) { case 343: { const int x = static_cast((g_renderer->viewport.width - 400) * g_depthAverageHalf - 100.0f); const int y = static_cast((g_renderer->viewport.height - 330) * g_depthAverageHalf); - this->sub_A978D0(8); + this->EnsureWindow(8); if (this->unknown_01D4) { this->unknown_01D4->Move(x + 400, y - this->unknown_01D4->geometry.height + 330); } diff --git a/Source/UI/Window/UIWindowMgr.h b/Source/UI/Window/UIWindowMgr.h index afc6ac8d..663ded20 100644 --- a/Source/UI/Window/UIWindowMgr.h +++ b/Source/UI/Window/UIWindowMgr.h @@ -471,7 +471,6 @@ public: void sub_AAB090(); void sub_AAB0B0(); UIWindow* EnsureWindow(int id); - UIWindow* sub_A978D0(int id); UIWindow* CreateLayoutWindow(int id); RECT GetMiniPartyUsableArea(); __declspec(noinline) UIWindow* FindSnapExcludedWindow(int cell); diff --git a/Source/Utility/EncryptedName.h b/Source/Utility/EncryptedName.h new file mode 100644 index 00000000..ced7f755 --- /dev/null +++ b/Source/Utility/EncryptedName.h @@ -0,0 +1,56 @@ +#ifndef RAGNAROK_SOURCE_UTILITY_ENCRYPTEDNAME_H +#define RAGNAROK_SOURCE_UTILITY_ENCRYPTEDNAME_H + +#include "Utility/Cipher/XorBytes.h" + +#include +#include + +template +class EncryptedName { +public: + // INLINED + explicit EncryptedName(const char (&source)[Length]) : m_encrypted(true) { + for (std::uint64_t index = 0; index < Length; ++index) { + this->m_text[index] = source[index]; + } + } + + // INLINED + explicit EncryptedName(const std::uint8_t (&source)[Length]) : m_encrypted(true) { + for (std::uint64_t index = 0; index < Length; ++index) { + this->m_text[index] = source[index]; + } + } + + ~EncryptedName() { + for (std::uint64_t index = 0; index < Length; ++index) { + this->m_text[index] = 0; + } + } + + // INLINED + bool Encrypted() const { + return this->m_encrypted; + } + + // INLINED + const char* Text() { + if (this->m_encrypted) { + utility::XorBytes(this->m_text, Length, Key); + this->m_encrypted = false; + } + + return reinterpret_cast(this->m_text); + } + + /* 0000 */ std::uint8_t m_text[Length]; + bool m_encrypted; +}; + +template <> +const char* EncryptedName<14, 0x3375B1C7DBB5FD55ULL>::Text(); +template <> +const char* EncryptedName<10, 0x4755C1355575FD37ULL>::Text(); + +#endif diff --git a/Source/Utility/GGHash.cpp b/Source/Utility/GGHash.cpp index 3f2bcc94..dc8bb9a3 100644 --- a/Source/Utility/GGHash.cpp +++ b/Source/Utility/GGHash.cpp @@ -1,7 +1,7 @@ #include "Utility/GGHash.h" #include "Utility/FileSignatureVerifier.h" -#include "Utility/MD5.h" +#include "Utility/Hash/MD5.h" #include #include diff --git a/Source/Utility/Hash/MD5.cpp b/Source/Utility/Hash/MD5.cpp index 308ffa5d..e7956b2d 100644 --- a/Source/Utility/Hash/MD5.cpp +++ b/Source/Utility/Hash/MD5.cpp @@ -6,12 +6,22 @@ namespace { // INLINED - inline std::uint32_t FoldDigest(const unsigned char* digest) { + __forceinline std::uint32_t FoldDigest(const unsigned char* digest) { return ((digest[0] ^ digest[1] ^ digest[2] ^ digest[3]) << 8) | (digest[4] ^ digest[5] ^ digest[6] ^ digest[7]) | ((digest[8] ^ digest[9] ^ digest[10] ^ digest[11]) << 16) | (static_cast(digest[12] ^ digest[13] ^ digest[14] ^ digest[15]) << 24); } + + // INLINED + __forceinline void Encode(unsigned char* output, const std::uint32_t* input, std::uint32_t length) { + for (std::uint32_t i = 0; i < length / 4; ++i) { + output[i * 4] = static_cast(input[i] & 0xFF); + output[i * 4 + 1] = static_cast((input[i] >> 8) & 0xFF); + output[i * 4 + 2] = static_cast((input[i] >> 16) & 0xFF); + output[i * 4 + 3] = static_cast((input[i] >> 24) & 0xFF); + } + } } // OFFSET: 0x00401C40 @@ -19,8 +29,32 @@ namespace { MD5::MD5() { } +// OFFSET: 0x00401C50 +// FUNCTION: fn_00122 +MD5::~MD5() { +} +// OFFSET: 0x00401C60 +// FUNCTION: fn_00123 +const unsigned char* MD5::Decode(std::uint32_t* output, const unsigned char* input, std::uint32_t count) { + do { + *output++ = input[0] | ((input[1] | ((input[2] | (static_cast(input[3]) << 8)) << 8)) << 8); + input += 4; + } while (--count != 0); + return input; +} +// OFFSET: 0x00401CA0 +// FUNCTION: fn_00124 +int MD5::Initialize() { + m_state[0] = 0x67452301; + m_state[1] = 0xEFCDAB89; + m_state[2] = 0x98BADCFE; + m_state[3] = 0x10325476; + m_byteCount[0] = 0; + m_byteCount[1] = 0; + return 0; +} #define MD5_F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) #define MD5_F2(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) @@ -31,6 +65,88 @@ MD5::MD5() { (a) = (((a) << (s)) | ((a) >> (32 - (s)))) + (b); \ } while (0) +// OFFSET: 0x00401CD0 +// FUNCTION: fn_00125 +std::uint32_t* MD5::Transform(std::uint32_t* state, const std::uint32_t* input) { + std::uint32_t a = state[0]; + std::uint32_t b = state[1]; + std::uint32_t c = state[2]; + std::uint32_t d = state[3]; + + MD5_STEP(MD5_F1, a, b, c, d, input[0], 7, 0xD76AA478); + MD5_STEP(MD5_F1, d, a, b, c, input[1], 12, 0xE8C7B756); + MD5_STEP(MD5_F1, c, d, a, b, input[2], 17, 0x242070DB); + MD5_STEP(MD5_F1, b, c, d, a, input[3], 22, 0xC1BDCEEE); + MD5_STEP(MD5_F1, a, b, c, d, input[4], 7, 0xF57C0FAF); + MD5_STEP(MD5_F1, d, a, b, c, input[5], 12, 0x4787C62A); + MD5_STEP(MD5_F1, c, d, a, b, input[6], 17, 0xA8304613); + MD5_STEP(MD5_F1, b, c, d, a, input[7], 22, 0xFD469501); + MD5_STEP(MD5_F1, a, b, c, d, input[8], 7, 0x698098D8); + MD5_STEP(MD5_F1, d, a, b, c, input[9], 12, 0x8B44F7AF); + MD5_STEP(MD5_F1, c, d, a, b, input[10], 17, 0xFFFF5BB1); + MD5_STEP(MD5_F1, b, c, d, a, input[11], 22, 0x895CD7BE); + MD5_STEP(MD5_F1, a, b, c, d, input[12], 7, 0x6B901122); + MD5_STEP(MD5_F1, d, a, b, c, input[13], 12, 0xFD987193); + MD5_STEP(MD5_F1, c, d, a, b, input[14], 17, 0xA679438E); + MD5_STEP(MD5_F1, b, c, d, a, input[15], 22, 0x49B40821); + + MD5_STEP(MD5_F2, a, b, c, d, input[1], 5, 0xF61E2562); + MD5_STEP(MD5_F2, d, a, b, c, input[6], 9, 0xC040B340); + MD5_STEP(MD5_F2, c, d, a, b, input[11], 14, 0x265E5A51); + MD5_STEP(MD5_F2, b, c, d, a, input[0], 20, 0xE9B6C7AA); + MD5_STEP(MD5_F2, a, b, c, d, input[5], 5, 0xD62F105D); + MD5_STEP(MD5_F2, d, a, b, c, input[10], 9, 0x02441453); + MD5_STEP(MD5_F2, c, d, a, b, input[15], 14, 0xD8A1E681); + MD5_STEP(MD5_F2, b, c, d, a, input[4], 20, 0xE7D3FBC8); + MD5_STEP(MD5_F2, a, b, c, d, input[9], 5, 0x21E1CDE6); + MD5_STEP(MD5_F2, d, a, b, c, input[14], 9, 0xC33707D6); + MD5_STEP(MD5_F2, c, d, a, b, input[3], 14, 0xF4D50D87); + MD5_STEP(MD5_F2, b, c, d, a, input[8], 20, 0x455A14ED); + MD5_STEP(MD5_F2, a, b, c, d, input[13], 5, 0xA9E3E905); + MD5_STEP(MD5_F2, d, a, b, c, input[2], 9, 0xFCEFA3F8); + MD5_STEP(MD5_F2, c, d, a, b, input[7], 14, 0x676F02D9); + MD5_STEP(MD5_F2, b, c, d, a, input[12], 20, 0x8D2A4C8A); + + MD5_STEP(MD5_F3, a, b, c, d, input[5], 4, 0xFFFA3942); + MD5_STEP(MD5_F3, d, a, b, c, input[8], 11, 0x8771F681); + MD5_STEP(MD5_F3, c, d, a, b, input[11], 16, 0x6D9D6122); + MD5_STEP(MD5_F3, b, c, d, a, input[14], 23, 0xFDE5380C); + MD5_STEP(MD5_F3, a, b, c, d, input[1], 4, 0xA4BEEA44); + MD5_STEP(MD5_F3, d, a, b, c, input[4], 11, 0x4BDECFA9); + MD5_STEP(MD5_F3, c, d, a, b, input[7], 16, 0xF6BB4B60); + MD5_STEP(MD5_F3, b, c, d, a, input[10], 23, 0xBEBFBC70); + MD5_STEP(MD5_F3, a, b, c, d, input[13], 4, 0x289B7EC6); + MD5_STEP(MD5_F3, d, a, b, c, input[0], 11, 0xEAA127FA); + MD5_STEP(MD5_F3, c, d, a, b, input[3], 16, 0xD4EF3085); + MD5_STEP(MD5_F3, b, c, d, a, input[6], 23, 0x04881D05); + MD5_STEP(MD5_F3, a, b, c, d, input[9], 4, 0xD9D4D039); + MD5_STEP(MD5_F3, d, a, b, c, input[12], 11, 0xE6DB99E5); + MD5_STEP(MD5_F3, c, d, a, b, input[15], 16, 0x1FA27CF8); + MD5_STEP(MD5_F3, b, c, d, a, input[2], 23, 0xC4AC5665); + + MD5_STEP(MD5_F4, a, b, c, d, input[0], 6, 0xF4292244); + MD5_STEP(MD5_F4, d, a, b, c, input[7], 10, 0x432AFF97); + MD5_STEP(MD5_F4, c, d, a, b, input[14], 15, 0xAB9423A7); + MD5_STEP(MD5_F4, b, c, d, a, input[5], 21, 0xFC93A039); + MD5_STEP(MD5_F4, a, b, c, d, input[12], 6, 0x655B59C3); + MD5_STEP(MD5_F4, d, a, b, c, input[3], 10, 0x8F0CCC92); + MD5_STEP(MD5_F4, c, d, a, b, input[10], 15, 0xFFEFF47D); + MD5_STEP(MD5_F4, b, c, d, a, input[1], 21, 0x85845DD1); + MD5_STEP(MD5_F4, a, b, c, d, input[8], 6, 0x6FA87E4F); + MD5_STEP(MD5_F4, d, a, b, c, input[15], 10, 0xFE2CE6E0); + MD5_STEP(MD5_F4, c, d, a, b, input[6], 15, 0xA3014314); + MD5_STEP(MD5_F4, b, c, d, a, input[13], 21, 0x4E0811A1); + MD5_STEP(MD5_F4, a, b, c, d, input[4], 6, 0xF7537E82); + MD5_STEP(MD5_F4, d, a, b, c, input[11], 10, 0xBD3AF235); + MD5_STEP(MD5_F4, c, d, a, b, input[2], 15, 0x2AD7D2BB); + MD5_STEP(MD5_F4, b, c, d, a, input[9], 21, 0xEB86D391); + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + return state; +} #undef MD5_STEP #undef MD5_F4 @@ -38,12 +154,169 @@ MD5::MD5() { #undef MD5_F2 #undef MD5_F1 +// OFFSET: 0x00402360 +// FUNCTION: fn_00126 +__declspec(noinline) void MD5::Update(const unsigned char* input, std::uint32_t length) { + std::uint32_t buffered = m_byteCount[0]; + m_byteCount[0] = buffered + length; + if (m_byteCount[0] < buffered) { + ++m_byteCount[1]; + } + buffered &= 63; + if (64 - buffered > length) { + std::memcpy(m_buffer + buffered, input, length); + return; + } + if (buffered != 0) { + std::memcpy(m_buffer + buffered, input, 64 - buffered); + Decode(m_words, m_buffer, 16); + Transform(m_state, m_words); + input += 64 - buffered; + length += buffered - 64; + } + while (length >= 64) { + Decode(m_words, input, 16); + Transform(m_state, m_words); + input += 64; + length -= 64; + } + if (length != 0) { + std::memcpy(m_buffer, input, length); + } +} +// OFFSET: 0x00402420 +// FUNCTION: fn_00127 +__declspec(noinline) unsigned char* MD5::Finalize() { + const std::uint32_t buffered = m_byteCount[0] & 63; + unsigned char* padding = m_buffer + buffered; + *padding++ = 0x80; + std::uint32_t remaining = 63 - buffered; + if (remaining < 8) { + std::memset(padding, 0, remaining); + Decode(m_words, m_buffer, 16); + Transform(m_state, m_words); + padding = m_buffer; + remaining = 64; + } + std::memset(padding, 0, remaining - 8); + Decode(m_words, m_buffer, 14); + m_words[14] = m_byteCount[0] << 3; + m_words[15] = (m_byteCount[1] << 3) | (m_byteCount[0] >> 29); + Transform(m_state, m_words); + unsigned char* digest = reinterpret_cast(m_state); + Encode(digest, m_state, 16); + return digest; +} +// OFFSET: 0x00402520 +// FUNCTION: fn_00128 +__declspec(noinline) unsigned char* MD5::DigestBuffer(const unsigned char* input, std::uint32_t length, unsigned char* digest) { + Initialize(); + Update(input, length); + Finalize(); + for (std::uint32_t i = 0; i < 4; ++i) { + std::memcpy(digest + i * sizeof(std::uint32_t), &m_state[i], sizeof(std::uint32_t)); + } + return digest; +} + +// OFFSET: 0x00402580 +// FUNCTION: fn_00129 +std::uint32_t MD5::HashBuffer(const unsigned char* input, std::uint32_t length) { + unsigned char digest[16] = {}; + DigestBuffer(input, length, digest); + return FoldDigest(digest); +} + +// OFFSET: 0x00402640 +// FUNCTION: fn_00130 +std::uint32_t MD5::HashString(const char* text) { + unsigned char digest[16] = {}; + const char* end = text; + do { + ++end; + } while (end[-1] != '\0'); + DigestBuffer(reinterpret_cast(text), static_cast(end - text - 1), digest); + return FoldDigest(digest); +} + +// OFFSET: 0x00402710 +// FUNCTION: fn_00131 +std::uint32_t MD5::HashString(const wchar_t* text) { + char converted[260]; + WideCharToMultiByte(CP_ACP, 0, text, -1, converted, 260, nullptr, nullptr); + return HashString(converted); +} + +// OFFSET: 0x00402770 +// FUNCTION: fn_00132 +__declspec(noinline) std::uint32_t MD5::HashFile(const wchar_t* filename) { + if (filename == nullptr || *filename == 0) { + return 0; + } + + HANDLE file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (file == INVALID_HANDLE_VALUE) { + return 0; + } + + std::uint32_t result = 0; + LARGE_INTEGER size; + if (!GetFileSizeEx(file, &size)) { + return result; + } + if (size.QuadPart > 500000000) { + size.QuadPart = 500000000; + } + if (size.QuadPart == 0) { + return 0; + } + + HANDLE mapping = CreateFileMappingW(file, nullptr, PAGE_READONLY, size.HighPart, size.LowPart, nullptr); + if (mapping != nullptr) { + const unsigned char* view = static_cast(MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, size.LowPart)); + if (view != nullptr) { + unsigned char digest[16] = {}; + DigestBuffer(view, size.LowPart, digest); + result = FoldDigest(digest); + UnmapViewOfFile(view); + } + CloseHandle(mapping); + } + CloseHandle(file); + return result; +} + +// OFFSET: 0x004029D0 +// FUNCTION: fn_00133 +std::uint32_t MD5::HashStringLower(const char* text) { + char lowered[260]; + strcpy_s(lowered, 260, text); + _strlwr_s(lowered, 260); + return HashString(lowered); +} + +// OFFSET: 0x00402A40 +// FUNCTION: fn_00134 +std::uint32_t MD5::HashStringLower(const wchar_t* text) { + wchar_t lowered[260]; + wcscpy_s(lowered, 260, text); + _wcslwr_s(lowered, 260); + return HashString(lowered); +} + +// OFFSET: 0x00402AB0 +// FUNCTION: fn_00135 +std::uint32_t MD5::HashFile(const char* filename) { + wchar_t converted[260]; + MultiByteToWideChar(CP_ACP, 0, filename, -1, converted, 260); + return HashFile(converted); +}