Files
hytale-server/docs/07-networking.md

10 KiB

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:

public interface Packet {
    // Packets are typically data classes
    // with fields for the packet data
}

Example Packet

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

// 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

// 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

Player player = getPlayer();

// Send a packet
player.sendPacket(new MyPacket(data));

Multiple Players

// 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

// 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:

// 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

// Configuration in HytaleServerConfig
ConnectionTimeouts {
    initialTimeout: Duration  // Initial connection timeout
    authTimeout: Duration     // Authentication timeout
    playTimeout: Duration     // Gameplay timeout
    joinTimeouts: Map<String, Duration>  // Per-world join timeouts
}

Custom Packet Handling

Receiving Packets (Server-Side)

To handle incoming packets, use the receiver system:

// 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:

// Define a custom packet with codec
public class MyCustomPacket implements Packet {
    public static final Codec<MyCustomPacket> 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:

// 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:

// 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

// 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