feat: add chat messages

This commit is contained in:
k0t9i
2023-01-25 18:42:53 +04:00
parent b3bb4a52f3
commit f7198a13ef
18 changed files with 313 additions and 2 deletions

View File

@@ -26,6 +26,7 @@ public:
m_AbstractFactory.GetSkillRepository(),
m_AbstractFactory.GetItemRepository(),
m_AbstractFactory.GetAbnormalEffectRepository(),
m_AbstractFactory.GetChatMessageRepository(),
m_Serializer,
m_Transport
)

View File

@@ -0,0 +1,12 @@
#pragma once
#include <cstdint>
#include <string>
struct ChatMessage
{
const uint32_t objectId = 0;
const uint8_t channel = 0;
const std::string name = "";
const std::string text = "";
};

View File

@@ -0,0 +1,34 @@
#pragma once
#include <cstdint>
#include <vector>
#include "Event.h"
#include "../DTO/ChatMessage.h"
class ChatMessageCreatedEvent : public Event
{
public:
static constexpr const char* name = "chatMessageCreated";
const std::string GetName() const
{
return std::string(name);
}
const ChatMessage& GetChatMessage() const
{
return m_ChatMessage;
}
ChatMessageCreatedEvent(const ChatMessage chatMessage) :
m_ChatMessage(chatMessage)
{
}
ChatMessageCreatedEvent() = delete;
virtual ~ChatMessageCreatedEvent() = default;
private:
const ChatMessage m_ChatMessage;
};

View File

@@ -164,7 +164,9 @@
<ClInclude Include="Common\apihook.h" />
<ClInclude Include="Common\Common.h" />
<ClInclude Include="Common\TimerMap.h" />
<ClInclude Include="DTO\ChatMessage.h" />
<ClInclude Include="DTO\ItemData.h" />
<ClInclude Include="Events\ChatMessageCreatedEvent.h" />
<ClInclude Include="Events\CreatureDiedEvent.h" />
<ClInclude Include="Events\Event.h" />
<ClInclude Include="Events\EventDispatcher.h" />
@@ -188,6 +190,7 @@
<ClInclude Include="Versions\GameStructs\GameEngineInterface.h" />
<ClInclude Include="Versions\GameStructs\L2GameDataInterface.h" />
<ClInclude Include="Versions\Interlude\Factories\AbnormalEffectFactory.h" />
<ClInclude Include="Versions\Interlude\Factories\ChatMessageFactory.h" />
<ClInclude Include="Versions\Interlude\Factories\HeroFactory.h" />
<ClInclude Include="Versions\Interlude\Factories\ItemFactory.h" />
<ClInclude Include="Versions\Interlude\Factories\NPCFactory.h" />
@@ -199,6 +202,7 @@
<ClInclude Include="Transports\DebugViewTransport.h" />
<ClInclude Include="Versions\Interlude\Helpers\EnchantHelper.h" />
<ClInclude Include="Versions\Interlude\Repositories\AbnormalEffectRepository.h" />
<ClInclude Include="Versions\Interlude\Repositories\ChatMessageRepository.h" />
<ClInclude Include="Versions\Interlude\Repositories\DropRepository.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="Versions\GameStructs\FindObjectsTrait.h" />

View File

@@ -186,6 +186,18 @@
<ClInclude Include="Versions\Interlude\Helpers\EnchantHelper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DTO\ChatMessage.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Events\ChatMessageCreatedEvent.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Versions\Interlude\Factories\ChatMessageFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Versions\Interlude\Repositories\ChatMessageRepository.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">

View File

@@ -5,6 +5,7 @@
#include <memory>
#include <Windows.h>
#include "Domain/Services/EntityService.h"
#include "Domain/Services/ChatMessageService.h"
#include "Domain/Serializers/SerializableStateContainer.h"
#include "Domain/Serializers/SerializerInterface.h"
#include "Domain/Repositories/EntityRepositoryInterface.h"
@@ -22,7 +23,8 @@ public:
Repositories::EntityRepositoryInterface& playerRepository,
Repositories::EntityRepositoryInterface& skillRepository,
Repositories::EntityRepositoryInterface& itemRepository,
Repositories::EntityRepositoryInterface& abnormalEffectService,
Repositories::EntityRepositoryInterface& abnormalEffectRepository,
Repositories::ChatMessageRepositoryInterface& chatMessageRepository,
const Serializers::SerializerInterface& serializer,
Transports::TransportInterface& transport
) :
@@ -32,7 +34,8 @@ public:
m_PlayerService(Services::EntityService(playerRepository)),
m_SkillService(Services::EntityService(skillRepository)),
m_ItemService(Services::EntityService(itemRepository)),
m_AbnormalEffectService(Services::EntityService(abnormalEffectService)),
m_AbnormalEffectService(Services::EntityService(abnormalEffectRepository)),
m_ChatMessageService(Services::ChatMessageService(chatMessageRepository)),
m_Serializer(serializer),
m_Transport(transport)
{
@@ -139,6 +142,11 @@ private:
}
}
for (const auto& message : m_ChatMessageService.GetMessages())
{
result.push_back(Serializers::Node{ "chat", message.BuildSerializationNodes() });
}
return result;
}
@@ -161,6 +169,7 @@ private:
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;

