F4MP/codigos originales/tiltedcode/Code/server/Services/OverlayService.cpp

108 lines
4.1 KiB
C++
Raw Normal View History

#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());
}