#pragma once #include #include #include #include #include "Domain/Services/EntityService.h" #include "Domain/Services/ChatMessageService.h" #include "Domain/Serializers/SerializerInterface.h" #include "Domain/Repositories/EntityRepositoryInterface.h" #include "Domain/Transports/TransportInterface.h" #include "Domain/DTO/Message.h" using namespace L2Bot::Domain; class WorldHandler { public: WorldHandler( Repositories::EntityRepositoryInterface& heroRepository, Repositories::EntityRepositoryInterface& dropRepository, Repositories::EntityRepositoryInterface& npcRepository, Repositories::EntityRepositoryInterface& playerRepository, Repositories::EntityRepositoryInterface& skillRepository, Repositories::EntityRepositoryInterface& itemRepository, Repositories::EntityRepositoryInterface& abnormalEffectRepository, Repositories::ChatMessageRepositoryInterface& chatMessageRepository, const Serializers::SerializerInterface& serializer, Transports::TransportInterface& transport ) : m_HeroService(Services::EntityService(heroRepository)), m_DropService(Services::EntityService(dropRepository)), m_NPCService(Services::EntityService(npcRepository)), m_PlayerService(Services::EntityService(playerRepository)), m_SkillService(Services::EntityService(skillRepository)), m_ItemService(Services::EntityService(itemRepository)), m_AbnormalEffectService(Services::EntityService(abnormalEffectRepository)), m_ChatMessageService(Services::ChatMessageService(chatMessageRepository)), m_Serializer(serializer), m_Transport(transport) { } void Start() { m_ConnectingThread = std::thread(&WorldHandler::Connect, this); m_SendingThread = std::thread(&WorldHandler::Send, this); m_ReceivingThread = std::thread(&WorldHandler::Receive, this); } void Stop() { m_Stopped = true; if (m_ConnectingThread.joinable()) { m_ConnectingThread.join(); } if (m_SendingThread.joinable()) { m_SendingThread.join(); } if (m_ReceivingThread.joinable()) { m_ReceivingThread.join(); } } virtual ~WorldHandler() { Stop(); } private: void Send() { while (!m_Stopped) { const auto& data = GetData(); if (m_Transport.IsConnected()) { for (const auto& item : data) { m_Transport.Send( m_Serializer.Serialize(item) ); } } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } } void Receive() { while (!m_Stopped) { if (m_Transport.IsConnected()) { const std::wstring& response = m_Transport.Receive(); if (response == L"invalidate") { Invalidate(); } } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } } void Connect() { while (!m_Stopped) { if (!m_Transport.IsConnected()) { m_Transport.Connect(); } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } } const std::vector> GetData() { std::map services { {L"hero", m_HeroService}, {L"drop", m_DropService}, {L"npc", m_NPCService}, {L"player", m_PlayerService}, {L"skill", m_SkillService}, {L"item", m_ItemService}, {L"abnormalEffect", m_AbnormalEffectService} }; std::vector> result; for (auto& kvp : services) { for (const auto& entity : kvp.second.GetEntities()) { if (entity->GetState() != Enums::EntityStateEnum::none) { const auto message = DTO::Message{ kvp.first, entity->GetState(), *entity->GetEntity().get() }; result.push_back(message.BuildSerializationNodes()); } }; } for (const auto& chatMessage : m_ChatMessageService.GetMessages()) { const auto message = DTO::Message{ L"chat", Enums::EntityStateEnum::created, chatMessage }; result.push_back(message.BuildSerializationNodes()); } return result; } void Invalidate() { m_DropService.Invalidate(); m_HeroService.Invalidate(); m_NPCService.Invalidate(); m_PlayerService.Invalidate(); m_SkillService.Invalidate(); m_ItemService.Invalidate(); m_AbnormalEffectService.Invalidate(); } private: Services::EntityService m_DropService; Services::EntityService m_HeroService; Services::EntityService m_NPCService; Services::EntityService m_PlayerService; Services::EntityService m_SkillService; Services::EntityService m_ItemService; Services::EntityService m_AbnormalEffectService; Services::ChatMessageService m_ChatMessageService; const Serializers::SerializerInterface& m_Serializer; Transports::TransportInterface& m_Transport; bool m_Stopped = false; std::thread m_ConnectingThread; std::thread m_SendingThread; std::thread m_ReceivingThread; };