From 2e025fd0cf09d7a166a60e74645ffafe5003a047 Mon Sep 17 00:00:00 2001 From: k0t9i Date: Thu, 19 Oct 2023 10:04:52 +0400 Subject: [PATCH] feat: add some low level error handling --- L2BotDll/Transports/NamedPipe.h | 16 +-- .../Versions/Interlude/GameStructs/FName.cpp | 16 ++- .../GameStructs/GameEngineWrapper.cpp | 4 +- .../GameStructs/L2GameDataWrapper.cpp | 30 ++-- .../Interlude/GameStructs/L2ParamStack.cpp | 63 +++++++-- .../GameStructs/NetworkHandlerWrapper.cpp | 129 +++++++++++++----- .../Repositories/AbnormalEffectRepository.h | 5 +- .../Interlude/Repositories/ItemRepository.h | 5 +- .../Interlude/Repositories/SkillRepository.h | 9 +- 9 files changed, 203 insertions(+), 74 deletions(-) diff --git a/L2BotDll/Transports/NamedPipe.h b/L2BotDll/Transports/NamedPipe.h index b731dfe..c033d5c 100644 --- a/L2BotDll/Transports/NamedPipe.h +++ b/L2BotDll/Transports/NamedPipe.h @@ -40,7 +40,7 @@ public: if (m_Pipe == INVALID_HANDLE_VALUE) { - throw RuntimeException(std::format(L"cannot create the pipe {}: {}", m_PipeName, GetLastError())); + throw CriticalRuntimeException(std::format(L"cannot create the pipe {}: {}", m_PipeName, GetLastError())); } } else @@ -83,13 +83,13 @@ public: if (!overlappedResult) { m_Connected = false; - throw RuntimeException(std::format(L"cannot get overlapped result for the pipe {} when writing", m_PipeName)); + throw CriticalRuntimeException(std::format(L"cannot get overlapped result for the pipe {} when writing", m_PipeName)); } } else { m_Connected = false; - throw RuntimeException(std::format(L"cannot write to the pipe {}: {}", m_PipeName, lastError)); + throw CriticalRuntimeException(std::format(L"cannot write to the pipe {}: {}", m_PipeName, lastError)); } } } @@ -116,13 +116,13 @@ public: if (!overlappedResult) { m_Connected = false; - throw RuntimeException(std::format(L"cannot get overlapped result for the pipe {} when reading", m_PipeName)); + throw CriticalRuntimeException(std::format(L"cannot get overlapped result for the pipe {} when reading", m_PipeName)); } } else { m_Connected = false; - throw RuntimeException(std::format(L"cannot read from the pipe {}: {}", m_PipeName, lastError)); + throw CriticalRuntimeException(std::format(L"cannot read from the pipe {}: {}", m_PipeName, lastError)); } } @@ -151,7 +151,7 @@ private: const bool connected = ConnectNamedPipe(m_Pipe, &m_ConntectingOverlapped) == 0; if (!connected) { - throw RuntimeException(std::format(L"cannot connect the pipe {}: {}", m_PipeName, GetLastError())); + throw CriticalRuntimeException(std::format(L"cannot connect the pipe {}: {}", m_PipeName, GetLastError())); } switch (GetLastError()) @@ -164,7 +164,7 @@ private: if (SetEvent(m_ConntectingOverlapped.hEvent)) break; default: - throw RuntimeException(std::format(L"an error has occurred when connecting to the pipe ""{}"": {}", m_PipeName, GetLastError())); + throw CriticalRuntimeException(std::format(L"an error has occurred when connecting to the pipe ""{}"": {}", m_PipeName, GetLastError())); } } @@ -175,7 +175,7 @@ private: overlapped.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); if (overlapped.hEvent == NULL) { - throw RuntimeException(std::format(L"cannot create overlapped for the pipe {}: {}", m_PipeName, GetLastError())); + throw CriticalRuntimeException(std::format(L"cannot create overlapped for the pipe {}: {}", m_PipeName, GetLastError())); } overlapped.Offset = 0; overlapped.OffsetHigh = 0; diff --git a/L2BotDll/Versions/Interlude/GameStructs/FName.cpp b/L2BotDll/Versions/Interlude/GameStructs/FName.cpp index 143ddc2..5bb30cf 100644 --- a/L2BotDll/Versions/Interlude/GameStructs/FName.cpp +++ b/L2BotDll/Versions/Interlude/GameStructs/FName.cpp @@ -1,17 +1,25 @@ #include "pch.h" #include "FName.h" +#include "Domain/Exceptions.h" + +using namespace L2Bot::Domain; namespace Interlude { FNameEntry* (__cdecl* FName::__GetEntry)(int) = 0; - //todo exception(?) FNameEntry* FName::GetEntry(int index) const { - if (__GetEntry) { - return(*__GetEntry)(index); + __try { + if (__GetEntry) { + return(*__GetEntry)(index); + } + return 0; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"FName::GetEntry failed"); } - return 0; } void FName::Init(HMODULE hModule) diff --git a/L2BotDll/Versions/Interlude/GameStructs/GameEngineWrapper.cpp b/L2BotDll/Versions/Interlude/GameStructs/GameEngineWrapper.cpp index 6c2bfad..019152e 100644 --- a/L2BotDll/Versions/Interlude/GameStructs/GameEngineWrapper.cpp +++ b/L2BotDll/Versions/Interlude/GameStructs/GameEngineWrapper.cpp @@ -78,6 +78,7 @@ namespace Interlude (FARPROC&)__OnDie = (FARPROC)splice( GetProcAddress(hModule, "?OnDie@UGameEngine@@UAEHPAUUser@@AAVL2ParamStack@@@Z"), __OnDie_hook ); + Services::ServiceLocator::GetInstance().GetLogger()->Info(L"UGameEngine hooks initialized"); } void GameEngineWrapper::Restore() @@ -94,6 +95,7 @@ namespace Interlude restore((void*&)__GetMaxTickRate); restore((void*&)__OnDie); restore((void*&)__Tick); + Services::ServiceLocator::GetInstance().GetLogger()->Info(L"UGameEngine hooks restored"); } void __fastcall GameEngineWrapper::__OnSkillListPacket_hook(GameEngine* This, uint32_t, L2ParamStack& stack) @@ -181,7 +183,7 @@ namespace Interlude if (_target == 0) { _target = This; - Services::ServiceLocator::GetInstance().GetLogger()->Info(L"UGameEngine {:#010x} obtained", (int)_target); + Services::ServiceLocator::GetInstance().GetLogger()->Info(L"UGameEngine pointer {:#010x} obtained", (int)_target); } (*__Tick)(This, deltaTime); diff --git a/L2BotDll/Versions/Interlude/GameStructs/L2GameDataWrapper.cpp b/L2BotDll/Versions/Interlude/GameStructs/L2GameDataWrapper.cpp index 3b361f4..e3571f2 100644 --- a/L2BotDll/Versions/Interlude/GameStructs/L2GameDataWrapper.cpp +++ b/L2BotDll/Versions/Interlude/GameStructs/L2GameDataWrapper.cpp @@ -3,6 +3,7 @@ #include "L2GameDataWrapper.h" #include "ProcessManipulation.h" #include "Domain/Services/ServiceLocator.h" +#include "Domain/Exceptions.h" using namespace L2Bot::Domain; @@ -23,40 +24,53 @@ namespace Interlude (FARPROC&)__GetItemData = GetProcAddress(hModule, "?GetItemData@FL2GameData@@QAEPAVFL2ItemDataBase@@H@Z"); (FARPROC&)__GetMSData = GetProcAddress(hModule, "?GetMSData@FL2GameData@@QAEPAUFL2MagicSkillData@@HH@Z"); + Services::ServiceLocator::GetInstance().GetLogger()->Info(L"FL2GameData hooks initialized"); } void L2GameDataWrapper::Restore() { restore(originalInitAddress); + Services::ServiceLocator::GetInstance().GetLogger()->Info(L"FL2GameData hooks restored"); } - //todo exception(?) FL2ItemDataBase* L2GameDataWrapper::GetItemData(int itemId) const { - if (__GetItemData && _target) { - return (*__GetItemData)(_target, itemId); + __try { + if (__GetItemData && _target) { + return (*__GetItemData)(_target, itemId); + } + return 0; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"FL2GameData::GetItemData failed"); } - return 0; } FL2MagicSkillData* L2GameDataWrapper::GetMSData(int skillId, int level) const { - if (__GetMSData && _target) { - return (*__GetMSData)(_target, skillId, level); + __try { + if (__GetMSData && _target) { + return (*__GetMSData)(_target, skillId, level); + } + return 0; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"FL2GameData::GetMSData failed"); } - return 0; } int __fastcall L2GameDataWrapper::__Init_hook(L2GameData* This, int, int unk, int unk1) { if (_target == 0) { _target = This; + Services::ServiceLocator::GetInstance().GetLogger()->Info(L"FL2GameData pointer {:#010x} obtained", (int)_target); InjectLibrary::StopCurrentProcess(); restore(originalInitAddress); InjectLibrary::StartCurrentProcess(); - Services::ServiceLocator::GetInstance().GetLogger()->Info(L"FL2GameData {:#010x} obtained", (int)_target); return (*__Init)(This, unk, unk1); } diff --git a/L2BotDll/Versions/Interlude/GameStructs/L2ParamStack.cpp b/L2BotDll/Versions/Interlude/GameStructs/L2ParamStack.cpp index 5556a93..25deb2f 100644 --- a/L2BotDll/Versions/Interlude/GameStructs/L2ParamStack.cpp +++ b/L2BotDll/Versions/Interlude/GameStructs/L2ParamStack.cpp @@ -1,5 +1,8 @@ #include "pch.h" #include "L2ParamStack.h" +#include "Domain/Exceptions.h" + +using namespace L2Bot::Domain; namespace Interlude { @@ -15,50 +18,94 @@ namespace Interlude L2ParamStack::L2ParamStack(int size) { Init(); - (*__Ctor)(this, size); + __try { + (*__Ctor)(this, size); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"L2ParamStack::constructor failed"); + } } L2ParamStack::~L2ParamStack() { Init(); - (*__Dtor)(this); + __try { + (*__Dtor)(this); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"L2ParamStack::desctructor failed"); + } } int L2ParamStack::PushBack(void* val) { Init(); - return (*__PushBack)(this, val); + __try { + return (*__PushBack)(this, val); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"L2ParamStack::PushBack failed"); + } } void* L2ParamStack::Top() { Init(); - return (*__Top)(this); + __try { + return (*__Top)(this); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"L2ParamStack::Top failed"); + } } void** L2ParamStack::GetBuffer() { Init(); - return (__GetBuffer)(this); + __try { + return (__GetBuffer)(this); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"L2ParamStack::GetBuffer failed"); + } } int L2ParamStack::GetBufferSize() { Init(); - return (__GetBufferSize)(this); + __try { + return (__GetBufferSize)(this); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"L2ParamStack::GetBufferSize failed"); + } } int L2ParamStack::GetTotalBufferSize() { Init(); - return (__GetTotalBufferSize)(this); + __try { + return (__GetTotalBufferSize)(this); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"L2ParamStack::GetTotalBufferSize failed"); + } } void L2ParamStack::Init() { - // todo exceptions if (_hModule == 0) { _hModule = GetModuleHandleA("Core.dll"); + if (!_hModule) { + throw CriticalRuntimeException(L"cannot load Core.dll"); + } (FARPROC&)__Ctor = GetProcAddress(_hModule, "??0L2ParamStack@@QAE@H@Z"); (FARPROC&)__Dtor = GetProcAddress(_hModule, "??1L2ParamStack@@QAE@XZ"); (FARPROC&)__PushBack = GetProcAddress(_hModule, "?PushBack@L2ParamStack@@QAEHPAX@Z"); diff --git a/L2BotDll/Versions/Interlude/GameStructs/NetworkHandlerWrapper.cpp b/L2BotDll/Versions/Interlude/GameStructs/NetworkHandlerWrapper.cpp index 9cb8157..e4e2e74 100644 --- a/L2BotDll/Versions/Interlude/GameStructs/NetworkHandlerWrapper.cpp +++ b/L2BotDll/Versions/Interlude/GameStructs/NetworkHandlerWrapper.cpp @@ -4,6 +4,7 @@ #include "Domain/Events/SpoiledEvent.h" #include "ProcessManipulation.h" #include "Domain/Services/ServiceLocator.h" +#include "Domain/Exceptions.h" using namespace L2Bot::Domain; @@ -26,22 +27,32 @@ namespace Interlude void(__thiscall* NetworkHandlerWrapper::__RequestAutoSoulShot)(NetworkHandler*, L2ParamStack&) = 0; void(__thiscall* NetworkHandlerWrapper::__ChangeWaitType)(NetworkHandler*, int) = 0; - //todo exception Item* NetworkHandlerWrapper::GetNextItem(float_t radius, int prevId) const { - if (__GetNextItem && _target) { - return (*__GetNextItem)(_target, radius, prevId); + __try { + if (__GetNextItem && _target) { + return (*__GetNextItem)(_target, radius, prevId); + } + return 0; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::GetNextItem failed"); } - return 0; } - //todo exception User* NetworkHandlerWrapper::GetNextCreature(float_t radius, int prevId) const { - if (__GetNextCreature && _target) { - return (*__GetNextCreature)(_target, radius, prevId); + __try { + if (__GetNextCreature && _target) { + return (*__GetNextCreature)(_target, radius, prevId); + } + return 0; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::GetNextCreature failed"); } - return 0; } User* NetworkHandlerWrapper::GetHero() const @@ -63,69 +74,123 @@ namespace Interlude User* NetworkHandlerWrapper::GetUser(int objectId) const { - if (__GetUser && _target) { - return (*__GetUser)(_target, objectId); + __try { + if (__GetUser && _target) { + return (*__GetUser)(_target, objectId); + } + return 0; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::GetUser failed"); } - return 0; } Item* NetworkHandlerWrapper::GetItem(int objectId) const { - if (__GetItem && _target) { - return (*__GetItem)(_target, objectId); + __try { + if (__GetItem && _target) { + return (*__GetItem)(_target, objectId); + } + return 0; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::GetItem failed"); } - return 0; } void NetworkHandlerWrapper::MTL(APawn* self, L2::FVector dst, L2::FVector src, void* terrainInfo, int unk1) const { - if (__MTL && _target) { - (*__MTL)(_target, self, dst, src, terrainInfo, unk1); + __try { + if (__MTL && _target) { + (*__MTL)(_target, self, dst, src, terrainInfo, unk1); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::MTL failed"); } } void NetworkHandlerWrapper::Action(int objectId, L2::FVector objectLocation, int unk) const { - if (__Action && _target) { - (*__Action)(_target, objectId, objectLocation, unk); + __try { + if (__Action && _target) { + (*__Action)(_target, objectId, objectLocation, unk); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::Action failed"); } } void NetworkHandlerWrapper::RequestMagicSkillUse(L2ParamStack& stack) const { - if (__RequestMagicSkillUse && _target) { - (*__RequestMagicSkillUse)(_target, stack); + __try { + if (__RequestMagicSkillUse && _target) { + (*__RequestMagicSkillUse)(_target, stack); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::RequestMagicSkillUse failed"); } } int NetworkHandlerWrapper::RequestUseItem(L2ParamStack& stack) const { - if (__RequestUseItem && _target) { - return (*__RequestUseItem)(_target, stack); + __try { + if (__RequestUseItem && _target) { + return (*__RequestUseItem)(_target, stack); + } + return 0; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::RequestUseItem failed"); } - return 0; } void NetworkHandlerWrapper::RequestAutoSoulShot(L2ParamStack& stack) const { - if (__RequestAutoSoulShot && _target) { - (*__RequestAutoSoulShot)(_target, stack); + __try { + if (__RequestAutoSoulShot && _target) { + (*__RequestAutoSoulShot)(_target, stack); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::RequestAutoSoulShot failed"); } } void NetworkHandlerWrapper::ChangeWaitType(int type) const { - if (__ChangeWaitType && _target) { - (*__ChangeWaitType)(_target, type); + __try { + if (__ChangeWaitType && _target) { + (*__ChangeWaitType)(_target, type); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::ChangeWaitType failed"); } } int NetworkHandlerWrapper::RequestItemList() const { - if (__RequestItemList && _target) { - return (*__RequestItemList)(_target); + __try { + if (__RequestItemList && _target) { + return (*__RequestItemList)(_target); + } + return 0; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + throw CriticalRuntimeException(L"UNetworkHandler::RequestItemList failed"); } - return 0; } void NetworkHandlerWrapper::Init(HMODULE hModule) @@ -149,24 +214,26 @@ namespace Interlude (FARPROC&)__AddNetworkQueue = (FARPROC)splice( GetProcAddress(hModule, "?AddNetworkQueue@UNetworkHandler@@UAEHPAUNetworkPacket@@@Z"), __AddNetworkQueue_hook ); + Services::ServiceLocator::GetInstance().GetLogger()->Info(L"UNetworkHandler hooks initialized"); } void NetworkHandlerWrapper::Restore() { restore(originalInitAddress); restore((void*&)__AddNetworkQueue); + Services::ServiceLocator::GetInstance().GetLogger()->Info(L"UNetworkHandler hooks restored"); } void __fastcall NetworkHandlerWrapper::__Init_hook(NetworkHandler* This, int /*edx*/, float unk) { if (_target == 0) { _target = This; + Services::ServiceLocator::GetInstance().GetLogger()->Info(L"UNetworkHandler pointer {:#010x} obtained", (int)_target); InjectLibrary::StopCurrentProcess(); restore(originalInitAddress); InjectLibrary::StartCurrentProcess(); - Services::ServiceLocator::GetInstance().GetLogger()->Info(L"UNetworkHandler {:#010x} obtained", (int)_target); (*__Init)(This, unk); } } diff --git a/L2BotDll/Versions/Interlude/Repositories/AbnormalEffectRepository.h b/L2BotDll/Versions/Interlude/Repositories/AbnormalEffectRepository.h index 0d1c574..aef01c7 100644 --- a/L2BotDll/Versions/Interlude/Repositories/AbnormalEffectRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/AbnormalEffectRepository.h @@ -30,10 +30,7 @@ namespace Interlude } AbnormalEffectRepository() = delete; - virtual ~AbnormalEffectRepository() - { - Reset(); - } + virtual ~AbnormalEffectRepository() = default; void Init() override { diff --git a/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h b/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h index 7fd1885..a4e55d7 100644 --- a/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h @@ -166,10 +166,7 @@ namespace Interlude } ItemRepository() = delete; - virtual ~ItemRepository() - { - Reset(); - } + virtual ~ItemRepository() = default; void Reset() override { diff --git a/L2BotDll/Versions/Interlude/Repositories/SkillRepository.h b/L2BotDll/Versions/Interlude/Repositories/SkillRepository.h index 0bea167..8fc79d0 100644 --- a/L2BotDll/Versions/Interlude/Repositories/SkillRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/SkillRepository.h @@ -38,14 +38,13 @@ namespace Interlude } SkillRepository() = delete; - virtual ~SkillRepository() - { - Reset(); - } + virtual ~SkillRepository() = default; void Reset() override { std::shared_lock(m_Mutex); + m_CastingTimers.StopAll(); + m_ReloadingTimers.StopAll(); m_Skills.clear(); m_IsNewCycle = false; m_NewSkills.clear(); @@ -100,8 +99,6 @@ namespace Interlude if (evt.GetName() == Events::HeroDeletedEvent::name) { Reset(); - m_CastingTimers.StopAll(); - m_ReloadingTimers.StopAll(); } }