View File

@@ -8,6 +8,7 @@
#include "Factories/SkillFactory.h"
#include "Factories/ItemFactory.h"
#include "Factories/AbnormalEffectFactory.h"
#include "Factories/ChatMessageFactory.h"
#include "Repositories/DropRepository.h"
#include "Repositories/HeroRepository.h"
#include "Repositories/NPCRepository.h"
@@ -15,6 +16,7 @@
#include "Repositories/SkillRepository.h"
#include "Repositories/ItemRepository.h"
#include "Repositories/AbnormalEffectRepository.h"
#include "Repositories/ChatMessageRepository.h"
#include "GameStructs/NetworkHandlerWrapper.h"
#include "GameStructs/GameEngineWrapper.h"
#include "GameStructs/L2GameDataWrapper.h"
@@ -115,6 +117,14 @@ namespace Interlude
);
return result;
}
ChatMessageRepository& GetChatMessageRepository() const override
{
static auto factory = ChatMessageFactory();
static auto result = ChatMessageRepository(
factory
);
return result;
}
NetworkHandlerWrapper& GetNetworkHandler() const override
{
static NetworkHandlerWrapper result;

View File

@@ -0,0 +1,26 @@
#pragma once
#include "Domain/ValueObjects/ChatMessage.h"
#include "../../../DTO/ChatMessage.h"
using namespace L2Bot::Domain;
namespace Interlude
{
class ChatMessageFactory
{
public:
ChatMessageFactory() = default;
virtual ~ChatMessageFactory() = default;
ValueObjects::ChatMessage Create(const ChatMessage& message) const
{
return ValueObjects::ChatMessage{
message.objectId,
static_cast<Enums::ChatChannelEnum>(message.channel),
message.name,
message.text
};
}
};
}

View File

@@ -1,5 +1,6 @@
#include "pch.h"
#include "../../../Common/apihook.h"
#include "../../../Common/Common.h"
#include "GameEngineWrapper.h"
#include "ProcessManipulation.h"
#include "../../../Events/SkillCreatedEvent.h"
@@ -12,7 +13,9 @@
#include "../../../Events/ItemDeletedEvent.h"
#include "../../../Events/ItemAutousedEvent.h"
#include "../../../Events/GameEngineTickedEvent.h"
#include "../../../Events/ChatMessageCreatedEvent.h"
#include "../../../DTO/ItemData.h"
#include "FName.h"
namespace Interlude
{
@@ -26,6 +29,7 @@ namespace Interlude
void(__thiscall* GameEngineWrapper::__OnReceiveUpdateItemList)(GameEngine*, UpdateItemListActionType, ItemInfo&) = 0;
void(__thiscall* GameEngineWrapper::__OnExAutoSoulShot)(GameEngine*, L2ParamStack&) = 0;
void(__thiscall* GameEngineWrapper::__Tick)(GameEngine*, float_t) = 0;
void(__thiscall* GameEngineWrapper::__OnSay2)(GameEngine*, L2ParamStack&) = 0;
void GameEngineWrapper::Init(HMODULE hModule)
@@ -54,6 +58,9 @@ namespace Interlude
(FARPROC&)__OnExAutoSoulShot = (FARPROC)splice(
GetProcAddress(hModule, "?OnExAutoSoulShot@UGameEngine@@UAEXAAVL2ParamStack@@@Z"), __OnExAutoSoulShot_hook
);
(FARPROC&)__OnSay2 = (FARPROC)splice(
GetProcAddress(hModule, "?OnSay2@UGameEngine@@UAEXAAVL2ParamStack@@@Z"), __OnSay2_hook
);
}
void GameEngineWrapper::Restore()
@@ -65,6 +72,7 @@ namespace Interlude
restore((void*&)__AddInventoryItem);
restore((void*&)__OnReceiveUpdateItemList);
restore((void*&)__OnExAutoSoulShot);
restore((void*&)__OnSay2);
}
void __fastcall GameEngineWrapper::__OnSkillListPacket_hook(GameEngine* This, uint32_t, L2ParamStack& stack)
@@ -158,4 +166,23 @@ namespace Interlude
EventDispatcher::GetInstance().Dispatch(GameEngineTickedEvent{});
}
void __fastcall GameEngineWrapper::__OnSay2_hook(GameEngine* This, uint32_t, L2ParamStack& stack)
{
const auto buffer = stack.GetBufferAsVector<uint32_t>();
EventDispatcher::GetInstance().Dispatch(
ChatMessageCreatedEvent
{
ChatMessage
{
buffer[0],
static_cast<uint8_t>(buffer[1]),
ConvertFromWideChar(reinterpret_cast<wchar_t*>(buffer[2])),
ConvertFromWideChar(reinterpret_cast<wchar_t*>(buffer[3]))
}
}
);
(*__OnSay2)(This, stack);
}
}

