R-Type 0.1
Loading...
Searching...
No Matches
SnapshotPayload.hpp
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <unordered_set>
6#include <utility>
7#include <vector>
8
9#include "BigEndian.hpp"
10#include "EntityPayload.hpp"
11#include "PayloadCodec.hpp"
12#include "Position.hpp"
13
14#include "config/NetworkConfig.hpp"
15#include "protocol/MessageHeader.hpp"
16
17namespace rtype::protocol {
35};
36
50 std::uint8_t entityType = 0;
54};
55
56static_assert(sizeof(SnapshotHeader) == sizeof(be32) + sizeof(be16),
57 "SnapshotHeader must not contain padding");
58static_assert(sizeof(SnapshotEntityState) ==
59 sizeof(be32) + sizeof(std::uint8_t) + sizeof(be16) * 3,
60 "SnapshotEntityState must not contain padding");
61
63inline constexpr std::size_t SNAPSHOT_MAX_ENTITIES =
65 sizeof(SnapshotEntityState);
66
73 std::vector<SnapshotEntityState> entities;
74};
75
82inline bool writeSnapshot(PacketWriter &writer,
83 const SnapshotPayload &payload) {
84 if (payload.entities.size() > SNAPSHOT_MAX_ENTITIES)
85 return false;
86
87 const SnapshotHeader header{
88 payload.serverTick, static_cast<std::uint16_t>(payload.entities.size())};
89
90 if (!writePayload(writer, header))
91 return false;
92
93 for (const auto &state : payload.entities) {
94 if (!writePayload(writer, state))
95 return false;
96 }
97 return true;
98}
99
106inline bool readSnapshot(PacketReader &reader, SnapshotPayload &payload) {
107 SnapshotHeader header;
108
109 if (!readPayload(reader, header))
110 return false;
111
112 const std::size_t count = header.entityCount.get();
113
114 if (count > SNAPSHOT_MAX_ENTITIES ||
115 reader.getRemaining() != count * sizeof(SnapshotEntityState))
116 return false;
117
118 std::vector<SnapshotEntityState> states(count);
119 std::unordered_set<std::uint32_t> ids;
120 ids.reserve(count);
121
122 for (auto &state : states) {
123 if (!readPayload(reader, state))
124 return false;
125
126 if (state.networkId.get() == 0 || !ids.insert(state.networkId.get()).second)
127 return false;
128 }
129
130 payload.serverTick = header.serverTick;
131 payload.entities = std::move(states);
132 return true;
133}
134
136} // namespace rtype::protocol
Bounds checked reader of big-endian values over a byte buffer.
Definition PacketReader.hpp:15
std::size_t getRemaining() const
Returns the number of bytes left to read.
Definition PacketReader.cpp:67
Growable buffer of big-endian values, capped at MAX_PAYLOAD_SIZE.
Definition PacketWriter.hpp:16
constexpr std::size_t MAX_MESSAGE_SIZE
Room left for messages after the packet header, in bytes.
Definition NetworkConfig.hpp:22
bool readPayload(PacketReader &reader, T &payload)
Reads the raw bytes of a padding free payload struct.
Definition PayloadCodec.hpp:38
bool writePayload(PacketWriter &writer, const T &payload)
Appends the raw bytes of a padding free payload struct.
Definition PayloadCodec.hpp:24
BigEndian< std::uint16_t > be16
16-bit unsigned integer stored in big-endian order.
Definition BigEndian.hpp:85
bool readSnapshot(PacketReader &reader, SnapshotPayload &payload)
Decodes and validates a snapshot.
Definition SnapshotPayload.hpp:106
BigEndian< std::uint32_t > be32
32-bit unsigned integer stored in big-endian order.
Definition BigEndian.hpp:87
constexpr std::size_t SNAPSHOT_MAX_ENTITIES
Largest number of entity states that fit in one Snapshot message.
Definition SnapshotPayload.hpp:63
bool writeSnapshot(PacketWriter &writer, const SnapshotPayload &payload)
Encodes a snapshot.
Definition SnapshotPayload.hpp:82
static constexpr std::size_t HEADER_SIZE
Encoded size of the header, in bytes.
Definition MessageHeader.hpp:55
constexpr T get() const
Returns the value in host byte order.
Definition BigEndian.hpp:76
State of one entity inside a Snapshot message, 11 bytes.
Definition SnapshotPayload.hpp:48
be16 rotation
Rotation, fraction of a full turn.
Definition SnapshotPayload.hpp:53
be16 positionX
Horizontal position, fixed point encoded.
Definition SnapshotPayload.hpp:51
std::uint8_t entityType
Low 8 bits of the archetype id.
Definition SnapshotPayload.hpp:50
be16 positionY
Vertical position, fixed point encoded.
Definition SnapshotPayload.hpp:52
be32 networkId
Identifier of the entity.
Definition SnapshotPayload.hpp:49
Fixed part of a Snapshot message, 6 bytes.
Definition SnapshotPayload.hpp:32
be32 serverTick
Server tick the states belong to.
Definition SnapshotPayload.hpp:33
be16 entityCount
Number of entity states that follow.
Definition SnapshotPayload.hpp:34
Decoded Snapshot message: a SnapshotHeader followed by entityCount SnapshotEntityState records.
Definition SnapshotPayload.hpp:71
be32 serverTick
Server tick the states belong to.
Definition SnapshotPayload.hpp:72
std::vector< SnapshotEntityState > entities
Entity states.
Definition SnapshotPayload.hpp:73