mirror of
https://github.com/Jous99/F4MP.git
synced 2026-01-13 00:20:54 +01:00
108 lines
4.1 KiB
C++
108 lines
4.1 KiB
C++
|
|
#include <GameServer.h>
|
||
|
|
|
||
|
|
#include <Services/OverlayService.h>
|
||
|
|
|
||
|
|
#include <ChatMessageTypes.h>
|
||
|
|
|
||
|
|
#include <Messages/NotifyChatMessageBroadcast.h>
|
||
|
|
#include <Messages/SendChatMessageRequest.h>
|
||
|
|
#include <Messages/PlayerDialogueRequest.h>
|
||
|
|
#include <Messages/NotifyPlayerDialogue.h>
|
||
|
|
#include <Messages/TeleportRequest.h>
|
||
|
|
#include <Messages/NotifyTeleport.h>
|
||
|
|
#include <Messages/RequestPlayerHealthUpdate.h>
|
||
|
|
#include <Messages/NotifyPlayerHealthUpdate.h>
|
||
|
|
|
||
|
|
#include "Game/Player.h"
|
||
|
|
|
||
|
|
#include <regex>
|
||
|
|
|
||
|
|
|
||
|
|
OverlayService::OverlayService(World& aWorld, entt::dispatcher& aDispatcher)
|
||
|
|
: m_world(aWorld)
|
||
|
|
{
|
||
|
|
m_chatMessageConnection = aDispatcher.sink<PacketEvent<SendChatMessageRequest>>().connect<&OverlayService::HandleChatMessage>(this);
|
||
|
|
m_playerDialogueConnection = aDispatcher.sink<PacketEvent<PlayerDialogueRequest>>().connect<&OverlayService::OnPlayerDialogue>(this);
|
||
|
|
m_teleportConnection = aDispatcher.sink<PacketEvent<TeleportRequest>>().connect<&OverlayService::OnTeleport>(this);
|
||
|
|
m_playerHealthConnection = aDispatcher.sink<PacketEvent<RequestPlayerHealthUpdate>>().connect<&OverlayService::OnPlayerHealthUpdate>(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
void sendPlayerMessage(const ChatMessageType acType, const String acContent, Player* aSendingPlayer) noexcept
|
||
|
|
{
|
||
|
|
NotifyChatMessageBroadcast notifyMessage{};
|
||
|
|
|
||
|
|
std::regex escapeHtml{"<[^>]+>\\s+(?=<)|<[^>]+>"};
|
||
|
|
notifyMessage.MessageType = acType;
|
||
|
|
notifyMessage.PlayerName = std::regex_replace(aSendingPlayer->GetUsername(), escapeHtml, "");
|
||
|
|
notifyMessage.ChatMessage = std::regex_replace(acContent, escapeHtml, "");
|
||
|
|
|
||
|
|
auto character = aSendingPlayer->GetCharacter();
|
||
|
|
|
||
|
|
switch (notifyMessage.MessageType)
|
||
|
|
{
|
||
|
|
case kGlobalChat: GameServer::Get()->SendToPlayers(notifyMessage); break;
|
||
|
|
|
||
|
|
case kSystemMessage: spdlog::error("PlayerId {} attempted to send a System Message.", aSendingPlayer->GetId()); break;
|
||
|
|
|
||
|
|
case kPlayerDialogue: GameServer::Get()->SendToParty(notifyMessage, aSendingPlayer->GetParty()); break;
|
||
|
|
|
||
|
|
case kPartyChat: GameServer::Get()->SendToParty(notifyMessage, aSendingPlayer->GetParty()); break;
|
||
|
|
|
||
|
|
case kLocalChat:
|
||
|
|
if (character)
|
||
|
|
{
|
||
|
|
if (!GameServer::Get()->SendToPlayersInRange(notifyMessage, *character))
|
||
|
|
spdlog::error("{}: SendToPlayersInRange failed", __FUNCTION__);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
default: spdlog::error("{} is not a known MessageType", static_cast<uint64_t>(notifyMessage.MessageType)); break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void OverlayService::HandleChatMessage(const PacketEvent<SendChatMessageRequest>& acMessage) const noexcept
|
||
|
|
{
|
||
|
|
auto [canceled, reason] = m_world.GetScriptService().HandleChatMessage(*acMessage.pPlayer->GetCharacter(), acMessage.Packet.ChatMessage);
|
||
|
|
if (canceled)
|
||
|
|
return;
|
||
|
|
|
||
|
|
sendPlayerMessage(acMessage.Packet.MessageType, acMessage.Packet.ChatMessage, acMessage.pPlayer);
|
||
|
|
}
|
||
|
|
|
||
|
|
void OverlayService::OnPlayerDialogue(const PacketEvent<PlayerDialogueRequest>& acMessage) const noexcept
|
||
|
|
{
|
||
|
|
sendPlayerMessage(kPlayerDialogue, acMessage.Packet.Text, acMessage.pPlayer);
|
||
|
|
}
|
||
|
|
|
||
|
|
void OverlayService::OnTeleport(const PacketEvent<TeleportRequest>& acMessage) const noexcept
|
||
|
|
{
|
||
|
|
Player* pTargetPlayer = m_world.GetPlayerManager().GetById(acMessage.Packet.PlayerId);
|
||
|
|
if (!pTargetPlayer)
|
||
|
|
return;
|
||
|
|
|
||
|
|
NotifyTeleport response{};
|
||
|
|
|
||
|
|
auto character = pTargetPlayer->GetCharacter();
|
||
|
|
if (character)
|
||
|
|
{
|
||
|
|
const auto* pMovementComponent = m_world.try_get<MovementComponent>(*character);
|
||
|
|
if (pMovementComponent)
|
||
|
|
{
|
||
|
|
const auto& cellComponent = pTargetPlayer->GetCellComponent();
|
||
|
|
response.CellId = cellComponent.Cell;
|
||
|
|
response.Position = pMovementComponent->Position;
|
||
|
|
response.WorldSpaceId = cellComponent.WorldSpaceId;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
acMessage.pPlayer->Send(response);
|
||
|
|
}
|
||
|
|
|
||
|
|
void OverlayService::OnPlayerHealthUpdate(const PacketEvent<RequestPlayerHealthUpdate>& acMessage) const noexcept
|
||
|
|
{
|
||
|
|
NotifyPlayerHealthUpdate notify{};
|
||
|
|
notify.PlayerId = acMessage.pPlayer->GetId();
|
||
|
|
notify.Percentage = acMessage.Packet.Percentage;
|
||
|
|
|
||
|
|
GameServer::Get()->SendToParty(notify, acMessage.pPlayer->GetParty(), acMessage.GetSender());
|
||
|
|
}
|