#pragma once #include "StarDataStream.hpp" #include "StarWorldTiles.hpp" #include "StarItemDescriptor.hpp" #include "StarCelestialDatabase.hpp" #include "StarDamageManager.hpp" #include "StarChatTypes.hpp" #include "StarUuid.hpp" #include "StarTileModification.hpp" #include "StarEntity.hpp" #include "StarInteractionTypes.hpp" #include "StarWarping.hpp" #include "StarWiring.hpp" #include "StarClientContext.hpp" #include "StarSystemWorld.hpp" namespace Star { STAR_STRUCT(Packet); STAR_EXCEPTION(StarPacketException, IOException); extern VersionNumber const StarProtocolVersion; // Packet types sent between the client and server over a NetSocket. Does not // correspond to actual packets, simply logical portions of NetSocket data. enum class PacketType : uint8_t { // Packets used as part of the initial handshake ProtocolRequest, ProtocolResponse, // Packets sent universe server -> universe client ServerDisconnect, ConnectSuccess, ConnectFailure, HandshakeChallenge, ChatReceive, UniverseTimeUpdate, CelestialResponse, PlayerWarpResult, PlanetTypeUpdate, Pause, ServerInfo, // Packets sent universe client -> universe server ClientConnect, ClientDisconnectRequest, HandshakeResponse, PlayerWarp, FlyShip, ChatSend, CelestialRequest, // Packets sent bidirectionally between the universe client and the universe // server ClientContextUpdate, // Packets sent world server -> world client WorldStart, WorldStop, WorldLayoutUpdate, WorldParametersUpdate, CentralStructureUpdate, TileArrayUpdate, TileUpdate, TileLiquidUpdate, TileDamageUpdate, TileModificationFailure, GiveItem, EnvironmentUpdate, UpdateTileProtection, SetDungeonGravity, SetDungeonBreathable, SetPlayerStart, FindUniqueEntityResponse, Pong, // Packets sent world client -> world server ModifyTileList, DamageTileGroup, CollectLiquid, RequestDrop, SpawnEntity, ConnectWire, DisconnectAllWires, WorldClientStateUpdate, FindUniqueEntity, WorldStartAcknowledge, Ping, // Packets sent bidirectionally between world client and world server EntityCreate, EntityUpdateSet, EntityDestroy, EntityInteract, EntityInteractResult, HitRequest, DamageRequest, DamageNotification, EntityMessage, EntityMessageResponse, UpdateWorldProperties, StepUpdate, // Packets sent system server -> system client SystemWorldStart, SystemWorldUpdate, SystemObjectCreate, SystemObjectDestroy, SystemShipCreate, SystemShipDestroy, // Packets sent system client -> system server SystemObjectSpawn }; extern EnumMap const PacketTypeNames; enum class NetCompressionMode : uint8_t { None, Zstd }; extern EnumMap const NetCompressionModeNames; enum class PacketCompressionMode : uint8_t { Disabled, Automatic, Enabled }; struct Packet { virtual ~Packet(); virtual PacketType type() const = 0; virtual void readLegacy(DataStream& ds); virtual void read(DataStream& ds) = 0; virtual void writeLegacy(DataStream& ds) const; virtual void write(DataStream& ds) const = 0; virtual void readJson(Json const& json); virtual Json writeJson() const; PacketCompressionMode compressionMode() const; void setCompressionMode(PacketCompressionMode compressionMode); PacketCompressionMode m_compressionMode = PacketCompressionMode::Automatic; }; PacketPtr createPacket(PacketType type); PacketPtr createPacket(PacketType type, Maybe const& args); template struct PacketBase : public Packet { static PacketType const Type = PacketT; PacketType type() const override { return Type; } }; struct ProtocolRequestPacket : PacketBase { ProtocolRequestPacket(); ProtocolRequestPacket(VersionNumber requestProtocolVersion); void read(DataStream& ds) override; void write(DataStream& ds) const override; VersionNumber requestProtocolVersion; }; struct ProtocolResponsePacket : PacketBase { ProtocolResponsePacket(bool allowed = false, Json info = {}); void read(DataStream& ds) override; void writeLegacy(DataStream& ds) const override; void write(DataStream& ds) const override; bool allowed; Json info; }; struct ServerDisconnectPacket : PacketBase { ServerDisconnectPacket(); ServerDisconnectPacket(String reason); void read(DataStream& ds) override; void write(DataStream& ds) const override; String reason; }; struct ConnectSuccessPacket : PacketBase { ConnectSuccessPacket(); ConnectSuccessPacket(ConnectionId clientId, Uuid serverUuid, CelestialBaseInformation celestialInformation); void read(DataStream& ds) override; void write(DataStream& ds) const override; ConnectionId clientId; Uuid serverUuid; CelestialBaseInformation celestialInformation; }; struct ConnectFailurePacket : PacketBase { ConnectFailurePacket(); ConnectFailurePacket(String reason); void read(DataStream& ds) override; void write(DataStream& ds) const override; String reason; }; struct HandshakeChallengePacket : PacketBase { HandshakeChallengePacket(); HandshakeChallengePacket(ByteArray const& passwordSalt); void read(DataStream& ds) override; void write(DataStream& ds) const override; ByteArray passwordSalt; }; struct ChatReceivePacket : PacketBase { ChatReceivePacket(); ChatReceivePacket(ChatReceivedMessage receivedMessage); void read(DataStream& ds) override; void write(DataStream& ds) const override; void readJson(Json const& json) override; Json writeJson() const override; ChatReceivedMessage receivedMessage; }; struct UniverseTimeUpdatePacket : PacketBase { UniverseTimeUpdatePacket(); UniverseTimeUpdatePacket(double universeTime); void read(DataStream& ds) override; void write(DataStream& ds) const override; double universeTime; float timescale; }; struct CelestialResponsePacket : PacketBase { CelestialResponsePacket(); CelestialResponsePacket(List responses); void read(DataStream& ds) override; void write(DataStream& ds) const override; List responses; }; struct PlayerWarpResultPacket : PacketBase { PlayerWarpResultPacket(); PlayerWarpResultPacket(bool success, WarpAction warpAction, bool warpActionInvalid); void read(DataStream& ds) override; void write(DataStream& ds) const override; bool success; WarpAction warpAction; bool warpActionInvalid; }; struct PlanetTypeUpdatePacket : PacketBase { PlanetTypeUpdatePacket(); PlanetTypeUpdatePacket(CelestialCoordinate coordinate); void read(DataStream& ds) override; void write(DataStream& ds) const override; CelestialCoordinate coordinate; }; struct PausePacket : PacketBase { PausePacket(); PausePacket(bool pause, float timescale = 1.0f); void readLegacy(DataStream& ds) override; void read(DataStream& ds) override; void writeLegacy(DataStream& ds) const override; void write(DataStream& ds) const override; void readJson(Json const& json) override; Json writeJson() const override; bool pause = false; float timescale = 1.0f; }; struct ServerInfoPacket : PacketBase { ServerInfoPacket(); ServerInfoPacket(uint16_t players, uint16_t maxPlayers); void read(DataStream& ds) override; void write(DataStream& ds) const override; void readJson(Json const& json) override; Json writeJson() const override; uint16_t players; uint16_t maxPlayers; }; struct ClientConnectPacket : PacketBase { ClientConnectPacket(); ClientConnectPacket(ByteArray assetsDigest, bool allowAssetsMismatch, Uuid playerUuid, String playerName, String playerSpecies, WorldChunks shipChunks, ShipUpgrades shipUpgrades, bool introComplete, String account, Json info = {}); void readLegacy(DataStream& ds) override; void read(DataStream& ds) override; void writeLegacy(DataStream& ds) const override; void write(DataStream& ds) const override; ByteArray assetsDigest; bool allowAssetsMismatch; Uuid playerUuid; String playerName; String playerSpecies; WorldChunks shipChunks; ShipUpgrades shipUpgrades; bool introComplete; String account; Json info; }; struct ClientDisconnectRequestPacket : PacketBase { ClientDisconnectRequestPacket(); void read(DataStream& ds) override; void write(DataStream& ds) const override; }; struct HandshakeResponsePacket : PacketBase { HandshakeResponsePacket(); HandshakeResponsePacket(ByteArray const& passHash); void read(DataStream& ds) override; void write(DataStream& ds) const override; ByteArray passHash; }; struct PlayerWarpPacket : PacketBase { PlayerWarpPacket(); PlayerWarpPacket(WarpAction action, bool deploy); void read(DataStream& ds) override; void write(DataStream& ds) const override; WarpAction action; bool deploy; }; struct FlyShipPacket : PacketBase { FlyShipPacket(); FlyShipPacket(Vec3I system, SystemLocation location); void read(DataStream& ds) override; void write(DataStream& ds) const override; Vec3I system; SystemLocation location; }; struct ChatSendPacket : PacketBase { ChatSendPacket(); ChatSendPacket(String text, ChatSendMode sendMode); void read(DataStream& ds) override; void write(DataStream& ds) const override; String text; ChatSendMode sendMode; }; struct CelestialRequestPacket : PacketBase { CelestialRequestPacket(); CelestialRequestPacket(List requests); void read(DataStream& ds) override; void write(DataStream& ds) const override; List requests; }; struct ClientContextUpdatePacket : PacketBase { ClientContextUpdatePacket(); ClientContextUpdatePacket(ByteArray updateData); void read(DataStream& ds) override; void write(DataStream& ds) const override; ByteArray updateData; }; // Sent when a client should initialize themselves on a new world struct WorldStartPacket : PacketBase { WorldStartPacket(); void read(DataStream& ds) override; void write(DataStream& ds) const override; Json templateData; ByteArray skyData; ByteArray weatherData; Vec2F playerStart; Vec2F playerRespawn; bool respawnInWorld; HashMap dungeonIdGravity; HashMap dungeonIdBreathable; Set protectedDungeonIds; Json worldProperties; ConnectionId clientId; bool localInterpolationMode; }; // Sent when a client is leaving a world struct WorldStopPacket : PacketBase { WorldStopPacket(); WorldStopPacket(String const& reason); void read(DataStream& ds) override; void write(DataStream& ds) const override; String reason; }; // Sent when the region data for the client's current world changes struct WorldLayoutUpdatePacket : PacketBase { WorldLayoutUpdatePacket(); WorldLayoutUpdatePacket(Json const& layoutData); void read(DataStream& ds) override; void write(DataStream& ds) const override; Json layoutData; }; // Sent when the environment status effect list for the client's current world changes struct WorldParametersUpdatePacket : PacketBase { WorldParametersUpdatePacket(); WorldParametersUpdatePacket(ByteArray const& parametersData); void read(DataStream& ds) override; void write(DataStream& ds) const override; ByteArray parametersData; }; struct CentralStructureUpdatePacket : PacketBase { CentralStructureUpdatePacket(); CentralStructureUpdatePacket(Json structureData); void read(DataStream& ds) override; void write(DataStream& ds) const override; Json structureData; }; struct TileArrayUpdatePacket : PacketBase { typedef MultiArray TileArray; TileArrayUpdatePacket(); void read(DataStream& ds) override; void write(DataStream& ds) const override; Vec2I min; TileArray array; }; struct TileUpdatePacket : PacketBase { TileUpdatePacket() {} void read(DataStream& ds) override; void write(DataStream& ds) const override; Vec2I position; NetTile tile; }; struct TileLiquidUpdatePacket : PacketBase { TileLiquidUpdatePacket(); TileLiquidUpdatePacket(Vec2I const& position, LiquidNetUpdate liquidUpdate); void read(DataStream& ds) override; void write(DataStream& ds) const override; Vec2I position; LiquidNetUpdate liquidUpdate; }; struct TileDamageUpdatePacket : PacketBase { TileDamageUpdatePacket(); TileDamageUpdatePacket(Vec2I const& position, TileLayer layer, TileDamageStatus const& tileDamage); void read(DataStream& ds) override; void write(DataStream& ds) const override; Vec2I position; TileLayer layer; TileDamageStatus tileDamage; }; struct TileModificationFailurePacket : PacketBase { TileModificationFailurePacket(); TileModificationFailurePacket(TileModificationList modifications); void read(DataStream& ds) override; void write(DataStream& ds) const override; TileModificationList modifications; }; struct GiveItemPacket : PacketBase { GiveItemPacket(); GiveItemPacket(ItemDescriptor const& item); void read(DataStream& ds) override; void write(DataStream& ds) const override; void readJson(Json const& json) override; Json writeJson() const override; ItemDescriptor item; }; struct EnvironmentUpdatePacket : PacketBase { EnvironmentUpdatePacket(); EnvironmentUpdatePacket(ByteArray skyDelta, ByteArray weatherDelta); void read(DataStream& ds) override; void write(DataStream& ds) const override; ByteArray skyDelta; ByteArray weatherDelta; }; struct UpdateTileProtectionPacket : PacketBase { UpdateTileProtectionPacket(); UpdateTileProtectionPacket(DungeonId dungeonId, bool isProtected); void read(DataStream& ds) override; void write(DataStream& ds) const override; void readJson(Json const& json) override; Json writeJson() const override; DungeonId dungeonId; bool isProtected; }; struct SetDungeonGravityPacket : PacketBase { SetDungeonGravityPacket(); SetDungeonGravityPacket(DungeonId dungeonId, Maybe gravity); void read(DataStream& ds) override; void write(DataStream& ds) const override; void readJson(Json const& json) override; Json writeJson() const override; DungeonId dungeonId; Maybe gravity; }; struct SetDungeonBreathablePacket : PacketBase { SetDungeonBreathablePacket(); SetDungeonBreathablePacket(DungeonId dungeonId, Maybe breathable); void read(DataStream& ds) override; void write(DataStream& ds) const override; void readJson(Json const& json) override; Json writeJson() const override; DungeonId dungeonId; Maybe breathable; }; struct SetPlayerStartPacket : PacketBase { SetPlayerStartPacket(); SetPlayerStartPacket(Vec2F playerStart, bool respawnInWorld); void read(DataStream& ds) override; void write(DataStream& ds) const override; void readJson(Json const& json) override; Json writeJson() const override; Vec2F playerStart; bool respawnInWorld; }; struct FindUniqueEntityResponsePacket : PacketBase { FindUniqueEntityResponsePacket(); FindUniqueEntityResponsePacket(String uniqueEntityId, Maybe entityPosition); void read(DataStream& ds) override; void write(DataStream& ds) const override; String uniqueEntityId; Maybe entityPosition; }; struct PongPacket : PacketBase { PongPacket(); PongPacket(int64_t time); void readLegacy(DataStream& ds) override; void read(DataStream& ds) override; void writeLegacy(DataStream& ds) const override; void write(DataStream& ds) const override; int64_t time = 0; }; struct ModifyTileListPacket : PacketBase { ModifyTileListPacket(); ModifyTileListPacket(TileModificationList modifications, bool allowEntityOverlap); void read(DataStream& ds) override; void write(DataStream& ds) const override; TileModificationList modifications; bool allowEntityOverlap; }; struct DamageTileGroupPacket : PacketBase { DamageTileGroupPacket(); DamageTileGroupPacket(List tilePositions, TileLayer layer, Vec2F sourcePosition, TileDamage tileDamage, Maybe sourceEntity); void read(DataStream& ds) override; void write(DataStream& ds) const override; List tilePositions; TileLayer layer; Vec2F sourcePosition; TileDamage tileDamage; Maybe sourceEntity; }; struct CollectLiquidPacket : PacketBase { CollectLiquidPacket(); CollectLiquidPacket(List tilePositions, LiquidId liquidId); void read(DataStream& ds) override; void write(DataStream& ds) const override; List tilePositions; LiquidId liquidId; }; struct RequestDropPacket : PacketBase { RequestDropPacket(); RequestDropPacket(EntityId dropEntityId); void read(DataStream& ds) override; void write(DataStream& ds) const override; EntityId dropEntityId; }; struct SpawnEntityPacket : PacketBase { SpawnEntityPacket(); SpawnEntityPacket(EntityType entityType, ByteArray storeData, ByteArray firstNetState); void read(DataStream& ds) override; void write(DataStream& ds) const override; EntityType entityType; ByteArray storeData; ByteArray firstNetState; }; struct ConnectWirePacket : PacketBase { ConnectWirePacket(); ConnectWirePacket(WireConnection outputConnection, WireConnection inputConnection); void read(DataStream& ds) override; void write(DataStream& ds) const override; WireConnection outputConnection; WireConnection inputConnection; }; struct DisconnectAllWiresPacket : PacketBase { DisconnectAllWiresPacket(); DisconnectAllWiresPacket(Vec2I entityPosition, WireNode wireNode); void read(DataStream& ds) override; void write(DataStream& ds) const override; Vec2I entityPosition; WireNode wireNode; }; struct WorldClientStateUpdatePacket : PacketBase { WorldClientStateUpdatePacket(); WorldClientStateUpdatePacket(ByteArray const& worldClientStateDelta); void read(DataStream& ds) override; void write(DataStream& ds) const override; ByteArray worldClientStateDelta; }; struct FindUniqueEntityPacket : PacketBase { FindUniqueEntityPacket(); FindUniqueEntityPacket(String uniqueEntityId); void read(DataStream& ds) override; void write(DataStream& ds) const override; String uniqueEntityId; }; struct WorldStartAcknowledgePacket : PacketBase { WorldStartAcknowledgePacket(); void read(DataStream& ds) override; void write(DataStream& ds) const override; }; struct PingPacket : PacketBase { PingPacket(); PingPacket(int64_t time); void readLegacy(DataStream& ds) override; void read(DataStream& ds) override; void writeLegacy(DataStream& ds) const override; void write(DataStream& ds) const override; int64_t time = 0; }; struct EntityCreatePacket : PacketBase { EntityCreatePacket(); EntityCreatePacket(EntityType entityType, ByteArray storeData, ByteArray firstNetState, EntityId entityId); void read(DataStream& ds) override; void write(DataStream& ds) const override; EntityType entityType; ByteArray storeData; ByteArray firstNetState; EntityId entityId; }; // All entity deltas will be sent at the same time for the same connection // where they are master, any entities whose master is from that connection can // be assumed to have produced a blank delta. struct EntityUpdateSetPacket : PacketBase { EntityUpdateSetPacket(ConnectionId forConnection = ServerConnectionId); void read(DataStream& ds) override; void write(DataStream& ds) const override; ConnectionId forConnection; HashMap deltas; }; struct EntityDestroyPacket : PacketBase { EntityDestroyPacket(); EntityDestroyPacket(EntityId entityId, ByteArray finalNetState, bool death); void read(DataStream& ds) override; void write(DataStream& ds) const override; EntityId entityId; ByteArray finalNetState; // If true, the entity removal is due to death rather simply for example // going out of range of the entity monitoring window. bool death; }; struct EntityInteractPacket : PacketBase { EntityInteractPacket(); EntityInteractPacket(InteractRequest interactRequest, Uuid requestId); void read(DataStream& ds) override; void write(DataStream& ds) const override; InteractRequest interactRequest; Uuid requestId; }; struct EntityInteractResultPacket : PacketBase { EntityInteractResultPacket(); EntityInteractResultPacket(InteractAction action, Uuid requestId, EntityId sourceEntityId); void read(DataStream& ds) override; void write(DataStream& ds) const override; InteractAction action; Uuid requestId; EntityId sourceEntityId; }; struct HitRequestPacket : PacketBase { HitRequestPacket(); HitRequestPacket(RemoteHitRequest remoteHitRequest); void read(DataStream& ds) override; void write(DataStream& ds) const override; RemoteHitRequest remoteHitRequest; }; struct DamageRequestPacket : PacketBase { DamageRequestPacket(); DamageRequestPacket(RemoteDamageRequest remoteDamageRequest); void read(DataStream& ds) override; void write(DataStream& ds) const override; RemoteDamageRequest remoteDamageRequest; }; struct DamageNotificationPacket : PacketBase { DamageNotificationPacket(); DamageNotificationPacket(RemoteDamageNotification remoteDamageNotification); void read(DataStream& ds) override; void write(DataStream& ds) const override; RemoteDamageNotification remoteDamageNotification; }; struct EntityMessagePacket : PacketBase { EntityMessagePacket(); EntityMessagePacket(Variant entityId, String message, JsonArray args, Uuid uuid, ConnectionId fromConnection = ServerConnectionId); void read(DataStream& ds) override; void write(DataStream& ds) const override; void readJson(Json const& json) override; Json writeJson() const override; Variant entityId; String message; JsonArray args; Uuid uuid; ConnectionId fromConnection; }; struct EntityMessageResponsePacket : PacketBase { EntityMessageResponsePacket(); EntityMessageResponsePacket(Either response, Uuid uuid); void read(DataStream& ds) override; void write(DataStream& ds) const override; Either response; Uuid uuid; }; struct UpdateWorldPropertiesPacket : PacketBase { UpdateWorldPropertiesPacket(); UpdateWorldPropertiesPacket(JsonObject const& updatedProperties); void read(DataStream& ds) override; void write(DataStream& ds) const override; void readJson(Json const& json) override; Json writeJson() const override; JsonObject updatedProperties; }; struct StepUpdatePacket : PacketBase { StepUpdatePacket(); StepUpdatePacket(double remoteTime); void readLegacy(DataStream& ds) override; void read(DataStream& ds) override; void writeLegacy(DataStream& ds) const override; void write(DataStream& ds) const override; double remoteTime; }; struct SystemWorldStartPacket : PacketBase { SystemWorldStartPacket(); SystemWorldStartPacket(Vec3I location, List objectStores, List shipStores, pair clientShip); void read(DataStream& ds) override; void write(DataStream& ds) const override; Vec3I location; List objectStores; List shipStores; pair clientShip; }; struct SystemWorldUpdatePacket : PacketBase { SystemWorldUpdatePacket(); SystemWorldUpdatePacket(HashMap objectUpdates, HashMap shipUpdates); void read(DataStream& ds) override; void write(DataStream& ds) const override; HashMap objectUpdates; HashMap shipUpdates; }; struct SystemObjectCreatePacket : PacketBase { SystemObjectCreatePacket(); SystemObjectCreatePacket(ByteArray objectStore); void read(DataStream& ds) override; void write(DataStream& ds) const override; ByteArray objectStore; }; struct SystemObjectDestroyPacket : PacketBase { SystemObjectDestroyPacket(); SystemObjectDestroyPacket(Uuid objectUuid); void read(DataStream& ds) override; void write(DataStream& ds) const override; Uuid objectUuid; }; struct SystemShipCreatePacket : PacketBase { SystemShipCreatePacket(); SystemShipCreatePacket(ByteArray shipStore); void read(DataStream& ds) override; void write(DataStream& ds) const override; ByteArray shipStore; }; struct SystemShipDestroyPacket : PacketBase { SystemShipDestroyPacket(); SystemShipDestroyPacket(Uuid shipUuid); void read(DataStream& ds) override; void write(DataStream& ds) const override; Uuid shipUuid; }; struct SystemObjectSpawnPacket : PacketBase { SystemObjectSpawnPacket(); SystemObjectSpawnPacket(String typeName, Uuid uuid, Maybe position, JsonObject parameters); void read(DataStream& ds) override; void write(DataStream& ds) const override; String typeName; Uuid uuid; Maybe position; JsonObject parameters; }; }