feat: add base item
This commit is contained in:
		| @@ -2,34 +2,33 @@ | ||||
| #include <cstdint> | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include "../DTO/BaseItem.h" | ||||
| #include "../Serializers/Serializable.h" | ||||
| #include "../Serializers/Node.h" | ||||
| #include "EntityInterface.h" | ||||
| 
 | ||||
| namespace L2Bot::Domain::ValueObjects | ||||
| namespace L2Bot::Domain::Entities | ||||
| { | ||||
| 	class BaseItem : public Serializers::Serializable | ||||
| 	class BaseItem : public EntityInterface | ||||
| 	{ | ||||
| 	public: | ||||
| 		const uint32_t GetId() const | ||||
| 		{ | ||||
| 			return m_ItemId; | ||||
| 		} | ||||
| 		void Update(const BaseItem* other) | ||||
| 		void Update(const EntityInterface* other) override | ||||
| 		{ | ||||
| 			const BaseItem* casted = static_cast<const BaseItem*>(other); | ||||
| 			SaveState(); | ||||
| 
 | ||||
| 			m_ItemId = other->m_ItemId; | ||||
| 			m_Amount = other->m_Amount; | ||||
| 			m_IsEquipped = other->m_IsEquipped; | ||||
| 			m_EnchantLevel = other->m_EnchantLevel; | ||||
| 			m_Mana = other->m_Mana; | ||||
| 			m_Name = other->m_Name; | ||||
| 			m_IconName = other->m_IconName; | ||||
| 			m_Description = other->m_Description; | ||||
| 			m_Weight = other->m_Weight; | ||||
| 			m_ItemId = casted->m_ItemId; | ||||
| 			m_Amount = casted->m_Amount; | ||||
| 			m_IsEquipped = casted->m_IsEquipped; | ||||
| 			m_EnchantLevel = casted->m_EnchantLevel; | ||||
| 			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; | ||||
| 		} | ||||
| 		void SaveState() | ||||
| 		void SaveState() override | ||||
| 		{ | ||||
| 			m_PrevState = | ||||
| 			{ | ||||
| @@ -41,17 +40,18 @@ namespace L2Bot::Domain::ValueObjects | ||||
| 				false | ||||
| 			}; | ||||
| 		} | ||||
| 		const bool IsEqual(const BaseItem* other) const | ||||
| 		const bool IsEqual(const EntityInterface* other) const override | ||||
| 		{ | ||||
| 			return m_ItemId == other->m_ItemId && | ||||
| 				m_Amount == other->m_Amount && | ||||
| 				m_IsEquipped == other->m_IsEquipped && | ||||
| 				m_EnchantLevel == other->m_EnchantLevel && | ||||
| 				m_Mana == other->m_Mana && | ||||
| 				m_Name == other->m_Name && | ||||
| 				m_IconName == other->m_IconName && | ||||
| 				m_Description == other->m_Description && | ||||
| 				m_Weight == other->m_Weight; | ||||
| 			const BaseItem* casted = static_cast<const BaseItem*>(other); | ||||
| 			return m_ItemId == casted->m_ItemId && | ||||
| 				m_Amount == casted->m_Amount && | ||||
| 				m_IsEquipped == casted->m_IsEquipped && | ||||
| 				m_EnchantLevel == casted->m_EnchantLevel && | ||||
| 				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; | ||||
| 		} | ||||
| 
 | ||||
| 		const std::vector<Serializers::Node> BuildSerializationNodes() const override | ||||
| @@ -114,6 +114,19 @@ namespace L2Bot::Domain::ValueObjects | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		BaseItem(const BaseItem* other) : | ||||
| 			m_ItemId(other->m_ItemId), | ||||
| 			m_Amount(other->m_Amount), | ||||
| 			m_IsEquipped(other->m_IsEquipped), | ||||
| 			m_EnchantLevel(other->m_EnchantLevel), | ||||
| 			m_Mana(other->m_Mana), | ||||
| 			m_Name(other->m_Name), | ||||
| 			m_IconName(other->m_IconName), | ||||
| 			m_Description(other->m_Description), | ||||
| 			m_Weight(other->m_Weight) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		BaseItem() = default; | ||||
| 		virtual ~BaseItem() = default; | ||||
| 
 | ||||
| @@ -2,7 +2,7 @@ | ||||
| #include <cstdint> | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include "WorldObject.h" | ||||
| #include "EntityInterface.h" | ||||
|  | ||||
| namespace L2Bot::Domain::Entities | ||||
| { | ||||
|   | ||||
| @@ -161,7 +161,7 @@ | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="Domain\DTO\EntityState.h" /> | ||||
|     <ClInclude Include="Domain\Entities\EntityInterface.h" /> | ||||
|     <ClInclude Include="Domain\ValueObjects\BaseItem.h" /> | ||||
|     <ClInclude Include="Domain\Entities\BaseItem.h" /> | ||||
|     <ClInclude Include="Domain\Entities\Skill.h" /> | ||||
|     <ClInclude Include="Domain\ValueObjects\Vector3.h" /> | ||||
|     <ClInclude Include="Domain\Enums\SpoilStateEnum.h" /> | ||||
|   | ||||
| @@ -102,7 +102,7 @@ | ||||
|     <ClInclude Include="Domain\Entities\Skill.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="Domain\ValueObjects\BaseItem.h"> | ||||
|     <ClInclude Include="Domain\Entities\BaseItem.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="Domain\DTO\EntityState.h"> | ||||
|   | ||||
| @@ -24,6 +24,7 @@ public: | ||||
| 			m_AbstractFactory.GetNPCRepository(), | ||||
| 			m_AbstractFactory.GetPlayerRepository(), | ||||
| 			m_AbstractFactory.GetSkillRepository(), | ||||
| 			m_AbstractFactory.GetItemRepository(), | ||||
| 			m_Serializer, | ||||
| 			m_Transport | ||||
| 		) | ||||
|   | ||||
							
								
								
									
										12
									
								
								L2BotDll/DTO/ItemData.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								L2BotDll/DTO/ItemData.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <cstdint> | ||||
|  | ||||
| struct ItemData | ||||
| { | ||||
| 	const uint32_t itemId = 0; | ||||
| 	const uint32_t amount = 0; | ||||
| 	const uint16_t isEquipped = 0; | ||||
| 	const uint16_t enchantLevel = 0; | ||||
| 	const int32_t mana = -1; | ||||
| }; | ||||
							
								
								
									
										34
									
								
								L2BotDll/Events/ItemCreatedEvent.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								L2BotDll/Events/ItemCreatedEvent.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <cstdint> | ||||
| #include <vector> | ||||
| #include "Event.h" | ||||
| #include "../DTO/ItemData.h" | ||||
|  | ||||
| class ItemCreatedEvent : public Event | ||||
| { | ||||
| public: | ||||
| 	static constexpr const char* name = "itemCreated"; | ||||
|  | ||||
| 	const std::string GetName() const | ||||
| 	{ | ||||
| 		return std::string(name); | ||||
| 	} | ||||
|  | ||||
| 	const ItemData& GetItemData() const | ||||
| 	{ | ||||
| 		return m_ItemData; | ||||
| 	} | ||||
|  | ||||
| 	ItemCreatedEvent(const ItemData& itemData) : | ||||
| 		m_ItemData(itemData) | ||||
| 	{ | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	ItemCreatedEvent() = delete; | ||||
| 	virtual ~ItemCreatedEvent() = default; | ||||
|  | ||||
| private: | ||||
| 	const ItemData m_ItemData; | ||||
| }; | ||||
							
								
								
									
										34
									
								
								L2BotDll/Events/ItemDeletedEvent.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								L2BotDll/Events/ItemDeletedEvent.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <cstdint> | ||||
| #include <vector> | ||||
| #include "Event.h" | ||||
| #include "../DTO/ItemData.h" | ||||
|  | ||||
| class ItemDeletedEvent : public Event | ||||
| { | ||||
| public: | ||||
| 	static constexpr const char* name = "itemDeleted"; | ||||
|  | ||||
| 	const std::string GetName() const | ||||
| 	{ | ||||
| 		return std::string(name); | ||||
| 	} | ||||
|  | ||||
| 	const uint32_t GetItemId() const | ||||
| 	{ | ||||
| 		return m_Id; | ||||
| 	} | ||||
|  | ||||
| 	ItemDeletedEvent(const uint32_t id) : | ||||
| 		m_Id(id) | ||||
| 	{ | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	ItemDeletedEvent() = delete; | ||||
| 	virtual ~ItemDeletedEvent() = default; | ||||
|  | ||||
| private: | ||||
| 	const uint32_t m_Id; | ||||
| }; | ||||
							
								
								
									
										34
									
								
								L2BotDll/Events/ItemUpdatedEvent.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								L2BotDll/Events/ItemUpdatedEvent.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <cstdint> | ||||
| #include <vector> | ||||
| #include "Event.h" | ||||
| #include "../DTO/ItemData.h" | ||||
|  | ||||
| class ItemUpdatedEvent : public Event | ||||
| { | ||||
| public: | ||||
| 	static constexpr const char* name = "itemUpdated"; | ||||
|  | ||||
| 	const std::string GetName() const | ||||
| 	{ | ||||
| 		return std::string(name); | ||||
| 	} | ||||
|  | ||||
| 	const ItemData& GetItemData() const | ||||
| 	{ | ||||
| 		return m_ItemData; | ||||
| 	} | ||||
|  | ||||
| 	ItemUpdatedEvent(const ItemData& itemData) : | ||||
| 		m_ItemData(itemData) | ||||
| 	{ | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	ItemUpdatedEvent() = delete; | ||||
| 	virtual ~ItemUpdatedEvent() = default; | ||||
|  | ||||
| private: | ||||
| 	const ItemData m_ItemData; | ||||
| }; | ||||
| @@ -164,11 +164,15 @@ | ||||
|     <ClInclude Include="Common\apihook.h" /> | ||||
|     <ClInclude Include="Common\Common.h" /> | ||||
|     <ClInclude Include="Common\TimerMap.h" /> | ||||
|     <ClInclude Include="DTO\ItemData.h" /> | ||||
|     <ClInclude Include="Events\CreatureDiedEvent.h" /> | ||||
|     <ClInclude Include="Events\Event.h" /> | ||||
|     <ClInclude Include="Events\EventDispatcher.h" /> | ||||
|     <ClInclude Include="Events\HeroCreatedEvent.h" /> | ||||
|     <ClInclude Include="Events\HeroDeletedEvent.h" /> | ||||
|     <ClInclude Include="Events\ItemCreatedEvent.h" /> | ||||
|     <ClInclude Include="Events\ItemDeletedEvent.h" /> | ||||
|     <ClInclude Include="Events\ItemUpdatedEvent.h" /> | ||||
|     <ClInclude Include="Events\SkillCancelledEvent.h" /> | ||||
|     <ClInclude Include="Events\SkillCreatedEvent.h" /> | ||||
|     <ClInclude Include="Events\AbnormalEffectChangedEvent.h" /> | ||||
| @@ -182,6 +186,7 @@ | ||||
|     <ClInclude Include="Versions\GameStructs\GameEngineInterface.h" /> | ||||
|     <ClInclude Include="Versions\GameStructs\L2GameDataInterface.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\Factories\HeroFactory.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\Factories\ItemFactory.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\Factories\NPCFactory.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\Factories\PlayerFactory.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\Factories\SkillFactory.h" /> | ||||
| @@ -203,6 +208,7 @@ | ||||
|     <ClInclude Include="Versions\Interlude\Factories\DropFactory.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\AbstractFactory.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\Repositories\HeroRepository.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\Repositories\ItemRepository.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\Repositories\NPCRepository.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\Repositories\PlayerRepository.h" /> | ||||
|     <ClInclude Include="Versions\Interlude\Repositories\SkillRepository.h" /> | ||||
|   | ||||
| @@ -153,6 +153,24 @@ | ||||
|     <ClInclude Include="Versions\Interlude\Repositories\SkillRepository.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="Versions\Interlude\Factories\ItemFactory.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="Versions\Interlude\Repositories\ItemRepository.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="Events\ItemCreatedEvent.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="DTO\ItemData.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="Events\ItemUpdatedEvent.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="Events\ItemDeletedEvent.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="dllmain.cpp"> | ||||
|   | ||||
| @@ -21,6 +21,7 @@ public: | ||||
| 		Repositories::EntityRepositoryInterface& npcRepository, | ||||
| 		Repositories::EntityRepositoryInterface& playerRepository, | ||||
| 		Repositories::EntityRepositoryInterface& skillRepository, | ||||
| 		Repositories::EntityRepositoryInterface& itemRepository, | ||||
| 		const Serializers::SerializerInterface& serializer, | ||||
| 		Transports::TransportInterface& transport | ||||
| 	) : | ||||
| @@ -29,6 +30,7 @@ public: | ||||
| 		m_NPCService(Services::EntityService(npcRepository)), | ||||
| 		m_PlayerService(Services::EntityService(playerRepository)), | ||||
| 		m_SkillService(Services::EntityService(skillRepository)), | ||||
| 		m_ItemService(Services::EntityService(itemRepository)), | ||||
| 		m_Serializer(serializer), | ||||
| 		m_Transport(transport) | ||||
| 	{ | ||||
| @@ -117,11 +119,12 @@ private: | ||||
| 	{ | ||||
| 		std::vector<Serializers::SerializableStateContainer> items | ||||
| 		{ | ||||
| 			Serializers::SerializableStateContainer{m_HeroService.GetEntities(), "hero"}, | ||||
| 			/*Serializers::SerializableStateContainer{m_HeroService.GetEntities(), "hero"}, | ||||
| 			Serializers::SerializableStateContainer{m_DropService.GetEntities(), "drop"}, | ||||
| 			Serializers::SerializableStateContainer{m_NPCService.GetEntities(), "npc"}, | ||||
| 			Serializers::SerializableStateContainer{m_PlayerService.GetEntities(), "player"}, | ||||
| 			Serializers::SerializableStateContainer{m_SkillService.GetEntities(), "skill"}, | ||||
| 			Serializers::SerializableStateContainer{m_SkillService.GetEntities(), "skill"},*/ | ||||
| 			Serializers::SerializableStateContainer{m_ItemService.GetEntities(), "item"}, | ||||
| 		}; | ||||
|  | ||||
| 		std::vector<Serializers::Node> result; | ||||
| @@ -143,6 +146,7 @@ private: | ||||
| 		m_NPCService.Invalidate(); | ||||
| 		m_PlayerService.Invalidate(); | ||||
| 		m_SkillService.Invalidate(); | ||||
| 		m_ItemService.Invalidate(); | ||||
| 	} | ||||
|  | ||||
| private: | ||||
| @@ -151,6 +155,7 @@ private: | ||||
| 	Services::EntityService m_NPCService; | ||||
| 	Services::EntityService m_PlayerService; | ||||
| 	Services::EntityService m_SkillService; | ||||
| 	Services::EntityService m_ItemService; | ||||
| 	const Serializers::SerializerInterface& m_Serializer; | ||||
| 	Transports::TransportInterface& m_Transport; | ||||
| 	bool m_Stopped = false; | ||||
|   | ||||
| @@ -6,11 +6,13 @@ | ||||
| #include "Factories/NPCFactory.h" | ||||
| #include "Factories/PlayerFactory.h" | ||||
| #include "Factories/SkillFactory.h" | ||||
| #include "Factories/ItemFactory.h" | ||||
| #include "Repositories/DropRepository.h" | ||||
| #include "Repositories/HeroRepository.h" | ||||
| #include "Repositories/NPCRepository.h" | ||||
| #include "Repositories/PlayerRepository.h" | ||||
| #include "Repositories/SkillRepository.h" | ||||
| #include "Repositories/ItemRepository.h" | ||||
| #include "GameStructs/NetworkHandlerWrapper.h" | ||||
| #include "GameStructs/GameEngineWrapper.h" | ||||
| #include "GameStructs/L2GameDataWrapper.h" | ||||
| @@ -88,6 +90,17 @@ namespace Interlude | ||||
| 			); | ||||
| 			return result; | ||||
| 		} | ||||
| 		ItemRepository& GetItemRepository() const override | ||||
| 		{ | ||||
| 			static auto factory = ItemFactory(GetL2GameData(), GetFName()); | ||||
| 			static EntityHandler handler; | ||||
| 			static auto result = ItemRepository( | ||||
| 				GetNetworkHandler(), | ||||
| 				factory, | ||||
| 				handler | ||||
| 			); | ||||
| 			return result; | ||||
| 		} | ||||
| 		NetworkHandlerWrapper& GetNetworkHandler() const override | ||||
| 		{ | ||||
| 			static NetworkHandlerWrapper result; | ||||
|   | ||||
							
								
								
									
										53
									
								
								L2BotDll/Versions/Interlude/Factories/ItemFactory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								L2BotDll/Versions/Interlude/Factories/ItemFactory.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <memory> | ||||
| #include <map> | ||||
| #include <chrono> | ||||
| #include "../GameStructs/L2GameDataWrapper.h" | ||||
| #include "../GameStructs/FName.h" | ||||
| #include "../../../Common/Common.h" | ||||
| #include "Domain/Entities/BaseItem.h" | ||||
| #include "../../../DTO/ItemData.h" | ||||
|  | ||||
| using namespace L2Bot::Domain; | ||||
|  | ||||
| namespace Interlude | ||||
| { | ||||
| 	class ItemFactory | ||||
| 	{ | ||||
| 	public: | ||||
| 		ItemFactory(const L2GameDataWrapper& l2GameData, const FName& fName) : | ||||
| 			m_L2GameData(l2GameData), | ||||
| 			m_FName(fName) | ||||
| 		{ | ||||
| 		} | ||||
|  | ||||
| 		ItemFactory() = delete; | ||||
| 		virtual ~ItemFactory() = default; | ||||
|  | ||||
| 		std::unique_ptr<Entities::BaseItem> Create(const ItemData& itemInfo) const | ||||
| 		{ | ||||
| 			const auto data = m_L2GameData.GetItemData(itemInfo.itemId); | ||||
|  | ||||
| 			const auto nameEntry = data ? m_FName.GetEntry(data->nameIndex) : nullptr; | ||||
| 			const auto iconEntry = data ? m_FName.GetEntry(data->iconNameIndex) : nullptr; | ||||
| 			const auto description = data && data->description ? data->description : L""; | ||||
|  | ||||
| 			return std::make_unique<Entities::BaseItem>( | ||||
| 				itemInfo.itemId, | ||||
| 				itemInfo.amount, | ||||
| 				itemInfo.isEquipped > 0, | ||||
| 				itemInfo.enchantLevel, | ||||
| 				itemInfo.mana, | ||||
| 				nameEntry ? ConvertFromWideChar(nameEntry->value) : "", | ||||
| 				iconEntry ? ConvertFromWideChar(iconEntry->value) : "", | ||||
| 				ConvertFromWideChar(description), | ||||
| 				data ? data->weight : 0 | ||||
| 			); | ||||
| 		} | ||||
|  | ||||
| 	private: | ||||
| 		const L2GameDataWrapper& m_L2GameData; | ||||
| 		const FName& m_FName; | ||||
| 	}; | ||||
| } | ||||
| @@ -30,8 +30,8 @@ namespace Interlude | ||||
|  | ||||
| 			const auto cost = data ? data->mpCost : 0; | ||||
| 			const auto range = data ? data->range : 0; | ||||
| 			const auto name = data ? data->name : L""; | ||||
| 			const auto description = data ? data->description : L""; | ||||
| 			const auto name = data && data->name ? data->name : L""; | ||||
| 			const auto description = data && data->description ? data->description : L""; | ||||
| 			const auto iconEntry = data ? m_FName.GetEntry(data->iconNameIndex) : nullptr; | ||||
|  | ||||
| 			return std::make_unique<Entities::Skill>( | ||||
|   | ||||
| @@ -7,6 +7,10 @@ | ||||
| #include "../../../Events/SkillCancelledEvent.h" | ||||
| #include "../../../Events/AbnormalEffectChangedEvent.h" | ||||
| #include "../../../Events/EventDispatcher.h" | ||||
| #include "../../../Events/ItemCreatedEvent.h" | ||||
| #include "../../../Events/ItemUpdatedEvent.h" | ||||
| #include "../../../Events/ItemDeletedEvent.h" | ||||
| #include "../../../DTO/ItemData.h" | ||||
|  | ||||
| namespace Interlude | ||||
| { | ||||
| @@ -18,6 +22,8 @@ namespace Interlude | ||||
| 	int(__thiscall* GameEngineWrapper::__OnReceiveMagicSkillUse)(GameEngine*, User*, User*, L2ParamStack&) = 0; | ||||
| 	void(__thiscall* GameEngineWrapper::__OnReceiveMagicSkillCanceled)(GameEngine*, User*) = 0; | ||||
| 	void(__thiscall* GameEngineWrapper::__AddAbnormalStatus)(GameEngine*, L2ParamStack&) = 0; | ||||
| 	void(__thiscall* GameEngineWrapper::__AddInventoryItem)(GameEngine*, ItemInfo&) = 0; | ||||
| 	void(__thiscall* GameEngineWrapper::__OnReceiveUpdateItemList)(GameEngine*, UpdateItemListActionType, ItemInfo&) = 0; | ||||
|  | ||||
|  | ||||
| 	void GameEngineWrapper::Init(HMODULE hModule) | ||||
| @@ -38,6 +44,12 @@ namespace Interlude | ||||
| 		(FARPROC&)__AddAbnormalStatus = (FARPROC)splice( | ||||
| 			GetProcAddress(hModule, "?AddAbnormalStatus@UGameEngine@@UAEXAAVL2ParamStack@@@Z"), __AddAbnormalStatus_hook | ||||
| 		); | ||||
| 		(FARPROC&)__AddInventoryItem = (FARPROC)splice( | ||||
| 			GetProcAddress(hModule, "?AddInventoryItem@UGameEngine@@UAEXAAUItemInfo@@@Z"), __AddInventoryItem_hook | ||||
| 		); | ||||
| 		(FARPROC&)__OnReceiveUpdateItemList = (FARPROC)splice( | ||||
| 			GetProcAddress(hModule, "?OnReceiveUpdateItemList@UGameEngine@@UAEXHAAUItemInfo@@@Z"), __OnReceiveUpdateItemList_hook | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
| 	void GameEngineWrapper::Restore() | ||||
| @@ -47,6 +59,8 @@ namespace Interlude | ||||
| 		restore((void*&)__OnReceiveMagicSkillUse); | ||||
| 		restore((void*&)__OnReceiveMagicSkillCanceled); | ||||
| 		restore((void*&)__AddAbnormalStatus); | ||||
| 		restore((void*&)__AddInventoryItem); | ||||
| 		restore((void*&)__OnReceiveUpdateItemList); | ||||
| 	} | ||||
|  | ||||
| 	void __fastcall GameEngineWrapper::__Init_hook(GameEngine* This, uint32_t /*edx*/, float_t unk) | ||||
| @@ -85,4 +99,48 @@ namespace Interlude | ||||
| 		EventDispatcher::GetInstance().Dispatch(AbnormalEffectChangedEvent{ stack.GetBufferAsVector<int32_t>(3) }); | ||||
| 		(*__AddAbnormalStatus)(This, stack); | ||||
| 	} | ||||
|  | ||||
| 	void __fastcall GameEngineWrapper::__AddInventoryItem_hook(GameEngine* This, int, ItemInfo& itemInfo) | ||||
| 	{ | ||||
| 		EventDispatcher::GetInstance().Dispatch( | ||||
| 			ItemCreatedEvent | ||||
| 			{ | ||||
| 				ItemData | ||||
| 				{ | ||||
| 					itemInfo.itemId, | ||||
| 					itemInfo.amount, | ||||
| 					itemInfo.isEquipped, | ||||
| 					itemInfo.enchantLevel, | ||||
| 					itemInfo.mana, | ||||
| 				} | ||||
| 			} | ||||
| 		); | ||||
| 		(*__AddInventoryItem)(This, itemInfo); | ||||
| 	} | ||||
|  | ||||
| 	void __fastcall GameEngineWrapper::__OnReceiveUpdateItemList_hook(GameEngine* This, int, UpdateItemListActionType actionType, ItemInfo& itemInfo) | ||||
| 	{ | ||||
| 		const ItemData itemData | ||||
| 		{ | ||||
| 			itemInfo.itemId, | ||||
| 			itemInfo.amount, | ||||
| 			itemInfo.isEquipped, | ||||
| 			itemInfo.enchantLevel, | ||||
| 			itemInfo.mana, | ||||
| 		}; | ||||
|  | ||||
| 		switch (actionType) | ||||
| 		{ | ||||
| 		case UpdateItemListActionType::created: | ||||
| 			EventDispatcher::GetInstance().Dispatch(ItemCreatedEvent{ itemData }); | ||||
| 			break; | ||||
| 		case UpdateItemListActionType::updated: | ||||
| 			EventDispatcher::GetInstance().Dispatch(ItemUpdatedEvent{ itemData }); | ||||
| 			break; | ||||
| 		case UpdateItemListActionType::deleted: | ||||
| 			EventDispatcher::GetInstance().Dispatch(ItemDeletedEvent{ itemInfo.itemId }); | ||||
| 			break; | ||||
| 		} | ||||
| 		(*__OnReceiveUpdateItemList)(This, actionType, itemInfo); | ||||
| 	} | ||||
| } | ||||
| @@ -24,12 +24,17 @@ namespace Interlude | ||||
| 		static int(__thiscall* __OnReceiveMagicSkillUse)(GameEngine*, User*, User*, L2ParamStack&); | ||||
| 		static void(__thiscall* __OnReceiveMagicSkillCanceled)(GameEngine*, User*); | ||||
| 		static void(__thiscall* __AddAbnormalStatus)(GameEngine*, L2ParamStack&); | ||||
| 		static void(__thiscall* __AddInventoryItem)(GameEngine*, ItemInfo&); | ||||
| 		static void(__thiscall* __OnReceiveUpdateItemList)(GameEngine*, UpdateItemListActionType, ItemInfo&); | ||||
|  | ||||
| 		static void __fastcall __Init_hook(GameEngine* This, uint32_t /*edx*/, float_t unk); | ||||
| 		static void __fastcall __OnSkillListPacket_hook(GameEngine* This, uint32_t /*edx*/, L2ParamStack& stack); | ||||
| 		static int __fastcall __OnReceiveMagicSkillUse_hook(GameEngine* This, uint32_t /*edx*/, User* u1, User* u2, L2ParamStack& stack); | ||||
| 		static void __fastcall __OnReceiveMagicSkillCanceled_hook(GameEngine* This, uint32_t /*edx*/, User* user); | ||||
| 		static void __fastcall __AddAbnormalStatus_hook(GameEngine* This, uint32_t /*edx*/, L2ParamStack& stack); | ||||
| 		static void __fastcall __AddInventoryItem_hook(GameEngine* This, int /*edx*/, ItemInfo& itemInfo); | ||||
| 		static void __fastcall __OnReceiveUpdateItemList_hook(GameEngine* This, int /*edx*/, UpdateItemListActionType actionType, ItemInfo& itemInfo); | ||||
| 		 | ||||
| 	private: | ||||
| 		static void* originalInitAddress; | ||||
| 		static GameEngine* _target; | ||||
|   | ||||
| @@ -255,4 +255,11 @@ namespace Interlude | ||||
| 		int32_t iconNameIndex; //0x0048 | ||||
| 		char pad_004C[52]; //0x004C | ||||
| 	}; //Size: 0x0080 | ||||
|  | ||||
| 	enum class UpdateItemListActionType : uint32_t | ||||
| 	{ | ||||
| 		created = 1, | ||||
| 		updated, | ||||
| 		deleted | ||||
| 	}; | ||||
| }; | ||||
|   | ||||
							
								
								
									
										134
									
								
								L2BotDll/Versions/Interlude/Repositories/ItemRepository.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								L2BotDll/Versions/Interlude/Repositories/ItemRepository.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <map> | ||||
| #include <chrono> | ||||
| #include <shared_mutex> | ||||
| #include "Domain/Repositories/EntityRepositoryInterface.h" | ||||
| #include "../Factories/ItemFactory.h" | ||||
| #include "../GameStructs/NetworkHandlerWrapper.h" | ||||
| #include "../../../Services/EntityHandler.h" | ||||
| #include "../../../Events/ItemCreatedEvent.h" | ||||
| #include "../../../Events/ItemUpdatedEvent.h" | ||||
| #include "../../../Events/ItemDeletedEvent.h" | ||||
| #include "../../../Events/EventDispatcher.h" | ||||
|  | ||||
| using namespace L2Bot::Domain; | ||||
|  | ||||
| namespace Interlude | ||||
| { | ||||
| 	class ItemRepository : public Repositories::EntityRepositoryInterface | ||||
| 	{ | ||||
| 	public: | ||||
| 		const std::vector<std::shared_ptr<DTO::EntityState>> GetEntities() override | ||||
| 		{ | ||||
| 			std::unique_lock<std::shared_timed_mutex>(m_Mutex); | ||||
|  | ||||
| 			std::map<uint32_t, Entities::BaseItem*> itemPtrs; | ||||
| 			for (const auto& kvp : m_Items) | ||||
| 			{ | ||||
| 				itemPtrs[kvp.first] = kvp.second.get(); | ||||
| 			} | ||||
|  | ||||
| 			const auto objects = m_EntityHandler.GetEntities<Entities::BaseItem*>(itemPtrs, [this](Entities::BaseItem* item) { | ||||
| 				return std::make_unique<Entities::BaseItem>(item); | ||||
| 			}); | ||||
|  | ||||
| 			auto result = std::vector<std::shared_ptr<DTO::EntityState>>(); | ||||
|  | ||||
| 			for (const auto kvp : objects) | ||||
| 			{ | ||||
| 				result.push_back(kvp.second); | ||||
| 			} | ||||
|  | ||||
| 			return result; | ||||
| 		} | ||||
|  | ||||
| 		ItemRepository(const NetworkHandlerWrapper& networkHandler, const ItemFactory& factory, EntityHandler& handler) : | ||||
| 			m_NetworkHandler(networkHandler), | ||||
| 			m_Factory(factory), | ||||
| 			m_EntityHandler(handler) | ||||
| 		{ | ||||
| 			EventDispatcher::GetInstance().Subscribe(ItemCreatedEvent::name, [this](const Event& evt) { | ||||
| 				OnItemCreated(evt); | ||||
| 			}); | ||||
| 			EventDispatcher::GetInstance().Subscribe(ItemUpdatedEvent::name, [this](const Event& evt) { | ||||
| 				OnItemUpdated(evt); | ||||
| 			}); | ||||
| 			EventDispatcher::GetInstance().Subscribe(ItemDeletedEvent::name, [this](const Event& evt) { | ||||
| 				OnItemDeleted(evt); | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 		void OnItemCreated(const Event& evt) | ||||
| 		{ | ||||
| 			std::shared_lock<std::shared_timed_mutex>(m_Mutex); | ||||
| 			if (evt.GetName() == ItemCreatedEvent::name) | ||||
| 			{ | ||||
| 				const auto casted = static_cast<const ItemCreatedEvent&>(evt); | ||||
| 				const auto& data = casted.GetItemData(); | ||||
|  | ||||
| 				auto item = m_Factory.Create(data); | ||||
| 				if (m_Items.find(data.itemId) == m_Items.end()) | ||||
| 				{ | ||||
| 					m_Items.emplace(data.itemId, std::move(item)); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					// When equip/unequip accessories | ||||
| 					m_Items[data.itemId]->Update(item.get()); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		void OnItemUpdated(const Event& evt) | ||||
| 		{ | ||||
| 			std::shared_lock<std::shared_timed_mutex>(m_Mutex); | ||||
| 			if (evt.GetName() == ItemUpdatedEvent::name) | ||||
| 			{ | ||||
| 				const auto casted = static_cast<const ItemUpdatedEvent&>(evt); | ||||
| 				const auto& data = casted.GetItemData(); | ||||
|  | ||||
| 				//todo exception? | ||||
| 				if (m_Items.find(data.itemId) == m_Items.end()) | ||||
| 				{ | ||||
| 					return; | ||||
| 				} | ||||
|  | ||||
| 				auto item = m_Factory.Create(data); | ||||
| 				m_Items[data.itemId]->Update(item.get()); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		void OnItemDeleted(const Event& evt) | ||||
| 		{ | ||||
| 			//fixme may be a race condition | ||||
| 			std::shared_lock<std::shared_timed_mutex>(m_Mutex); | ||||
| 			if (evt.GetName() == ItemDeletedEvent::name) | ||||
| 			{ | ||||
| 				const auto casted = static_cast<const ItemDeletedEvent&>(evt); | ||||
|  | ||||
| 				m_Items.erase(casted.GetItemId()); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		ItemRepository() = delete; | ||||
| 		virtual ~ItemRepository() | ||||
| 		{ | ||||
| 			Reset(); | ||||
| 		} | ||||
|  | ||||
| 		void Reset() override | ||||
| 		{ | ||||
| 			std::shared_lock<std::shared_timed_mutex>(m_Mutex); | ||||
| 			m_Items.clear(); | ||||
| 		} | ||||
|  | ||||
| 	private: | ||||
| 		const ItemFactory& m_Factory; | ||||
| 		std::map<uint32_t, std::unique_ptr<Entities::BaseItem>> m_Items; | ||||
| 		uint32_t m_UsedSkillId = 0; | ||||
| 		const NetworkHandlerWrapper& m_NetworkHandler; | ||||
| 		std::shared_timed_mutex m_Mutex; | ||||
| 		EntityHandler& m_EntityHandler; | ||||
| 	}; | ||||
| } | ||||
| @@ -21,6 +21,7 @@ public: | ||||
| 	virtual Repositories::EntityRepositoryInterface& GetNPCRepository() const = 0; | ||||
| 	virtual Repositories::EntityRepositoryInterface& GetPlayerRepository() const = 0; | ||||
| 	virtual Repositories::EntityRepositoryInterface& GetSkillRepository() const = 0; | ||||
| 	virtual Repositories::EntityRepositoryInterface& GetItemRepository() const = 0; | ||||
| 	virtual NetworkHandlerInterface& GetNetworkHandler() const = 0; | ||||
| 	virtual GameEngineInterface& GetGameEngine() const = 0; | ||||
| 	virtual L2GameDataInterface& GetL2GameData() const = 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 k0t9i
					k0t9i