# Networking and Protocol The Hytale server uses a packet-based networking system for client-server communication. This guide covers the protocol system, packet types, and how to work with networking in your mods. ## Overview The networking layer is built on QUIC protocol and handles: - Client connections and authentication - Game state synchronization - Player input handling - Entity updates - World data streaming - UI communication ## Key Components | Component | Description | |-----------|-------------| | `Packet` | Base interface for all packets | | `PacketRegistry` | Central packet type registration | | `PacketHandler` | Manages client connections and packet processing | | `ServerManager` | Server network manager | ## Packet Categories Packets are organized into categories in `com.hypixel.hytale.protocol.packets`: | Category | Description | |----------|-------------| | `connection/` | Connection lifecycle (connect, disconnect, ping) | | `auth/` | Authentication and session management | | `player/` | Player-specific packets (movement, actions) | | `entities/` | Entity creation, updates, removal | | `world/` | World/chunk data streaming | | `inventory/` | Inventory operations | | `interaction/` | Player interactions | | `interface_/` | UI/interface packets | | `camera/` | Camera control | | `setup/` | Initial setup and configuration | | `window/` | Window/container management | | `assets/` | Asset loading and management | | `asseteditor/` | Asset editor tools (dev) | | `buildertools/` | Building tools | | `machinima/` | Machinima/cinematic tools | | `serveraccess/` | Server access control | | `worldmap/` | World map data | ## Packet Structure ### Packet Interface All packets implement the `Packet` interface: ```java public interface Packet { // Packets are typically data classes // with fields for the packet data } ``` ### Example Packet ```java public class PlayerPositionPacket implements Packet { private final UUID playerId; private final Vector3d position; private final float yaw; private final float pitch; public PlayerPositionPacket(UUID playerId, Vector3d position, float yaw, float pitch) { this.playerId = playerId; this.position = position; this.yaw = yaw; this.pitch = pitch; } public UUID getPlayerId() { return playerId; } public Vector3d getPosition() { return position; } public float getYaw() { return yaw; } public float getPitch() { return pitch; } } ``` ## Client Sessions ### Managing Clients ```java // Get the server manager ServerManager serverManager = ServerManager.get(); // Get handler for a client PacketHandler handler = serverManager.getHandler(channel); // Send packet to client handler.sendPacket(packet); // Send multiple packets handler.sendPackets(Arrays.asList(packet1, packet2, packet3)); ``` ### Client Events ```java // Player connected getEventRegistry().register(PlayerConnectEvent.class, event -> { Player player = event.getPlayer(); // Handle connection }); // Player disconnected getEventRegistry().register(PlayerDisconnectEvent.class, event -> { Player player = event.getPlayer(); // Handle disconnection }); ``` ## Sending Packets to Players ### Single Player ```java Player player = getPlayer(); // Send a packet player.sendPacket(new MyPacket(data)); ``` ### Multiple Players ```java // Send to all players for (Player player : Universe.get().getPlayers()) { player.sendPacket(packet); } // Send to players in a world World world = Universe.get().getWorld("default"); for (Player player : world.getPlayers()) { player.sendPacket(packet); } // Broadcast to all Universe.get().broadcast(packet); ``` ### Area-Based Broadcasting ```java // Send to players near a position Vector3d center = new Vector3d(100, 64, 100); double radius = 50.0; for (Player player : Universe.get().getPlayers()) { if (player.getPosition().distance(center) <= radius) { player.sendPacket(packet); } } ``` ## Common Packet Types ### Connection Packets | Packet | Direction | Description | |--------|-----------|-------------| | `ConnectionRequestPacket` | C->S | Client requests connection | | `ConnectionResponsePacket` | S->C | Server accepts/rejects connection | | `DisconnectPacket` | Both | Connection termination | | `PingPacket` | Both | Latency measurement | ### Player Packets | Packet | Direction | Description | |--------|-----------|-------------| | `PlayerPositionPacket` | Both | Position update | | `PlayerInputPacket` | C->S | Player input (movement, actions) | | `PlayerActionPacket` | C->S | Player actions | ### Entity Packets | Packet | Direction | Description | |--------|-----------|-------------| | `EntitySpawnPacket` | S->C | Entity creation | | `EntityUpdatePacket` | S->C | Entity state update | | `EntityRemovePacket` | S->C | Entity removal | | `EntityMovePacket` | S->C | Entity movement | ### World Packets | Packet | Direction | Description | |--------|-----------|-------------| | `ChunkDataPacket` | S->C | Chunk data transfer | | `BlockChangePacket` | S->C | Block state change | | `WorldTimePacket` | S->C | World time sync | ### Inventory Packets | Packet | Direction | Description | |--------|-----------|-------------| | `InventoryUpdatePacket` | S->C | Inventory contents | | `SlotChangePacket` | Both | Single slot update | | `ItemPickupPacket` | S->C | Item pickup notification | ## Rate Limiting The server includes built-in rate limiting for packet handling: ```java // Configuration in HytaleServerConfig RateLimitConfig { enabled: boolean // Enable rate limiting packetsPerSecond: int // Max packets per second burstCapacity: int // Burst allowance } ``` Rate limiting protects against packet spam and potential exploits. ## Connection Timeouts ```java // Configuration in HytaleServerConfig ConnectionTimeouts { initialTimeout: Duration // Initial connection timeout authTimeout: Duration // Authentication timeout playTimeout: Duration // Gameplay timeout joinTimeouts: Map // Per-world join timeouts } ``` ## Custom Packet Handling ### Receiving Packets (Server-Side) To handle incoming packets, use the receiver system: ```java // Register a packet receiver getPacketReceiverRegistry().register(MyCustomPacket.class, (player, packet) -> { // Handle the packet String data = packet.getData(); processData(player, data); }); ``` ### Custom Packet Registration For advanced mods that need custom packet types: ```java // Define a custom packet with codec public class MyCustomPacket implements Packet { public static final Codec CODEC = BuilderCodec.of(MyCustomPacket::new) .with("data", Codec.STRING, p -> p.data) .build(); private final String data; public MyCustomPacket(String data) { this.data = data; } public String getData() { return data; } } ``` ## UI Communication ### Server UI Pages The server can send UI pages to clients: ```java // Send a UI page to player player.showUI(new MyUIPage(data)); // Close UI player.closeUI(); ``` ### UI Packets | Packet | Direction | Description | |--------|-----------|-------------| | `UIOpenPacket` | S->C | Open a UI screen | | `UIClosePacket` | S->C | Close UI | | `UIUpdatePacket` | S->C | Update UI data | | `UIInteractionPacket` | C->S | UI button/element interaction | ## Network Compression The server supports packet compression for bandwidth optimization: ```java // In server config localCompressionEnabled: boolean ``` When enabled, large packets are compressed before transmission. ## Authentication ### Auth Flow 1. Client sends `ConnectionRequestPacket` 2. Server validates and sends auth challenge 3. Client responds with credentials 4. Server verifies and sends `ConnectionResponsePacket` 5. If successful, player enters play state ### Auth Events ```java // Handle authentication getEventRegistry().register(PlayerAuthEvent.class, event -> { Player player = event.getPlayer(); // Custom auth logic if (!isAuthorized(player)) { event.setCancelled(true); event.setKickMessage("Not authorized!"); } }); ``` ## Best Practices 1. **Minimize packet size** - Only send necessary data 2. **Batch updates** - Combine multiple small updates into single packets when possible 3. **Use appropriate packet types** - Don't repurpose packets for unintended uses 4. **Handle disconnections gracefully** - Clean up resources when players disconnect 5. **Respect rate limits** - Don't spam packets to clients 6. **Validate incoming data** - Never trust client data without validation 7. **Use async for heavy operations** - Don't block the network thread 8. **Consider bandwidth** - Players may have limited bandwidth 9. **Test latency scenarios** - Test with simulated network delays 10. **Secure sensitive operations** - Validate permissions server-side ## Security Considerations - **Never trust client data** - Always validate on the server - **Use server authority** - Server is the source of truth for game state - **Validate permissions** - Check permissions before processing sensitive packets - **Rate limit custom packets** - Prevent abuse of custom packet handlers - **Sanitize inputs** - Prevent injection attacks in text data