Files
flayerproxy/codebase_map.md
sebseb7 373378de15 fix
2026-05-21 09:50:06 +02:00

47 KiB
Raw Permalink Blame History

🗺️ FlayerProxy Codebase Map

This document provides a comprehensive mapping of all the classes, functions, and files in the src/ directory of FlayerProxy, along with Mermaid diagrams showing how the components interact during different modes of operation.


📑 Table of Contents


🏗️ Architecture & Interaction Diagrams

1. High-Level Core System Diagram

This diagram shows how the core components cooperate across play (single client, port 25566), spectator (multi-client watch-only, port 25568), and bot mode (idle behaviour when no player is connected).

graph TD
    classDef main fill:#d4e1f5,stroke:#1a5f7a,stroke-width:2px;
    classDef helper fill:#f5f0d4,stroke:#7a6b1a,stroke-width:1px;
    classDef external fill:#e1d5e7,stroke:#9673a6,stroke-width:1px;

    Client["Play Client (25566, max 1)"]:::external
    Specs["Spectator Clients (25568, max N)"]:::external
    Server["Target Minecraft Server"]:::external

    subgraph FlayerProxy ["FlayerProxy Core"]
        SM["[SessionManager]"]:::main
        SC["[ServerConnection]"]:::main
        PS["[ProxyServer]"]:::main
        SPS["[SpectatorProxyServer]"]:::main
        SH["[SpectatorHub]"]:::main
        WSC["[WorldStateCache]"]:::main
        SR["[StateReplayer]"]:::main
        CB["[ClientBridge]"]:::main
        IB["[BotIdleBehavior]"]:::helper
    end

    SM -->|Orchestrates| SC
    SM -->|Orchestrates| PS
    SM -->|Orchestrates| SPS
    SM -->|Orchestrates| WSC
    SM -->|Orchestrates| SR
    SM -->|Handoff| CB
    SPS -->|on join| SH
    SH -->|Uses| SR
    SH -->|Fans out S2C from| SC

    SC -->|Holds session with| Bot["Mineflayer Bot"]:::external
    SC -->|BOT_MODE| IB
    IB -->|onSwing → botVisual| SH
    Bot -->|Connects to| Server
    SC -->|Captures play packets to| WSC
    PS -->|Single slot login| Client
    SR -->|replay / replaySpectator| Client
    SR -->|replaySpectator| Specs
    CB -->|Bidirectional play| Client
    CB -->|Bidirectional play| SC

2. Client Handoff Flow Diagram

This sequence diagram shows the step-by-step handoff process when a standard Minecraft client connects to the proxy, disabling the bot's AI, replaying the cached state, and establishing the packet-forwarding bridge.

sequenceDiagram
    autonumber
    actor Player as Minecraft Client
    participant PS as ProxyServer
    participant SM as SessionManager
    participant SC as ServerConnection
    participant WSC as WorldStateCache
    participant SR as StateReplayer
    participant Server as Upstream Server

    Note over SM,SC: State: BOT_MODE (Bot AI holds session)
    Player->>PS: Connect to Proxy (Port 25566)
    Note over PS: login reserves single activeClient slot
    PS->>SM: _onClientConnect(client)
    Note over SM: State -> HANDOFF
    SM->>SC: setBotControl(false) [Disable Bot physics/AI]
    SM->>SM: _primeChunksNearBot() [Confirm position & await chunks]
    SM->>SR: replay(client)
    SR->>Player: Send 'login' packet (join_game)
    SR->>Player: Send difficulty, abilities, permission level
    SR->>Player: Send early misc packets (tags, commands, server_data, time)
    SR->>Player: Send recipe & advancement sync packets
    SR->>Player: Send initial 'position' teleport packet
    Player-->>SR: Send 'teleport_confirm' packet
    SR->>Player: Send tab list (player_info)
    SR->>Player: Send level info (world border, spawn, time)
    SR->>Player: Send chunks (chunk_batch_start, map_chunks, light, block_changes, chunk_batch_finished)
    SR->>Player: Send spawned entities (metadata, equipment, effects, passengers)
    SR->>Player: Send experience, health, and status effects
    SR->>Player: Send inventory snapshot (window_items, set_slot, held_item_slot)
    Note over SR: State replay complete
    SM->>SC: syncProxyClientPosition(client) [Final snap]
    SC->>Player: Send updated 'position' + 'update_view_position'
    Player-->>SC: Send 'teleport_confirm'
    SM->>SC: confirmServerPosition() [Confirm to Server]
    SC->>Server: Send serverbound 'position_look'
    SM->>Server: Send 'player_loaded' (hasClientLoaded)
    Note over SM: State -> CLIENT_MODE
    SM->>CB: Start ClientBridge(client, serverConn, worldState)
    Note over CB: Bidirectional Packet Piping Active

