From 297d0281d46fb0a088e674ebd91eace21cf0650a Mon Sep 17 00:00:00 2001 From: Robbe Bryssinck Date: Mon, 16 May 2022 12:59:20 +0200 Subject: [PATCH] feat: infrastructure for teleport button --- .../client/Services/Generic/OverlayClient.cpp | 11 +++++++ .../Services/Generic/OverlayService.cpp | 31 ++++++++++++++++++ Code/client/Services/OverlayClient.h | 1 + Code/client/Services/OverlayService.h | 3 ++ Code/encoding/Messages/ClientMessageFactory.h | 3 +- Code/encoding/Messages/NotifyTeleport.cpp | 18 +++++++++++ Code/encoding/Messages/NotifyTeleport.h | 32 +++++++++++++++++++ Code/encoding/Messages/ServerMessageFactory.h | 4 ++- Code/encoding/Messages/TeleportRequest.cpp | 13 ++++++++ Code/encoding/Messages/TeleportRequest.h | 24 ++++++++++++++ Code/encoding/Opcodes.h | 2 ++ Code/server/Services/OverlayService.cpp | 32 +++++++++++++++++-- Code/server/Services/OverlayService.h | 3 ++ 13 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 Code/encoding/Messages/NotifyTeleport.cpp create mode 100644 Code/encoding/Messages/NotifyTeleport.h create mode 100644 Code/encoding/Messages/TeleportRequest.cpp create mode 100644 Code/encoding/Messages/TeleportRequest.h diff --git a/Code/client/Services/Generic/OverlayClient.cpp b/Code/client/Services/Generic/OverlayClient.cpp index 608261e10..bd863221e 100644 --- a/Code/client/Services/Generic/OverlayClient.cpp +++ b/Code/client/Services/Generic/OverlayClient.cpp @@ -8,6 +8,7 @@ #include #include +#include #include @@ -69,6 +70,8 @@ bool OverlayClient::OnProcessMessageReceived(CefRefPtr browser, CefR uint32_t aPlayerId = eventArgs->GetInt(0); World::Get().GetPartyService().ChangePartyLeader(aPlayerId); } + else if (eventName == "teleportToPlayer") + ProcessTeleportMessage(eventArgs); return true; } @@ -117,3 +120,11 @@ void OverlayClient::ProcessChatMessage(CefRefPtr aEventArgs) } } } + +void OverlayClient::ProcessTeleportMessage(CefRefPtr aEventArgs) +{ + TeleportRequest request{}; + request.PlayerId = aEventArgs->GetInt(0); + + m_transport.Send(request); +} diff --git a/Code/client/Services/Generic/OverlayService.cpp b/Code/client/Services/Generic/OverlayService.cpp index 7138f606a..633153a56 100644 --- a/Code/client/Services/Generic/OverlayService.cpp +++ b/Code/client/Services/Generic/OverlayService.cpp @@ -21,6 +21,9 @@ #include #include #include +#include + +#include #include #include @@ -108,6 +111,7 @@ OverlayService::OverlayService(World& aWorld, TransportService& transport, entt: m_playerRemovedConnection = m_world.on_destroy().connect<&OverlayService::OnPlayerComponentRemoved>(this); m_playerLevelConnection = aDispatcher.sink().connect<&OverlayService::OnPlayerLevel>(this); m_cellChangedConnection = aDispatcher.sink().connect<&OverlayService::OnPlayerCellChanged>(this); + m_teleportConnection = aDispatcher.sink().connect<&OverlayService::OnNotifyTeleport>(this); } OverlayService::~OverlayService() noexcept @@ -379,3 +383,30 @@ void OverlayService::OnPlayerCellChanged(const NotifyPlayerCellChanged& acMessag pArguments->SetString(3, cellName.c_str()); m_pOverlay->ExecuteAsync("setCell", pArguments); } + +void OverlayService::OnNotifyTeleport(const NotifyTeleport& acMessage) noexcept +{ + auto& modSystem = m_world.GetModSystem(); + + const uint32_t cellId = modSystem.GetGameId(acMessage.CellId); + TESObjectCELL* pCell = Cast(TESForm::GetById(cellId)); + if (!pCell) + { + const uint32_t worldSpaceId = modSystem.GetGameId(acMessage.WorldSpaceId); + TESWorldSpace* pWorldSpace = Cast(TESForm::GetById(worldSpaceId)); + if (pWorldSpace) + { + GridCellCoords coordinates = GridCellCoords::CalculateGridCellCoords(acMessage.Position); + pCell = pWorldSpace->LoadCell(coordinates.X, coordinates.Y); + } + + if (!pCell) + { + spdlog::error("Failed to fetch cell to teleport to."); + m_world.GetOverlayService().SendSystemMessage("Teleporting to player failed."); + return; + } + } + + PlayerCharacter::Get()->MoveTo(pCell, acMessage.Position); +} diff --git a/Code/client/Services/OverlayClient.h b/Code/client/Services/OverlayClient.h index 473c041e9..b3ccfa7b2 100644 --- a/Code/client/Services/OverlayClient.h +++ b/Code/client/Services/OverlayClient.h @@ -26,6 +26,7 @@ struct OverlayClient : TiltedPhoques::OverlayClient void ProcessConnectMessage(CefRefPtr aEventArgs); void ProcessDisconnectMessage(); void ProcessChatMessage(CefRefPtr aEventArgs); + void ProcessTeleportMessage(CefRefPtr aEventArgs); TransportService& m_transport; }; diff --git a/Code/client/Services/OverlayService.h b/Code/client/Services/OverlayService.h index ab7db37ea..f7595711c 100644 --- a/Code/client/Services/OverlayService.h +++ b/Code/client/Services/OverlayService.h @@ -24,6 +24,7 @@ struct NotifyPlayerDialogue; struct ConnectionErrorEvent; struct NotifyPlayerLevel; struct NotifyPlayerCellChanged; +struct NotifyTeleport; using TiltedPhoques::OverlayApp; @@ -75,6 +76,7 @@ struct OverlayService void OnPlayerLeft(const NotifyPlayerLeft&) noexcept; void OnPlayerLevel(const NotifyPlayerLevel&) noexcept; void OnPlayerCellChanged(const NotifyPlayerCellChanged& acMessage) const noexcept; + void OnNotifyTeleport(const NotifyTeleport& acMessage) noexcept; private: CefRefPtr m_pOverlay{nullptr}; @@ -99,4 +101,5 @@ struct OverlayService entt::scoped_connection m_playerRemovedConnection; entt::scoped_connection m_playerLevelConnection; entt::scoped_connection m_cellChangedConnection; + entt::scoped_connection m_teleportConnection; }; diff --git a/Code/encoding/Messages/ClientMessageFactory.h b/Code/encoding/Messages/ClientMessageFactory.h index d0f4b96db..a7f24bd37 100644 --- a/Code/encoding/Messages/ClientMessageFactory.h +++ b/Code/encoding/Messages/ClientMessageFactory.h @@ -49,6 +49,7 @@ #include #include #include +#include using TiltedPhoques::UniquePtr; @@ -70,7 +71,7 @@ struct ClientMessageFactory AddTargetRequest, ScriptAnimationRequest, DrawWeaponRequest, MountRequest, NewPackageRequest, RequestRespawn, SyncExperienceRequest, RequestEquipmentChanges, SendChatMessageRequest, TeleportCommandRequest, PlayerRespawnRequest, DialogueRequest, SubtitleRequest, PlayerDialogueRequest, - PlayerLevelRequest>; + PlayerLevelRequest, TeleportRequest>; return s_visitor(std::forward(func)); } diff --git a/Code/encoding/Messages/NotifyTeleport.cpp b/Code/encoding/Messages/NotifyTeleport.cpp new file mode 100644 index 000000000..9b0b3ed45 --- /dev/null +++ b/Code/encoding/Messages/NotifyTeleport.cpp @@ -0,0 +1,18 @@ +#include +#include + +void NotifyTeleport::SerializeRaw(TiltedPhoques::Buffer::Writer& aWriter) const noexcept +{ + CellId.Serialize(aWriter); + Position.Serialize(aWriter); + WorldSpaceId.Serialize(aWriter); +} + +void NotifyTeleport::DeserializeRaw(TiltedPhoques::Buffer::Reader& aReader) noexcept +{ + ServerMessage::DeserializeRaw(aReader); + + CellId.Deserialize(aReader); + Position.Deserialize(aReader); + WorldSpaceId.Deserialize(aReader); +} diff --git a/Code/encoding/Messages/NotifyTeleport.h b/Code/encoding/Messages/NotifyTeleport.h new file mode 100644 index 000000000..19b581a47 --- /dev/null +++ b/Code/encoding/Messages/NotifyTeleport.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Message.h" +#include +#include + +struct NotifyTeleport final : ServerMessage +{ + static constexpr ServerOpcode Opcode = kNotifyTeleport; + + NotifyTeleport() : + ServerMessage(Opcode) + { + } + + virtual ~NotifyTeleport() = default; + + void SerializeRaw(TiltedPhoques::Buffer::Writer& aWriter) const noexcept override; + void DeserializeRaw(TiltedPhoques::Buffer::Reader& aReader) noexcept override; + + bool operator==(const NotifyTeleport& acRhs) const noexcept + { + return GetOpcode() == acRhs.GetOpcode() && + CellId == acRhs.CellId && + Position == acRhs.Position && + WorldSpaceId == acRhs.WorldSpaceId; + } + + GameId CellId{}; + Vector3_NetQuantize Position{}; + GameId WorldSpaceId{}; +}; diff --git a/Code/encoding/Messages/ServerMessageFactory.h b/Code/encoding/Messages/ServerMessageFactory.h index f1710df82..be425ae95 100644 --- a/Code/encoding/Messages/ServerMessageFactory.h +++ b/Code/encoding/Messages/ServerMessageFactory.h @@ -50,6 +50,7 @@ #include #include #include +#include using TiltedPhoques::UniquePtr; @@ -70,7 +71,8 @@ struct ServerMessageFactory NotifyAddTarget, NotifyScriptAnimation, NotifyDrawWeapon, NotifyMount, NotifyNewPackage, NotifyRespawn, NotifySyncExperience, NotifyEquipmentChanges, NotifyChatMessageBroadcast, TeleportCommandResponse, NotifyPlayerRespawn, NotifyPlayerLeft, NotifyPlayerJoined, - NotifyDialogue, NotifySubtitle, NotifyPlayerDialogue, NotifyPlayerLevel, NotifyPlayerCellChanged>; + NotifyDialogue, NotifySubtitle, NotifyPlayerDialogue, NotifyPlayerLevel, NotifyPlayerCellChanged, + NotifyTeleport>; return s_visitor(std::forward(func)); } diff --git a/Code/encoding/Messages/TeleportRequest.cpp b/Code/encoding/Messages/TeleportRequest.cpp new file mode 100644 index 000000000..a8ef83091 --- /dev/null +++ b/Code/encoding/Messages/TeleportRequest.cpp @@ -0,0 +1,13 @@ +#include + +void TeleportRequest::SerializeRaw(TiltedPhoques::Buffer::Writer& aWriter) const noexcept +{ + Serialization::WriteVarInt(aWriter, PlayerId); +} + +void TeleportRequest::DeserializeRaw(TiltedPhoques::Buffer::Reader& aReader) noexcept +{ + ClientMessage::DeserializeRaw(aReader); + + PlayerId = Serialization::ReadVarInt(aReader) & 0xFFFFFFFF; +} diff --git a/Code/encoding/Messages/TeleportRequest.h b/Code/encoding/Messages/TeleportRequest.h new file mode 100644 index 000000000..51ccba88a --- /dev/null +++ b/Code/encoding/Messages/TeleportRequest.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Message.h" +#include + +struct TeleportRequest final : ClientMessage +{ + static constexpr ClientOpcode Opcode = kTeleportRequest; + + TeleportRequest() : ClientMessage(Opcode) + { + } + + void SerializeRaw(TiltedPhoques::Buffer::Writer& aWriter) const noexcept override; + void DeserializeRaw(TiltedPhoques::Buffer::Reader& aReader) noexcept override; + + bool operator==(const TeleportRequest& acRhs) const noexcept + { + return GetOpcode() == acRhs.GetOpcode() && + PlayerId == acRhs.PlayerId; + } + + uint16_t PlayerId{}; +}; diff --git a/Code/encoding/Opcodes.h b/Code/encoding/Opcodes.h index d51b6b750..8c5958abc 100644 --- a/Code/encoding/Opcodes.h +++ b/Code/encoding/Opcodes.h @@ -47,6 +47,7 @@ enum ClientOpcode : unsigned char kSubtitleRequest, kPlayerDialogueRequest, kPlayerLevelRequest, + kTeleportRequest, kClientOpcodeMax }; @@ -98,5 +99,6 @@ enum ServerOpcode : unsigned char kNotifyPlayerJoined, kNotifyPlayerLevel, kNotifyPlayerCellChanged, + kNotifyTeleport, kServerOpcodeMax }; diff --git a/Code/server/Services/OverlayService.cpp b/Code/server/Services/OverlayService.cpp index 5edd847f8..e85d39835 100644 --- a/Code/server/Services/OverlayService.cpp +++ b/Code/server/Services/OverlayService.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include @@ -14,11 +16,12 @@ OverlayService::OverlayService(World& aWorld, entt::dispatcher& aDispatcher) { m_chatMessageConnection = aDispatcher.sink>().connect<&OverlayService::HandleChatMessage>(this); m_playerDialogueConnection = aDispatcher.sink>().connect<&OverlayService::OnPlayerDialogue>(this); + m_teleportConnection = aDispatcher.sink>().connect<&OverlayService::OnTeleport>(this); } void OverlayService::HandleChatMessage(const PacketEvent& acMessage) const noexcept { - NotifyChatMessageBroadcast notifyMessage; + NotifyChatMessageBroadcast notifyMessage{}; notifyMessage.PlayerName = acMessage.pPlayer->GetUsername(); // TODO: std regex is slow @@ -32,15 +35,38 @@ void OverlayService::OnPlayerDialogue(const PacketEvent& { auto& message = acMessage.Packet; - NotifyPlayerDialogue notify; + NotifyPlayerDialogue notify{}; notify.Text = acMessage.pPlayer->GetUsername() + ": " + message.Text; auto& party = acMessage.pPlayer->GetParty(); - // TODO(cosideci): exclude player? GameServer::Get()->SendToParty(notify, party); } +void OverlayService::OnTeleport(const PacketEvent& 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(*character); + if (pMovementComponent) + { + const auto& cellComponent = pTargetPlayer->GetCellComponent(); + response.CellId = cellComponent.Cell; + response.Position = pMovementComponent->Position; + response.WorldSpaceId = cellComponent.WorldSpaceId; + } + } + + acMessage.pPlayer->Send(response); +} + #if 0 #include #include diff --git a/Code/server/Services/OverlayService.h b/Code/server/Services/OverlayService.h index bc057c77c..32a42406c 100644 --- a/Code/server/Services/OverlayService.h +++ b/Code/server/Services/OverlayService.h @@ -8,6 +8,7 @@ struct World; struct PlayerDialogueRequest; +struct TeleportRequest; /** * @brief Dispatches UI events that modify the UI view of other cients. @@ -24,6 +25,7 @@ class OverlayService void HandleChatMessage(const PacketEvent& acMessage) const noexcept; void HandlePlayerJoin(const PlayerEnterWorldEvent& acEvent) const noexcept; void OnPlayerDialogue(const PacketEvent& acMessage) const noexcept; + void OnTeleport(const PacketEvent& acMessage) const noexcept; private: World& m_world; @@ -31,4 +33,5 @@ class OverlayService entt::scoped_connection m_chatMessageConnection; entt::scoped_connection m_playerEnterWorldConnection; entt::scoped_connection m_playerDialogueConnection; + entt::scoped_connection m_teleportConnection; };