From 787f4969eda9f09b982c16455e99a0f2ea2b37a8 Mon Sep 17 00:00:00 2001 From: k0t9i Date: Mon, 16 Oct 2023 00:03:43 +0400 Subject: [PATCH] refactor: remove unnecessary classes --- L2BotCore/Domain/Entities/AbnormalEffect.h | 61 +-- L2BotCore/Domain/Entities/ArmorItem.h | 140 ++--- L2BotCore/Domain/Entities/BaseItem.h | 91 ++-- L2BotCore/Domain/Entities/ChatMessage.cpp | 7 + .../{ValueObjects => Entities}/ChatMessage.h | 31 +- L2BotCore/Domain/Entities/Drop.h | 54 +- L2BotCore/Domain/Entities/EntityInterface.h | 8 +- L2BotCore/Domain/Entities/EtcItem.h | 87 ++- L2BotCore/Domain/Entities/Hashable.h | 15 + L2BotCore/Domain/Entities/Hero.h | 170 +++--- L2BotCore/Domain/Entities/NPC.h | 97 ++-- L2BotCore/Domain/Entities/Player.h | 76 +-- L2BotCore/Domain/Entities/ShieldItem.h | 113 ++-- L2BotCore/Domain/Entities/Skill.h | 237 +++------ L2BotCore/Domain/Entities/WeaponItem.h | 178 +++---- L2BotCore/Domain/Entities/WorldObject.h | 38 +- L2BotCore/Domain/Helpers/HashCombiner.cpp | 14 + L2BotCore/Domain/Helpers/HashCombiner.h | 9 + .../ChatMessageRepositoryInterface.h | 12 - .../Repositories/EntityRepositoryInterface.h | 8 +- .../Domain/Services/ChatMessageHandler.h | 25 - L2BotCore/Domain/Services/EntityHandler.h | 34 -- L2BotCore/Domain/Services/UnitOfWork.h | 61 +++ .../Domain/ValueObjects/ExperienceInfo.h | 13 +- L2BotCore/Domain/ValueObjects/FullName.h | 12 +- L2BotCore/Domain/ValueObjects/InventoryInfo.h | 15 +- .../Domain/ValueObjects/PermanentStats.h | 21 +- L2BotCore/Domain/ValueObjects/Phenotype.h | 17 +- L2BotCore/Domain/ValueObjects/Reputation.h | 19 +- L2BotCore/Domain/ValueObjects/Transform.h | 16 +- L2BotCore/Domain/ValueObjects/VariableStats.h | 27 +- L2BotCore/Domain/ValueObjects/Vector3.h | 20 +- L2BotCore/Domain/ValueObjects/VitalStats.h | 21 +- L2BotCore/L2BotCore.vcxproj | 14 +- L2BotCore/L2BotCore.vcxproj.filters | 26 +- L2BotDll/L2BotDll.vcxproj | 1 - L2BotDll/L2BotDll.vcxproj.filters | 3 - L2BotDll/Services/EntityFinder.h | 85 --- L2BotDll/Services/WorldHandler.h | 115 ++-- .../Versions/GameStructs/FindObjectsTrait.h | 6 +- L2BotDll/Versions/Interlude/AbstractFactory.h | 25 +- .../Interlude/Factories/ChatMessageFactory.h | 8 +- .../Interlude/Factories/DropFactory.h | 43 +- .../Interlude/Factories/HeroFactory.h | 187 ++++--- .../Interlude/Factories/ItemFactory.h | 498 +++++++++++++----- .../Versions/Interlude/Factories/NPCFactory.h | 44 +- .../Interlude/Factories/PlayerFactory.h | 38 +- .../Interlude/Factories/SkillFactory.h | 40 +- .../Repositories/AbnormalEffectRepository.h | 79 ++- .../Repositories/ChatMessageRepository.h | 19 +- .../Interlude/Repositories/DropRepository.h | 35 +- .../Interlude/Repositories/HeroRepository.h | 53 +- .../Interlude/Repositories/ItemRepository.h | 50 +- .../Interlude/Repositories/NPCRepository.h | 44 +- .../Interlude/Repositories/PlayerRepository.h | 47 +- .../Interlude/Repositories/SkillRepository.h | 41 +- L2BotDll/Versions/VersionAbstractFactory.h | 3 +- 57 files changed, 1651 insertions(+), 1600 deletions(-) create mode 100644 L2BotCore/Domain/Entities/ChatMessage.cpp rename L2BotCore/Domain/{ValueObjects => Entities}/ChatMessage.h (55%) create mode 100644 L2BotCore/Domain/Entities/Hashable.h create mode 100644 L2BotCore/Domain/Helpers/HashCombiner.cpp create mode 100644 L2BotCore/Domain/Helpers/HashCombiner.h delete mode 100644 L2BotCore/Domain/Repositories/ChatMessageRepositoryInterface.h delete mode 100644 L2BotCore/Domain/Services/ChatMessageHandler.h delete mode 100644 L2BotCore/Domain/Services/EntityHandler.h create mode 100644 L2BotCore/Domain/Services/UnitOfWork.h delete mode 100644 L2BotDll/Services/EntityFinder.h diff --git a/L2BotCore/Domain/Entities/AbnormalEffect.h b/L2BotCore/Domain/Entities/AbnormalEffect.h index 68f21ce..bc17e9b 100644 --- a/L2BotCore/Domain/Entities/AbnormalEffect.h +++ b/L2BotCore/Domain/Entities/AbnormalEffect.h @@ -2,7 +2,9 @@ #include #include #include +#include #include "EntityInterface.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::Entities { @@ -14,29 +16,30 @@ namespace L2Bot::Domain::Entities return m_SkillId; } - void Update(const EntityInterface* other) override - { - const AbnormalEffect* casted = static_cast(other); - SaveState(); - - m_SkillId = casted->m_SkillId; - m_Level = casted->m_Level; - m_Name = casted->m_Name; - m_Description = casted->m_Description; - m_IconName = casted->m_IconName; + void Update( + const uint8_t level, + const std::wstring& name, + const std::wstring& description, + const std::wstring& iconName + ) { + m_Level = level; + m_Name = name; + m_Description = description; + m_IconName = iconName; } - void SaveState() override + const size_t GetHash() const override { - m_IsNewState = false; + return Helpers::CombineHashes({ + std::hash{}(m_SkillId), + std::hash{}(m_Level), + std::hash{}(m_Name), + std::hash{}(m_Description), + std::hash{}(m_IconName) + }); } - const bool IsEqual(const EntityInterface* other) const override + const std::string GetEntityName() const override { - const AbnormalEffect* casted = static_cast(other); - return m_SkillId == casted->m_SkillId && - m_Level == casted->m_Level && - m_Name == casted->m_Name && - m_Description == casted->m_Description && - m_IconName == casted->m_IconName; + return "abnormalEffect"; } const std::vector BuildSerializationNodes() const override @@ -45,13 +48,9 @@ namespace L2Bot::Domain::Entities result.push_back({ L"id", std::to_wstring(m_SkillId) }); result.push_back({ L"level", std::to_wstring(m_Level) }); - - if (m_IsNewState) - { - result.push_back({ L"name", m_Name }); - result.push_back({ L"iconName", m_IconName }); - result.push_back({ L"description", m_Description }); - } + result.push_back({ L"name", m_Name }); + result.push_back({ L"iconName", m_IconName }); + result.push_back({ L"description", m_Description }); return result; } @@ -72,15 +71,6 @@ namespace L2Bot::Domain::Entities } - AbnormalEffect(const AbnormalEffect* other) : - m_SkillId(other->m_SkillId), - m_Level(other->m_Level), - m_Name(other->m_Name), - m_Description(other->m_Description), - m_IconName(other->m_IconName) - { - } - AbnormalEffect() = default; virtual ~AbnormalEffect() = default; @@ -90,6 +80,5 @@ namespace L2Bot::Domain::Entities std::wstring m_Name = L""; std::wstring m_Description = L""; std::wstring m_IconName = L""; - bool m_IsNewState = true; }; } diff --git a/L2BotCore/Domain/Entities/ArmorItem.h b/L2BotCore/Domain/Entities/ArmorItem.h index eb18ace..0f31cd8 100644 --- a/L2BotCore/Domain/Entities/ArmorItem.h +++ b/L2BotCore/Domain/Entities/ArmorItem.h @@ -2,87 +2,75 @@ #include #include #include +#include #include "BaseItem.h" #include "../Enums/ArmorTypeEnum.h" #include "../Enums/CrystalTypeEnum.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::Entities { class ArmorItem : public BaseItem { public: - void Update(const EntityInterface* other) override - { - const ArmorItem* casted = static_cast(other); + void Update( + const uint32_t itemId, + const int32_t mana, + const std::wstring& name, + const std::wstring& iconName, + const std::wstring& description, + const uint16_t weight, + const bool isEquipped, + const uint16_t enchantLevel, + const Enums::ArmorTypeEnum armorType, + const Enums::CrystalTypeEnum crystalType, + const uint32_t pDefense, + const uint32_t mDefense, + const std::wstring& setEffect, + const std::wstring& addSetEffect, + const std::wstring& enchantEffect + ) { + BaseItem::Update(itemId, mana, name, iconName, description, weight); - BaseItem::Update(other); - - m_IsEquipped = casted->m_IsEquipped; - m_EnchantLevel = casted->m_EnchantLevel; - m_ArmorType = casted->m_ArmorType; - m_CrystalType = casted->m_CrystalType; - m_PDefense = casted->m_PDefense; - m_MDefense = casted->m_MDefense; - m_SetEffect = casted->m_SetEffect; - m_AddSetEffect = casted->m_AddSetEffect; - m_EnchantEffect = casted->m_EnchantEffect; + m_IsEquipped = isEquipped; + m_EnchantLevel = enchantLevel; + m_ArmorType = armorType; + m_CrystalType = crystalType; + m_PDefense = pDefense; + m_MDefense = mDefense; + m_SetEffect = setEffect; + m_AddSetEffect = addSetEffect; + m_EnchantEffect = enchantEffect; } - void SaveState() override + const size_t GetHash() const override { - BaseItem::SaveState(); - m_PrevState = - { - m_IsEquipped, - m_EnchantLevel, - m_PDefense, - m_MDefense, - false - }; - } - const bool IsEqual(const EntityInterface* other) const override - { - const ArmorItem* casted = static_cast(other); - return BaseItem::IsEqual(other) && - m_IsEquipped == casted->m_IsEquipped && - m_EnchantLevel == casted->m_EnchantLevel && - m_ArmorType == casted->m_ArmorType && - m_CrystalType == casted->m_CrystalType && - m_PDefense == casted->m_PDefense && - m_MDefense == casted->m_MDefense && - m_SetEffect == casted->m_SetEffect && - m_AddSetEffect == casted->m_AddSetEffect && - m_EnchantEffect == casted->m_EnchantEffect; + return Helpers::CombineHashes({ + BaseItem::GetHash(), + std::hash{}(m_IsEquipped), + std::hash{}(m_EnchantLevel), + std::hash{}(m_ArmorType), + std::hash{}(m_CrystalType), + std::hash{}(m_PDefense), + std::hash{}(m_MDefense), + std::hash{}(m_SetEffect), + std::hash{}(m_AddSetEffect), + std::hash{}(m_EnchantEffect) + }); } const std::vector BuildSerializationNodes() const override { std::vector result = BaseItem::BuildSerializationNodes(); - if (m_PrevState.isNewState) - { - result.push_back({ L"armorType", std::to_wstring(static_cast(m_ArmorType)) }); - result.push_back({ L"crystalType", std::to_wstring(static_cast(m_CrystalType)) }); - result.push_back({ L"setEffect", m_SetEffect }); - result.push_back({ L"addSetEffect", m_AddSetEffect }); - result.push_back({ L"enchantEffect", m_EnchantEffect }); - } - - if (m_PrevState.isNewState || m_IsEquipped != m_PrevState.isEquipped) - { - result.push_back({ L"isEquipped", std::to_wstring(m_IsEquipped) }); - } - if (m_PrevState.isNewState || m_EnchantLevel != m_PrevState.enchantLevel) - { - result.push_back({ L"enchantLevel", std::to_wstring(m_EnchantLevel) }); - } - if (m_PrevState.isNewState || m_PDefense != m_PrevState.pDefense) - { - result.push_back({ L"pDefense", std::to_wstring(m_PDefense) }); - } - if (m_PrevState.isNewState || m_MDefense != m_PrevState.mDefense) - { - result.push_back({ L"mDefense", std::to_wstring(m_MDefense) }); - } + result.push_back({ L"armorType", std::to_wstring(static_cast(m_ArmorType)) }); + result.push_back({ L"crystalType", std::to_wstring(static_cast(m_CrystalType)) }); + result.push_back({ L"setEffect", m_SetEffect }); + result.push_back({ L"addSetEffect", m_AddSetEffect }); + result.push_back({ L"enchantEffect", m_EnchantEffect }); + result.push_back({ L"isEquipped", std::to_wstring(m_IsEquipped) }); + result.push_back({ L"enchantLevel", std::to_wstring(m_EnchantLevel) }); + result.push_back({ L"pDefense", std::to_wstring(m_PDefense) }); + result.push_back({ L"mDefense", std::to_wstring(m_MDefense) }); return result; } @@ -128,34 +116,9 @@ namespace L2Bot::Domain::Entities { } - ArmorItem(const ArmorItem* other) : - BaseItem(other), - m_IsEquipped(other->m_IsEquipped), - m_EnchantLevel(other->m_EnchantLevel), - m_ArmorType(other->m_ArmorType), - m_CrystalType(other->m_CrystalType), - m_PDefense(other->m_PDefense), - m_MDefense(other->m_MDefense), - m_SetEffect(other->m_SetEffect), - m_AddSetEffect(other->m_AddSetEffect), - m_EnchantEffect(other->m_EnchantEffect) - { - } - ArmorItem() = default; virtual ~ArmorItem() = default; - private: - struct GetState - { - bool isEquipped = 0; - uint16_t enchantLevel = 0; - uint32_t pDefense = 0; - uint32_t mDefense = 0; - - bool isNewState = true; - }; - private: bool m_IsEquipped = 0; uint16_t m_EnchantLevel = 0; @@ -166,6 +129,5 @@ namespace L2Bot::Domain::Entities std::wstring m_SetEffect = L""; std::wstring m_AddSetEffect = L""; std::wstring m_EnchantEffect = L""; - GetState m_PrevState = GetState(); }; } diff --git a/L2BotCore/Domain/Entities/BaseItem.h b/L2BotCore/Domain/Entities/BaseItem.h index 427efe9..80f4bef 100644 --- a/L2BotCore/Domain/Entities/BaseItem.h +++ b/L2BotCore/Domain/Entities/BaseItem.h @@ -2,8 +2,10 @@ #include #include #include +#include #include "EntityInterface.h" #include "../Enums/ItemTypeEnum.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::Entities { @@ -18,40 +20,36 @@ namespace L2Bot::Domain::Entities { return m_ItemId; } - virtual void Update(const EntityInterface* other) override - { - const BaseItem* casted = static_cast(other); - SaveState(); - - m_ObjectId = casted->m_ObjectId; - m_ItemId = casted->m_ItemId; - m_Mana = casted->m_Mana; - m_Name = casted->m_Name; - m_IconName = casted->m_IconName; - m_Description = casted->m_Description; - m_Weight = casted->m_Weight; - m_Type = casted->m_Type; + void Update( + const uint32_t itemId, + const int32_t mana, + const std::wstring& name, + const std::wstring& iconName, + const std::wstring& description, + const uint16_t weight + ) { + m_ItemId = itemId; + m_Mana = mana; + m_Name = name; + m_IconName = iconName; + m_Description = description; + m_Weight = weight; } - virtual void SaveState() override + virtual const size_t GetHash() const override { - m_PrevState = - { - m_Mana, - m_Weight, - false - }; + return Helpers::CombineHashes({ + std::hash{}(m_ObjectId), + std::hash{}(m_ItemId), + std::hash{}(m_Mana), + std::hash{}(m_Name), + std::hash{}(m_Description), + std::hash{}(m_IconName), + std::hash{}(m_Weight) + }); } - virtual const bool IsEqual(const EntityInterface* other) const override + const std::string GetEntityName() const override { - const BaseItem* casted = static_cast(other); - return m_ObjectId == casted->m_ObjectId && - m_ItemId == casted->m_ItemId && - m_Mana == casted->m_Mana && - m_Name == casted->m_Name && - m_IconName == casted->m_IconName && - m_Description == casted->m_Description && - m_Weight == casted->m_Weight && - m_Type == casted->m_Type; + return "item"; } virtual const std::vector BuildSerializationNodes() const override @@ -60,23 +58,12 @@ namespace L2Bot::Domain::Entities result.push_back({ L"id", std::to_wstring(m_ObjectId) }); result.push_back({ L"itemId", std::to_wstring(m_ItemId) }); - - if (m_PrevState.isNewState) - { - result.push_back({ L"type", std::to_wstring(static_cast(m_Type))}); - result.push_back({ L"name", m_Name }); - result.push_back({ L"iconName", m_IconName }); - result.push_back({ L"description", m_Description }); - } - - if (m_PrevState.isNewState || m_Mana != m_PrevState.mana) - { - result.push_back({ L"mana", std::to_wstring(m_Mana) }); - } - if (m_PrevState.isNewState || m_Weight != m_PrevState.weight) - { - result.push_back({ L"weight", std::to_wstring(m_Weight) }); - } + result.push_back({ L"type", std::to_wstring(static_cast(m_Type)) }); + result.push_back({ L"name", m_Name }); + result.push_back({ L"iconName", m_IconName }); + result.push_back({ L"description", m_Description }); + result.push_back({ L"mana", std::to_wstring(m_Mana) }); + result.push_back({ L"weight", std::to_wstring(m_Weight) }); return result; } @@ -117,15 +104,6 @@ namespace L2Bot::Domain::Entities BaseItem() = default; virtual ~BaseItem() = default; - private: - struct GetState - { - int32_t mana = -1; - uint16_t weight = 0; - - bool isNewState = true; - }; - private: uint32_t m_ObjectId = 0; uint32_t m_ItemId = 0; @@ -135,6 +113,5 @@ namespace L2Bot::Domain::Entities std::wstring m_Description = L""; uint16_t m_Weight = 0; Enums::ItemTypeEnum m_Type = Enums::ItemTypeEnum::none; - GetState m_PrevState = GetState(); }; } diff --git a/L2BotCore/Domain/Entities/ChatMessage.cpp b/L2BotCore/Domain/Entities/ChatMessage.cpp new file mode 100644 index 0000000..33cbf78 --- /dev/null +++ b/L2BotCore/Domain/Entities/ChatMessage.cpp @@ -0,0 +1,7 @@ +#include "..\..\pch.h" +#include "ChatMessage.h" + +namespace L2Bot::Domain::Entities +{ + uint32_t ChatMessage::m_ChatGlobalId = 0; +} \ No newline at end of file diff --git a/L2BotCore/Domain/ValueObjects/ChatMessage.h b/L2BotCore/Domain/Entities/ChatMessage.h similarity index 55% rename from L2BotCore/Domain/ValueObjects/ChatMessage.h rename to L2BotCore/Domain/Entities/ChatMessage.h index d5887f8..a5d6fc1 100644 --- a/L2BotCore/Domain/ValueObjects/ChatMessage.h +++ b/L2BotCore/Domain/Entities/ChatMessage.h @@ -1,14 +1,34 @@ #pragma once #include #include -#include "../Serializers/Serializable.h" +#include +#include "EntityInterface.h" #include "../Enums/ChatChannelEnum.h" +#include "../Helpers/HashCombiner.h" -namespace L2Bot::Domain::ValueObjects +namespace L2Bot::Domain::Entities { - class ChatMessage : public Serializers::Serializable + class ChatMessage : public EntityInterface { public: + const uint32_t GetId() const override + { + return m_Id; + } + const size_t GetHash() const override + { + return Helpers::CombineHashes({ + std::hash{}(m_Id), + std::hash{}(m_ObjectId), + std::hash{}(m_Channel), + std::hash{}(m_Name), + std::hash{}(m_Text) + }); + } + const std::string GetEntityName() const override + { + return "chat"; + } const std::vector BuildSerializationNodes() const override { return std::vector @@ -26,20 +46,21 @@ namespace L2Bot::Domain::ValueObjects const std::wstring& name, const std::wstring& text ) : + m_Id(++m_ChatGlobalId), m_ObjectId(objectId), m_Channel(channel), m_Name(name), m_Text(text) { - } - ChatMessage() = default; virtual ~ChatMessage() = default; private: + uint32_t m_Id = 0; uint32_t m_ObjectId = 0; Enums::ChatChannelEnum m_Channel = Enums::ChatChannelEnum::all; std::wstring m_Name = L""; std::wstring m_Text = L""; + static uint32_t m_ChatGlobalId; }; } diff --git a/L2BotCore/Domain/Entities/Drop.h b/L2BotCore/Domain/Entities/Drop.h index 45b703d..3db04e5 100644 --- a/L2BotCore/Domain/Entities/Drop.h +++ b/L2BotCore/Domain/Entities/Drop.h @@ -8,48 +8,49 @@ namespace L2Bot::Domain::Entities class Drop : public WorldObject { public: - void Update(const EntityInterface* other) override - { - const Drop* casted = static_cast(other); - WorldObject::Update(other); - m_ItemId = casted->m_ItemId; - m_Amount = casted->m_Amount; - m_Name = casted->m_Name; - m_IconName = casted->m_IconName; + void Update( + const ValueObjects::Transform &transform, + const uint32_t itemId, + const uint32_t amount, + const std::wstring& name, + const std::wstring& iconName + ) { + WorldObject::Update(transform); + m_ItemId = itemId; + m_Amount = amount; + m_Name = name; + m_IconName = iconName; } - void SaveState() override + const size_t GetHash() const override { - WorldObject::SaveState(); - m_IsNewState = false; + return Helpers::CombineHashes({ + WorldObject::GetHash(), + std::hash{}(m_ItemId), + std::hash{}(m_Amount), + std::hash{}(m_Name), + std::hash{}(m_IconName) + }); } - const bool IsEqual(const EntityInterface* other) const override + const std::string GetEntityName() const override { - const Drop* casted = static_cast(other); - return WorldObject::IsEqual(other) && - m_ItemId == casted->m_ItemId && - m_Amount == casted->m_Amount && - m_Name == casted->m_Name && - m_IconName == casted->m_IconName; + return "drop"; } const std::vector BuildSerializationNodes() const override { std::vector result = WorldObject::BuildSerializationNodes(); - if (m_IsNewState) - { - result.push_back({ L"itemId", std::to_wstring(m_ItemId) }); - result.push_back({ L"amount", std::to_wstring(m_Amount) }); - result.push_back({ L"name", m_Name }); - result.push_back({ L"iconName", m_IconName }); - } + result.push_back({ L"itemId", std::to_wstring(m_ItemId) }); + result.push_back({ L"amount", std::to_wstring(m_Amount) }); + result.push_back({ L"name", m_Name }); + result.push_back({ L"iconName", m_IconName }); return result; } Drop( const uint32_t id, - const ValueObjects::Transform transform, + const ValueObjects::Transform &transform, const uint32_t itemId, const uint32_t amount, const std::wstring& name, @@ -71,6 +72,5 @@ namespace L2Bot::Domain::Entities uint32_t m_Amount = 0; std::wstring m_Name = L""; std::wstring m_IconName = L""; - bool m_IsNewState = true; }; } diff --git a/L2BotCore/Domain/Entities/EntityInterface.h b/L2BotCore/Domain/Entities/EntityInterface.h index 34d1b15..eb08aca 100644 --- a/L2BotCore/Domain/Entities/EntityInterface.h +++ b/L2BotCore/Domain/Entities/EntityInterface.h @@ -2,17 +2,17 @@ #include #include +#include #include "../Serializers/Serializable.h" +#include "Hashable.h" namespace L2Bot::Domain::Entities { - class EntityInterface : public Serializers::Serializable + class EntityInterface : public Serializers::Serializable, public Hashable { public: virtual const uint32_t GetId() const = 0; - virtual void Update(const EntityInterface* other) = 0; - virtual void SaveState() = 0; - virtual const bool IsEqual(const EntityInterface* other) const = 0; + virtual const std::string GetEntityName() const = 0; EntityInterface() = default; virtual ~EntityInterface() = default; diff --git a/L2BotCore/Domain/Entities/EtcItem.h b/L2BotCore/Domain/Entities/EtcItem.h index 43fa6db..38a0a2c 100644 --- a/L2BotCore/Domain/Entities/EtcItem.h +++ b/L2BotCore/Domain/Entities/EtcItem.h @@ -2,68 +2,59 @@ #include #include #include +#include #include "BaseItem.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::Entities { class EtcItem : public BaseItem { public: - void Autouse(bool enabled) + void StartAutouse() { - m_IsAutoused = enabled; + m_IsAutoused = true; + } + void StopAutouse() + { + m_IsAutoused = true; } const bool IsAutoused() const { return m_IsAutoused; } - void Update(const EntityInterface* other) override - { - const EtcItem* casted = static_cast(other); - - BaseItem::Update(other); + void Update( + const uint32_t itemId, + const int32_t mana, + const std::wstring& name, + const std::wstring& iconName, + const std::wstring& description, + const uint16_t weight, + const uint32_t amount, + const bool isQuest + ) { + BaseItem::Update(itemId, mana, name, iconName, description, weight); - m_Amount = casted->m_Amount; - m_IsQuest = casted->m_IsQuest; - m_IsAutoused = casted->m_IsAutoused; + m_Amount = amount; + m_IsQuest = isQuest; } - void SaveState() override + const size_t GetHash() const override { - BaseItem::SaveState(); - m_PrevState = - { - m_Amount, - m_IsAutoused, - false - }; - } - const bool IsEqual(const EntityInterface* other) const override - { - const EtcItem* casted = static_cast(other); - return BaseItem::IsEqual(other) && - m_IsQuest == casted->m_IsQuest && - m_Amount == casted->m_Amount && - m_IsAutoused == casted->m_IsAutoused; + return Helpers::CombineHashes({ + BaseItem::GetHash(), + std::hash{}(m_Amount), + std::hash{}(m_IsQuest) + }); } const std::vector BuildSerializationNodes() const override { std::vector result = BaseItem::BuildSerializationNodes(); - if (m_PrevState.isNewState) - { - result.push_back({ L"isQuest", std::to_wstring(m_IsQuest) }); - } - - if (m_PrevState.isNewState || m_Amount != m_PrevState.amount) - { - result.push_back({ L"amount", std::to_wstring(m_Amount) }); - } - if (m_PrevState.isNewState || m_IsAutoused != m_PrevState.isAutoused) - { - result.push_back({ L"isAutoused", std::to_wstring(m_IsAutoused) }); - } + result.push_back({ L"isQuest", std::to_wstring(m_IsQuest) }); + result.push_back({ L"amount", std::to_wstring(m_Amount) }); + result.push_back({ L"isAutoused", std::to_wstring(m_IsAutoused) }); return result; } @@ -95,30 +86,12 @@ namespace L2Bot::Domain::Entities { } - EtcItem(const EtcItem* other) : - BaseItem(other), - m_Amount(other->m_Amount), - m_IsAutoused(other->m_IsAutoused), - m_IsQuest(other->m_IsQuest) - { - } - EtcItem() = default; virtual ~EtcItem() = default; - private: - struct GetState - { - uint32_t amount = 0; - bool isAutoused = false; - - bool isNewState = true; - }; - private: uint32_t m_Amount = 0; bool m_IsQuest = false; bool m_IsAutoused = false; - GetState m_PrevState = GetState(); }; } diff --git a/L2BotCore/Domain/Entities/Hashable.h b/L2BotCore/Domain/Entities/Hashable.h new file mode 100644 index 0000000..3537ac3 --- /dev/null +++ b/L2BotCore/Domain/Entities/Hashable.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace L2Bot::Domain::Entities +{ + class Hashable + { + public: + virtual const std::size_t GetHash() const = 0; + + Hashable() = default; + virtual ~Hashable() = default; + }; +} \ No newline at end of file diff --git a/L2BotCore/Domain/Entities/Hero.h b/L2BotCore/Domain/Entities/Hero.h index 6ba604b..06552bf 100644 --- a/L2BotCore/Domain/Entities/Hero.h +++ b/L2BotCore/Domain/Entities/Hero.h @@ -15,114 +15,82 @@ namespace L2Bot::Domain::Entities class Hero : public WorldObject { public: - void Update(const EntityInterface* other) override - { - const Hero* casted = static_cast(other); - WorldObject::Update(other); - m_FullName = casted->m_FullName; - m_VitalStats = casted->m_VitalStats; - m_Phenotype = casted->m_Phenotype; - m_ExperienceInfo = casted->m_ExperienceInfo; - m_PermanentStats = casted->m_PermanentStats; - m_VariableStats = casted->m_VariableStats; - m_Reputation = casted->m_Reputation; - m_InventoryInfo = casted->m_InventoryInfo; - m_TargetId = casted->m_TargetId; - m_IsStanding = casted->m_IsStanding; + void Update( + const ValueObjects::Transform& transform, + const ValueObjects::FullName& fullName, + const ValueObjects::VitalStats& vitalStats, + const ValueObjects::Phenotype& phenotype, + const ValueObjects::ExperienceInfo& experienceInfo, + const ValueObjects::PermanentStats& permanentStats, + const ValueObjects::VariableStats& variableStats, + const ValueObjects::Reputation& reputation, + const ValueObjects::InventoryInfo& inventoryInfo, + const uint32_t targetId, + const bool isStanding + ) { + WorldObject::Update(transform); + + m_FullName = fullName; + m_VitalStats = vitalStats; + m_Phenotype = phenotype; + m_ExperienceInfo = experienceInfo; + m_PermanentStats = permanentStats; + m_VariableStats = variableStats; + m_Reputation = reputation; + m_InventoryInfo = inventoryInfo; + m_TargetId = targetId; + m_IsStanding = isStanding; } - void SaveState() override + const size_t GetHash() const override { - WorldObject::SaveState(); - m_PrevState = - { - m_FullName, - m_VitalStats, - m_Phenotype, - m_ExperienceInfo, - m_PermanentStats, - m_VariableStats, - m_Reputation, - m_InventoryInfo, - m_TargetId, - m_IsStanding, - false - }; + return Helpers::CombineHashes({ + WorldObject::GetHash(), + m_FullName.GetHash(), + m_VitalStats.GetHash(), + m_Phenotype.GetHash(), + m_ExperienceInfo.GetHash(), + m_PermanentStats.GetHash(), + m_VariableStats.GetHash(), + m_Reputation.GetHash(), + m_InventoryInfo.GetHash(), + std::hash{}(m_TargetId), + std::hash{}(m_IsStanding) + }); } - const bool IsEqual(const EntityInterface* other) const override + const std::string GetEntityName() const override { - const Hero* casted = static_cast(other); - return WorldObject::IsEqual(other) && - m_FullName.IsEqual(&casted->m_FullName) && - m_VitalStats.IsEqual(&casted->m_VitalStats) && - m_Phenotype.IsEqual(&casted->m_Phenotype) && - m_ExperienceInfo.IsEqual(&casted->m_ExperienceInfo) && - m_PermanentStats.IsEqual(&casted->m_PermanentStats) && - m_VariableStats.IsEqual(&casted->m_VariableStats) && - m_Reputation.IsEqual(&casted->m_Reputation) && - m_InventoryInfo.IsEqual(&casted->m_InventoryInfo) && - m_TargetId == casted->m_TargetId && - m_IsStanding == casted->m_IsStanding; + return "hero"; } const std::vector BuildSerializationNodes() const override { std::vector result = WorldObject::BuildSerializationNodes(); - if (m_PrevState.isNewState || !m_FullName.IsEqual(&m_PrevState.fullName)) - { - result.push_back({ L"fullName", m_FullName.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState || !m_VitalStats.IsEqual(&m_PrevState.vitalStats)) - { - result.push_back({ L"vitalStats", m_VitalStats.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState || !m_Phenotype.IsEqual(&m_PrevState.phenotype)) - { - result.push_back({ L"phenotype", m_Phenotype.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState || !m_ExperienceInfo.IsEqual(&m_PrevState.experienceInfo)) - { - result.push_back({ L"experienceInfo", m_ExperienceInfo.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState || !m_PermanentStats.IsEqual(&m_PrevState.permanentStats)) - { - result.push_back({ L"permanentStats", m_PermanentStats.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState || !m_VariableStats.IsEqual(&m_PrevState.variableStats)) - { - result.push_back({ L"variableStats", m_VariableStats.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState || !m_Reputation.IsEqual(&m_PrevState.reputation)) - { - result.push_back({ L"reputation", m_Reputation.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState || !m_InventoryInfo.IsEqual(&m_PrevState.inventoryInfo)) - { - result.push_back({ L"inventoryInfo", m_InventoryInfo.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState || m_TargetId != m_PrevState.targetId) - { - result.push_back({ L"targetId", std::to_wstring(m_TargetId) }); - } - if (m_PrevState.isNewState || m_IsStanding != m_PrevState.isStanding) - { - result.push_back({ L"isStanding", std::to_wstring(m_IsStanding) }); - } + result.push_back({ L"fullName", m_FullName.BuildSerializationNodes() }); + result.push_back({ L"vitalStats", m_VitalStats.BuildSerializationNodes() }); + result.push_back({ L"phenotype", m_Phenotype.BuildSerializationNodes() }); + result.push_back({ L"experienceInfo", m_ExperienceInfo.BuildSerializationNodes() }); + result.push_back({ L"permanentStats", m_PermanentStats.BuildSerializationNodes() }); + result.push_back({ L"variableStats", m_VariableStats.BuildSerializationNodes() }); + result.push_back({ L"reputation", m_Reputation.BuildSerializationNodes() }); + result.push_back({ L"inventoryInfo", m_InventoryInfo.BuildSerializationNodes() }); + result.push_back({ L"targetId", std::to_wstring(m_TargetId) }); + result.push_back({ L"isStanding", std::to_wstring(m_IsStanding) }); return result; } Hero( const uint32_t id, - const ValueObjects::Transform transform, - const ValueObjects::FullName fullName, - const ValueObjects::VitalStats vitalStats, - const ValueObjects::Phenotype phenotype, - const ValueObjects::ExperienceInfo experienceInfo, - const ValueObjects::PermanentStats permanentStats, - const ValueObjects::VariableStats variableStats, - const ValueObjects::Reputation reputation, - const ValueObjects::InventoryInfo inventoryInfo, + const ValueObjects::Transform& transform, + const ValueObjects::FullName& fullName, + const ValueObjects::VitalStats& vitalStats, + const ValueObjects::Phenotype& phenotype, + const ValueObjects::ExperienceInfo& experienceInfo, + const ValueObjects::PermanentStats& permanentStats, + const ValueObjects::VariableStats& variableStats, + const ValueObjects::Reputation& reputation, + const ValueObjects::InventoryInfo& inventoryInfo, const uint32_t targetId, const bool isStanding ) : @@ -144,23 +112,6 @@ namespace L2Bot::Domain::Entities Hero() = default; virtual ~Hero() = default; - private: - struct GetState - { - ValueObjects::FullName fullName = ValueObjects::FullName(); - ValueObjects::VitalStats vitalStats = ValueObjects::VitalStats(); - ValueObjects::Phenotype phenotype = ValueObjects::Phenotype(); - ValueObjects::ExperienceInfo experienceInfo = ValueObjects::ExperienceInfo(); - ValueObjects::PermanentStats permanentStats = ValueObjects::PermanentStats(); - ValueObjects::VariableStats variableStats = ValueObjects::VariableStats(); - ValueObjects::Reputation reputation = ValueObjects::Reputation(); - ValueObjects::InventoryInfo inventoryInfo = ValueObjects::InventoryInfo(); - uint32_t targetId = 0; - bool isStanding = true; - - bool isNewState = true; - }; - private: ValueObjects::FullName m_FullName = ValueObjects::FullName(); ValueObjects::VitalStats m_VitalStats = ValueObjects::VitalStats(); @@ -172,6 +123,5 @@ namespace L2Bot::Domain::Entities ValueObjects::InventoryInfo m_InventoryInfo = ValueObjects::InventoryInfo(); uint32_t m_TargetId = 0; bool m_IsStanding = true; - GetState m_PrevState = GetState(); }; } diff --git a/L2BotCore/Domain/Entities/NPC.h b/L2BotCore/Domain/Entities/NPC.h index 5f279ad..1f3c522 100644 --- a/L2BotCore/Domain/Entities/NPC.h +++ b/L2BotCore/Domain/Entities/NPC.h @@ -11,76 +11,66 @@ namespace L2Bot::Domain::Entities class NPC : public WorldObject { public: - void Update(const EntityInterface* other) override + void UpdateSpoilState(const Enums::SpoilStateEnum spoilState) { - const NPC* casted = static_cast(other); - WorldObject::Update(other); - m_IsHostile = casted->m_IsHostile; - m_NpcId = casted->m_NpcId; - m_SpoilState = casted->m_SpoilState; - m_FullName = casted->m_FullName; - m_VitalStats = casted->m_VitalStats; + m_SpoilState = spoilState; } - void SaveState() override - { - WorldObject::SaveState(); - m_PrevState = - { - m_FullName, - m_SpoilState, - m_VitalStats, - false - }; + + void Update( + const ValueObjects::Transform& transform, + const bool isHostile, + const uint32_t npcId, + const ValueObjects::FullName& fullName, + const ValueObjects::VitalStats& vitalStats + ) { + WorldObject::Update(transform); + + m_IsHostile = isHostile; + m_NpcId = npcId; + m_FullName = fullName; + m_VitalStats = vitalStats; } - const bool IsEqual(const EntityInterface* other) const override + const size_t GetHash() const override { - const NPC* casted = static_cast(other); - return WorldObject::IsEqual(other) && - m_IsHostile == casted->m_IsHostile && - m_NpcId == casted->m_NpcId && - m_SpoilState == casted->m_SpoilState && - m_FullName.IsEqual(&casted->m_FullName) && - m_VitalStats.IsEqual(&casted->m_VitalStats); + return Helpers::CombineHashes({ + WorldObject::GetHash(), + std::hash{}(m_IsHostile), + std::hash{}(m_NpcId), + std::hash{}(m_SpoilState), + m_FullName.GetHash(), + m_VitalStats.GetHash() + }); + } + const std::string GetEntityName() const override + { + return "npc"; } const std::vector BuildSerializationNodes() const override { std::vector result = WorldObject::BuildSerializationNodes(); - if (m_PrevState.isNewState || !m_FullName.IsEqual(&m_PrevState.fullName)) - { - result.push_back({ L"fullName", m_FullName.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState) - { - result.push_back({ L"isHostile", std::to_wstring(m_IsHostile) }); - result.push_back({ L"npcId", std::to_wstring(m_NpcId) }); - } - if (m_PrevState.isNewState || m_SpoilState != m_PrevState.spoilState) - { - result.push_back({ L"spoilState", std::to_wstring(static_cast(m_SpoilState)) }); - } - if (m_PrevState.isNewState || !m_VitalStats.IsEqual(&m_PrevState.vitalStats)) - { - result.push_back({ L"vitalStats", m_VitalStats.BuildSerializationNodes() }); - } + result.push_back({ L"fullName", m_FullName.BuildSerializationNodes() }); + result.push_back({ L"isHostile", std::to_wstring(m_IsHostile) }); + result.push_back({ L"npcId", std::to_wstring(m_NpcId) }); + result.push_back({ L"spoilState", std::to_wstring(static_cast(m_SpoilState)) }); + result.push_back({ L"vitalStats", m_VitalStats.BuildSerializationNodes() }); return result; } + NPC( const uint32_t id, - const ValueObjects::Transform transform, + const ValueObjects::Transform& transform, const bool isHostile, const uint32_t npcId, - const Enums::SpoilStateEnum spoilState, - const ValueObjects::FullName fullName, - const ValueObjects::VitalStats vitalStats + const ValueObjects::FullName& fullName, + const ValueObjects::VitalStats& vitalStats ) : WorldObject(id, transform), m_IsHostile(isHostile), m_NpcId(npcId), - m_SpoilState(spoilState), m_FullName(fullName), m_VitalStats(vitalStats) { @@ -90,22 +80,11 @@ namespace L2Bot::Domain::Entities NPC() = default; virtual ~NPC() = default; - private: - struct GetState - { - ValueObjects::FullName fullName = ValueObjects::FullName(); - Enums::SpoilStateEnum spoilState = Enums::SpoilStateEnum::none; - ValueObjects::VitalStats vitalStats = ValueObjects::VitalStats(); - - bool isNewState = true; - }; - private: bool m_IsHostile = false; uint32_t m_NpcId = 0; Enums::SpoilStateEnum m_SpoilState = Enums::SpoilStateEnum::none; ValueObjects::FullName m_FullName = ValueObjects::FullName(); ValueObjects::VitalStats m_VitalStats = ValueObjects::VitalStats(); - GetState m_PrevState = GetState(); }; } diff --git a/L2BotCore/Domain/Entities/Player.h b/L2BotCore/Domain/Entities/Player.h index d2e60d6..48aa2cf 100644 --- a/L2BotCore/Domain/Entities/Player.h +++ b/L2BotCore/Domain/Entities/Player.h @@ -9,60 +9,49 @@ namespace L2Bot::Domain::Entities class Player : public WorldObject { public: - void Update(const EntityInterface* other) override - { - const Player* casted = static_cast(other); - WorldObject::Update(other); - m_FullName = casted->m_FullName; - m_Phenotype = casted->m_Phenotype; - m_VitalStats = casted->m_VitalStats; + void Update( + const ValueObjects::Transform& transform, + const ValueObjects::FullName& fullName, + const ValueObjects::Phenotype& phenotype, + const ValueObjects::VitalStats& vitalStats + ) { + WorldObject::Update(transform); + + m_FullName = fullName; + m_Phenotype = phenotype; + m_VitalStats = vitalStats; } - void SaveState() override + const size_t GetHash() const override { - WorldObject::SaveState(); - m_PrevState = - { - m_FullName, - m_Phenotype, - m_VitalStats, - false - }; + return Helpers::CombineHashes({ + WorldObject::GetHash(), + m_FullName.GetHash(), + m_Phenotype.GetHash(), + m_VitalStats.GetHash() + }); } - const bool IsEqual(const EntityInterface* other) const override + const std::string GetEntityName() const override { - const Player* casted = static_cast(other); - return WorldObject::IsEqual(other) && - m_FullName.IsEqual(&casted->m_FullName) && - m_Phenotype.IsEqual(&casted->m_Phenotype) && - m_VitalStats.IsEqual(&casted->m_VitalStats); + return "player"; } const std::vector BuildSerializationNodes() const override { std::vector result = WorldObject::BuildSerializationNodes(); - if (m_PrevState.isNewState || !m_FullName.IsEqual(&m_PrevState.fullName)) - { - result.push_back({ L"fullName", m_FullName.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState || !m_Phenotype.IsEqual(&m_PrevState.phenotype)) - { - result.push_back({ L"phenotype", m_Phenotype.BuildSerializationNodes() }); - } - if (m_PrevState.isNewState || !m_VitalStats.IsEqual(&m_PrevState.vitalStats)) - { - result.push_back({ L"vitalStats", m_VitalStats.BuildSerializationNodes() }); - } + result.push_back({ L"fullName", m_FullName.BuildSerializationNodes() }); + result.push_back({ L"phenotype", m_Phenotype.BuildSerializationNodes() }); + result.push_back({ L"vitalStats", m_VitalStats.BuildSerializationNodes() }); return result; } Player( const uint32_t id, - const ValueObjects::Transform transform, - const ValueObjects::FullName fullName, - const ValueObjects::Phenotype phenotype, - const ValueObjects::VitalStats vitalStats + const ValueObjects::Transform& transform, + const ValueObjects::FullName& fullName, + const ValueObjects::Phenotype& phenotype, + const ValueObjects::VitalStats& vitalStats ) : WorldObject(id, transform), m_FullName(fullName), @@ -74,20 +63,9 @@ namespace L2Bot::Domain::Entities Player() = default; virtual ~Player() = default; - private: - struct GetState - { - ValueObjects::FullName fullName = ValueObjects::FullName(); - ValueObjects::Phenotype phenotype = ValueObjects::Phenotype(); - ValueObjects::VitalStats vitalStats = ValueObjects::VitalStats(); - - bool isNewState = true; - }; - private: ValueObjects::FullName m_FullName = ValueObjects::FullName(); ValueObjects::Phenotype m_Phenotype = ValueObjects::Phenotype(); ValueObjects::VitalStats m_VitalStats = ValueObjects::VitalStats(); - GetState m_PrevState = GetState(); }; } diff --git a/L2BotCore/Domain/Entities/ShieldItem.h b/L2BotCore/Domain/Entities/ShieldItem.h index 275b148..9ae4826 100644 --- a/L2BotCore/Domain/Entities/ShieldItem.h +++ b/L2BotCore/Domain/Entities/ShieldItem.h @@ -2,73 +2,62 @@ #include #include #include +#include #include "BaseItem.h" #include "../Enums/CrystalTypeEnum.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::Entities { class ShieldItem : public BaseItem { public: - void Update(const EntityInterface* other) override - { - const ShieldItem* casted = static_cast(other); + void Update( + const uint32_t itemId, + const int32_t mana, + const std::wstring& name, + const std::wstring& iconName, + const std::wstring& description, + const uint16_t weight, + const bool isEquipped, + const uint16_t enchantLevel, + const Enums::CrystalTypeEnum crystalType, + const int16_t evasion, + const uint32_t pDefense, + const uint16_t defRate + ) { + BaseItem::Update(itemId, mana, name, iconName, description, weight); - BaseItem::Update(other); - - m_IsEquipped = casted->m_IsEquipped; - m_EnchantLevel = casted->m_EnchantLevel; - m_CrystalType = casted->m_CrystalType; - m_Evasion = casted->m_Evasion; - m_PDefense = casted->m_PDefense; - m_DefRate = casted->m_DefRate; + m_IsEquipped = isEquipped; + m_EnchantLevel = enchantLevel; + m_CrystalType = crystalType; + m_Evasion = evasion; + m_PDefense = pDefense; + m_DefRate = defRate; } - void SaveState() override + const size_t GetHash() const override { - BaseItem::SaveState(); - m_PrevState = - { - m_IsEquipped, - m_EnchantLevel, - m_PDefense, - false - }; - } - const bool IsEqual(const EntityInterface* other) const override - { - const ShieldItem* casted = static_cast(other); - return BaseItem::IsEqual(other) && - m_IsEquipped == casted->m_IsEquipped && - m_EnchantLevel == casted->m_EnchantLevel && - m_CrystalType == casted->m_CrystalType && - m_Evasion == casted->m_Evasion && - m_PDefense == casted->m_PDefense && - m_DefRate == casted->m_DefRate; + return Helpers::CombineHashes({ + BaseItem::GetHash(), + std::hash{}(m_IsEquipped), + std::hash{}(m_EnchantLevel), + std::hash{}(m_CrystalType), + std::hash{}(m_Evasion), + std::hash{}(m_PDefense), + std::hash{}(m_DefRate) + }); } const std::vector BuildSerializationNodes() const override { std::vector result = BaseItem::BuildSerializationNodes(); - if (m_PrevState.isNewState) - { - result.push_back({ L"crystalType", std::to_wstring(static_cast(m_CrystalType)) }); - result.push_back({ L"evasion", std::to_wstring(m_Evasion) }); - result.push_back({ L"defRate", std::to_wstring(m_DefRate) }); - } - - if (m_PrevState.isNewState || m_IsEquipped != m_PrevState.isEquipped) - { - result.push_back({ L"isEquipped", std::to_wstring(m_IsEquipped) }); - } - if (m_PrevState.isNewState || m_EnchantLevel != m_PrevState.enchantLevel) - { - result.push_back({ L"enchantLevel", std::to_wstring(m_EnchantLevel) }); - } - if (m_PrevState.isNewState || m_PDefense != m_PrevState.pDefense) - { - result.push_back({ L"pDefense", std::to_wstring(m_PDefense) }); - } + result.push_back({ L"crystalType", std::to_wstring(static_cast(m_CrystalType)) }); + result.push_back({ L"evasion", std::to_wstring(m_Evasion) }); + result.push_back({ L"defRate", std::to_wstring(m_DefRate) }); + result.push_back({ L"isEquipped", std::to_wstring(m_IsEquipped) }); + result.push_back({ L"enchantLevel", std::to_wstring(m_EnchantLevel) }); + result.push_back({ L"pDefense", std::to_wstring(m_PDefense) }); return result; } @@ -108,31 +97,9 @@ namespace L2Bot::Domain::Entities { } - ShieldItem(const ShieldItem* other) : - BaseItem(other), - m_IsEquipped(other->m_IsEquipped), - m_EnchantLevel(other->m_EnchantLevel), - m_CrystalType(other->m_CrystalType), - m_Evasion(other->m_Evasion), - m_PDefense(other->m_PDefense), - m_DefRate(other->m_DefRate) - - { - } - ShieldItem() = default; virtual ~ShieldItem() = default; - private: - struct GetState - { - bool isEquipped = 0; - uint16_t enchantLevel = 0; - uint32_t pDefense = 0; - - bool isNewState = true; - }; - private: bool m_IsEquipped = 0; uint16_t m_EnchantLevel = 0; @@ -140,7 +107,5 @@ namespace L2Bot::Domain::Entities int16_t m_Evasion = 0; uint32_t m_PDefense = 0; uint16_t m_DefRate = 0; - - GetState m_PrevState = GetState(); }; } diff --git a/L2BotCore/Domain/Entities/Skill.h b/L2BotCore/Domain/Entities/Skill.h index 8c83579..2613985 100644 --- a/L2BotCore/Domain/Entities/Skill.h +++ b/L2BotCore/Domain/Entities/Skill.h @@ -2,25 +2,14 @@ #include #include #include +#include #include "EntityInterface.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::Entities { class Skill : public EntityInterface { - public: - struct Data - { - uint32_t skillId; - uint8_t level; - bool isActive; - uint8_t cost; - int16_t range; - std::wstring name; - std::wstring description; - std::wstring iconName; - }; - public: const uint32_t GetId() const override { @@ -59,180 +48,89 @@ namespace L2Bot::Domain::Entities { m_IsToggled = false; } - void Update(const Data &data) { - m_Level = data.level; - m_IsActive = data.isActive; - m_Cost = data.cost; - m_Range = data.range; - m_Name = data.name; - m_Description = data.description; - m_IconName = data.iconName; + void Update( + const uint8_t level, + const bool isActive, + const uint8_t cost, + const int16_t range, + const std::wstring& name, + const std::wstring& description, + const std::wstring& iconName + ) { + m_Level = level; + m_IsActive = isActive; + m_Cost = cost; + m_Range = range; + m_Name = name; + m_Description = description; + m_IconName = iconName; + } + const size_t GetHash() const override + { + return Helpers::CombineHashes({ + std::hash{}(m_SkillId), + std::hash{}(m_Level), + std::hash{}(m_IsActive), + std::hash{}(m_Cost), + std::hash{}(m_Range), + std::hash{}(m_Name), + std::hash{}(m_Description), + std::hash{}(m_IconName), + std::hash{}(m_IsToggled), + std::hash{}(m_IsCasting), + std::hash{}(m_IsReloading) + }); + } + const std::string GetEntityName() const override + { + return "skill"; } - /** - * @deprecated - **/ - void Update(const EntityInterface* other) override - { - const Skill* casted = static_cast(other); - SaveState(); - - m_SkillId = casted->m_SkillId; - m_Level = casted->m_Level; - m_IsActive = casted->m_IsActive; - m_Cost = casted->m_Cost; - m_Range = casted->m_Range; - m_Name = casted->m_Name; - m_Description = casted->m_Description; - m_IconName = casted->m_IconName; - m_IsToggled = casted->m_IsToggled; - m_IsCasting = casted->m_IsCasting; - m_IsReloading = casted->m_IsReloading; - } - /** - * @deprecated - **/ - void SaveState() override - { - m_PrevState = - { - m_Name, - m_IconName, - m_Cost, - m_Range, - m_Description, - m_IsToggled, - m_IsCasting, - m_IsReloading, - IsReadyToUse(), - false - }; - } - /** - * @deprecated - **/ - const bool IsEqual(const EntityInterface* other) const override - { - const Skill* casted = static_cast(other); - return m_SkillId == casted->m_SkillId && - m_Level == casted->m_Level && - m_IsActive == casted->m_IsActive && - m_Cost == casted->m_Cost && - m_Range == casted->m_Range && - m_Name == casted->m_Name && - m_Description == casted->m_Description && - m_IconName == casted->m_IconName && - m_IsToggled == casted->m_IsToggled && - m_IsCasting == casted->m_IsCasting && - m_IsReloading == casted->m_IsReloading; - } - /** - * @deprecated - **/ const std::vector BuildSerializationNodes() const override { std::vector result; result.push_back({ L"id", std::to_wstring(m_SkillId) }); result.push_back({ L"level", std::to_wstring(m_Level) }); - - if (m_PrevState.isNewState) - { - result.push_back({ L"isActive", std::to_wstring(m_IsActive) }); - } - - if (m_PrevState.isNewState || m_Name != m_PrevState.name) - { - result.push_back({ L"name", m_Name }); - } - if (m_PrevState.isNewState || m_IconName != m_PrevState.iconName) - { - result.push_back({ L"iconName", m_IconName }); - } - if (m_PrevState.isNewState || m_Description != m_PrevState.description) - { - result.push_back({ L"description", m_Description }); - } - if (m_PrevState.isNewState || m_Cost != m_PrevState.cost) - { - result.push_back({ L"cost", std::to_wstring(m_Cost) }); - } - if (m_PrevState.isNewState || m_Range != m_PrevState.range) - { - result.push_back({ L"range", std::to_wstring(m_Range) }); - } - if (m_PrevState.isNewState || m_IsToggled != m_PrevState.isToggled) - { - result.push_back({ L"isToggled", std::to_wstring(m_IsToggled) }); - } - if (m_PrevState.isNewState || m_IsCasting != m_PrevState.isCasting) - { - result.push_back({ L"isCasting", std::to_wstring(m_IsCasting) }); - } - if (m_PrevState.isNewState || m_IsReloading != m_PrevState.isReloading) - { - result.push_back({ L"isReloading", std::to_wstring(m_IsReloading) }); - } - if (m_PrevState.isNewState || IsReadyToUse() != m_PrevState.isReadyToUse) - { - result.push_back({ L"isReadyToUse", std::to_wstring(IsReadyToUse()) }); - } + result.push_back({ L"isActive", std::to_wstring(m_IsActive) }); + result.push_back({ L"name", m_Name }); + result.push_back({ L"iconName", m_IconName }); + result.push_back({ L"description", m_Description }); + result.push_back({ L"cost", std::to_wstring(m_Cost) }); + result.push_back({ L"range", std::to_wstring(m_Range) }); + result.push_back({ L"isToggled", std::to_wstring(m_IsToggled) }); + result.push_back({ L"isCasting", std::to_wstring(m_IsCasting) }); + result.push_back({ L"isReloading", std::to_wstring(m_IsReloading) }); + result.push_back({ L"isReadyToUse", std::to_wstring(IsReadyToUse()) }); return result; } - Skill(const Data &data) : - m_SkillId(data.skillId), - m_Level(data.level), - m_IsActive(data.isActive), - m_Cost(data.cost), - m_Range(data.range), - m_Name(data.name), - m_Description(data.description), - m_IconName(data.iconName) + Skill( + const uint32_t skillId, + const uint8_t level, + const bool isActive, + const uint8_t cost, + const int16_t range, + const std::wstring& name, + const std::wstring& description, + const std::wstring& iconName + ) : + m_SkillId(skillId), + m_Level(level), + m_IsActive(isActive), + m_Cost(cost), + m_Range(range), + m_Name(name), + m_Description(description), + m_IconName(iconName) { } - /** - * @deprecated - **/ - Skill(const Skill* other) : - m_SkillId(other->m_SkillId), - m_Level(other->m_Level), - m_IsActive(other->m_IsActive), - m_Cost(other->m_Cost), - m_Range(other->m_Range), - m_Name(other->m_Name), - m_Description(other->m_Description), - m_IconName(other->m_IconName), - m_IsToggled(other->m_IsToggled), - m_IsCasting(other->m_IsCasting), - m_IsReloading(other->m_IsReloading) - { - } - + Skill() = default; virtual ~Skill() = default; - private: - /** - * @deprecated - **/ - struct GetState - { - std::wstring name = L""; - std::wstring iconName = L""; - uint8_t cost = 0; - int16_t range = 0; - std::wstring description = L""; - bool isToggled = false; - bool isCasting = false; - bool isReloading = false; - bool isReadyToUse = true; - - bool isNewState = true; - }; - private: uint32_t m_SkillId = 0; uint8_t m_Level = 0; @@ -245,6 +143,5 @@ namespace L2Bot::Domain::Entities bool m_IsToggled = false; bool m_IsCasting = false; bool m_IsReloading = false; - GetState m_PrevState = GetState(); }; } diff --git a/L2BotCore/Domain/Entities/WeaponItem.h b/L2BotCore/Domain/Entities/WeaponItem.h index e6c8999..279e870 100644 --- a/L2BotCore/Domain/Entities/WeaponItem.h +++ b/L2BotCore/Domain/Entities/WeaponItem.h @@ -2,99 +2,91 @@ #include #include #include +#include #include "BaseItem.h" #include "../Enums/WeaponTypeEnum.h" #include "../Enums/CrystalTypeEnum.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::Entities { class WeaponItem : public BaseItem { public: - void Update(const EntityInterface* other) override - { - const WeaponItem* casted = static_cast(other); + void Update( + const uint32_t itemId, + const int32_t mana, + const std::wstring& name, + const std::wstring& iconName, + const std::wstring& description, + const uint16_t weight, + const bool isEquipped, + const uint16_t enchantLevel, + const Enums::WeaponTypeEnum weaponType, + const Enums::CrystalTypeEnum crystalType, + const uint8_t rndDamage, + const uint32_t pAttack, + const uint32_t mAttack, + const uint16_t critical, + const int8_t hitModify, + const uint16_t attackSpeed, + const uint8_t mpConsume, + const uint8_t soulshotCount, + const uint8_t spiritshotCount + ) { + BaseItem::Update(itemId, mana, name, iconName, description, weight); - BaseItem::Update(other); - - m_IsEquipped = casted->m_IsEquipped; - m_EnchantLevel = casted->m_EnchantLevel; - m_WeaponType = casted->m_WeaponType; - m_CrystalType = casted->m_CrystalType; - m_PAttack = casted->m_PAttack; - m_MAttack = casted->m_MAttack; - m_RndDamage = casted->m_RndDamage; - m_Critical = casted->m_Critical; - m_HitModify = casted->m_HitModify; - m_AttackSpeed = casted->m_AttackSpeed; - m_MpConsume = casted->m_MpConsume; - m_SoulshotCount = casted->m_SoulshotCount; - m_SpiritshotCount = casted->m_SpiritshotCount; + m_IsEquipped = isEquipped; + m_EnchantLevel = enchantLevel; + m_WeaponType = weaponType; + m_CrystalType = crystalType; + m_RndDamage = rndDamage; + m_PAttack = pAttack; + m_MAttack = mAttack; + m_Critical = critical; + m_HitModify = hitModify; + m_AttackSpeed = attackSpeed; + m_MpConsume = mpConsume; + m_SoulshotCount = soulshotCount; + m_SpiritshotCount = spiritshotCount; } - void SaveState() override + const size_t GetHash() const override { - BaseItem::SaveState(); - m_PrevState = - { - m_IsEquipped, - m_EnchantLevel, - m_PAttack, - m_MAttack, - false - }; - } - const bool IsEqual(const EntityInterface* other) const override - { - const WeaponItem* casted = static_cast(other); - return BaseItem::IsEqual(other) && - m_IsEquipped == casted->m_IsEquipped && - m_EnchantLevel == casted->m_EnchantLevel && - m_WeaponType == casted->m_WeaponType && - m_CrystalType == casted->m_CrystalType && - m_PAttack == casted->m_PAttack && - m_MAttack == casted->m_MAttack && - m_RndDamage == casted->m_RndDamage && - m_Critical == casted->m_Critical && - m_HitModify == casted->m_HitModify && - m_AttackSpeed == casted->m_AttackSpeed && - m_MpConsume == casted->m_MpConsume && - m_SoulshotCount == casted->m_SoulshotCount && - m_SpiritshotCount == casted->m_SpiritshotCount; + return Helpers::CombineHashes({ + BaseItem::GetHash(), + std::hash{}(m_IsEquipped), + std::hash{}(m_EnchantLevel), + std::hash{}(m_WeaponType), + std::hash{}(m_CrystalType), + std::hash{}(m_RndDamage), + std::hash{}(m_PAttack), + std::hash{}(m_MAttack), + std::hash{}(m_Critical), + std::hash{}(m_HitModify), + std::hash{}(m_AttackSpeed), + std::hash{}(m_MpConsume), + std::hash{}(m_SoulshotCount), + std::hash{}(m_SpiritshotCount) + }); } const std::vector BuildSerializationNodes() const override { std::vector result = BaseItem::BuildSerializationNodes(); - if (m_PrevState.isNewState) - { - result.push_back({ L"weaponType", std::to_wstring(static_cast(m_WeaponType)) }); - result.push_back({ L"crystalType", std::to_wstring(static_cast(m_CrystalType)) }); - result.push_back({ L"rndDamage", std::to_wstring(m_RndDamage) }); - result.push_back({ L"critical", std::to_wstring(m_Critical) }); - result.push_back({ L"hitModify", std::to_wstring(m_HitModify) }); - result.push_back({ L"attackSpeed", std::to_wstring(m_AttackSpeed) }); - result.push_back({ L"mpConsume", std::to_wstring(m_MpConsume) }); - result.push_back({ L"soulshotCount", std::to_wstring(m_SoulshotCount) }); - result.push_back({ L"spiritshotCount", std::to_wstring(m_SpiritshotCount) }); - } - - if (m_PrevState.isNewState || m_IsEquipped != m_PrevState.isEquipped) - { - result.push_back({ L"isEquipped", std::to_wstring(m_IsEquipped) }); - } - if (m_PrevState.isNewState || m_EnchantLevel != m_PrevState.enchantLevel) - { - result.push_back({ L"enchantLevel", std::to_wstring(m_EnchantLevel) }); - } - if (m_PrevState.isNewState || m_PAttack != m_PrevState.pAttack) - { - result.push_back({ L"pAttack", std::to_wstring(m_PAttack) }); - } - if (m_PrevState.isNewState || m_MAttack != m_PrevState.mAttack) - { - result.push_back({ L"mAttack", std::to_wstring(m_MAttack) }); - } + result.push_back({ L"weaponType", std::to_wstring(static_cast(m_WeaponType)) }); + result.push_back({ L"crystalType", std::to_wstring(static_cast(m_CrystalType)) }); + result.push_back({ L"rndDamage", std::to_wstring(m_RndDamage) }); + result.push_back({ L"critical", std::to_wstring(m_Critical) }); + result.push_back({ L"hitModify", std::to_wstring(m_HitModify) }); + result.push_back({ L"attackSpeed", std::to_wstring(m_AttackSpeed) }); + result.push_back({ L"mpConsume", std::to_wstring(m_MpConsume) }); + result.push_back({ L"soulshotCount", std::to_wstring(m_SoulshotCount) }); + result.push_back({ L"spiritshotCount", std::to_wstring(m_SpiritshotCount) }); + result.push_back({ L"isEquipped", std::to_wstring(m_IsEquipped) }); + result.push_back({ L"enchantLevel", std::to_wstring(m_EnchantLevel) }); + result.push_back({ L"pAttack", std::to_wstring(m_PAttack) }); + result.push_back({ L"mAttack", std::to_wstring(m_MAttack) }); return result; } @@ -116,7 +108,7 @@ namespace L2Bot::Domain::Entities const uint32_t mAttack, const uint16_t critical, const int8_t hitModify, - const uint16_t atkSpd, + const uint16_t attackSpeed, const uint8_t mpConsume, const uint8_t soulshotCount, const uint8_t spiritshotCount @@ -141,46 +133,16 @@ namespace L2Bot::Domain::Entities m_MAttack(mAttack), m_Critical(critical), m_HitModify(hitModify), - m_AttackSpeed(atkSpd), + m_AttackSpeed(attackSpeed), m_MpConsume(mpConsume), m_SoulshotCount(soulshotCount), m_SpiritshotCount(spiritshotCount) { } - WeaponItem(const WeaponItem* other) : - BaseItem(other), - m_IsEquipped(other->m_IsEquipped), - m_EnchantLevel(other->m_EnchantLevel), - m_WeaponType(other->m_WeaponType), - m_CrystalType(other->m_CrystalType), - m_RndDamage(other->m_RndDamage), - m_PAttack(other->m_PAttack), - m_MAttack(other->m_MAttack), - m_Critical(other->m_Critical), - m_HitModify(other->m_HitModify), - m_AttackSpeed(other->m_AttackSpeed), - m_MpConsume(other->m_MpConsume), - m_SoulshotCount(other->m_SoulshotCount), - m_SpiritshotCount(other->m_SpiritshotCount) - - { - } - WeaponItem() = default; virtual ~WeaponItem() = default; - private: - struct GetState - { - bool isEquipped = 0; - uint16_t enchantLevel = 0; - uint32_t pAttack = 0; - uint32_t mAttack = 0; - - bool isNewState = true; - }; - private: bool m_IsEquipped = 0; uint16_t m_EnchantLevel = 0; @@ -195,7 +157,5 @@ namespace L2Bot::Domain::Entities uint8_t m_MpConsume = 0; uint8_t m_SoulshotCount = 0; uint8_t m_SpiritshotCount = 0; - - GetState m_PrevState = GetState(); }; } diff --git a/L2BotCore/Domain/Entities/WorldObject.h b/L2BotCore/Domain/Entities/WorldObject.h index f74df4f..308134d 100644 --- a/L2BotCore/Domain/Entities/WorldObject.h +++ b/L2BotCore/Domain/Entities/WorldObject.h @@ -1,7 +1,9 @@ #pragma once #include +#include #include "../ValueObjects/Transform.h" #include "EntityInterface.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::Entities { @@ -12,22 +14,16 @@ namespace L2Bot::Domain::Entities { return m_Id; } - virtual void Update(const EntityInterface* other) override + virtual void Update(const ValueObjects::Transform& transform) { - SaveState(); - - const WorldObject* casted = static_cast(other); - m_Id = casted->m_Id; - m_Transform = casted->m_Transform; + m_Transform = transform; } - virtual void SaveState() override + virtual const size_t GetHash() const override { - m_PrevState = { m_Transform, false }; - } - virtual const bool IsEqual(const EntityInterface* other) const override - { - const WorldObject* casted = static_cast(other); - return m_Id == casted->m_Id && m_Transform.IsEqual(&casted->m_Transform); + return Helpers::CombineHashes({ + std::hash{}(m_Id), + m_Transform.GetHash() + }); } virtual const std::vector BuildSerializationNodes() const override @@ -35,15 +31,12 @@ namespace L2Bot::Domain::Entities std::vector result; result.push_back({ L"id", std::to_wstring(GetId()) }); - if (m_PrevState.isNewState || !m_Transform.IsEqual(&m_PrevState.transform)) - { - result.push_back({ L"transform", m_Transform.BuildSerializationNodes() }); - } + result.push_back({ L"transform", m_Transform.BuildSerializationNodes() }); return result; } - WorldObject(const uint32_t id, const ValueObjects::Transform transform) : + WorldObject(const uint32_t id, const ValueObjects::Transform& transform) : m_Id(id), m_Transform(transform) { @@ -51,18 +44,9 @@ namespace L2Bot::Domain::Entities WorldObject() = default; virtual ~WorldObject() = default; - private: - private: - struct GetState - { - ValueObjects::Transform transform = ValueObjects::Transform(); - - bool isNewState = true; - }; private: uint32_t m_Id = 0; ValueObjects::Transform m_Transform = ValueObjects::Transform(); - GetState m_PrevState = GetState(); }; } diff --git a/L2BotCore/Domain/Helpers/HashCombiner.cpp b/L2BotCore/Domain/Helpers/HashCombiner.cpp new file mode 100644 index 0000000..6985b28 --- /dev/null +++ b/L2BotCore/Domain/Helpers/HashCombiner.cpp @@ -0,0 +1,14 @@ +#include "..\..\pch.h" +#include "HashCombiner.h" + +namespace L2Bot::Domain::Helpers +{ + const size_t CombineHashes(const std::vector hashes, size_t seed) + { + for (const auto hash : hashes) { + seed = hash + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } + + return seed; + } +} \ No newline at end of file diff --git a/L2BotCore/Domain/Helpers/HashCombiner.h b/L2BotCore/Domain/Helpers/HashCombiner.h new file mode 100644 index 0000000..099688c --- /dev/null +++ b/L2BotCore/Domain/Helpers/HashCombiner.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace L2Bot::Domain::Helpers +{ + const size_t CombineHashes(const std::vector hashes, size_t seed = 0); +} + diff --git a/L2BotCore/Domain/Repositories/ChatMessageRepositoryInterface.h b/L2BotCore/Domain/Repositories/ChatMessageRepositoryInterface.h deleted file mode 100644 index 07eda0d..0000000 --- a/L2BotCore/Domain/Repositories/ChatMessageRepositoryInterface.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include -#include "../ValueObjects/ChatMessage.h" - -namespace L2Bot::Domain::Repositories -{ - class ChatMessageRepositoryInterface - { - public: - virtual const std::vector GetMessages() = 0; - }; -} diff --git a/L2BotCore/Domain/Repositories/EntityRepositoryInterface.h b/L2BotCore/Domain/Repositories/EntityRepositoryInterface.h index 7156a11..3d34459 100644 --- a/L2BotCore/Domain/Repositories/EntityRepositoryInterface.h +++ b/L2BotCore/Domain/Repositories/EntityRepositoryInterface.h @@ -1,15 +1,13 @@ #pragma once -#include -#include -#include "../Entities/WorldObject.h" -#include "../DTO/EntityState.h" +#include +#include "../Entities/EntityInterface.h" namespace L2Bot::Domain::Repositories { class EntityRepositoryInterface { public: - virtual const std::vector> GetEntities() = 0; + virtual const std::unordered_map> GetEntities() = 0; virtual void Reset() = 0; }; } diff --git a/L2BotCore/Domain/Services/ChatMessageHandler.h b/L2BotCore/Domain/Services/ChatMessageHandler.h deleted file mode 100644 index f85d29e..0000000 --- a/L2BotCore/Domain/Services/ChatMessageHandler.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include -#include "../Repositories/ChatMessageRepositoryInterface.h" - -namespace L2Bot::Domain::Services -{ - class ChatMessageHandler - { - public: - ChatMessageHandler(Repositories::ChatMessageRepositoryInterface& repository) : m_Repository(repository) - { - - } - ChatMessageHandler() = delete; - virtual ~ChatMessageHandler() = default; - - virtual const std::vector GetMessages() - { - return m_Repository.GetMessages(); - } - private: - Repositories::ChatMessageRepositoryInterface& m_Repository; - }; -} diff --git a/L2BotCore/Domain/Services/EntityHandler.h b/L2BotCore/Domain/Services/EntityHandler.h deleted file mode 100644 index d250d81..0000000 --- a/L2BotCore/Domain/Services/EntityHandler.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include "../DTO/EntityState.h" -#include "../Entities/WorldObject.h" -#include "../Repositories/EntityRepositoryInterface.h" - -namespace L2Bot::Domain::Services -{ - class EntityHandler - { - public: - EntityHandler(Repositories::EntityRepositoryInterface& repository) : m_Repository(repository) - { - - } - EntityHandler() = delete; - virtual ~EntityHandler() = default; - - virtual const std::vector> GetEntities() - { - return m_Repository.GetEntities(); - } - - void Invalidate() - { - m_Repository.Reset(); - } - private: - Repositories::EntityRepositoryInterface& m_Repository; - }; -} diff --git a/L2BotCore/Domain/Services/UnitOfWork.h b/L2BotCore/Domain/Services/UnitOfWork.h new file mode 100644 index 0000000..1110c9c --- /dev/null +++ b/L2BotCore/Domain/Services/UnitOfWork.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "../Entities/EntityInterface.h" +#include "../Enums/EntityStateEnum.h" + +namespace L2Bot::Domain::Services +{ + class UnitOfWork + { + public: + const std::unordered_map ConnectEntities(const std::wstring& name, const std::unordered_map>& entites) + { + std::unordered_map result; + + auto& hashes = m_Hashes[name]; + + for (const auto& kvp : entites) { + const auto &entity = kvp.second; + + if (hashes.size() == 0) { + result[entity->GetId()] = Enums::EntityStateEnum::created; + } + else + { + if (hashes.find(entity->GetId()) == hashes.end()) { + result[entity->GetId()] = Enums::EntityStateEnum::created; + } + else if (hashes[entity->GetId()] != entity->GetHash()) { + result[entity->GetId()] = Enums::EntityStateEnum::updated; + } + } + + hashes[entity->GetId()] = entity->GetHash(); + } + + + for (auto it = hashes.begin(); it != hashes.end();) + { + if (entites.find(it->first) == entites.end()) + { + result[it->first] = Enums::EntityStateEnum::deleted; + it = hashes.erase(it); + } + else + { + ++it; + } + } + + return result; + } + + private: + std::unordered_map > m_Hashes; + }; +} \ No newline at end of file diff --git a/L2BotCore/Domain/ValueObjects/ExperienceInfo.h b/L2BotCore/Domain/ValueObjects/ExperienceInfo.h index 0641af9..8d42128 100644 --- a/L2BotCore/Domain/ValueObjects/ExperienceInfo.h +++ b/L2BotCore/Domain/ValueObjects/ExperienceInfo.h @@ -1,10 +1,13 @@ #pragma once #include +#include #include "../Serializers/Serializable.h" +#include "../Entities/Hashable.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::ValueObjects { - class ExperienceInfo : public Serializers::Serializable + class ExperienceInfo : public Serializers::Serializable, public Entities::Hashable { public: const uint8_t GetLevel() const @@ -19,9 +22,13 @@ namespace L2Bot::Domain::ValueObjects { return m_Sp; } - const bool IsEqual(const ExperienceInfo* other) const + const size_t GetHash() const override { - return m_Level == other->m_Level && m_Exp == other->m_Exp && m_Sp == other->m_Sp; + return Helpers::CombineHashes({ + std::hash{}(m_Level), + std::hash{}(m_Exp), + std::hash{}(m_Sp) + }); } const std::vector BuildSerializationNodes() const override diff --git a/L2BotCore/Domain/ValueObjects/FullName.h b/L2BotCore/Domain/ValueObjects/FullName.h index 934b7b5..a10bbe5 100644 --- a/L2BotCore/Domain/ValueObjects/FullName.h +++ b/L2BotCore/Domain/ValueObjects/FullName.h @@ -1,10 +1,13 @@ #pragma once #include +#include #include "../Serializers/Serializable.h" +#include "../Entities/Hashable.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::ValueObjects { - class FullName : public Serializers::Serializable + class FullName : public Serializers::Serializable, public Entities::Hashable { public: const std::wstring& GetNickname() const @@ -15,9 +18,12 @@ namespace L2Bot::Domain::ValueObjects { return m_Title; } - const bool IsEqual(const FullName* other) const + const size_t GetHash() const override { - return m_Nickname == other->m_Nickname && m_Title == other->m_Title; + return Helpers::CombineHashes({ + std::hash{}(m_Nickname), + std::hash{}(m_Title) + }); } const std::vector BuildSerializationNodes() const override diff --git a/L2BotCore/Domain/ValueObjects/InventoryInfo.h b/L2BotCore/Domain/ValueObjects/InventoryInfo.h index 167257d..9bc316e 100644 --- a/L2BotCore/Domain/ValueObjects/InventoryInfo.h +++ b/L2BotCore/Domain/ValueObjects/InventoryInfo.h @@ -1,10 +1,13 @@ #pragma once #include +#include #include "../Serializers/Serializable.h" +#include "../Entities/Hashable.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::ValueObjects { - class InventoryInfo : public Serializers::Serializable + class InventoryInfo : public Serializers::Serializable, public Entities::Hashable { public: const uint32_t GetMaxWeight() const @@ -19,11 +22,13 @@ namespace L2Bot::Domain::ValueObjects { return m_Slots; } - const bool IsEqual(const InventoryInfo* other) const + const size_t GetHash() const override { - return m_MaxWeight == other->m_MaxWeight && - m_Weight == other->m_Weight && - m_Slots == other->m_Slots; + return Helpers::CombineHashes({ + std::hash{}(m_MaxWeight), + std::hash{}(m_Weight), + std::hash{}(m_Slots) + }); } const std::vector BuildSerializationNodes() const override diff --git a/L2BotCore/Domain/ValueObjects/PermanentStats.h b/L2BotCore/Domain/ValueObjects/PermanentStats.h index 3386c88..1779412 100644 --- a/L2BotCore/Domain/ValueObjects/PermanentStats.h +++ b/L2BotCore/Domain/ValueObjects/PermanentStats.h @@ -1,10 +1,13 @@ #pragma once #include +#include #include "../Serializers/Serializable.h" +#include "../Entities/Hashable.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::ValueObjects { - class PermanentStats : public Serializers::Serializable + class PermanentStats : public Serializers::Serializable, public Entities::Hashable { public: const uint16_t GetStr() const @@ -31,14 +34,16 @@ namespace L2Bot::Domain::ValueObjects { return m_Wit; } - const bool IsEqual(const PermanentStats* other) const + const size_t GetHash() const override { - return m_Str == other->m_Str && - m_Dex == other->m_Dex && - m_Con == other->m_Con && - m_Int == other->m_Int && - m_Men == other->m_Men && - m_Wit == other->m_Wit; + return Helpers::CombineHashes({ + std::hash{}(m_Str), + std::hash{}(m_Dex), + std::hash{}(m_Con), + std::hash{}(m_Int), + std::hash{}(m_Men), + std::hash{}(m_Wit) + }); } const std::vector BuildSerializationNodes() const override diff --git a/L2BotCore/Domain/ValueObjects/Phenotype.h b/L2BotCore/Domain/ValueObjects/Phenotype.h index 9f4121f..2edc4c1 100644 --- a/L2BotCore/Domain/ValueObjects/Phenotype.h +++ b/L2BotCore/Domain/ValueObjects/Phenotype.h @@ -1,11 +1,14 @@ #pragma once +#include #include "../Enums/RaceEnum.h" #include "../Enums/ClassEnum.h" #include "../Serializers/Serializable.h" +#include "../Entities/Hashable.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::ValueObjects { - class Phenotype : public Serializers::Serializable + class Phenotype : public Serializers::Serializable, public Entities::Hashable { public: const bool IsSubClass() const @@ -28,12 +31,14 @@ namespace L2Bot::Domain::ValueObjects { return m_ActiveClass; } - const bool IsEqual(const Phenotype* other) const + const size_t GetHash() const override { - return m_Race == other->m_Race && - m_IsMale == other->m_IsMale && - m_Class == other->m_Class && - m_ActiveClass == other->m_ActiveClass; + return Helpers::CombineHashes({ + std::hash{}(m_Race), + std::hash{}(m_IsMale), + std::hash{}(m_Class), + std::hash{}(m_ActiveClass) + }); } const std::vector BuildSerializationNodes() const override diff --git a/L2BotCore/Domain/ValueObjects/Reputation.h b/L2BotCore/Domain/ValueObjects/Reputation.h index cb0bd2c..e3e535c 100644 --- a/L2BotCore/Domain/ValueObjects/Reputation.h +++ b/L2BotCore/Domain/ValueObjects/Reputation.h @@ -1,10 +1,13 @@ #pragma once #include +#include #include "../Serializers/Serializable.h" +#include "../Entities/Hashable.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::ValueObjects { - class Reputation : public Serializers::Serializable + class Reputation : public Serializers::Serializable, public Entities::Hashable { public: const bool IsPlayerKiller() const @@ -31,13 +34,15 @@ namespace L2Bot::Domain::ValueObjects { return m_EvalScore; } - const bool IsEqual(const Reputation* other) const + const size_t GetHash() const override { - return m_Karma == other->m_Karma && - m_PkKills == other->m_PkKills && - m_PvpKills == other->m_PvpKills && - m_RecRemaining == other->m_RecRemaining && - m_EvalScore == other->m_EvalScore; + return Helpers::CombineHashes({ + std::hash{}(m_Karma), + std::hash{}(m_PkKills), + std::hash{}(m_PvpKills), + std::hash{}(m_RecRemaining), + std::hash{}(m_EvalScore) + }); } const std::vector BuildSerializationNodes() const override diff --git a/L2BotCore/Domain/ValueObjects/Transform.h b/L2BotCore/Domain/ValueObjects/Transform.h index 1c83f06..e5d8618 100644 --- a/L2BotCore/Domain/ValueObjects/Transform.h +++ b/L2BotCore/Domain/ValueObjects/Transform.h @@ -1,10 +1,12 @@ #pragma once #include "../ValueObjects/Vector3.h" #include "../Serializers/Serializable.h" +#include "../Entities/Hashable.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::ValueObjects { - class Transform : public Serializers::Serializable + class Transform : public Serializers::Serializable, public Entities::Hashable { public: const Vector3& GetPosition() const @@ -23,12 +25,14 @@ namespace L2Bot::Domain::ValueObjects { return m_Acceleration; } - const bool IsEqual(const Transform* other) const + const size_t GetHash() const override { - return m_Position.IsEqual(&other->m_Position) && - m_Rotation.IsEqual(&other->m_Rotation) && - m_Velocity.IsEqual(&other->m_Velocity) && - m_Acceleration.IsEqual(&other->m_Acceleration); + return Helpers::CombineHashes({ + m_Position.GetHash(), + m_Rotation.GetHash(), + m_Velocity.GetHash(), + m_Acceleration.GetHash() + }); } const float_t GetSqrDistance(const Transform& other) const { diff --git a/L2BotCore/Domain/ValueObjects/VariableStats.h b/L2BotCore/Domain/ValueObjects/VariableStats.h index 8dab172..da9df66 100644 --- a/L2BotCore/Domain/ValueObjects/VariableStats.h +++ b/L2BotCore/Domain/ValueObjects/VariableStats.h @@ -1,10 +1,13 @@ #pragma once +#include #include #include "../Serializers/Serializable.h" +#include "../Entities/Hashable.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::ValueObjects { - class VariableStats : public Serializers::Serializable + class VariableStats : public Serializers::Serializable, public Entities::Hashable { public: const uint16_t GetAccuracy() const @@ -43,17 +46,19 @@ namespace L2Bot::Domain::ValueObjects { return m_CastingSpeed; } - const bool IsEqual(const VariableStats* other) const + const size_t GetHash() const override { - return m_Accuracy == other->m_Accuracy && - m_CritRate == other->m_CritRate && - m_PAttack == other->m_PAttack && - m_AttackSpeed == other->m_AttackSpeed && - m_PDefense == other->m_PDefense && - m_Evasion == other->m_Evasion && - m_MAttack == other->m_MAttack && - m_MDefense == other->m_MDefense && - m_CastingSpeed == other->m_CastingSpeed; + return Helpers::CombineHashes({ + std::hash{}(m_Accuracy), + std::hash{}(m_CritRate), + std::hash{}(m_PAttack), + std::hash{}(m_AttackSpeed), + std::hash{}(m_PDefense), + std::hash{}(m_Evasion), + std::hash{}(m_MAttack), + std::hash{}(m_MDefense), + std::hash{}(m_CastingSpeed) + }); } const std::vector BuildSerializationNodes() const override diff --git a/L2BotCore/Domain/ValueObjects/Vector3.h b/L2BotCore/Domain/ValueObjects/Vector3.h index 4ccb1d7..2e5f0f9 100644 --- a/L2BotCore/Domain/ValueObjects/Vector3.h +++ b/L2BotCore/Domain/ValueObjects/Vector3.h @@ -1,10 +1,13 @@ #pragma once #include +#include #include "../Serializers/Serializable.h" +#include "../Entities/Hashable.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::ValueObjects { - class Vector3 : public Serializers::Serializable + class Vector3 : public Serializers::Serializable, public Entities::Hashable { public: const float_t GetX() const @@ -19,12 +22,17 @@ namespace L2Bot::Domain::ValueObjects { return m_Z; } - const bool IsEqual(const Vector3* other) const + const size_t GetHash() const override { - float_t epsilon = 0.0001f; - return fabsf(m_X - other->m_X) < epsilon && - fabsf(m_Y - other->m_Y) < epsilon && - fabsf(m_Z - other->m_Z) < epsilon; + const auto x = std::round(m_X * 10000.0f) / 10000.0f; + const auto y = std::round(m_Y * 10000.0f) / 10000.0f; + const auto z = std::round(m_Z * 10000.0f) / 10000.0f; + + return Helpers::CombineHashes({ + std::hash{}(m_X), + std::hash{}(m_Y), + std::hash{}(m_Z) + }); } const float_t GetSqrDistance(const Vector3& other) const { diff --git a/L2BotCore/Domain/ValueObjects/VitalStats.h b/L2BotCore/Domain/ValueObjects/VitalStats.h index 70ede93..9fd9294 100644 --- a/L2BotCore/Domain/ValueObjects/VitalStats.h +++ b/L2BotCore/Domain/ValueObjects/VitalStats.h @@ -1,10 +1,13 @@ #pragma once #include +#include #include "../Serializers/Serializable.h" +#include "../Entities/Hashable.h" +#include "../Helpers/HashCombiner.h" namespace L2Bot::Domain::ValueObjects { - class VitalStats : public Serializers::Serializable + class VitalStats : public Serializers::Serializable, public Entities::Hashable { public: const bool IsAlive() const @@ -35,14 +38,16 @@ namespace L2Bot::Domain::ValueObjects { return m_Cp; } - const bool IsEqual(const VitalStats* other) const + const size_t GetHash() const override { - return m_MaxHp == other->m_MaxHp && - m_Hp == other->m_Hp && - m_MaxMp == other->m_MaxMp && - m_Mp == other->m_Mp && - m_MaxCp == other->m_MaxCp && - m_Cp == other->m_Cp; + return Helpers::CombineHashes({ + std::hash{}(m_MaxHp), + std::hash{}(m_Hp), + std::hash{}(m_MaxMp), + std::hash{}(m_Mp), + std::hash{}(m_MaxCp), + std::hash{}(m_Cp) + }); } const std::vector BuildSerializationNodes() const override diff --git a/L2BotCore/L2BotCore.vcxproj b/L2BotCore/L2BotCore.vcxproj index 0931b6b..53d9e04 100644 --- a/L2BotCore/L2BotCore.vcxproj +++ b/L2BotCore/L2BotCore.vcxproj @@ -166,6 +166,7 @@ + @@ -174,12 +175,11 @@ - - - + + @@ -195,7 +195,6 @@ - @@ -206,9 +205,16 @@ + + + ..\..\pch.h + + + ..\..\pch.h + Create Create diff --git a/L2BotCore/L2BotCore.vcxproj.filters b/L2BotCore/L2BotCore.vcxproj.filters index 0f4b1a8..6d606c8 100644 --- a/L2BotCore/L2BotCore.vcxproj.filters +++ b/L2BotCore/L2BotCore.vcxproj.filters @@ -72,9 +72,6 @@ Header Files - - Header Files - Header Files @@ -138,13 +135,7 @@ Header Files - - Header Files - - - Header Files - - + Header Files @@ -159,10 +150,25 @@ Header Files + + Header Files + + + Header Files + + + Header Files + Source Files + + Source Files + + + Source Files + \ No newline at end of file diff --git a/L2BotDll/L2BotDll.vcxproj b/L2BotDll/L2BotDll.vcxproj index 5dbc15a..6ff9057 100644 --- a/L2BotDll/L2BotDll.vcxproj +++ b/L2BotDll/L2BotDll.vcxproj @@ -188,7 +188,6 @@ - diff --git a/L2BotDll/L2BotDll.vcxproj.filters b/L2BotDll/L2BotDll.vcxproj.filters index a4a5db8..3bf6805 100644 --- a/L2BotDll/L2BotDll.vcxproj.filters +++ b/L2BotDll/L2BotDll.vcxproj.filters @@ -126,9 +126,6 @@ Header Files - - Header Files - Header Files diff --git a/L2BotDll/Services/EntityFinder.h b/L2BotDll/Services/EntityFinder.h deleted file mode 100644 index f3cc960..0000000 --- a/L2BotDll/Services/EntityFinder.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once - -#include -#include -#include -#include "Domain/Repositories/EntityRepositoryInterface.h" -#include "Domain/DTO/EntityState.h" - -using namespace L2Bot::Domain; - -class EntityFinder -{ -public: - template - const std::map>& FindEntities(const std::map items, std::function(T)> callback) - { - RemoveOutdatedStates(); - - for (const auto& kvp : items) - { - const auto item = kvp.second; - auto newObject = callback(item); - if (m_Objects.contains(newObject->GetId())) - { - if (!m_Objects[kvp.first]->GetEntity()->IsEqual(newObject.get())) { - m_Objects[kvp.first]->GetEntity()->Update(newObject.get()); - m_Objects[kvp.first]->UpdateState(Enums::EntityStateEnum::updated); - } - else - { - m_Objects[kvp.first]->UpdateState(Enums::EntityStateEnum::none); - } - } - else - { - const auto objectId = newObject->GetId(); - m_Objects.emplace( - objectId, - std::make_shared(newObject, Enums::EntityStateEnum::created) - ); - } - } - - for (auto& kvp : m_Objects) - { - if (!items.contains(kvp.second->GetEntity()->GetId())) - { - m_Objects[kvp.first]->GetEntity()->SaveState(); - kvp.second->UpdateState(Enums::EntityStateEnum::deleted); - } - } - - return m_Objects; - } - - void Reset() - { - m_Objects.clear(); - } - - EntityFinder() = default; - virtual ~EntityFinder() - { - Reset(); - } -private: - void RemoveOutdatedStates() - { - auto it = m_Objects.begin(); - while (it != m_Objects.end()) - { - if (it->second->GetState() == Enums::EntityStateEnum::deleted) - { - m_Objects.erase(it++); - } - else - { - it++; - } - } - } - -private: - std::map> m_Objects; -}; \ No newline at end of file diff --git a/L2BotDll/Services/WorldHandler.h b/L2BotDll/Services/WorldHandler.h index 386933e..5859e51 100644 --- a/L2BotDll/Services/WorldHandler.h +++ b/L2BotDll/Services/WorldHandler.h @@ -4,14 +4,13 @@ #include #include #include -#include "Domain/Services/EntityHandler.h" -#include "Domain/Services/ChatMessageHandler.h" #include "Domain/Services/HeroServiceInterface.h" #include "Domain/Serializers/SerializerInterface.h" #include "Domain/Serializers/IncomingMessageFactoryInterface.h" #include "Domain/Repositories/EntityRepositoryInterface.h" #include "Domain/Transports/TransportInterface.h" #include "Domain/DTO/Message.h" +#include "Domain/Services/UnitOfWork.h" using namespace L2Bot::Domain; @@ -26,20 +25,20 @@ public: Repositories::EntityRepositoryInterface& skillRepository, Repositories::EntityRepositoryInterface& itemRepository, Repositories::EntityRepositoryInterface& abnormalEffectRepository, - Repositories::ChatMessageRepositoryInterface& chatMessageRepository, + Repositories::EntityRepositoryInterface& chatMessageRepository, const Serializers::SerializerInterface& serializer, const Serializers::IncomingMessageFactoryInterface& incomingMessageFactory, Services::HeroServiceInterface& heroService, Transports::TransportInterface& transport ) : - m_HeroHandler(Services::EntityHandler(heroRepository)), - m_DropHandler(Services::EntityHandler(dropRepository)), - m_NPCHandler(Services::EntityHandler(npcRepository)), - m_PlayerHandler(Services::EntityHandler(playerRepository)), - m_SkillHandler(Services::EntityHandler(skillRepository)), - m_ItemHandler(Services::EntityHandler(itemRepository)), - m_AbnormalEffectHandler(Services::EntityHandler(abnormalEffectRepository)), - m_ChatMessageHandler(Services::ChatMessageHandler(chatMessageRepository)), + m_HeroRepository(heroRepository), + m_DropRepository(dropRepository), + m_NPCRepository(npcRepository), + m_PlayerRepository(playerRepository), + m_SkillRepository(skillRepository), + m_ItemRepository(itemRepository), + m_AbnormalEffectRepository(abnormalEffectRepository), + m_ChatMessageRepository(chatMessageRepository), m_Serializer(serializer), m_IncomingMessageFactory(incomingMessageFactory), m_HeroService(heroService), @@ -157,34 +156,56 @@ private: const std::vector> GetData() { - std::map handlers + std::map handlers { - {L"hero", m_HeroHandler}, - {L"drop", m_DropHandler}, - {L"npc", m_NPCHandler}, - {L"player", m_PlayerHandler}, - {L"skill", m_SkillHandler}, - {L"item", m_ItemHandler}, - {L"abnormalEffect", m_AbnormalEffectHandler} + {L"hero", m_HeroRepository}, + {L"drop", m_DropRepository}, + {L"npc", m_NPCRepository}, + {L"player", m_PlayerRepository}, + {L"skill", m_SkillRepository}, + {L"item", m_ItemRepository}, + {L"abnormalEffect", m_AbnormalEffectRepository}, + {L"chat", m_ChatMessageRepository} }; std::vector> result; - for (auto& kvp : handlers) + for (const auto& kvp : handlers) { - for (const auto& entity : kvp.second.GetEntities()) - { - if (entity->GetState() != Enums::EntityStateEnum::none) + auto& entities = kvp.second.GetEntities(); + const auto& changes = m_UnitOfWork.ConnectEntities(kvp.first, entities); + + for (const auto &changeKvp : changes) { + const auto id = changeKvp.first; + + std::wstring operation = L"none"; + switch (changeKvp.second) { - const auto message = DTO::Message{ kvp.first, entity->GetState(), *entity->GetEntity().get() }; - result.push_back(message.BuildSerializationNodes()); + case Enums::EntityStateEnum::created: + operation = L"create"; + break; + case Enums::EntityStateEnum::updated: + operation = L"update"; + break; + case Enums::EntityStateEnum::deleted: + operation = L"delete"; } - }; - } - for (const auto& chatMessage : m_ChatMessageHandler.GetMessages()) - { - const auto message = DTO::Message{ L"chat", Enums::EntityStateEnum::created, chatMessage }; - result.push_back(message.BuildSerializationNodes()); + + if (entities.find(id) != entities.end()) { + result.push_back({ + Serializers::Node{ L"type", kvp.first }, + Serializers::Node{ L"operation", operation }, + Serializers::Node{ L"content", entities.at(id)->BuildSerializationNodes()} + }); + } + else { + result.push_back({ + Serializers::Node{ L"type", kvp.first }, + Serializers::Node{ L"operation", operation }, + Serializers::Node{ L"content", {Serializers::Node{ L"id", std::to_wstring(id) }}} + }); + } + } } return result; @@ -192,24 +213,24 @@ private: void Invalidate() { - m_DropHandler.Invalidate(); - m_HeroHandler.Invalidate(); - m_NPCHandler.Invalidate(); - m_PlayerHandler.Invalidate(); - m_SkillHandler.Invalidate(); - m_ItemHandler.Invalidate(); - m_AbnormalEffectHandler.Invalidate(); + m_DropRepository.Reset(); + m_HeroRepository.Reset(); + m_NPCRepository.Reset(); + m_PlayerRepository.Reset(); + m_SkillRepository.Reset(); + m_ItemRepository.Reset(); + m_AbnormalEffectRepository.Reset(); } private: - Services::EntityHandler m_DropHandler; - Services::EntityHandler m_HeroHandler; - Services::EntityHandler m_NPCHandler; - Services::EntityHandler m_PlayerHandler; - Services::EntityHandler m_SkillHandler; - Services::EntityHandler m_ItemHandler; - Services::EntityHandler m_AbnormalEffectHandler; - Services::ChatMessageHandler m_ChatMessageHandler; + Repositories::EntityRepositoryInterface& m_DropRepository; + Repositories::EntityRepositoryInterface& m_HeroRepository; + Repositories::EntityRepositoryInterface& m_NPCRepository; + Repositories::EntityRepositoryInterface& m_PlayerRepository; + Repositories::EntityRepositoryInterface& m_SkillRepository; + Repositories::EntityRepositoryInterface& m_ItemRepository; + Repositories::EntityRepositoryInterface& m_AbnormalEffectRepository; + Repositories::EntityRepositoryInterface& m_ChatMessageRepository; const Serializers::SerializerInterface& m_Serializer; const Serializers::IncomingMessageFactoryInterface& m_IncomingMessageFactory; Services::HeroServiceInterface& m_HeroService; @@ -218,4 +239,6 @@ private: std::thread m_ConnectingThread; std::thread m_SendingThread; std::thread m_ReceivingThread; + + Services::UnitOfWork m_UnitOfWork; }; diff --git a/L2BotDll/Versions/GameStructs/FindObjectsTrait.h b/L2BotDll/Versions/GameStructs/FindObjectsTrait.h index bbb3b7f..f12b3a9 100644 --- a/L2BotDll/Versions/GameStructs/FindObjectsTrait.h +++ b/L2BotDll/Versions/GameStructs/FindObjectsTrait.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "GameStructs.h" @@ -9,9 +9,9 @@ class FindObjectsTrait { public: template - std::map FindAllObjects(float_t radius, std::function getNextObject) const + std::unordered_map FindAllObjects(float_t radius, std::function getNextObject) const { - std::map result; + std::unordered_map result; auto object = getNextObject(radius, -1); diff --git a/L2BotDll/Versions/Interlude/AbstractFactory.h b/L2BotDll/Versions/Interlude/AbstractFactory.h index 6d6e7f1..83088a5 100644 --- a/L2BotDll/Versions/Interlude/AbstractFactory.h +++ b/L2BotDll/Versions/Interlude/AbstractFactory.h @@ -22,7 +22,6 @@ #include "GameStructs/GameEngineWrapper.h" #include "GameStructs/L2GameDataWrapper.h" #include "GameStructs/FName.h" -#include "../../Services/EntityFinder.h" #include "Helpers/EnchantHelper.h" namespace Interlude @@ -41,22 +40,18 @@ namespace Interlude HeroRepository& GetHeroRepository() const override { static auto factory = HeroFactory(); - static EntityFinder finder; static auto result = HeroRepository( GetNetworkHandler(), - factory, - finder + factory ); return result; } DropRepository& GetDropRepository() const override { static auto factory = DropFactory(GetL2GameData(), GetFName()); - static EntityFinder finder; static auto result = DropRepository( GetNetworkHandler(), factory, - finder, m_Radius ); return result; @@ -64,11 +59,9 @@ namespace Interlude NPCRepository& GetNPCRepository() const override { static auto factory = NPCFactory(); - static EntityFinder finder; static auto result = NPCRepository( GetNetworkHandler(), factory, - finder, m_Radius ); return result; @@ -76,11 +69,9 @@ namespace Interlude PlayerRepository& GetPlayerRepository() const override { static auto factory = PlayerFactory(); - static EntityFinder finder; static auto result = PlayerRepository( GetNetworkHandler(), factory, - finder, m_Radius ); return result; @@ -88,11 +79,9 @@ namespace Interlude SkillRepository& GetSkillRepository() const override { static auto factory = SkillFactory(GetL2GameData(), GetFName()); - static EntityFinder finder; static auto result = SkillRepository( GetNetworkHandler(), - factory, - finder + factory ); return result; } @@ -100,22 +89,16 @@ namespace Interlude { static EnchantHelper enchantHelper; static auto factory = ItemFactory(GetL2GameData(), GetFName(), enchantHelper); - static EntityFinder finder; static auto result = ItemRepository( GetNetworkHandler(), - factory, - finder + factory ); return result; } AbnormalEffectRepository& GetAbnormalEffectRepository() const override { static auto factory = AbnormalEffectFactory(GetL2GameData(), GetFName()); - static EntityFinder finder; - static auto result = AbnormalEffectRepository( - factory, - finder - ); + static auto result = AbnormalEffectRepository(factory); return result; } ChatMessageRepository& GetChatMessageRepository() const override diff --git a/L2BotDll/Versions/Interlude/Factories/ChatMessageFactory.h b/L2BotDll/Versions/Interlude/Factories/ChatMessageFactory.h index a150846..091009e 100644 --- a/L2BotDll/Versions/Interlude/Factories/ChatMessageFactory.h +++ b/L2BotDll/Versions/Interlude/Factories/ChatMessageFactory.h @@ -1,6 +1,6 @@ #pragma once -#include "Domain/ValueObjects/ChatMessage.h" +#include "Domain/Entities/ChatMessage.h" #include "../../../DTO/ChatMessage.h" using namespace L2Bot::Domain; @@ -13,14 +13,14 @@ namespace Interlude ChatMessageFactory() = default; virtual ~ChatMessageFactory() = default; - ValueObjects::ChatMessage Create(const ChatMessage& message) const + std::shared_ptr Create(const ChatMessage& message) const { - return ValueObjects::ChatMessage{ + return std::make_shared( message.objectId, static_cast(message.channel), message.name, message.text - }; + ); } }; } \ No newline at end of file diff --git a/L2BotDll/Versions/Interlude/Factories/DropFactory.h b/L2BotDll/Versions/Interlude/Factories/DropFactory.h index 5441a97..f038d8a 100644 --- a/L2BotDll/Versions/Interlude/Factories/DropFactory.h +++ b/L2BotDll/Versions/Interlude/Factories/DropFactory.h @@ -11,6 +11,17 @@ namespace Interlude { class DropFactory { + private: + struct Data + { + uint32_t id; + ValueObjects::Transform transform; + uint32_t itemId; + uint32_t amount; + std::wstring name; + std::wstring iconName; + }; + public: DropFactory(const L2GameDataWrapper& l2GameData, const FName& fName) : m_L2GameData(l2GameData), @@ -22,12 +33,40 @@ namespace Interlude virtual ~DropFactory() = default; std::shared_ptr Create(const Item* item) const + { + const auto &data = GetData(item); + + return std::make_shared( + data.id, + data.transform, + data.itemId, + data.amount, + data.name, + data.iconName + ); + } + + void Update(std::shared_ptr& drop, const Item* item) const + { + const auto& data = GetData(item); + + drop->Update( + data.transform, + data.itemId, + data.amount, + data.name, + data.iconName + ); + } + + private: + const Data GetData(const Item* item) const { const auto itemData = m_L2GameData.GetItemData(item->itemId); const auto nameEntry = itemData ? m_FName.GetEntry(itemData->nameIndex) : nullptr; const auto iconEntry = itemData ? m_FName.GetEntry(itemData->iconNameIndex) : nullptr; - return std::make_shared( + return { item->objectId, ValueObjects::Transform( ValueObjects::Vector3(item->pawn->Location.x, item->pawn->Location.y, item->pawn->Location.z), @@ -43,7 +82,7 @@ namespace Interlude item->amount, nameEntry ? std::wstring(nameEntry->value) : L"", iconEntry ? std::wstring(iconEntry->value) : L"" - ); + }; } private: diff --git a/L2BotDll/Versions/Interlude/Factories/HeroFactory.h b/L2BotDll/Versions/Interlude/Factories/HeroFactory.h index 158d542..3db48fc 100644 --- a/L2BotDll/Versions/Interlude/Factories/HeroFactory.h +++ b/L2BotDll/Versions/Interlude/Factories/HeroFactory.h @@ -9,80 +9,137 @@ namespace Interlude { class HeroFactory { + private: + struct Data + { + uint32_t id; + ValueObjects::Transform transform; + ValueObjects::FullName fullName; + ValueObjects::VitalStats vitalStats; + ValueObjects::Phenotype phenotype; + ValueObjects::ExperienceInfo experienceInfo; + ValueObjects::PermanentStats permanentStats; + ValueObjects::VariableStats variableStats; + ValueObjects::Reputation reputation; + ValueObjects::InventoryInfo inventoryInfo; + uint32_t targetId; + bool isStanding; + }; + public: HeroFactory() = default; virtual ~HeroFactory() = default; std::shared_ptr Create(const User* item) const { - const auto playerController = item->pawn ? item->pawn->lineagePlayerController : nullptr; + const auto& data = GetData(item); return std::make_shared( - item->objectId, - ValueObjects::Transform( - ValueObjects::Vector3(item->pawn->Location.x, item->pawn->Location.y, item->pawn->Location.z), - ValueObjects::Vector3( - static_cast(item->pawn->Rotation.Pitch), - static_cast(item->pawn->Rotation.Yaw), - static_cast(item->pawn->Rotation.Roll) - ), - ValueObjects::Vector3(item->pawn->Velocity.x, item->pawn->Velocity.y, item->pawn->Velocity.z), - ValueObjects::Vector3(item->pawn->Acceleration.x, item->pawn->Acceleration.y, item->pawn->Acceleration.z) - ), - ValueObjects::FullName( - std::wstring(item->nickname), - std::wstring(item->title) - ), - ValueObjects::VitalStats( - item->maxHp, item->hp, - item->maxMp, item->mp, - item->maxCp, item->cp - ), - ValueObjects::Phenotype( - (Enums::RaceEnum)item->raceId, - item->gender == L2::Gender::MALE, - (Enums::ClassEnum)item->classId, - (Enums::ClassEnum)item->activeClassId - ), - ValueObjects::ExperienceInfo( - item->lvl, - item->exp, - item->sp - ), - ValueObjects::PermanentStats( - item->str, - item->dex, - item->con, - item->int_, - item->men, - item->wit - ), - ValueObjects::VariableStats( - item->accuracy, - item->critRate, - item->pAttack, - item->attackSpeed, - item->pDefense, - item->evasion, - item->mAttack, - item->mDefense, - item->castingSpeed - ), - ValueObjects::Reputation( - item->karma, - item->pkKills, - item->pvpKills, - static_cast(item->recRemaining), - static_cast(item->evalScore) - ), - ValueObjects::InventoryInfo( - item->maxWeight, - item->weight, - item->invSlotCount - ), - playerController ? playerController->targetObjectId : 0, - playerController ? playerController->isStanding == 1 : true + data.id, + data.transform, + data.fullName, + data.vitalStats, + data.phenotype, + data.experienceInfo, + data.permanentStats, + data.variableStats, + data.reputation, + data.inventoryInfo, + data.targetId, + data.isStanding ); } + + void Update(std::shared_ptr& hero, const User* item) const + { + const auto& data = GetData(item); + + hero->Update( + data.transform, + data.fullName, + data.vitalStats, + data.phenotype, + data.experienceInfo, + data.permanentStats, + data.variableStats, + data.reputation, + data.inventoryInfo, + data.targetId, + data.isStanding + ); + } + + private: + const Data GetData(const User* item) const + { + const auto playerController = item->pawn ? item->pawn->lineagePlayerController : nullptr; + + return { + item->objectId, + ValueObjects::Transform( + ValueObjects::Vector3(item->pawn->Location.x, item->pawn->Location.y, item->pawn->Location.z), + ValueObjects::Vector3( + static_cast(item->pawn->Rotation.Pitch), + static_cast(item->pawn->Rotation.Yaw), + static_cast(item->pawn->Rotation.Roll) + ), + ValueObjects::Vector3(item->pawn->Velocity.x, item->pawn->Velocity.y, item->pawn->Velocity.z), + ValueObjects::Vector3(item->pawn->Acceleration.x, item->pawn->Acceleration.y, item->pawn->Acceleration.z) + ), + ValueObjects::FullName( + std::wstring(item->nickname), + std::wstring(item->title) + ), + ValueObjects::VitalStats( + item->maxHp, item->hp, + item->maxMp, item->mp, + item->maxCp, item->cp + ), + ValueObjects::Phenotype( + (Enums::RaceEnum)item->raceId, + item->gender == L2::Gender::MALE, + (Enums::ClassEnum)item->classId, + (Enums::ClassEnum)item->activeClassId + ), + ValueObjects::ExperienceInfo( + item->lvl, + item->exp, + item->sp + ), + ValueObjects::PermanentStats( + item->str, + item->dex, + item->con, + item->int_, + item->men, + item->wit + ), + ValueObjects::VariableStats( + item->accuracy, + item->critRate, + item->pAttack, + item->attackSpeed, + item->pDefense, + item->evasion, + item->mAttack, + item->mDefense, + item->castingSpeed + ), + ValueObjects::Reputation( + item->karma, + item->pkKills, + item->pvpKills, + static_cast(item->recRemaining), + static_cast(item->evalScore) + ), + ValueObjects::InventoryInfo( + item->maxWeight, + item->weight, + item->invSlotCount + ), + playerController ? playerController->targetObjectId : 0, + playerController ? playerController->isStanding == 1 : true + }; + } }; } \ No newline at end of file diff --git a/L2BotDll/Versions/Interlude/Factories/ItemFactory.h b/L2BotDll/Versions/Interlude/Factories/ItemFactory.h index d868519..e34cca2 100644 --- a/L2BotDll/Versions/Interlude/Factories/ItemFactory.h +++ b/L2BotDll/Versions/Interlude/Factories/ItemFactory.h @@ -19,6 +19,64 @@ namespace Interlude { class ItemFactory { + private: + struct BaseData + { + uint32_t objectId; + uint32_t itemId; + int32_t mana; + std::wstring name; + std::wstring iconName; + std::wstring description; + uint16_t weight; + }; + + struct EtcData : public BaseData + { + uint32_t amount; + bool isQuest; + }; + + struct ArmorData : public BaseData + { + bool isEquipped; + uint16_t enchantLevel; + Enums::ArmorTypeEnum armorType; + Enums::CrystalTypeEnum crystalType; + uint32_t pDefense; + uint32_t mDefense; + std::wstring setEffect; + std::wstring addSetEffect; + std::wstring enchantEffect; + }; + + struct ShieldData : public BaseData + { + bool isEquipped; + uint16_t enchantLevel; + Enums::CrystalTypeEnum crystalType; + int16_t evasion; + uint32_t pDefense; + uint16_t defRate; + }; + + struct WeaponData : public BaseData + { + bool isEquipped; + uint16_t enchantLevel; + Enums::WeaponTypeEnum weaponType; + Enums::CrystalTypeEnum crystalType; + uint8_t rndDamage; + uint32_t pAttack; + uint32_t mAttack; + uint16_t critical; + int8_t hitModify; + uint16_t atkSpd; + uint8_t mpConsume; + uint8_t soulshotCount; + uint8_t spiritshotCount; + }; + public: ItemFactory(const L2GameDataWrapper& l2GameData, const FName& fName, const EnchantHelper& enchantHelper) : m_L2GameData(l2GameData), @@ -33,7 +91,237 @@ namespace Interlude std::shared_ptr Create(const ItemData& itemInfo) const { //FIXME during first start data may be undefined - const auto data = m_L2GameData.GetItemData(itemInfo.itemId); + const auto data = GetItemData(itemInfo.itemId); + + if (data) + { + switch (data->dataType) + { + case L2::ItemDataType::ARMOR: + return CreateArmor(itemInfo); + case L2::ItemDataType::WEAPON: + return CreateWeaponOrShield(itemInfo); + } + + return CreateEtc(itemInfo); + } + + return nullptr; + } + + void Update(std::shared_ptr& item, const ItemData& itemInfo) const + { + //FIXME during first start data may be undefined + const auto data = GetItemData(itemInfo.itemId); + + if (data) + { + switch (data->dataType) + { + case L2::ItemDataType::ARMOR: + UpdateArmor(item, itemInfo); + return; + case L2::ItemDataType::WEAPON: + UpdateWeaponOrShield(item, itemInfo); + return; + } + } + + UpdateEtc(item, itemInfo); + } + + private: + std::shared_ptr CreateEtc(const ItemData& itemInfo) const + { + const auto& data = GetEtcData(itemInfo); + + return std::make_shared( + data.objectId, + data.itemId, + data.mana, + data.name, + data.iconName, + data.description, + data.weight, + data.amount, + data.isQuest + ); + } + + void UpdateEtc(std::shared_ptr &item, const ItemData& itemInfo) const + { + auto etcItem = std::dynamic_pointer_cast(item); + + const auto& data = GetEtcData(itemInfo); + + etcItem->Update( + data.itemId, + data.mana, + data.name, + data.iconName, + data.description, + data.weight, + data.amount, + data.isQuest + ); + } + + std::shared_ptr CreateArmor(const ItemData& itemInfo) const + { + const auto& data = GetArmorData(itemInfo); + + return std::make_shared( + data.objectId, + data.itemId, + data.mana, + data.name, + data.iconName, + data.description, + data.weight, + data.isEquipped, + data.enchantLevel, + data.armorType, + data.crystalType, + data.pDefense, + data.mDefense, + data.setEffect, + data.addSetEffect, + data.enchantEffect + ); + } + + void UpdateArmor(std::shared_ptr& item, const ItemData& itemInfo) const + { + auto armorItem = std::dynamic_pointer_cast(item); + + const auto& data = GetArmorData(itemInfo); + + armorItem->Update( + data.itemId, + data.mana, + data.name, + data.iconName, + data.description, + data.weight, + data.isEquipped, + data.enchantLevel, + data.armorType, + data.crystalType, + data.pDefense, + data.mDefense, + data.setEffect, + data.addSetEffect, + data.enchantEffect + ); + } + + std::shared_ptr CreateWeaponOrShield(const ItemData& itemInfo) const + { + const auto itemData = static_cast(GetItemData(itemInfo.itemId)); + + if (itemData->weaponType != L2::WeaponType::SHIELD) + { + const auto& data = GetWeaponData(itemInfo, itemData); + + return std::make_shared( + data.objectId, + data.itemId, + data.mana, + data.name, + data.iconName, + data.description, + data.weight, + data.isEquipped, + data.enchantLevel, + data.weaponType, + data.crystalType, + data.rndDamage, + data.pAttack, + data.mAttack, + data.critical, + data.hitModify, + data.atkSpd, + data.mpConsume, + data.soulshotCount, + data.spiritshotCount + ); + } + + const auto& data = GetShieldData(itemInfo, itemData); + + return std::make_shared( + data.objectId, + data.itemId, + data.mana, + data.name, + data.iconName, + data.description, + data.weight, + data.isEquipped, + data.enchantLevel, + data.crystalType, + data.evasion, + data.pDefense, + data.defRate + ); + } + + void UpdateWeaponOrShield(std::shared_ptr& item, const ItemData& itemInfo) const + { + const auto itemData = static_cast(GetItemData(itemInfo.itemId)); + + if (itemData->weaponType != L2::WeaponType::SHIELD) + { + auto weaponItem = std::dynamic_pointer_cast(item); + const auto& data = GetWeaponData(itemInfo, itemData); + + weaponItem->Update( + data.itemId, + data.mana, + data.name, + data.iconName, + data.description, + data.weight, + data.isEquipped, + data.enchantLevel, + data.weaponType, + data.crystalType, + data.rndDamage, + data.pAttack, + data.mAttack, + data.critical, + data.hitModify, + data.atkSpd, + data.mpConsume, + data.soulshotCount, + data.spiritshotCount + ); + + return; + } + + auto shieldItem = std::dynamic_pointer_cast(item); + const auto& data = GetShieldData(itemInfo, itemData); + + shieldItem->Update( + data.itemId, + data.mana, + data.name, + data.iconName, + data.description, + data.weight, + data.isEquipped, + data.enchantLevel, + data.crystalType, + data.evasion, + data.pDefense, + data.defRate + ); + } + + const BaseData GetBaseData(const ItemData& itemInfo) const + { + const auto data = GetItemData(itemInfo.itemId); const auto nameEntry = data ? m_FName.GetEntry(data->nameIndex) : nullptr; const auto name = nameEntry ? std::wstring(nameEntry->value) : L""; @@ -41,99 +329,52 @@ namespace Interlude const auto icon = iconEntry ? std::wstring(iconEntry->value) : L""; const auto description = data && data->description ? std::wstring(data->description) : L""; - if (data) - { - switch (data->dataType) - { - case L2::ItemDataType::ARMOR: - return CreateArmor(itemInfo, data, name, icon, description); - case L2::ItemDataType::WEAPON: - return CreateWeaponOrShield(itemInfo, data, name, icon, description); - } - } - - return CreateEtc(itemInfo, data, name, icon, description); - } - - std::shared_ptr Copy(std::shared_ptr other) const - { - auto otherPtr = other.get(); - { - const auto object = dynamic_cast(otherPtr); - if (object) - { - return std::make_shared(object); - } - } - { - const auto object = dynamic_cast(otherPtr); - if (object) - { - return std::make_shared(object); - } - } - { - const auto object = dynamic_cast(otherPtr); - if (object) - { - return std::make_shared(object); - } - } - { - const auto object = dynamic_cast(otherPtr); - if (object) - { - return std::make_shared(object); - } - } - - return std::make_shared(otherPtr); - } - - private: - std::shared_ptr CreateEtc( - const ItemData& itemInfo, - const FL2ItemDataBase* itemData, - const std::wstring& name, - const std::wstring& icon, - const std::wstring& description - ) const - { - return std::make_shared( + return { itemInfo.objectId, itemInfo.itemId, itemInfo.mana, name, icon, description, - itemData ? itemData->weight : 0, - itemInfo.amount, - itemInfo.isQuest - ); + (uint16_t)(data ? data->weight : 0) + }; } - std::shared_ptr CreateArmor( - const ItemData& itemInfo, - const FL2ItemDataBase* itemData, - const std::wstring& name, - const std::wstring& icon, - const std::wstring& description - ) const + const EtcData GetEtcData(const ItemData& itemInfo) const { - const auto casted = static_cast(itemData); + const auto& baseData = GetBaseData(itemInfo); + + return { + baseData.objectId, + baseData.itemId, + baseData.mana, + baseData.name, + baseData.iconName, + baseData.description, + baseData.weight, + itemInfo.amount, + itemInfo.isQuest + }; + } + + const ArmorData GetArmorData(const ItemData& itemInfo) const + { + const auto& baseData = GetBaseData(itemInfo); + + const auto casted = static_cast(GetItemData(itemInfo.itemId)); const auto setEffect = casted && casted->setEffect ? std::wstring(casted->setEffect) : L""; const auto addSetEffect = casted && casted->setEffect ? std::wstring(casted->setEffect) : L""; const auto enchantEffect = casted && casted->enchantEffect ? std::wstring(casted->enchantEffect) : L""; - return std::make_shared( - itemInfo.objectId, - itemInfo.itemId, - itemInfo.mana, - name, - icon, - description, - itemData ? itemData->weight : 0, + return { + baseData.objectId, + baseData.itemId, + baseData.mana, + baseData.name, + baseData.iconName, + baseData.description, + baseData.weight, itemInfo.isEquipped > 0, itemInfo.enchantLevel, casted ? static_cast(casted->armorType) : Enums::ArmorTypeEnum::none, @@ -143,60 +384,61 @@ namespace Interlude setEffect, addSetEffect, enchantEffect - ); + }; } - std::shared_ptr CreateWeaponOrShield( - const ItemData& itemInfo, - const FL2ItemDataBase* itemData, - const std::wstring& name, - const std::wstring& icon, - const std::wstring& description - ) const + const ShieldData GetShieldData(const ItemData& itemInfo, const FL2WeaponItemData* itemData) const { - const auto casted = static_cast(itemData); + const auto& baseData = GetBaseData(itemInfo); - if (casted->weaponType != L2::WeaponType::SHIELD) - { - return std::make_shared( - itemInfo.objectId, - itemInfo.itemId, - itemInfo.mana, - name, - icon, - description, - itemData ? itemData->weight : 0, - itemInfo.isEquipped > 0, - itemInfo.enchantLevel, - casted ? static_cast(casted->weaponType) : Enums::WeaponTypeEnum::none, - casted ? static_cast(casted->crystalType) : Enums::CrystalTypeEnum::none, - casted ? casted->rndDamage : 0, - m_EnchantHelper.GetPAttackEnchantValue(casted->weaponType, itemInfo.isTwoHanded, casted->crystalType, casted ? casted->pAttack : 0, itemInfo.enchantLevel), - m_EnchantHelper.GetMAttackEnchantValue(casted->crystalType, casted ? casted->mAttack : 0, itemInfo.enchantLevel), - casted ? casted->critical : 0, - casted ? casted->hitModify : 0, - casted ? casted->atkSpd : 0, - casted ? casted->mpConsume : 0, - casted ? casted->soulshotCount : 0, - casted ? casted->spiritshotCount : 0 - ); - } - - return std::make_shared( - itemInfo.objectId, - itemInfo.itemId, - itemInfo.mana, - name, - icon, - description, - itemData ? itemData->weight : 0, + return { + baseData.objectId, + baseData.itemId, + baseData.mana, + baseData.name, + baseData.iconName, + baseData.description, + baseData.weight, itemInfo.isEquipped > 0, itemInfo.enchantLevel, - casted ? static_cast(casted->crystalType) : Enums::CrystalTypeEnum::none, - casted ? casted->shieldEvasion : 0, - m_EnchantHelper.GetDefenseEnchantValue(casted ? casted->shieldPdef : 0, itemInfo.enchantLevel), - casted ? casted->shieldDefRate : 0 - ); + itemData ? static_cast(itemData->crystalType) : Enums::CrystalTypeEnum::none, + (int16_t)(itemData ? itemData->shieldEvasion : 0), + m_EnchantHelper.GetDefenseEnchantValue(itemData ? itemData->shieldPdef : 0, itemInfo.enchantLevel), + (uint16_t)(itemData ? itemData->shieldDefRate : 0) + }; + } + + const WeaponData GetWeaponData(const ItemData& itemInfo, const FL2WeaponItemData* itemData) const + { + const auto& baseData = GetBaseData(itemInfo); + + return { + baseData.objectId, + baseData.itemId, + baseData.mana, + baseData.name, + baseData.iconName, + baseData.description, + baseData.weight, + itemInfo.isEquipped > 0, + itemInfo.enchantLevel, + itemData ? static_cast(itemData->weaponType) : Enums::WeaponTypeEnum::none, + itemData ? static_cast(itemData->crystalType) : Enums::CrystalTypeEnum::none, + (uint8_t)(itemData ? itemData->rndDamage : 0), + m_EnchantHelper.GetPAttackEnchantValue(itemData->weaponType, itemInfo.isTwoHanded, itemData->crystalType, itemData ? itemData->pAttack : 0, itemInfo.enchantLevel), + m_EnchantHelper.GetMAttackEnchantValue(itemData->crystalType, itemData ? itemData->mAttack : 0, itemInfo.enchantLevel), + (uint16_t)(itemData ? itemData->critical : 0), + (int8_t)(itemData ? itemData->hitModify : 0), + (uint16_t)(itemData ? itemData->atkSpd : 0), + (uint8_t)(itemData ? itemData->mpConsume : 0), + (uint8_t)(itemData ? itemData->soulshotCount : 0), + (uint8_t)(itemData ? itemData->spiritshotCount : 0) + }; + } + + const FL2ItemDataBase* GetItemData(const uint32_t itemId) const + { + return m_L2GameData.GetItemData(itemId); } private: diff --git a/L2BotDll/Versions/Interlude/Factories/NPCFactory.h b/L2BotDll/Versions/Interlude/Factories/NPCFactory.h index c4c26f1..5d9f60e 100644 --- a/L2BotDll/Versions/Interlude/Factories/NPCFactory.h +++ b/L2BotDll/Versions/Interlude/Factories/NPCFactory.h @@ -8,13 +8,52 @@ namespace Interlude { class NPCFactory { + private: + struct Data + { + uint32_t id; + ValueObjects::Transform transform; + bool isHostile; + uint32_t npcId; + ValueObjects::FullName fullName; + ValueObjects::VitalStats vitalStats; + }; + public: NPCFactory() = default; virtual ~NPCFactory() = default; - std::shared_ptr Create(const User* item, const Enums::SpoilStateEnum spoiledState) const + std::shared_ptr Create(const User* item) const { + const auto& data = GetData(item); + return std::make_shared( + data.id, + data.transform, + data.isHostile, + data.npcId, + data.fullName, + data.vitalStats + ); + } + + void Update(std::shared_ptr& npc, const User* item) const + { + const auto& data = GetData(item); + + npc->Update( + data.transform, + data.isHostile, + data.npcId, + data.fullName, + data.vitalStats + ); + } + + private: + const Data GetData(const User* item) const + { + return { item->objectId, ValueObjects::Transform( ValueObjects::Vector3(item->pawn->Location.x, item->pawn->Location.y, item->pawn->Location.z), @@ -28,7 +67,6 @@ namespace Interlude ), item->isMob != 0, item->npcId, - spoiledState, ValueObjects::FullName( std::wstring(item->nickname), std::wstring(item->title) @@ -38,7 +76,7 @@ namespace Interlude item->maxMp, item->mp, item->maxCp, item->cp ) - ); + }; } }; } \ No newline at end of file diff --git a/L2BotDll/Versions/Interlude/Factories/PlayerFactory.h b/L2BotDll/Versions/Interlude/Factories/PlayerFactory.h index 54e8139..4c4f2ae 100644 --- a/L2BotDll/Versions/Interlude/Factories/PlayerFactory.h +++ b/L2BotDll/Versions/Interlude/Factories/PlayerFactory.h @@ -8,13 +8,49 @@ namespace Interlude { class PlayerFactory { + private: + struct Data + { + uint32_t id; + ValueObjects::Transform transform; + ValueObjects::FullName fullName; + ValueObjects::Phenotype phenotype; + ValueObjects::VitalStats vitalStats; + }; + public: PlayerFactory() = default; virtual ~PlayerFactory() = default; std::shared_ptr Create(const User* item) const { + const auto& data = GetData(item); + return std::make_shared( + data.id, + data.transform, + data.fullName, + data.phenotype, + data.vitalStats + ); + } + + void Update(std::shared_ptr &player, const User* item) const + { + const auto& data = GetData(item); + + player->Update( + data.transform, + data.fullName, + data.phenotype, + data.vitalStats + ); + } + + private: + const Data GetData(const User* item) const + { + return { item->objectId, ValueObjects::Transform( ValueObjects::Vector3(item->pawn->Location.x, item->pawn->Location.y, item->pawn->Location.z), @@ -41,7 +77,7 @@ namespace Interlude item->maxMp, item->mp, item->maxCp, item->cp ) - ); + }; } }; } \ No newline at end of file diff --git a/L2BotDll/Versions/Interlude/Factories/SkillFactory.h b/L2BotDll/Versions/Interlude/Factories/SkillFactory.h index 800608a..c102da4 100644 --- a/L2BotDll/Versions/Interlude/Factories/SkillFactory.h +++ b/L2BotDll/Versions/Interlude/Factories/SkillFactory.h @@ -14,6 +14,19 @@ namespace Interlude { class SkillFactory { + private: + struct Data + { + uint32_t skillId; + uint8_t level; + bool isActive; + uint8_t cost; + int16_t range; + std::wstring name; + std::wstring description; + std::wstring iconName; + }; + public: SkillFactory(const L2GameDataWrapper& l2GameData, const FName& fName) : m_L2GameData(l2GameData), @@ -26,16 +39,37 @@ namespace Interlude std::shared_ptr Create(const uint32_t skillId, const uint32_t level, const uint32_t isActive) const { - return std::make_shared(BuildSkillData(skillId, level, isActive)); + const auto& data = GetData(skillId, level, isActive); + + return std::make_shared( + data.skillId, + data.level, + data.isActive, + data.cost, + data.range, + data.name, + data.description, + data.iconName + ); } void Update(std::shared_ptr& skill, const uint32_t skillId, const uint32_t level, const uint32_t isActive) const { - skill->Update(BuildSkillData(skillId, level, isActive)); + const auto& data = GetData(skillId, level, isActive); + + skill->Update( + data.level, + data.isActive, + data.cost, + data.range, + data.name, + data.description, + data.iconName + ); } private: - const Entities::Skill::Data BuildSkillData(const uint32_t skillId, const uint32_t level, const uint32_t isActive) const + const Data GetData(const uint32_t skillId, const uint32_t level, const uint32_t isActive) const { const auto data = m_L2GameData.GetMSData(skillId, level); diff --git a/L2BotDll/Versions/Interlude/Repositories/AbnormalEffectRepository.h b/L2BotDll/Versions/Interlude/Repositories/AbnormalEffectRepository.h index 68ba36d..dc5162d 100644 --- a/L2BotDll/Versions/Interlude/Repositories/AbnormalEffectRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/AbnormalEffectRepository.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "Domain/Repositories/EntityRepositoryInterface.h" @@ -9,7 +9,6 @@ #include "../../../Events/HeroDeletedEvent.h" #include "../../../Events/EventDispatcher.h" #include "../GameStructs/NetworkHandlerWrapper.h" -#include "../../../Services/EntityFinder.h" using namespace L2Bot::Domain; @@ -18,27 +17,15 @@ namespace Interlude class AbnormalEffectRepository : public Repositories::EntityRepositoryInterface { public: - const std::vector> GetEntities() override + const std::unordered_map> GetEntities() override { std::unique_lock(m_Mutex); - const auto objects = m_EntityFinder.FindEntities>(m_Effects, [this](std::shared_ptr item) { - return std::make_shared(item.get()); - }); - - auto result = std::vector>(); - - for (const auto kvp : objects) - { - result.push_back(kvp.second); - } - - return result; + return m_Effects; } - AbnormalEffectRepository(const AbnormalEffectFactory& factory, EntityFinder& finder) : - m_Factory(factory), - m_EntityFinder(finder) + AbnormalEffectRepository(const AbnormalEffectFactory& factory) : + m_Factory(factory) { EventDispatcher::GetInstance().Subscribe(AbnormalEffectChangedEvent::name, [this](const Event& evt) { OnEffectToggled(evt); @@ -75,40 +62,48 @@ namespace Interlude if (evt.GetName() == AbnormalEffectChangedEvent::name) { const auto casted = static_cast(evt); - const auto skillInfo = casted.GetSkillInfo(); + + const auto &actualIds = Create(casted.GetSkillInfo()); + Delete(actualIds); + } + } - std::map ids; - for (size_t i = 0; i < skillInfo.size(); i += 3) + private: + const std::unordered_map Create(const std::vector &skillInfo) + { + std::unordered_map ids; + + for (size_t i = 0; i < skillInfo.size(); i += 3) + { + const auto effectId = skillInfo[i]; + const auto level = skillInfo[i + 1]; + + m_Effects[effectId] = m_Factory.Create(effectId, level); + + ids[effectId] = effectId; + } + + return ids; + } + + void Delete(const std::unordered_map &actualIds) + { + for (auto it = m_Effects.begin(); it != m_Effects.end();) + { + if (actualIds.find(it->second->GetId()) == actualIds.end()) { - const auto effectId = skillInfo[i]; - const auto level = skillInfo[i + 1]; - - auto effect = m_Factory.Create(effectId, level); - m_Effects.emplace(effect->GetId(), effect); - - ids[effectId] = effectId; + it = m_Effects.erase(it); } - - for (auto it = m_Effects.begin(); it != m_Effects.end();) + else { - const auto& effect = it->second; - - if (ids.find(effect->GetId()) == ids.end()) - { - it = m_Effects.erase(it); - } - else - { - ++it; - } + ++it; } } } private: const AbnormalEffectFactory& m_Factory; - std::map> m_Effects; + std::unordered_map> m_Effects; std::shared_timed_mutex m_Mutex; - EntityFinder& m_EntityFinder; }; } \ No newline at end of file diff --git a/L2BotDll/Versions/Interlude/Repositories/ChatMessageRepository.h b/L2BotDll/Versions/Interlude/Repositories/ChatMessageRepository.h index 7293127..aab817d 100644 --- a/L2BotDll/Versions/Interlude/Repositories/ChatMessageRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/ChatMessageRepository.h @@ -2,7 +2,6 @@ #include #include -#include "Domain/Repositories/ChatMessageRepositoryInterface.h" #include "../Factories/ChatMessageFactory.h" #include "../../../Events/ChatMessageCreatedEvent.h" #include "../../../Events/EventDispatcher.h" @@ -11,17 +10,20 @@ using namespace L2Bot::Domain; namespace Interlude { - class ChatMessageRepository : public Repositories::ChatMessageRepositoryInterface + class ChatMessageRepository : public Repositories::EntityRepositoryInterface { public: - const std::vector GetMessages() override + const std::unordered_map> GetEntities() override { std::unique_lock(m_Mutex); - const auto result = m_Messages; - m_Messages.clear(); + return m_Messages; + } - return result; + void Reset() + { + std::shared_lock(m_Mutex); + m_Messages.clear(); } ChatMessageRepository(const ChatMessageFactory& factory) : @@ -39,7 +41,8 @@ namespace Interlude { const auto casted = static_cast(evt); - m_Messages.push_back(m_Factory.Create(casted.GetChatMessage())); + const auto message = m_Factory.Create(casted.GetChatMessage()); + m_Messages[message->GetId()] = message; } } @@ -48,7 +51,7 @@ namespace Interlude private: const ChatMessageFactory& m_Factory; - std::vector m_Messages; + std::unordered_map> m_Messages; std::shared_timed_mutex m_Mutex; }; } \ No newline at end of file diff --git a/L2BotDll/Versions/Interlude/Repositories/DropRepository.h b/L2BotDll/Versions/Interlude/Repositories/DropRepository.h index cade317..d4afecd 100644 --- a/L2BotDll/Versions/Interlude/Repositories/DropRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/DropRepository.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "Domain/Repositories/EntityRepositoryInterface.h" @@ -8,7 +8,6 @@ #include "../Factories/DropFactory.h" #include "../../GameStructs/FindObjectsTrait.h" #include "../GameStructs/NetworkHandlerWrapper.h" -#include "../../../Services/EntityFinder.h" using namespace L2Bot::Domain; @@ -17,22 +16,25 @@ namespace Interlude class DropRepository : public Repositories::EntityRepositoryInterface, public FindObjectsTrait { public: - const std::vector> GetEntities() override + const std::unordered_map> GetEntities() override { std::unique_lock(m_Mutex); - const std::map items = FindAllObjects(m_Radius, [this](float_t radius, int32_t prevId) { + const auto allItems = FindAllObjects(m_Radius, [this](float_t radius, int32_t prevId) { return m_NetworkHandler.GetNextItem(radius, prevId); }); - const auto objects = m_EntityFinder.FindEntities(items, [this](Item* item) { - return m_Factory.Create(item); - }); - auto result = std::vector>(); - - for (const auto kvp : objects) - { - result.push_back(kvp.second); + std::unordered_map> result; + for (const auto kvp : allItems) { + const auto item = kvp.second; + if (m_Drops.find(item->objectId) == m_Drops.end()) { + m_Drops[item->objectId] = m_Factory.Create(item); + } + else + { + m_Factory.Update(m_Drops[item->objectId], item); + } + result[item->objectId] = m_Drops[item->objectId]; } return result; @@ -41,14 +43,13 @@ namespace Interlude void Reset() override { std::shared_lock(m_Mutex); - m_EntityFinder.Reset(); + m_Drops.clear(); } - DropRepository(const NetworkHandlerWrapper& networkHandler, const DropFactory& factory, EntityFinder& finder, const uint16_t radius) : + DropRepository(const NetworkHandlerWrapper& networkHandler, const DropFactory& factory, const uint16_t radius) : m_NetworkHandler(networkHandler), m_Factory(factory), - m_Radius(radius), - m_EntityFinder(finder) + m_Radius(radius) { } @@ -60,7 +61,7 @@ namespace Interlude const NetworkHandlerWrapper& m_NetworkHandler; const DropFactory& m_Factory; const uint16_t m_Radius; - EntityFinder& m_EntityFinder; std::shared_timed_mutex m_Mutex; + std::unordered_map> m_Drops; }; } diff --git a/L2BotDll/Versions/Interlude/Repositories/HeroRepository.h b/L2BotDll/Versions/Interlude/Repositories/HeroRepository.h index 1f04bdb..e836d35 100644 --- a/L2BotDll/Versions/Interlude/Repositories/HeroRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/HeroRepository.h @@ -7,7 +7,6 @@ #include "../../../Events/HeroCreatedEvent.h" #include "../../../Events/HeroDeletedEvent.h" #include "../GameStructs/NetworkHandlerWrapper.h" -#include "../../../Services/EntityFinder.h" using namespace L2Bot::Domain; @@ -16,39 +15,28 @@ namespace Interlude class HeroRepository : public Repositories::EntityRepositoryInterface { public: - const std::vector> GetEntities() override + const std::unordered_map> GetEntities() override { std::unique_lock(m_Mutex); - auto hero = m_NetworkHandler.GetHero(); + const auto hero = m_NetworkHandler.GetHero(); - if (hero != nullptr && m_PrevHero == nullptr) - { - EventDispatcher::GetInstance().Dispatch(HeroCreatedEvent{}); + std::unordered_map> result; + if (hero) { + if (!m_Hero) { + m_Hero = m_Factory.Create(hero); + EventDispatcher::GetInstance().Dispatch(HeroCreatedEvent{}); + } + else + { + m_Factory.Update(m_Hero, hero); + } + result[hero->objectId] = m_Hero; } - if (hero == nullptr && m_PrevHero != nullptr) - { + else { + m_Hero = nullptr; EventDispatcher::GetInstance().Dispatch(HeroDeletedEvent{}); } - m_PrevHero = hero; - - std::map items; - - if (hero) - { - items.emplace(hero->objectId, hero); - } - - const auto objects = m_EntityFinder.FindEntities(items, [this](User* item) { - return m_Factory.Create(item); - }); - - auto result = std::vector>(); - - for (const auto kvp : objects) - { - result.push_back(kvp.second); - } return result; } @@ -56,13 +44,12 @@ namespace Interlude void Reset() override { std::shared_lock(m_Mutex); - m_EntityFinder.Reset(); + m_Hero = nullptr; } - HeroRepository(const NetworkHandlerWrapper& networkHandler, const HeroFactory& factory, EntityFinder& finder) : + HeroRepository(const NetworkHandlerWrapper& networkHandler, const HeroFactory& factory) : m_NetworkHandler(networkHandler), - m_Factory(factory), - m_EntityFinder(finder) + m_Factory(factory) { } @@ -73,8 +60,6 @@ namespace Interlude private: const HeroFactory& m_Factory; const NetworkHandlerWrapper& m_NetworkHandler; - User* m_PrevHero = nullptr; - EntityFinder& m_EntityFinder; - std::shared_timed_mutex m_Mutex; + std::shared_ptr m_Hero; }; } \ No newline at end of file diff --git a/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h b/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h index f72a435..52eef0b 100644 --- a/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h @@ -1,12 +1,11 @@ #pragma once -#include +#include #include #include #include "Domain/Repositories/EntityRepositoryInterface.h" #include "../Factories/ItemFactory.h" #include "../GameStructs/NetworkHandlerWrapper.h" -#include "../../../Services/EntityFinder.h" #include "../../../Events/ItemCreatedEvent.h" #include "../../../Events/ItemUpdatedEvent.h" #include "../../../Events/ItemDeletedEvent.h" @@ -22,21 +21,11 @@ namespace Interlude class ItemRepository : public Repositories::EntityRepositoryInterface { public: - const std::vector> GetEntities() override + const std::unordered_map> GetEntities() override { std::unique_lock(m_Mutex); - const auto objects = m_EntityFinder.FindEntities>(m_Items, [this](std::shared_ptr item) { - return m_Factory.Copy(item); - }); - - auto result = std::vector>(); - - for (const auto kvp : objects) - { - result.push_back(kvp.second); - } - + std::unordered_map> result(m_Items.begin(), m_Items.end()); return result; } @@ -51,10 +40,9 @@ namespace Interlude return nullptr; } - ItemRepository(const NetworkHandlerWrapper& networkHandler, const ItemFactory& factory, EntityFinder& finder) : + ItemRepository(const NetworkHandlerWrapper& networkHandler, const ItemFactory& factory) : m_NetworkHandler(networkHandler), - m_Factory(factory), - m_EntityFinder(finder) + m_Factory(factory) { EventDispatcher::GetInstance().Subscribe(ItemCreatedEvent::name, [this](const Event& evt) { OnItemCreated(evt); @@ -121,10 +109,13 @@ namespace Interlude { if (kvp.second->GetItemId() == itemId) { - auto ptr = dynamic_cast(kvp.second.get()); - if (ptr) + auto casted = std::dynamic_pointer_cast(kvp.second); + if (isEnabled) { + casted->StartAutouse(); + } + else { - ptr->Autouse(isEnabled); + casted->StopAutouse(); } } } @@ -145,15 +136,18 @@ namespace Interlude const auto casted = static_cast(evt); const auto& data = casted.GetItemData(); - auto item = m_Factory.Create(data); + if (m_Items.find(data.objectId) == m_Items.end()) { - m_Items.emplace(data.objectId, item); + auto item = m_Factory.Create(data); + if (item) { + m_Items[data.objectId] = item; + } } else { // When equip/unequip accessories - m_Items[data.objectId]->Update(item.get()); + m_Factory.Update(m_Items[data.objectId], data); } m_NewItems[data.objectId] = data.objectId; } @@ -173,8 +167,7 @@ namespace Interlude return; } - auto item = m_Factory.Create(data); - m_Items[data.objectId]->Update(item.get()); + m_Factory.Update(m_Items[data.objectId], data); } } @@ -207,12 +200,11 @@ namespace Interlude private: const ItemFactory& m_Factory; - std::map> m_Items; - std::map m_NewItems; + std::unordered_map> m_Items; + std::unordered_map m_NewItems; bool m_IsNewCycle = true; - uint32_t m_UsedSkillId = 0; + std::uint32_t m_UsedSkillId = 0; const NetworkHandlerWrapper& m_NetworkHandler; std::shared_timed_mutex m_Mutex; - EntityFinder& m_EntityFinder; }; } \ No newline at end of file diff --git a/L2BotDll/Versions/Interlude/Repositories/NPCRepository.h b/L2BotDll/Versions/Interlude/Repositories/NPCRepository.h index e4f3cf5..7e95c30 100644 --- a/L2BotDll/Versions/Interlude/Repositories/NPCRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/NPCRepository.h @@ -9,7 +9,6 @@ #include "../../../Events/SpoiledEvent.h" #include "../../../Events/CreatureDiedEvent.h" #include "../../GameStructs/FindObjectsTrait.h" -#include "../../../Services/EntityFinder.h" using namespace L2Bot::Domain; @@ -18,33 +17,33 @@ namespace Interlude class NPCRepository : public Repositories::EntityRepositoryInterface, public FindObjectsTrait { public: - const std::vector> GetEntities() override + const std::unordered_map> GetEntities() override { std::unique_lock(m_Mutex); - const auto creatures = FindAllObjects(m_Radius, [this](float_t radius, int32_t prevId) { + const auto allCreatures = FindAllObjects(m_Radius, [this](float_t radius, int32_t prevId) { return m_NetworkHandler.GetNextCreature(radius, prevId); }); - std::map items; - for (const auto& kvp : creatures) - { + std::unordered_map> result; + for (const auto kvp : allCreatures) { const auto creature = kvp.second; - if (creature->userType == L2::UserType::NPC) { - items.emplace(creature->objectId, creature); + if (creature->userType != L2::UserType::NPC) { + continue; } - } - const auto objects = m_EntityFinder.FindEntities(items, [this](User* item) { - const auto spoilState = m_Spoiled.find(item->objectId) == m_Spoiled.end() ? Enums::SpoilStateEnum::none : m_Spoiled.at(item->objectId); - return m_Factory.Create(item, spoilState); - }); + if (m_Npcs.find(creature->objectId) == m_Npcs.end()) { + m_Npcs[creature->objectId] = m_Factory.Create(creature); + } + else + { + m_Factory.Update(m_Npcs[creature->objectId], creature); + } - auto result = std::vector>(); + const auto spoilState = m_Spoiled.find(creature->objectId) == m_Spoiled.end() ? Enums::SpoilStateEnum::none : m_Spoiled[creature->objectId]; + m_Npcs[creature->objectId]->UpdateSpoilState(spoilState); - for (const auto kvp : objects) - { - result.push_back(kvp.second); + result[creature->objectId] = m_Npcs[creature->objectId]; } return result; @@ -53,14 +52,13 @@ namespace Interlude void Reset() override { std::shared_lock(m_Mutex); - m_EntityFinder.Reset(); + m_Npcs.clear(); } - NPCRepository(const NetworkHandlerWrapper& networkHandler, const NPCFactory& factory, EntityFinder& finder, const uint16_t radius) : + NPCRepository(const NetworkHandlerWrapper& networkHandler, const NPCFactory& factory, const uint16_t radius) : m_NetworkHandler(networkHandler), m_Factory(factory), - m_Radius(radius), - m_EntityFinder(finder) + m_Radius(radius) { EventDispatcher::GetInstance().Subscribe(SpoiledEvent::name, [this](const Event& evt) { OnSpoiled(evt); @@ -75,6 +73,7 @@ namespace Interlude void OnSpoiled(const Event& evt) { + std::shared_lock(m_Mutex); if (evt.GetName() == SpoiledEvent::name) { const auto casted = static_cast(evt); @@ -92,6 +91,7 @@ namespace Interlude void OnCreatureDied(const Event& evt) { + std::shared_lock(m_Mutex); if (evt.GetName() == CreatureDiedEvent::name) { const auto casted = static_cast(evt); @@ -115,7 +115,7 @@ namespace Interlude std::map m_Spoiled; const NetworkHandlerWrapper& m_NetworkHandler; const uint16_t m_Radius = 0; - EntityFinder& m_EntityFinder; std::shared_timed_mutex m_Mutex; + std::unordered_map> m_Npcs; }; } \ No newline at end of file diff --git a/L2BotDll/Versions/Interlude/Repositories/PlayerRepository.h b/L2BotDll/Versions/Interlude/Repositories/PlayerRepository.h index cbe674a..8452b56 100644 --- a/L2BotDll/Versions/Interlude/Repositories/PlayerRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/PlayerRepository.h @@ -1,11 +1,9 @@ #pragma once -#include -#include +#include #include "Domain/Repositories/EntityRepositoryInterface.h" #include "../Factories/PlayerFactory.h" #include "../../GameStructs/FindObjectsTrait.h" #include "../GameStructs/NetworkHandlerWrapper.h" -#include "../../../Services/EntityFinder.h" using namespace L2Bot::Domain; @@ -14,32 +12,29 @@ namespace Interlude class PlayerRepository : public Repositories::EntityRepositoryInterface, public FindObjectsTrait { public: - const std::vector> GetEntities() override + const std::unordered_map> GetEntities() override { - std::unique_lock(m_Mutex); - - const auto creatures = FindAllObjects(m_Radius, [this](float_t radius, int32_t prevId) { + const auto allCreatures = FindAllObjects(m_Radius, [this](float_t radius, int32_t prevId) { return m_NetworkHandler.GetNextCreature(radius, prevId); }); - std::map items; - for (const auto& kvp : creatures) + std::unordered_map> result; + for (const auto& kvp : allCreatures) { - const auto creature = kvp.second; - if (creature->userType == L2::UserType::USER && creature->lvl == 0) { - items.emplace(creature->objectId, creature); + const auto &creature = kvp.second; + if (creature->userType != L2::UserType::USER || creature->lvl != 0) { + continue; } - } - const auto objects = m_EntityFinder.FindEntities(items, [this](User* item) { - return m_Factory.Create(item); - }); + if (m_Players.find(creature->objectId) == m_Players.end()) { + m_Players[creature->objectId] = m_Factory.Create(creature); + } + else + { + m_Factory.Update(m_Players[creature->objectId], creature); + } - auto result = std::vector>(); - - for (const auto kvp : objects) - { - result.push_back(kvp.second); + result[creature->objectId] = m_Players[creature->objectId]; } return result; @@ -48,14 +43,13 @@ namespace Interlude void Reset() override { std::shared_lock(m_Mutex); - m_EntityFinder.Reset(); + m_Players.clear(); } - PlayerRepository(const NetworkHandlerWrapper& networkHandler, const PlayerFactory& factory, EntityFinder& finder, const uint16_t radius) : + PlayerRepository(const NetworkHandlerWrapper& networkHandler, const PlayerFactory& factory, const uint16_t radius) : m_NetworkHandler(networkHandler), m_Factory(factory), - m_Radius(radius), - m_EntityFinder(finder) + m_Radius(radius) { } @@ -67,7 +61,6 @@ namespace Interlude const PlayerFactory& m_Factory; const NetworkHandlerWrapper& m_NetworkHandler; const uint16_t m_Radius; - EntityFinder& m_EntityFinder; - std::shared_timed_mutex m_Mutex; + std::unordered_map> m_Players; }; } \ No newline at end of file diff --git a/L2BotDll/Versions/Interlude/Repositories/SkillRepository.h b/L2BotDll/Versions/Interlude/Repositories/SkillRepository.h index e063819..b3b6f1c 100644 --- a/L2BotDll/Versions/Interlude/Repositories/SkillRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/SkillRepository.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "Domain/Repositories/EntityRepositoryInterface.h" @@ -14,7 +14,6 @@ #include "../../../Events/EventDispatcher.h" #include "../GameStructs/NetworkHandlerWrapper.h" #include "../../../Common/TimerMap.h" -#include "../../../Services/EntityFinder.h" using namespace L2Bot::Domain; @@ -23,28 +22,17 @@ namespace Interlude class SkillRepository : public Repositories::EntityRepositoryInterface { public: - const std::vector> GetEntities() override + const std::unordered_map> GetEntities() override { std::unique_lock(m_Mutex); - const auto objects = m_EntityFinder.FindEntities>(m_Skills, [this](std::shared_ptr item) { - return std::make_shared(item.get()); - }); - - auto result = std::vector>(); - - for (const auto kvp : objects) - { - result.push_back(kvp.second); - } - + std::unordered_map> result(m_Skills.begin(), m_Skills.end()); return result; } - SkillRepository(const NetworkHandlerWrapper& networkHandler, const SkillFactory& factory, EntityFinder& finder) : + SkillRepository(const NetworkHandlerWrapper& networkHandler, const SkillFactory& factory) : m_NetworkHandler(networkHandler), - m_Factory(factory), - m_EntityFinder(finder) + m_Factory(factory) { EventDispatcher::GetInstance().Subscribe(SkillCreatedEvent::name, [this](const Event& evt) { OnSkillCreated(evt); @@ -130,17 +118,17 @@ namespace Interlude if (m_Skills.find(skillId) == m_Skills.end()) { - auto skill = m_Factory.Create( + m_Skills[skillId] = m_Factory.Create( skillInfo[2], skillInfo[1], skillInfo[0] ); - m_Skills[skill->GetId()] = skill; } else { + auto skill = m_Skills[skillId]; m_Factory.Update( - m_Skills[skillId], + skill, skillInfo[2], skillInfo[1], skillInfo[0] @@ -198,10 +186,8 @@ namespace Interlude return; } - const auto& skill = m_Skills[m_UsedSkillId]; - - skill->StopCasting(); - m_CastingTimers.StopTimer(skill->GetId()); + m_Skills[m_UsedSkillId]->StopCasting(); + m_CastingTimers.StopTimer(m_UsedSkillId); m_UsedSkillId = 0; } @@ -215,7 +201,7 @@ namespace Interlude const auto casted = static_cast(evt); const auto skillInfo = casted.GetSkillInfo(); - std::map ids; + std::unordered_map ids; for (size_t i = 0; i < skillInfo.size(); i += 3) { @@ -244,14 +230,13 @@ namespace Interlude private: const SkillFactory& m_Factory; - std::map> m_Skills; - std::map m_NewSkills; + std::unordered_map> m_Skills; + std::unordered_map m_NewSkills; bool m_IsNewCycle = true; uint32_t m_UsedSkillId = 0; const NetworkHandlerWrapper& m_NetworkHandler; TimerMap m_ReloadingTimers; TimerMap m_CastingTimers; std::shared_timed_mutex m_Mutex; - EntityFinder& m_EntityFinder; }; } \ No newline at end of file diff --git a/L2BotDll/Versions/VersionAbstractFactory.h b/L2BotDll/Versions/VersionAbstractFactory.h index 5cd1674..ad2455c 100644 --- a/L2BotDll/Versions/VersionAbstractFactory.h +++ b/L2BotDll/Versions/VersionAbstractFactory.h @@ -1,7 +1,6 @@ #pragma once #include "Domain/Repositories/EntityRepositoryInterface.h" -#include "Domain/Repositories/ChatMessageRepositoryInterface.h" #include "Domain/Services/HeroServiceInterface.h" #include "GameStructs/NetworkHandlerInterface.h" #include "GameStructs/GameEngineInterface.h" @@ -25,7 +24,7 @@ public: virtual Repositories::EntityRepositoryInterface& GetSkillRepository() const = 0; virtual Repositories::EntityRepositoryInterface& GetItemRepository() const = 0; virtual Repositories::EntityRepositoryInterface& GetAbnormalEffectRepository() const = 0; - virtual Repositories::ChatMessageRepositoryInterface& GetChatMessageRepository() const = 0; + virtual Repositories::EntityRepositoryInterface& GetChatMessageRepository() const = 0; virtual Services::HeroServiceInterface& GetHeroService() const = 0; virtual NetworkHandlerInterface& GetNetworkHandler() const = 0; virtual GameEngineInterface& GetGameEngine() const = 0;