3. Spectator Watch Flow Diagram

Spectators connect on a separate port (default 25568). They receive a spectator replay, then a read-only fan-out of upstream S2C packets. Movement is blocked; the camera is locked to the bot entity. Idle arm swings are synthesized locally (the server does not echo the bot's own swing).

sequenceDiagram
    autonumber
    actor Spec as Spectator Client
    participant SPS as SpectatorProxyServer
    participant SH as SpectatorHub
    participant SR as StateReplayer
    participant SC as ServerConnection
    participant IB as BotIdleBehavior

    Note over SC: BOT_MODE (bot control + idle)
    Spec->>SPS: Connect (Port 25568)
    SPS->>SH: addSpectator(client)
    SH->>SR: replaySpectator(client)
    SR->>Spec: login, terrain, entities (spectator gamemode + camera)
    SH->>Spec: camera lock + position snap to bot
    SH->>SC: listen serverPacket + botVisual
    loop Live watch
        SC->>SH: serverPacket (chunks, entities, position, …)
        SH->>Spec: forward S2C (writeRaw where needed)
        IB->>SC: swingArm → emit botVisual animation
        SC->>SH: botVisual animation
        SH->>Spec: entity swing animation
        Spec--xSH: movement C2S dropped / camera re-lock
    end

4. MITM Sniffer Architecture Diagram

The Packet Sniffer has two modes of operation:

  • MitmProxy: Decrypts both the client leg and the server leg using custom negotiated encryption keys to print and inspect packet structures in real time.
  • TransparentProxy: Pipes TCP streams directly without decryption, using a non-disruptive StreamTap to record unencrypted packets (like status handshakes or offline logins).
graph LR
    classDef sniffer fill:#d4f5d4,stroke:#1a7a1a,stroke-width:2px;
    classDef external fill:#e1d5e7,stroke:#9673a6,stroke-width:1px;

    Client["Minecraft Client (Port 25567)"]:::external
    Server["Target Minecraft Server"]:::external

    subgraph MitmProxyApp ["MitmProxy (Packet Sniffer)"]
        MProxy["MitmProxy (mc.createServer)"]:::sniffer
        PacketLog["PacketLog (JSONL log file)"]:::sniffer
        StreamTap["StreamTap (C2S & S2C frame parsing)"]:::sniffer
    end

    Client -->|connects| MProxy
    MProxy -->|initiates upstream client| UpstreamClient["mc.createClient"]:::sniffer
    UpstreamClient -->|connects| Server

    MProxy -->|logs packets| PacketLog
    MProxy -->|taps packets for state tracking| StreamTap

🔑 Cross-Cutting Behavior

Summary of policies that span multiple modules (not obvious from individual class tables).

Ports and connection policy

Port (default) Listener Max clients When accepted
25566 ProxyServer 1 BOT_MODE only; slot reserved on login, released on reject/disconnect
25568 SpectatorProxyServer 20 (configurable) Upstream connected and not INIT/HANDOFF; allowed in BOT_MODE (bot control) or CLIENT_MODE

Disable spectators with spectator.enabled: false in config.json.

Chunk cache vs live forwarding

Phase map_chunk behavior
Bot session (cache) ChunkCache stores only chunks within view distance of the bot view center (update_view_position or player position + update_view_distance). Out-of-view chunks are skipped on ingest and pruned via forgetOutsideView.
Handoff replay StateReplayer + getChunksForReplay() send only in-view cached chunks (nearest-first).
CLIENT_MODE bridge ClientBridge forwards all upstream map_chunk packets. May send update_view_position so the client accepts chunks outside its local cache radius.

Chunks are server-pushed; the bot/client mainly acks via chunk_batch_received and movement/view packets.

Block/light merge and structuredClone

map_chunk binary fields (chunkData, heightmaps, etc.) must stay as Node Buffer instances for prismarine-chunk / smart-buffer. structuredClone in the cache path can turn them into Uint8Array, which breaks merges (Invalid Buffer provided in SmartBufferOptions). chunkMerge.js normalizes via asBuffer() / normalizeMapChunkPacket() before column load and merge.

Spectator watch (movement and visuals)

  • Movement: Vanilla spectator free-cam is largely client-side. The proxy cannot rely on dropping C2S alone; SpectatorHub locks the camera to the bot entity (camera packet), snaps position on movement C2S, and runs a 1s correction loop.
  • Idle swing: The server does not echo the bots own arm swing. BotIdleBehaviorServerConnection._emitBotSwingAnimationbotVisual → spectator animation fan-out.

Bot idle (no play client)

While in BOT_MODE with bot control enabled, BotIdleBehavior runs random look / sneak / swing on a timer (config.bot.antiAfk*). Started/stopped with ServerConnection.setBotControl.


🗂️ Detailed File Mapping

1. Root Scripts & Configuration

📄 src/index.js

The main entry point for the application. Loads system config, logs play and spectator proxy ports, starts SessionManager, hooks SIGINT/SIGTERM for graceful shutdown, and captures uncaughtException / unhandledRejection.

Function Description
shutdown(signal) Gracefully stops the proxy and exits the node process.

📄 src/config.js

Handles configuration loading, validation, and parsing.

Function Description
loadConfig() Synchronously reads config.json, validates host, port, version, and auth configuration, applies defaults for proxy, spectator, bot (anti-Afk intervals), and cache, and returns the configuration object.

Default config sections: proxy (port 25566, maxClients: 1), spectator (port 25568, maxClients: 20, enabled: true), bot (antiAfk, antiAfkMinInterval, antiAfkMaxInterval, viewDistance).


2. session — Session State Machine

🧩 SessionManager class

Orchestrates the dual-mode proxy state machine: INITBOT_MODEHANDOFFCLIENT_MODE.

Method Description
constructor(config) Initializes state machine, play proxy, optional spectator proxy/hub, and replayer.
start() Connects upstream bot, starts play proxy (25566), and spectator proxy (25568) if enabled.
_scheduleReconnect(delaySec) Schedules a timed reconnect sequence if the connection is lost.
_setupServerEvents() Hooks upstream server events (connected, disconnected, kicked, error, death, respawn).
_primeChunksNearBot() Triggers server movement packets to verify that the chunk cache is loaded near the bot before handing off.
_refreshClientAfterBotRespawn() Re-aligns position and client view in case the bot respawns while a client is connected.
_clientSlotStatus() Returns whether the play port may accept a new login (single client, BOT_MODE only).
_spectatorSlotStatus() Returns whether the spectator port may accept logins (connected, not INIT/HANDOFF; BOT_MODE with bot control or CLIENT_MODE).
_rejectClient(client, reason) Kicks play client and releases ProxyServer.activeClient slot.
_onClientConnect(client) Validates play slot, then handoff BOT_MODECLIENT_MODE.
_cleanupClient() Stops bridge, releases play client slot, clears currentClient.
_transitionTo(newState) Transitions the machine state and logs status summaries.
stop() Gracefully halts all services.

🧩 ServerConnection class extends EventEmitter

Manages the persistent Mineflayer bot connection to the target server.

Method Description
constructor(config, worldState) Initializes bot connection manager with config and world state reference.
connect() Spawns the bot connection via Mineflayer.
_setupConfigCapture() Caches configuration-phase registry data and tags.
_setupPacketCapture() Hooks play packets and routes them directly to the state cache.
_setupBotEvents() Listens for bot lifecycle events; creates BotIdleBehavior on spawn.
_emitBotSwingAnimation(hand) Emits botVisual (animation packet) so spectators see idle swings (server does not echo self-swing).
setBotControl(enabled) Enables/disables physics; starts/stops BotIdleBehavior.
setClientDrivesChunkBatchAck(clientDrives) Delegates chunk batch acknowledgement control between client and Mineflayer.
flushChunkBatchAck() Unblocks the server chunk sender.
refreshProxyClientPermissions(client) Sends player permissions status packets.
syncProxyClientPosition(client) Snaps client position coordinates to the bot.
confirmServerPosition() Confirms final block coordinates back to the server.
setProxyClientChunkAck(enabled) Configures the ChunkAckManager.
relayClientMovement(name, data) Translates Notchian/mineflayer coordinates and forwards client movements upstream.
writeToServer(name, data) Writes raw packets directly upstream.
disconnect() Safely disconnects the bot.

Events: connected, disconnected, kicked, error, death, respawn, serverPacket (name, data, buffer), botVisual (name, data) (synthetic S2C for spectators).

🧩 ChunkAckManager class

Intercepts Mineflayer's chunk batch acknowledgement listeners to prevent double-acknowledging packets during the client session.

Method Description
constructor() Initializes acknowledgement state.
disable(rawClient) Disables auto-acknowledgement on the client stream.
restore(rawClient) Restores Mineflayer auto-acknowledgement.
flush(rawClient) Sends a manual chunk batch received acknowledgement packet.

📄 MovementRelay.js functions

Function Description
relayClientMovement(bot, rawClient, name, data) Applies client movement packets to the bot entity structure and writes updates upstream.
syncProxyClientPosition(bot, worldState, client) Sends a teleport/position packet to the client and awaits a matching teleport_confirm.
confirmServerPosition(bot, rawClient, connected) Writes a position_look verification packet to the upstream server.

📄 handoffFlow.js functions

Function Description
performHandoff({...}) Coordinates the sequential handoff sequence: installs temporary upstream forwarding rules, primes nearby chunks, triggers the StateReplayer, aligns player coordinates/permissions, and spawns the ClientBridge.

🧩 BotIdleBehavior class

Random look / sneak / swing while the bot holds the session (BOT_MODE, no play client). Started from ServerConnection.setBotControl(true).

Method Description
constructor(bot, botConfig, hooks) Optional onSwing(hand) hook for spectator animation relay.
start() / stop() Enables/disables timed idle actions (config.bot.antiAfk).
_scheduleNext() Random delay between antiAfkMinInterval and antiAfkMaxInterval.
_tick() Picks random action: look, sneak, or swing.
_randomLook() bot.look() with small yaw/pitch delta.
_randomSneak() Toggles sneak via setControlState for a random duration.
_randomSwing() bot.swingArm() then onSwing callback.

3. proxy — Client Connection Proxy

🧩 ProxyServer class

Listens for connection attempts from standard Minecraft Java clients.

Method Description
constructor(config, onClientConnect, worldState, canAcceptClient) Play proxy; optional canAcceptClient() gate from SessionManager.
releaseClient(client) Clears activeClient if it matches (used on reject/disconnect).
start() mc.createServer on config.proxy.port; reserves single slot on login; replays raw config on login_acknowledged; playerJoin only for reserved client.
updateRegistryCodec(codec) Replaces the registry codec object in the protocol handler options.
stop() Disconnects active client and closes listener.

🧩 ClientBridge class

Manages bidirectional packet pipelines when in CLIENT_MODE.

Method Description
constructor(client, serverConn, worldState) Initializes bridge with client, server connection, and world state references.
_getViewDistance() Resolves the view distance from configuration or state records.
_syncClientViewFromBlockCoords(blockX, blockZ) Computes chunk coordinates and updates client view center position.
_syncClientViewFromBot() Aligns client view center with the bot entity position.
_playerBlockCoordsForView() Returns coordinates representing the client player's view anchor.
_ensureViewIncludesChunk(chunkX, chunkZ) Ensures the client's view includes target coordinates prior to sending map chunks.
enableMovement() Authorizes client movement and syncs view center alignment.
start() Sets up packet intercept listeners to route packets between legs, excluding blocked elements (e.g. keep_alive, teleport_confirm, message_acknowledgement) and re-signing client chat events.
_shouldForwardPlayerInfo(data) Filters latency updates for unknown players.
stop() Tears down the forwarding pipe.

Play client forwarding: All upstream map_chunk packets are forwarded (no radius filter). update_view_position may be sent before chunks outside the client cache radius.


4. spectator — Watch-Only Multi-Client Proxy

🧩 SpectatorProxyServer class

Separate mc.createServer on config.spectator.port (default 25568). Allows multiple simultaneous spectators; no upstream connection per spectator.

Method Description
constructor(config, hub, worldState, canAcceptClient) Spectator listener with slot/status callback from SessionManager._spectatorSlotStatus.
start() Binds port, replays raw config packets, calls hub.addSpectator on playerJoin.
updateRegistryCodec(codec) Same registry injection as play proxy.
stop() Closes spectator listener.

🧩 SpectatorHub class

Manages spectator clients: replay, S2C fan-out, movement block, camera lock.

Method Description
constructor(serverConn, worldState, replayer, config) Subscribes to serverConn serverPacket and botVisual events.
addSpectator(client) replaySpectator, camera lock, position snap, join fan-out set.
removeSpectator(client) Removes client; detaches fan-out when last spectator leaves.
kickAll(reason) / stop() Disconnects all spectators; removes listeners.
_installClientGuard(client, state) Whitelist C2S only; on movement packets, re-lock camera + snap position.
_lockCamera(client) Sends camera with bot entityId.
_snapPosition(client, state) Sends clientbound position from bot entity.
_startSnapLoop() / _stopSnapLoop() Periodic camera/position correction (1s).
_forwardToSpectators(name, data, buffer) Fans upstream S2C to all spectators (writeRaw for chunk packets).

📄 spectatorPackets.js constants

Export Description
SPECTATOR_GAMEMODE Gamemode id 3 for replay.
SPECTATOR_ALLOWED_C2S Whitelist: chunk_batch_received, teleport_confirm, keep_alive, etc.
SPECTATOR_BLOCKED_S2C Dropped S2C fan-out (e.g. tracked_waypoint — mid-join UPDATE without prior TRACK crashes clients).
SPECTATOR_MOVEMENT_C2S Movement packets that trigger camera re-lock.
ANIMATION_SWING_MAIN_HAND / ANIMATION_SWING_OFF_HAND Clientbound animation ids for idle swing relay.

ServerConnection events used by spectators:

Event Payload Description
serverPacket (name, data, buffer) Same stream as play cache (from upstream bot).
botVisual (name, data) Synthetic S2C (e.g. idle animation) not echoed by server.

5. state — World State Caching

🧩 WorldStateCache class

Master coordinator for world cache segments. Integrates and clears sub-caches on server switches.

Method Description
constructor(config) Initializes all sub-caches from configuration.
handleConfigPacket(name, data) Caches parsed config-phase packets.
buildRegistryCodec() Combines cached config packets to build a custom Minecraft registry codec.
handleRawConfigPacket(name, buffer) Appends raw configuration buffers.
getRawConfigPacketsForReplay() Filters and returns config-phase buffers for client replay.
hasRawConfigPackets() Returns true if raw configuration buffers are cached.
handleServerPacket(name, data, buffer) Evaluates incoming play packets and routes them to sub-caches.
_getChunkViewContext() Resolves view center (update_view_position or player position) + view distance for cache retention.
_forgetChunksOutsideView() Drops cached chunks outside isChunkWithinViewDistance.
getSummary() Returns cache sizing info for log monitoring.
clear() Wipes all cached structures.

🧩 ChunkCache class

Manages loaded map chunks, light maps, and block overlays using an LRU cache. Merges block/light updates via chunkMerge.js (prismarine-chunk columns).

Method Description
constructor(maxChunks, options) LRU storage; version + getWorldBounds() for column decode.
_key(x, z) Computes string key for map lookups.
forgetOutsideView(centerChunkX, centerChunkZ, viewDistance) Removes chunks outside server ChunkTrackingView distance.
handleMapChunk(data, rawBuffer, view?) Skips store if outside view; prunes cache; normalizes Buffers after structuredClone.
handleUpdateLight(data) Merges light into cached column via applyUpdateLight.
handleUnloadChunk(data) Evicts chunk records from cache.
handleBlockChange(data) Merges single block into column; logs merge failures.
handleMultiBlockChange(data) Merges section block records into column.
_ensureColumn(stored) Lazy-loads prismarine column from map_chunk packet data.
_syncPacketFromColumn(stored) Re-exports merged column to packetData.
getChunksForReplay(centerChunkX, centerChunkZ, viewDistance) Returns in-view chunks only (same distance test as forget), nearest-first.
hasChunkAtBlock(x, z) Verifies if a chunk is loaded.
clear() Wipes chunk maps.

📄 chunkMerge.js functions

Function Description
asBuffer(value) Coerces Buffer / Uint8Array for prismarine-chunk / smart-buffer.
normalizeMapChunkPacket(packet) Fixes binary fields after structuredClone.
loadColumnFromMapChunk(packet, version, worldBounds) Builds prismarine column from map_chunk.
exportMapChunkPacket(column, packet) Dumps column back to map_chunk shape.
applyBlockChange / applyUpdateLight / applyMultiBlockChange Merge incremental updates into column.

🧩 EntityCache class

Tracks entities, positions, gear, and status effects.

Method Category Description
constructor() Initializes entity tracking maps.
handleSpawnEntity(data) Lifecycle Instantiates a new tracked entity.
handleEntityDestroy(data) Lifecycle Removes entities.
handleEntityMetadata(data) State Updates metadata flags.
handleEntityEquipment(data) State Caches equipment items.
handleEntityEffect(data) State Adds status effects.
handleRemoveEntityEffect(data) State Removes status effects.
handleSetPassengers(data) State Caches passenger mounting structures.
handleEntityPosition(data) Movement Updates entity coordinates.
handleSyncEntityPosition(data) Movement Translates and maps sync positions.
handleRelEntityMove(data) Movement Applies relative move differentials.
handleEntityMoveLook(data) Movement Applies move and rotation differentials.
handleEntityTeleport(data) Movement Sets absolute coordinates.
getAllEntities() Query Returns sanitized entity arrays.
removePlayerEntity(entityId) Query Excludes own entity.
clear() Clears entity maps.

🧩 PlayerStateCache class

Caches player-specific attributes.

Method Description
constructor() Initializes player state storage.
handleLogin(data) Stores the initial login join_game packet.
handlePosition(data) Stores coordinate positions.
handleUpdateHealth(data) Stores health/hunger levels.
handleExperience(data) Caches XP level values.
handleAbilities(data) Caches flight capabilities and speeds.
handleEntityStatus(data) Caches permissions status.
handleSpawnPosition(data) Caches spawn points.
handleDifficulty(data) Caches difficulty levels.
handleGameStateChange(data) Captures gamemode updates.
handleRespawn(data) Resets active position, health, and status values on player respawn.
handleEntityEffect(data) Caches player status effects.
handleRemoveEntityEffect(data) Evicts player status effects.
getState() Returns all active player data.
clear() Wipes player state.

🧩 InventoryCache class

Caches slot lists, inventories, and held items.

Method Description
constructor() Initializes inventory storage.
handleWindowItems(data) Caches full item lists.
handleSetSlot(data) Caches individual slot updates.
handleHeldItemSlot(data) Stores current hotbar slot index.
handleSetPlayerInventory(data) Stores inventory slots.
handleSetCursorItem(data) Stores cursor items.
getReplayPackets() Assembles sequence of inventory packet states.
clear() Clears inventory states.

🧩 MiscCache class

Coordinates world data, tab lists, scoreboards, tags, and bossbars.

Method Category Description
constructor() Initializes miscellaneous state storage.
handleUpdateTime(data) World Caches time variables.
handleGameStateChange(data) World Tracks weather triggers.
handleSimulationDistance(data) World Caches simulation distance settings.
handleUpdateViewDistance(data) World Caches view distance settings.
handleUpdateViewPosition(data) World Caches view position markers.
handlePlayerInfo(data) Tab list Tracks player additions.
handlePlayerRemove(data) Tab list Tracks player removals.
handlePlayerListHeader(data) Tab list Caches tab list headers.
handleBossBar(data) UI Caches bossbar indicators.
handleTags(data) Registry Caches server tag structures.
handleServerData(data) Registry Caches server description parameters.
handleDeclareCommands(data) Registry Caches commands registry.
getReplayPackets() Replay Compiles time, weather, border, teams, scoreboard, and bossbar packets.
getPlayerInfoReplayPackets() Replay Compiles player_info packets.
getKnownPlayerUuids() Query Identifies player UUIDs.
clear() Clears variables.

🧩 JoinSyncCache class

Holds configuration elements that are typically sent only once at login, such as advancement criteria and recipe lists.

Method Description
constructor() Initializes join-sync storage.
handlePacket(name, data) Identifies and caches advancements and recipe book packets.
getReplayPackets() Returns advancement and recipe packets.
clear() Clears variables.

🧩 WorldBorderCache class

Caches world border coordinates and warn margins.

Method Description
constructor() Initializes border state storage.
handleInitWorldBorder(data) Caches initial world border packet.
handleWorldBorderCenter(data) Caches center coordinates.
handleWorldBorderSize(data) Caches border size.
handleWorldBorderLerpSize(data) Caches border interpolation size.
handleWorldBorderWarningDelay(data) Caches warning delay.
handleWorldBorderWarningReach(data) Caches warning reach distance.
getReplayPackets() Returns border initialization packets.
clear() Resets variables.

🧩 ScoreboardCache class

Caches teams, scores, objectives, and scoreboard layouts.

Method Description
constructor() Initializes scoreboard storage.
handleScoreboardObjective(data) Caches objective structures.
handleScoreboardDisplayObjective(data) Caches display positions.
handleScoreboardScore(data) Caches score updates.
handleResetScore(data) Removes score records.
handleTeams(data) Caches teams.
getReplayPackets() Aggregates objectives, displays, scores, and teams.
clear() Clears variables.

6. replay — Client Handoff Replay

🧩 StateReplayer class

Replays the cached world state to a connecting play or spectator client.

Method Description
constructor(worldState, serverConn) Initializes replayer with world state and server connection references.
replaySpectator(client) Calls replay(client, { spectator: true }) — gamemode 3, camera lock, no inventory.
replay(client, options) Sequential packet delivery; options.spectator adjusts abilities/gamemode/camera.

replay() sequence:

Step Packets sent
1 login packet (join_game)
2 Difficulty, abilities, and permission level
3 Pre-level metadata
4 Active hotbar selection
5 Recipe books and advancements
6 Teleport client player → await teleport_confirm
7 Tab list names
8 Time, spawn, world border, weather, view distance
9 Chunk loading start → replay chunks
10 Spawned entities (metadata, passengers, effects)
11 XP, health, and status effects
12 Full inventory (window_items)

📄 replayChunks.js functions

Function Description
replayChunks(write, writeRaw, chunks, center, totalCached) Loops through chunk arrays, sending raw chunk/light buffers and block overlay edits, and issues a final chunk_batch_finished packet.

📄 replayHelpers.js functions

Function Description
yieldEventLoop() Yields the event loop using setImmediate.
replayPacketData(client, name, data) Overrides enforcesSecureChat to false for clients connecting without secure Mojang keys.
getPlayerChunkCenter(playerState, misc, bot) Resolves chunk coordinates for position center checks.
splitMiscReplayPackets(packets) Splits misc packets into early configurations, level coordinates, and weather variables.
waitForClientTeleportConfirm(client) Awaits the client's teleport_confirm packet.

Spectator replay differences: Sends game_state_change (gamemode 3), camera (bot entity id), flying ability flags; skips full inventory and permission entity_status.


7. utils — Helper Utilities

📄 angles.js functions

Function Description
toByteAngle(value) Converts float degrees to i8 byte angles.
sanitizeSpawnEntity(spawnData) Normalizes angle properties of entity spawn packets.

📄 chatRelay.js functions

Function Description
disableInboundChatValidation(client) Removes message acknowledgement checks to prevent chat validation kicks.
extractChatText(name, data) Extracts text string parameter values from chat packets.
relayClientChatAsUpstream(serverConn, name, data, log) Re-signs and forwards client messages using the bot's credentials.

📄 clientDisconnect.js functions

Function Description
disconnectReasonText(reason) Formats error reason arguments into plain text strings.
wrapClientEnd(client) Wraps connection end methods to prevent formatting exceptions.
safeEndClient(client, reason) Disconnects client sockets.

📄 handoffSync.js functions

Function Description
installHandoffUpstreamRelay(client, serverConn, log) Pipes chunk batch and player loaded packets directly to the server connection during handoff.
removeHandoffUpstreamRelay(client, handler) Removes the handoff forwarding pipe.
sendPermissionStatusToClient(client, permissionStatus, log) Sends the player's OP status packet to the client.

📄 logger.js functions

Function Description
createLogger(module) Returns console logging utilities formatted with module tags and colors.

📄 positionSync.js functions

Function Description
buildClientboundPositionPacket(bot, teleportId) Creates a player teleport packet from the bot's current coordinates.
waitForClientTeleportConfirm(client, timeoutMs, log) Awaits the client's position confirmation.
movementFlags(onGround, hasHorizontalCollision) Builds movement flags objects.
buildServerboundPositionLook(bot) Creates a serverbound player position verification packet.
distanceSq(a, b) Computes squared distance.
chunkCoordsFromBlock(x, z) Resolves block coordinates to chunk coordinates.
isChunkWithinViewDistance(centerChunkX, centerChunkZ, chunkX, chunkZ, viewDistance) Checks if a chunk lies within view distance limits.
updateClientViewPosition(client, chunkX, chunkZ, lastView) Sends update_view_position to the client.
ensureClientViewIncludesChunk(client, playerBlockX, playerBlockZ, chunkX, chunkZ, viewDistance, lastView) Snaps the client view center forward if a target chunk is about to load outside of its radius.

8. constants — Shared Packet Sets

📄 rawPackets.js

Export Description
RAW_FORWARD_PACKETS Play packets forwarded with writeRaw (chunks, lights, view position, batch markers). Used by ClientBridge and SpectatorHub.

📄 spectatorPackets.js

See spectator — Watch-Only Multi-Client Proxy.


9. sniffer — MITM Packet Sniffer

📄 src/sniffer/index.js

Main launcher file for the sniffer tool. Parses arguments, applies default configurations for local hosting and logging directory, launches the MitmProxy engine, and sets up shutdown listeners.

🧩 MitmProxy class

Configures an interception proxy that decrypts packet bytes on both connections.

Method Description
constructor(config) Initializes the MITM proxy with configuration.
start() Initializes the server.
_onConnection(client) Sets up packet listeners, configures log files, and spawns the upstream server client.
_startUpstream(session, cleanup) Begins the upstream connection flow.
_tryBeginJavaCrypto(session, cleanup) Checks state before negotiating encryption.
_doJavaCrypto(session, cleanup) Sets up local encryption filters.
stop() Shuts down proxy services.

🧩 TransparentProxy class

Transparently forwards TCP bytes between the client and server while feeding a copy to the StreamTap to extract and log packets.

Method Description
constructor(config) Initializes transparent proxy with configuration.
start() Binds the transparent port listener.
_onClientConnect(clientSocket, targetHost, targetPort, sniffer) Pipes client and server sockets together and hooks up stream taps.
stop() Shuts down socket handlers.

🧩 StreamTap class

Parses packet streams without modifying the underlying bytes.

Method Description
constructor(dir, version, packetLog, hooks) Initializes stream tap with direction, version, logger, and hooks.
feed(chunk) Passes byte chunks to the framer/splitter.
_syncState() Aligns state variables.
_parser() Creates deserializers.
_parseFrame(frame) Decompresses frame data.
_onFrame(frame) Parses parameters, extracts compression settings and login handshakes, and writes entries to logs.
_setState(next) Sets protocol states.
_advanceState(name, data) Advances states.

🧩 PacketLog class

Formats and writes packet data into JSONL logs.

Method Description
constructor(opts) Initializes log output streams.
writeMeta(record) Writes metadata entries.
logUnparsed(dir, state, frame, message) Logs parser errors.
logOpaque(dir, bytes, extra) Summarizes encrypted play traffic volume.
logPacket(dir, meta, data, rawBuffer, extra) Records details for parsed packets.
close(reason) Safely closes output write streams.

📄 mitmEncryption.js functions

Function Description
enableJavaEncryption(client, server, options) Negotiates the encryption phase on the client connection.

📄 mitmGate.js functions

Packet gating logic — controls buffering, ordering, and flushing of packets during connection state transitions.

Function Category Description
canRelayC2S(session, meta) C2S Checks if a client packet should be sent upstream.
c2sForwardLabel(session, meta) C2S Labels C2S traffic.
classifyS2C(session, meta) S2C Classifies S2C traffic.
shouldBufferS2C(session, meta) S2C Checks if S2C packets should be buffered.
queueBufferedS2C(session, data, meta, buffer) S2C Appends packets to buffer arrays.
queueHeldS2C(session, data, meta, buffer) S2C Queues packets while encryption is pending.
isStalePlayS2C(meta) S2C Filters out stale packets.
flushQueue(session, queue) Flush Flushes a packet queue to the client.
flushPendingConfig(session) Flush Flushes configuration packets.
flushPendingPlay(session) Flush Flushes play packets to client.
sortPlayPending(pending) Ordering Sorts play-phase packets to match join sequence requirements.
partitionAfterCrypto(pendingS2C) Ordering Partitions packets by state.
hasPendingSuccess(session) State Checks if a login success packet is waiting.
onJavaLoginAcknowledged(session) State Shifts connection states to CONFIGURATION.
onJavaFinishConfiguration(session, packetLog) State Shifts connection states to PLAY.

📄 mitmLogin.js functions

Function Description
applyLoginStartIdentity(client, packet, server, options) Verifies Mojang public key signatures.

📄 mitmRelay.js functions

Handles low-level packet relay, compression synchronization, and raw buffer forwarding decisions.

Function Description
shouldWriteRaw(meta, buffer) Decides if a packet should be written as a raw buffer.
relayPacket(target, meta, data, buffer) Writes a packet parsed or raw.
syncCompression(target, name, data) Synchronizes compression threshold.
sortLoginPending(pending) Sorts login packets.
relayLoginCompressToJava(client, meta, data, buffer) Writes compression setting.
relayToJava(client, meta, data, buffer) Safely writes packets to Java.

📄 mitmSession.js functions

Function Description
createMitmSession(client, packetLog) Initializes a sniffer session.
createSessionCleanup(session, packetLog, proxy) Returns a session cleanup function.

📄 mitmUpstream.js functions

Function Description
startStatusPipe(session, config, packetLog, proxy) Pipes status pings at the TCP socket layer.
startUpstream(session, config, cleanup, callbacks) Starts the upstream server connection.