View File

@@ -27,6 +27,7 @@ namespace Interlude
static void(__thiscall* __OnReceiveUpdateItemList)(GameEngine*, UpdateItemListActionType, ItemInfo&);
static void(__thiscall* __OnExAutoSoulShot)(GameEngine*, L2ParamStack&);
static void(__thiscall* __Tick)(GameEngine*, float_t);
static void(__thiscall* __OnSay2)(GameEngine*, L2ParamStack&);
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);
@@ -36,6 +37,7 @@ namespace Interlude
static void __fastcall __OnReceiveUpdateItemList_hook(GameEngine* This, uint32_t /*edx*/, UpdateItemListActionType actionType, ItemInfo& itemInfo);
static void __fastcall __OnExAutoSoulShot_hook(GameEngine* This, uint32_t /*edx*/, L2ParamStack& stack);
static void __fastcall __Tick_hook(GameEngine* This, uint32_t /*edx*/, float_t unk);
static void __fastcall __OnSay2_hook(GameEngine* This, uint32_t /*edx*/, L2ParamStack& stack);
private:
static GameEngine* _target;

View File

@@ -0,0 +1,54 @@
#pragma once
#include <vector>
#include <shared_mutex>
#include "Domain/Repositories/ChatMessageRepositoryInterface.h"
#include "../Factories/ChatMessageFactory.h"
#include "../../../Events/ChatMessageCreatedEvent.h"
#include "../../../Events/EventDispatcher.h"
using namespace L2Bot::Domain;
namespace Interlude
{
class ChatMessageRepository : public Repositories::ChatMessageRepositoryInterface
{
public:
const std::vector<ValueObjects::ChatMessage> GetMessages() override
{
std::unique_lock<std::shared_timed_mutex>(m_Mutex);
const auto result = m_Messages;
m_Messages.clear();
return result;
}
ChatMessageRepository(const ChatMessageFactory& factory) :
m_Factory(factory)
{
EventDispatcher::GetInstance().Subscribe(ChatMessageCreatedEvent::name, [this](const Event& evt) {
OnMessageCreated(evt);
});
}
void OnMessageCreated(const Event& evt)
{
std::shared_lock<std::shared_timed_mutex>(m_Mutex);
if (evt.GetName() == ChatMessageCreatedEvent::name)
{
const auto casted = static_cast<const ChatMessageCreatedEvent&>(evt);
m_Messages.push_back(m_Factory.Create(casted.GetChatMessage()));
}
}
ChatMessageRepository() = delete;
virtual ~ChatMessageRepository() = default;
private:
const ChatMessageFactory& m_Factory;
std::vector<ValueObjects::ChatMessage> m_Messages;
std::shared_timed_mutex m_Mutex;
};
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include "Domain/Repositories/EntityRepositoryInterface.h"
#include "Domain/Repositories/ChatMessageRepositoryInterface.h"
#include "GameStructs/NetworkHandlerInterface.h"
#include "GameStructs/GameEngineInterface.h"
#include "GameStructs/L2GameDataInterface.h"
@@ -23,6 +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 NetworkHandlerInterface& GetNetworkHandler() const = 0;
virtual GameEngineInterface& GetGameEngine() const = 0;
virtual L2GameDataInterface& GetL2GameData() const = 0;