filename:
src/network/protocol/PacketCodec.h
branch:
feature/world
back to repo
/*
*
* _____ _ _
* / ___|| | | |
* \ `--. | |_ _ __ __ _ | |_ ___ ___
* `--. \| __|| '__| / _` || __| / _ \ / __|
* /\__/ /| |_ | | | (_| || |_ | (_) |\__ \
* \____/ \__||_| \__,_| \__| \___/ |___/
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2025 Armen Deroian
*
*/
#ifndef PACKETCODEC_H
#define PACKETCODEC_H
#include "math/Angle.h"
#include "math/Position.h"
#include "Packet.h"
#include "utils/Types.h"
#include <cstdint>
#include <optional>
#include <string>
#include <utility>
#define PROTOCOL_VERSION 770
#define PROTOCOL_VERSION_STRING "1.21.5"
namespace stratos {
class ServerboundKnownPacks;
class ConfigurationResourcePackResponse;
class ConfigurationPong;
class ConfigurationServerboundKeepAlive;
class AcknowledgeFinishConfiguration;
class ConfigurationServerPluginMessage;
class ConfigurationCookieResponse;
class ConfigurationClientInformation;
class EncryptionResponse;
class LoginCookieResponse;
class LoginAcknowledge;
class LoginPluginResponse;
class LoginStart;
class PingRequest;
class StatusRequest;
class LegacyServerListPing;
class ClientHandshake;
class NetworkConnection;
using UUID = std::array<uint8_t, 16>;
class PacketHandler {
public:
virtual ~PacketHandler() = default;
virtual bool handle(Packet&) { return false; }
virtual bool handle(ClientHandshake&) { return false; }
virtual bool handle(LegacyServerListPing&) { return false; }
virtual bool handle(StatusRequest&) { return false; }
virtual bool handle(PingRequest&) { return false; }
virtual bool handle(LoginStart&) { return false; }
virtual bool handle(EncryptionResponse&) { return false; }
virtual bool handle(LoginPluginResponse&) { return false; }
virtual bool handle(LoginAcknowledge&) { return false; }
virtual bool handle(LoginCookieResponse&) { return false; }
virtual bool handle(ConfigurationClientInformation&) { return false; }
virtual bool handle(ConfigurationCookieResponse&) { return false; }
virtual bool handle(ConfigurationServerPluginMessage&) { return false; }
virtual bool handle(AcknowledgeFinishConfiguration&) { return false; }
virtual bool handle(ConfigurationServerboundKeepAlive&) { return false; }
virtual bool handle(ConfigurationPong&) { return false; }
virtual bool handle(ConfigurationResourcePackResponse&) { return false; }
virtual bool handle(ServerboundKnownPacks&) { return false; }
};
#define SERVERBOUND_PACKET_FOOTER(clazz) \
bool accept(PacketHandler& handler) override { return handler.handle(*this); } \
~clazz() override = default; \
void decrypt(PacketBuffer& buffer) override;
#define CLIENTBOUND_PACKET_FOOTER(clazz) \
~clazz() override = default; \
void encrypt(PacketBuffer& buffer) override;
// Handshake Packets
class ClientHandshake final : public ServerboundPacket {
public:
constexpr static int ID = 0x00;
int protocolVersion;
std::string serverAddress;
uint16_t serverPort;
HandshakeIntent intent;
explicit ClientHandshake() : Packet(ID), ServerboundPacket(ID), protocolVersion(0), serverPort(0), intent() {}
SERVERBOUND_PACKET_FOOTER(ClientHandshake)
};
class LegacyServerListPing final : public ServerboundPacket {
public:
constexpr static int ID = 0xFE;
uint8_t payload = 0x01; // Legacy server list ping payload
explicit LegacyServerListPing() : Packet(ID), ServerboundPacket(ID) {}
SERVERBOUND_PACKET_FOOTER(LegacyServerListPing)
};
class LegacyServerListPong final : public ClientboundPacket {
public:
constexpr static int ID = 0xFF;
int protocolVersion;
std::string version;
std::string motd;
int onlinePlayers;
int maxPlayers;
LegacyServerListPong() : Packet(ID), ClientboundPacket(ID), protocolVersion(0), onlinePlayers(0), maxPlayers(0) {}
LegacyServerListPong(const int protocol_version, std::string version, std::string motd, const int online_players, const int max_players)
: Packet(ID), ClientboundPacket(ID), protocolVersion(protocol_version), version(std::move(version)), motd(std::move(motd)), onlinePlayers(online_players), maxPlayers(max_players) {}
CLIENTBOUND_PACKET_FOOTER(LegacyServerListPong)
};
// Status Packets
class StatusResponse final : public ClientboundPacket {
public:
constexpr static int ID = 0x00;
std::string jsonResponse;
StatusResponse() : Packet(ID), ClientboundPacket(ID) {}
explicit StatusResponse(std::string&& jsonResponse) : Packet(ID), ClientboundPacket(ID), jsonResponse(std::move(jsonResponse)) {}
CLIENTBOUND_PACKET_FOOTER(StatusResponse)
};
class PongResponse final : public ClientboundPacket {
public:
constexpr static int ID = 0x01;
int64_t timestamp;
PongResponse() : Packet(ID), ClientboundPacket(ID), timestamp(0) {}
explicit PongResponse(const int64_t timestamp) : Packet(ID), ClientboundPacket(ID), timestamp(timestamp) {}
CLIENTBOUND_PACKET_FOOTER(PongResponse)
};
class StatusRequest final : public ServerboundPacket {
public:
constexpr static int ID = 0x00;
explicit StatusRequest() : Packet(ID), ServerboundPacket(ID) {}
SERVERBOUND_PACKET_FOOTER(StatusRequest)
};
class PingRequest final : public ServerboundPacket {
public:
constexpr static int ID = 0x01;
int64_t timestamp = 0;
explicit PingRequest() : Packet(ID), ServerboundPacket(ID) {}
SERVERBOUND_PACKET_FOOTER(PingRequest)
};
// Login Packets
class LoginStart final : public ServerboundPacket {
public:
constexpr static int ID = 0x00;
std::string name; // String(16)
UUID uuid;
LoginStart() : Packet(ID), ServerboundPacket(ID), uuid() {}
SERVERBOUND_PACKET_FOOTER(LoginStart)
};
class EncryptionResponse final : public ServerboundPacket {
public:
constexpr static int ID = 0x01;
std::vector<uint8_t> sharedSecret; // prefixed ByteArray
std::vector<uint8_t> verifyToken; // prefixed ByteArray
EncryptionResponse() : Packet(ID), ServerboundPacket(ID) {}
SERVERBOUND_PACKET_FOOTER(EncryptionResponse)
};
class LoginPluginResponse final : public ServerboundPacket {
public:
constexpr static int ID = 0x02;
int messageId; // VarInt
std::optional<std::vector<uint8_t>> data; // prefixed optional ByteArray
LoginPluginResponse() : Packet(ID), ServerboundPacket(ID), messageId(0), data() {}
SERVERBOUND_PACKET_FOOTER(LoginPluginResponse)
};
class LoginAcknowledge final : public ServerboundPacket {
public:
constexpr static int ID = 0x03;
LoginAcknowledge() : Packet(ID), ServerboundPacket(ID) {}
SERVERBOUND_PACKET_FOOTER(LoginAcknowledge)
};
class LoginCookieResponse final : public ServerboundPacket {
public:
constexpr static int ID = 0x04;
utils::Identifier cookie;
std::optional<std::vector<uint8_t>> payload; // prefixed optional ByteArray
LoginCookieResponse() : Packet(ID), ServerboundPacket(ID), cookie({"",""}) {}
SERVERBOUND_PACKET_FOOTER(LoginCookieResponse)
};
class LoginDisconnect final : public ClientboundPacket {
public:
constexpr static int ID = 0x00;
std::string reason; // JSON Text Component
LoginDisconnect() : Packet(ID), ClientboundPacket(ID) {}
explicit LoginDisconnect(std::string&& reason) : Packet(ID), ClientboundPacket(ID), reason(std::move(reason)) {}
CLIENTBOUND_PACKET_FOOTER(LoginDisconnect)
};
class EncryptionRequest final : public ClientboundPacket {
public:
constexpr static int ID = 0x01;
std::string serverId; // String(20)
std::vector<uint8_t> publicKey; // prefixed ByteArray
std::vector<uint8_t> verifyToken; // prefixed ByteArray
bool shouldAuthenticate;
EncryptionRequest() : Packet(ID), ClientboundPacket(ID), shouldAuthenticate(false) {}
EncryptionRequest(std::string&& serverId, std::vector<uint8_t>&& publicKey, std::vector<uint8_t>&& verifyToken, const bool shouldAuthenticate)
: Packet(ID), ClientboundPacket(ID), serverId(std::move(serverId)), publicKey(std::move(publicKey)), verifyToken(std::move(verifyToken)), shouldAuthenticate(shouldAuthenticate) {}
CLIENTBOUND_PACKET_FOOTER(EncryptionRequest)
};
class LoginSuccess final : public ClientboundPacket {
public:
constexpr static int ID = 0x02;
UUID uuid;
std::string username; // String(16)
std::vector<LoginProperty> properties; // prefixed array(16)
LoginSuccess() : Packet(ID), ClientboundPacket(ID), uuid() {}
LoginSuccess(const UUID& uuid, std::string&& username, std::vector<LoginProperty>&& properties)
: Packet(ID), ClientboundPacket(ID), uuid(uuid), username(std::move(username)), properties(std::move(properties)) {}
CLIENTBOUND_PACKET_FOOTER(LoginSuccess)
};
class SetCompression final : public ClientboundPacket {
public:
constexpr static int ID = 0x03;
int threshold; // VarInt
SetCompression() : Packet(ID), ClientboundPacket(ID), threshold(0) {}
explicit SetCompression(const int threshold) : Packet(ID), ClientboundPacket(ID), threshold(threshold) {}
CLIENTBOUND_PACKET_FOOTER(SetCompression)
};
class LoginPluginRequest final : public ClientboundPacket {
public:
constexpr static int ID = 0x04;
int messageId; // VarInt
utils::Identifier channel;
std::vector<uint8_t> data; // ByteArray
LoginPluginRequest() : Packet(ID), ClientboundPacket(ID), messageId(0), channel({"",""}) {}
LoginPluginRequest(const int messageId, utils::Identifier channel, std::vector<uint8_t>&& data)
: Packet(ID), ClientboundPacket(ID), messageId(messageId), channel(std::move(channel)), data(std::move(data)) {}
CLIENTBOUND_PACKET_FOOTER(LoginPluginRequest)
};
class LoginCookieRequest final : public ClientboundPacket {
public:
constexpr static int ID = 0x05;
utils::Identifier cookie;
LoginCookieRequest() : Packet(ID), ClientboundPacket(ID), cookie({"",""}) {}
explicit LoginCookieRequest(utils::Identifier cookie) : Packet(ID), ClientboundPacket(ID), cookie(std::move(cookie)) {}
CLIENTBOUND_PACKET_FOOTER(LoginCookieRequest)
};
// Configuration Packets
class ConfigurationClientInformation final : public ServerboundPacket {
public:
constexpr static int ID = 0x00;
std::string locale; // String(16)
int8_t viewDistance;
ChatMode chatMode; // VarInt Enum
bool chatColors;
uint8_t skinParts;
Hand mainHand; // VarInt Enum
bool enableTextFiltering;
bool allowServerListing;
ParticleStatus particleStatus; // VarInt Enum
ConfigurationClientInformation() : Packet(ID), ServerboundPacket(ID), viewDistance(0), chatMode(), chatColors(false), skinParts(0), mainHand(), enableTextFiltering(false), allowServerListing(false), particleStatus() {}
SERVERBOUND_PACKET_FOOTER(ConfigurationClientInformation)
};
class ConfigurationCookieResponse final : public ServerboundPacket {
public:
constexpr static int ID = 0x01;
utils::Identifier key;
std::optional<std::vector<uint8_t>> value; // prefixed optional prefixed ByteArray(5120)
ConfigurationCookieResponse() : Packet(ID), ServerboundPacket(ID), key({"",""}), value() {}
SERVERBOUND_PACKET_FOOTER(ConfigurationCookieResponse)
};
class ConfigurationServerPluginMessage final : public ServerboundPacket {
public:
constexpr static int ID = 0x02;
utils::Identifier channel;
std::vector<uint8_t> data; // prefixed ByteArray(32767)
ConfigurationServerPluginMessage() : Packet(ID), ServerboundPacket(ID), channel({"",""}), data() {}
SERVERBOUND_PACKET_FOOTER(ConfigurationServerPluginMessage)
};
class AcknowledgeFinishConfiguration final : public ServerboundPacket {
public:
constexpr static int ID = 0x03;
AcknowledgeFinishConfiguration() : Packet(ID), ServerboundPacket(ID) {}
SERVERBOUND_PACKET_FOOTER(AcknowledgeFinishConfiguration)
};
class ConfigurationServerboundKeepAlive final : public ServerboundPacket {
public:
constexpr static int ID = 0x04;
int64_t id;
ConfigurationServerboundKeepAlive() : Packet(ID), ServerboundPacket(ID), id(0) {}
SERVERBOUND_PACKET_FOOTER(ConfigurationServerboundKeepAlive)
};
class ConfigurationPong final : public ServerboundPacket {
public:
constexpr static int ID = 0x05;
int id;
ConfigurationPong() : Packet(ID), ServerboundPacket(ID), id(0) {}
SERVERBOUND_PACKET_FOOTER(ConfigurationPong)
};
class ConfigurationResourcePackResponse final : public ServerboundPacket {
public:
constexpr static int ID = 0x06;
UUID uuid;
ResourcePackResult result; // VarInt Enum
ConfigurationResourcePackResponse() : Packet(ID), ServerboundPacket(ID), uuid(), result() {}
SERVERBOUND_PACKET_FOOTER(ConfigurationResourcePackResponse)
};
class ServerboundKnownPacks final : public ServerboundPacket {
public:
constexpr static int ID = 0x07;
std::vector<ResourcePackHeader> knownPacks; // prefixed array;
ServerboundKnownPacks() : Packet(ID), ServerboundPacket(ID) {}
SERVERBOUND_PACKET_FOOTER(ServerboundKnownPacks)
};
class ConfigurationCookieRequest final : public ClientboundPacket {
public:
constexpr static int ID = 0x00;
utils::Identifier key;
ConfigurationCookieRequest() : Packet(ID), ClientboundPacket(ID), key({"",""}) {}
explicit ConfigurationCookieRequest(utils::Identifier key) : Packet(ID), ClientboundPacket(ID), key(std::move(key)) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationCookieRequest)
};
class ConfigurationClientboundPluginMessage final : public ClientboundPacket {
public:
constexpr static int ID = 0x01;
utils::Identifier channel;
std::vector<uint8_t> data; // ByteArray
ConfigurationClientboundPluginMessage() : Packet(ID), ClientboundPacket(ID), channel({"",""}) {}
ConfigurationClientboundPluginMessage(utils::Identifier channel, std::vector<uint8_t> data)
: Packet(ID), ClientboundPacket(ID), channel(std::move(channel)), data(std::move(data)) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationClientboundPluginMessage)
};
class ConfigurationDisconnect final : public ClientboundPacket {
public:
constexpr static int ID = 0x02;
std::string reason; // Text Component
ConfigurationDisconnect() : Packet(ID), ClientboundPacket(ID) {}
explicit ConfigurationDisconnect(std::string&& reason) : Packet(ID), ClientboundPacket(ID), reason(std::move(reason)) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationDisconnect)
};
class FinishConfiguration final : public ClientboundPacket {
public:
constexpr static int ID = 0x03;
FinishConfiguration() : Packet(ID), ClientboundPacket(ID) {}
CLIENTBOUND_PACKET_FOOTER(FinishConfiguration)
};
class ConfigurationClientboundKeepAlive final : public ClientboundPacket {
public:
constexpr static int ID = 0x04;
int64_t id;
ConfigurationClientboundKeepAlive() : Packet(ID), ClientboundPacket(ID), id(0) {}
explicit ConfigurationClientboundKeepAlive(const int64_t id) : Packet(ID), ClientboundPacket(ID), id(id) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationClientboundKeepAlive)
};
class ConfigurationPing final : public ClientboundPacket {
public:
constexpr static int ID = 0x05;
int id;
ConfigurationPing() : Packet(ID), ClientboundPacket(ID), id(0) {}
explicit ConfigurationPing(const int id) : Packet(ID), ClientboundPacket(ID), id(id) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationPing)
};
class ResetChat final : public ClientboundPacket {
public:
constexpr static int ID = 0x06;
ResetChat() : Packet(ID), ClientboundPacket(ID) {}
CLIENTBOUND_PACKET_FOOTER(ResetChat)
};
class RegistryDataPacket final : public ClientboundPacket {
public:
constexpr static int ID = 0x07;
utils::Identifier registryKey;
std::vector<RegistryEntry> entries;
RegistryDataPacket() : Packet(ID), ClientboundPacket(ID), registryKey({"",""}) {}
RegistryDataPacket(utils::Identifier registryKey, std::vector<RegistryEntry>&& entries)
: Packet(ID), ClientboundPacket(ID), registryKey(std::move(registryKey)), entries(std::move(entries)) {}
CLIENTBOUND_PACKET_FOOTER(RegistryDataPacket)
};
class ConfigurationRemoveRemoveResourcePack final : public ClientboundPacket {
public:
constexpr static int ID = 0x08;
std::optional<UUID> uuid; // prefixed optional UUID
ConfigurationRemoveRemoveResourcePack() : Packet(ID), ClientboundPacket(ID), uuid(std::nullopt) {}
explicit ConfigurationRemoveRemoveResourcePack(const UUID& uuid) : Packet(ID), ClientboundPacket(ID), uuid(uuid) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationRemoveRemoveResourcePack)
};
class ConfigurationAddResourcePack final : public ClientboundPacket {
public:
constexpr static int ID = 0x09;
UUID uuid;
std::string url; // String(32767)
std::string hash; // String(40)
bool forced;
std::optional<std::string> prompt; // prefixed optional Text Component
ConfigurationAddResourcePack() : Packet(ID), ClientboundPacket(ID), uuid(), forced(false), prompt(std::nullopt) {}
ConfigurationAddResourcePack(const UUID uuid, std::string url, std::string hash, const bool forced, std::optional<std::string> prompt = std::nullopt)
: Packet(ID), ClientboundPacket(ID), uuid(uuid), url(std::move(url)), hash(std::move(hash)), forced(forced), prompt(std::move(prompt)) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationAddResourcePack)
};
class ConfigurationStoreCookie final : public ClientboundPacket {
public:
constexpr static int ID = 0x0A;
utils::Identifier key;
std::vector<uint8_t> value; // prefixed ByteArray(5120)
ConfigurationStoreCookie() : Packet(ID), ClientboundPacket(ID), key({"",""}), value() {}
ConfigurationStoreCookie(utils::Identifier key, std::vector<uint8_t>&& value) : Packet(ID), ClientboundPacket(ID), key(std::move(key)), value(std::move(value)) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationStoreCookie)
};
class ConfigurationTransfer final : public ClientboundPacket {
public:
constexpr static int ID = 0x0B;
std::string host; // String(32767)
int port; // VarInt
ConfigurationTransfer() : Packet(ID), ClientboundPacket(ID), port(0) {}
ConfigurationTransfer(std::string host, const int port) : Packet(ID), ClientboundPacket(ID), host(std::move(host)), port(port) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationTransfer)
};
class FeatureFlags final : public ClientboundPacket {
public:
constexpr static int ID = 0x0C;
std::vector<utils::Identifier> features; // prefixed array
FeatureFlags() : Packet(ID), ClientboundPacket(ID) {}
explicit FeatureFlags(std::vector<utils::Identifier>& features) : Packet(ID), ClientboundPacket(ID), features(std::move(features)) {}
CLIENTBOUND_PACKET_FOOTER(FeatureFlags)
};
class ConfigurationUpdateTags final : public ClientboundPacket {
public:
constexpr static int ID = 0x0D;
std::vector<RegistryTagData> tags; // prefixed array
ConfigurationUpdateTags() : Packet(ID), ClientboundPacket(ID) {}
explicit ConfigurationUpdateTags(std::vector<RegistryTagData>& tags) : Packet(ID), ClientboundPacket(ID), tags(std::move(tags)) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationUpdateTags)
};
class ClientboundKnownPacks final : public ClientboundPacket {
public:
constexpr static int ID = 0x0E;
std::vector<ResourcePackHeader> knownPackets; // prefixed array
ClientboundKnownPacks() : Packet(ID), ClientboundPacket(ID) {}
explicit ClientboundKnownPacks(std::vector<ResourcePackHeader>& knownPackets) : Packet(ID), ClientboundPacket(ID), knownPackets(std::move(knownPackets)) {}
CLIENTBOUND_PACKET_FOOTER(ClientboundKnownPacks)
};
class ConfigurationCustomReportDetails final : public ClientboundPacket {
public:
constexpr static int ID = 0x0F;
std::vector<ReportDetail> details; // prefixed array [{String(128), String(4096)}]
ConfigurationCustomReportDetails() : Packet(ID), ClientboundPacket(ID) {}
explicit ConfigurationCustomReportDetails(std::vector<ReportDetail>& details) : Packet(ID), ClientboundPacket(ID), details(std::move(details)) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationCustomReportDetails)
};
class ConfigurationServerLinks final : public ClientboundPacket {
public:
constexpr static int ID = 0x10;
std::vector<ServerLink> links; // prefixed array
ConfigurationServerLinks() : Packet(ID), ClientboundPacket(ID) {}
explicit ConfigurationServerLinks(std::vector<ServerLink>& links) : Packet(ID), ClientboundPacket(ID), links(std::move(links)) {}
CLIENTBOUND_PACKET_FOOTER(ConfigurationServerLinks)
};
class GameEventPacket final : public ClientboundPacket {
public:
constexpr static int ID = 0x22;
GameEvent event;
float data;
GameEventPacket() : Packet(ID), ClientboundPacket(ID), event(), data(0) {}
explicit GameEventPacket(const GameEvent event, const float data = 0.0f)
: Packet(ID), ClientboundPacket(ID), event(event), data(data){}
CLIENTBOUND_PACKET_FOOTER(GameEventPacket)
};
// Play Packets
class SynchronizePlayerPosition final : public ClientboundPacket {
public:
constexpr static int ID = 0x41;
int teleportId; // VarInt
double x;
double y;
double z;
double velocityX;
double velocityY;
double velocityZ;
float yaw;
float pitch;
int flags;
SynchronizePlayerPosition() : Packet(ID), ClientboundPacket(ID), teleportId(), x(), y(), z(), velocityX(), velocityY(), velocityZ(), yaw(), pitch(), flags() {}
SynchronizePlayerPosition(const int teleportId, const double x, const double y, const double z, const double velocityX, const double velocityY, const double velocityZ, const float yaw, const float pitch, const int flags = 0)
: Packet(ID), ClientboundPacket(ID), teleportId(teleportId), x(x), y(y), z(z), velocityX(velocityX), velocityY(velocityY), velocityZ(velocityZ), yaw(yaw), pitch(pitch), flags(flags) {}
CLIENTBOUND_PACKET_FOOTER(SynchronizePlayerPosition)
};
class LoginPlay final : public ClientboundPacket {
public:
constexpr static int ID = 0x2B;
int entityId; // int
bool isHardcore;
std::vector<utils::Identifier> dimensions; // prefixed array
int maxPlayers; // VarInt
int viewDistance; // VarInt
int simulationDistance; // VarInt
bool reducedDebugInfo;
bool enableRespawnScreen;
bool doLimitedCrafting;
int dimensionType; // VarInt
utils::Identifier dimensionName;
long hashedSeed;
uint8_t gamemode;
int8_t previousGamemode;
bool debug;
bool flat;
bool hasDeathLocation;
std::optional<utils::Identifier> deathDimension; // optional utils::Identifier
std::optional<math::Position> deathPosition; // optional position
int portalCooldown; // VarInt
int seaLevel; // VarInt
bool enforcesSecureChat;
LoginPlay()
: Packet(ID), ClientboundPacket(ID), entityId(0), isHardcore(false), maxPlayers(0), viewDistance(0), simulationDistance(0), reducedDebugInfo(false),
enableRespawnScreen(false), doLimitedCrafting(false), dimensionType(0), dimensionName(utils::Identifier{"", ""}), hashedSeed(0), gamemode(0), previousGamemode(0), debug(false),
flat(false), hasDeathLocation(false), portalCooldown(0), seaLevel(0), enforcesSecureChat(false) {}
LoginPlay(const int entity_id, const bool is_hardcore, const std::vector<utils::Identifier> dimensions, const int max_players, const int view_distance, const int simulation_distance, const bool reduced_debug_info,
bool const enable_respawn_screen, bool const do_limited_crafting, const int dimension_type, const utils::Identifier dimension_name, const long hashed_seed, const uint8_t gamemode, const int8_t previous_gamemode,
const bool debug, const bool flat, const bool has_death_location, const std::optional<utils::Identifier> death_dimension, const std::optional<math::Position> death_position, const int portal_cooldown,
const int sea_level, const bool enforces_secure_chat)
: Packet(ID), ClientboundPacket(ID), entityId(entity_id), isHardcore(is_hardcore), dimensions(dimensions), maxPlayers(max_players), viewDistance(view_distance),
simulationDistance(simulation_distance), reducedDebugInfo(reduced_debug_info), enableRespawnScreen(enable_respawn_screen), doLimitedCrafting(do_limited_crafting),
dimensionType(dimension_type), dimensionName(dimension_name), hashedSeed(hashed_seed), gamemode(gamemode), previousGamemode(previous_gamemode), debug(debug), flat(flat),
hasDeathLocation(has_death_location), deathDimension(death_dimension), deathPosition(death_position), portalCooldown(portal_cooldown), seaLevel(sea_level),
enforcesSecureChat(enforces_secure_chat) {}
CLIENTBOUND_PACKET_FOOTER(LoginPlay)
};
class SetCenterChunk final : public ClientboundPacket {
public:
constexpr static int ID = 0x57;
int chunkX; // VarInt
int chunkZ; // VarInt
SetCenterChunk() : Packet(ID), ClientboundPacket(ID), chunkX(0), chunkZ(0) {}
SetCenterChunk(const int chunkX, const int chunkZ) : Packet(ID), ClientboundPacket(ID), chunkX(chunkX), chunkZ(chunkZ) {}
CLIENTBOUND_PACKET_FOOTER(SetCenterChunk)
};
class SetDefaultSpawnPosition final : public ClientboundPacket {
public:
constexpr static int ID = 0x5A;
math::Position location;
float angle;
SetDefaultSpawnPosition() : Packet(ID), ClientboundPacket(ID), location(), angle() {}
SetDefaultSpawnPosition(const math::Position location, const float angle)
: Packet(ID), ClientboundPacket(ID), location(location), angle(angle) {}
CLIENTBOUND_PACKET_FOOTER(SetDefaultSpawnPosition)
};
class HandshakePacketHandler final : public PacketHandler {
public:
using PacketHandler::handle;
explicit HandshakePacketHandler(NetworkConnection* connection) : connection(connection) {}
bool handle(ClientHandshake& packet) override;
bool handle(LegacyServerListPing& packet) override;
protected:
NetworkConnection* connection;
};
class StatusPacketHandler final : public PacketHandler {
public:
using PacketHandler::handle;
explicit StatusPacketHandler(NetworkConnection* connection) : connection(connection) {}
bool handle(StatusRequest& packet) override;
bool handle(PingRequest& packet) override;
protected:
NetworkConnection* connection;
};
class LoginPacketHandler final : public PacketHandler {
public:
using PacketHandler::handle;
explicit LoginPacketHandler(NetworkConnection* connection) : connection(connection) {}
bool handle(LoginStart& packet) override;
bool handle(EncryptionResponse& packet) override;
bool handle(LoginPluginResponse& packet) override;
bool handle(LoginAcknowledge& packet) override;
bool handle(LoginCookieResponse& packet) override;
protected:
NetworkConnection* connection;
};
class ConfigurationPacketHandler final : public PacketHandler {
public:
using PacketHandler::handle;
explicit ConfigurationPacketHandler(NetworkSession* session) : session(session) {}
bool handle(ConfigurationClientInformation& packet) override;
bool handle(ConfigurationCookieResponse& packet) override;
bool handle(ConfigurationServerPluginMessage& packet) override;
bool handle(AcknowledgeFinishConfiguration& packet) override;
bool handle(ConfigurationServerboundKeepAlive& packet) override;
bool handle(ConfigurationPong& packet) override;
bool handle(ConfigurationResourcePackResponse& packet) override;
bool handle(ServerboundKnownPacks& packet) override;
protected:
NetworkSession* session;
};
class PlayPacketHandler final : public PacketHandler {
public:
explicit PlayPacketHandler(NetworkSession* session) : PacketHandler(), session(session) {}
private:
NetworkSession* session;
};
} // namespace stratos
#endif //PACKETCODEC_H