Skip to content
LeviMC
English
AutoLightDark
LeviLamina
Loading...
Searching...
No Matches
Packet.h
1#pragma once
2
3#include <memory>
4#include <string>
5
6#include "ll/api/base/Macro.h"
7#include "ll/api/base/Meta.h"
8#include "ll/api/network/packet/PacketRegistrar.h"
9#include "ll/api/reflection/TypeName.h"
10#include "ll/api/utils/HashUtils.h"
11#include "mc/common/SubClientId.h"
12#include "mc/deps/raknet/PacketPriority.h"
13#include "mc/network/Compressibility.h"
14#include "mc/network/NetworkPeer.h"
15#include "mc/platform/Result.h"
16
17class Player;
18class Actor;
19class BlockPos;
20class BinaryStream;
27struct DimensionType;
28
29namespace ll::network {
30
31class IPacketHandler;
32class PacketRegistrar;
33
34class Packet {
35public:
36 PacketPriority mPriority;
37 NetworkPeer::Reliability mReliability;
38 SubClientId mSenderSubId;
39 Compressibility mCompressible;
40
41 static constexpr std::string_view CustomPacketId{};
42
43 static constexpr uint PacketVersion{0};
44
45 static constexpr PacketSide Side{PacketSide::Both};
46
47 static constexpr bool Optional{false};
48
49 [[nodiscard]] constexpr explicit Packet(
50 PacketPriority priority = PacketPriority::MediumPriority,
51 NetworkPeer::Reliability reliability = NetworkPeer::Reliability::ReliableOrdered,
52 SubClientId clientSubId = SubClientId::PrimaryClient,
53 bool compress = true
54 )
55 : mPriority(priority),
56 mReliability(reliability),
57 mSenderSubId(clientSubId),
58 mCompressible(compress ? Compressibility::Compressible : Compressibility::Incompressible) {}
59
60 virtual ~Packet() = default;
61
62 virtual void write(::BinaryStream&) const = 0;
63 [[nodiscard]] virtual ::Bedrock::Result<void> read(::ReadOnlyBinaryStream&) = 0;
64 [[nodiscard]] virtual ::std::string_view getName() const = 0;
65
66 [[nodiscard]] LLNDAPI virtual PacketRuntimeId getRuntimeId() const;
67
68 LLAPI void sendTo(Player const& player) const;
69 LLAPI void sendTo(BlockPos const& pos, DimensionType dimId, optional_ref<Player const> except = std::nullopt) const;
70 LLAPI void sendTo(Actor const& actor, optional_ref<Player const> except = std::nullopt) const;
71
72 LLAPI void sendToClient(NetworkIdentifier const& identifier, ::SubClientId clientId) const;
73 LLAPI void sendToClient(NetworkIdentifierWithSubId const& identifierWithSubId) const;
74
75 LLAPI void sendToClients() const;
76 LLAPI void sendToClients(NetworkIdentifier const& exceptId, ::SubClientId exceptSubid) const;
77
78 LLAPI void sendToServer() const;
79
80 LLNDAPI bool canSendTo(Player const& player) const;
81
82 LLNDAPI bool canSendTo(NetworkIdentifier const& identifier) const;
83
84 LLNDAPI bool canSendToServer() const;
85
86 LLNDAPI static bool canSendTo(PacketRuntimeId runtimeId, Player const& player);
87
88 LLNDAPI static bool canSendTo(PacketRuntimeId runtimeId, NetworkIdentifier const& identifier);
89
90 LLNDAPI static bool canSendToServer(PacketRuntimeId runtimeId);
91};
92
94public:
95 virtual ~IPacketHandler() = default;
96 virtual void handle(
97 NetworkIdentifier const& netId,
98 NetEventCallback& callback,
99 PacketSide side,
100 ll::network::Packet const& packet
101 ) const = 0;
102};
103
104template <class T>
105constexpr std::string_view getPacketId = []() -> std::string_view {
106 using self = std::remove_cvref_t<T>;
107 if constexpr (!self::CustomPacketId.empty()) {
108 return self::CustomPacketId;
109 } else {
110 return reflection::type_unprefix_name_v<self>;
111 }
112}();
113
114[[nodiscard]] constexpr PacketRuntimeId makePacketRuntimeId(std::string_view id, uint version = 0) {
115 auto hash = hash_utils::doHash(id);
116 return version == 0 ? hash : hash_utils::HashCombiner{hash}.add(version).hash();
117}
118
119template <class T>
120constexpr PacketRuntimeId getPacketRuntimeId =
121 makePacketRuntimeId(getPacketId<T>, std::remove_cvref_t<T>::PacketVersion);
122
123namespace detail {
124template <class Derived>
125inline bool packetRegistration = [] {
126 PacketRegistrar::getInstance().registerPacket(
127 getPacketId<Derived>,
128 getPacketRuntimeId<Derived>,
129 []() -> std::unique_ptr<Packet> { return std::make_unique<Derived>(); },
130 Derived::Side,
131 Derived::Optional
132 );
133 return true;
134}();
135
136template <class Derived, class PacketType, PacketSide Side>
137inline bool packetHandlerRegistration = [] {
138 static Derived instance;
139 PacketRegistrar::getInstance()
140 .registerHandler(getPacketId<PacketType>, getPacketRuntimeId<PacketType>, instance, Side);
141 return true;
142}();
143} // namespace detail
144
145template <class Derived>
146class PacketBase : public Packet, private meta::StaticRegistrationAnchor<detail::packetRegistration<Derived>> {
147 static bool ensureRegistered() { return detail::packetRegistration<Derived>; }
148
149protected:
150 using Packet::Packet;
151
152public:
153 [[nodiscard]] ::std::string_view getName() const override { return getPacketId<Derived>; }
154 [[nodiscard]] PacketRuntimeId getRuntimeId() const override { return getPacketRuntimeId<Derived>; }
155
156 [[nodiscard]] static bool canSendTo(Player const& player) {
157 return Packet::canSendTo(getPacketRuntimeId<Derived>, player);
158 }
159
160 [[nodiscard]] static bool canSendTo(NetworkIdentifier const& identifier) {
161 return Packet::canSendTo(getPacketRuntimeId<Derived>, identifier);
162 }
163
164 [[nodiscard]] static bool canSendToServer() { return Packet::canSendToServer(getPacketRuntimeId<Derived>); }
165
166 inline static bool sRegistered = ensureRegistered();
167};
168
169template <class Derived, class PacketType, PacketSide Side = PacketType::Side>
171: public IPacketHandler,
172 private meta::StaticRegistrationAnchor<detail::packetHandlerRegistration<Derived, PacketType, Side>> {
173 static bool ensureRegistered() { return detail::packetHandlerRegistration<Derived, PacketType, Side>; }
174
175 inline static bool sRegistered = ensureRegistered();
176
177public:
178 void handle(
179 NetworkIdentifier const& netId,
180 NetEventCallback& callback,
181 PacketSide side,
182 Packet const& packet
183 ) const final {
184 static_cast<Derived const*>(this)->handlePacket(netId, callback, side, static_cast<PacketType const&>(packet));
185 }
186};
187
188} // namespace ll::network
Definition Actor.h:116
Definition BinaryStream.h:10
Definition BlockPos.h:14
Definition IPacketHandlerDispatcher.h:12
Definition NetEventCallback.h:273
Definition NetworkIdentifier.h:10
Definition Player.h:131
Definition ReadOnlyBinaryStream.h:8
Definition UserEntityIdentifierComponent.h:17
Definition Packet.h:93
Definition Packet.h:146
Definition Packet.h:172
Definition PacketRegistrar.h:29
Definition Packet.h:34
Definition optional_ref.h:10
Definition DimensionType.h:5
Definition NetworkIdentifierWithSubId.h:10