Skip to content

Commit 89eb66d

Browse files
authored
Merge pull request ferrumc-rs#283 from ferrumc-rs/fix/cleanup
Fix/cleanup
2 parents 91bbdb1 + 5a8fc74 commit 89eb66d

20 files changed

+1214
-458
lines changed

docs/ferrumc-specific-features.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
TODO:
2+
3+
Add
4+
- Dashboard (ferrumc's dashboard),
5+
- Custom Plugins (plugins developed specifically for ferrumc),
6+
- FerrumC CLI
7+
- importing
8+
- exporting (?)
9+
- etc
10+
- ...

docs/protocol-flow.md

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
# Minecraft Protocol Flow
2+
3+
This document explains how ferrumc handles the Minecraft Java Edition protocol, from initial connection to gameplay.
4+
5+
## Overview
6+
7+
The Minecraft protocol is a state machine with 5 connection states:
8+
9+
```mermaid
10+
stateDiagram-v2
11+
[*] --> Handshake: TCP Connect
12+
Handshake --> Status: Intent = 1
13+
Handshake --> Login: Intent = 2
14+
Status --> [*]: Close
15+
Login --> Configuration: Login Success
16+
Configuration --> Play: Finish Config
17+
Play --> Configuration: Reconfigure
18+
Play --> [*]: Disconnect
19+
```
20+
21+
## Connection States
22+
23+
| State | Purpose | Code Reference |
24+
|-------|---------|----------------|
25+
| **Handshake** | Initial packet determines intent | `ConnState::Handshake` in [`lib.rs`](../src/lib/net/src/lib.rs) |
26+
| **Status** | Server list ping (MOTD, player count) | `ConnState::Status` |
27+
| **Login** | Authentication, compression setup | `ConnState::Login` |
28+
| **Configuration** | Registry data, resource packs | `ConnState::Configuration` |
29+
| **Play** | Actual gameplay packets | `ConnState::Play` |
30+
31+
---
32+
33+
## Status Ping Flow
34+
35+
When a client pings the server (multiplayer menu), it follows this flow:
36+
37+
```mermaid
38+
sequenceDiagram
39+
participant C as Client
40+
participant S as Server
41+
42+
C->>S: TCP Connect
43+
C->>S: Handshake (intent=1)
44+
Note over S: State → Status
45+
C->>S: Status Request (0x00)
46+
S->>C: Status Response (JSON)
47+
C->>S: Ping Request (timestamp)
48+
S->>C: Pong Response (echo timestamp)
49+
C->>S: TCP Close
50+
```
51+
52+
### Code Flow
53+
54+
1. **TCP Accept** - [`game_loop.rs`](../src/bin/src/game_loop.rs) `tcp_conn_acceptor()`
55+
2. **Handle Connection** - [`connection.rs`](../src/lib/net/src/connection.rs) `handle_connection()`
56+
3. **Handshake** - [`conn_init/mod.rs`](../src/lib/net/src/conn_init/mod.rs) `handle_handshake()`
57+
4. **Status Handler** - [`conn_init/status.rs`](../src/lib/net/src/conn_init/status.rs) `status()`
58+
59+
### Status Response JSON
60+
61+
```json
62+
{
63+
"version": { "name": "1.21.8", "protocol": 772 },
64+
"players": { "max": 100, "online": 5, "sample": [...] },
65+
"description": { "text": "A ferrumc server" },
66+
"favicon": "data:image/png;base64,...",
67+
"enforces_secure_chat": false
68+
}
69+
```
70+
71+
---
72+
73+
## Login → Play Flow
74+
75+
When a client actually joins the server:
76+
77+
```mermaid
78+
sequenceDiagram
79+
participant C as Client
80+
participant S as Server
81+
82+
C->>S: Handshake (intent=2)
83+
Note over S: State → Login
84+
85+
rect rgb(40, 40, 60)
86+
Note over C,S: LOGIN STATE
87+
C->>S: Login Start (username, UUID)
88+
89+
opt Encryption Enabled
90+
S->>C: Encryption Request
91+
C->>S: Encryption Response
92+
Note over C,S: Enable AES encryption
93+
end
94+
95+
opt Compression Enabled
96+
S->>C: Set Compression (threshold)
97+
Note over C,S: Enable zlib compression
98+
end
99+
100+
S->>C: Login Success (UUID, username)
101+
C->>S: Login Acknowledged
102+
end
103+
104+
rect rgb(40, 60, 40)
105+
Note over C,S: CONFIGURATION STATE
106+
C->>S: Client Information
107+
S->>C: Known Packs
108+
C->>S: Select Known Packs
109+
S->>C: Registry Data (dimensions, biomes, etc.)
110+
S->>C: Plugin Message (brand)
111+
S->>C: Finish Configuration
112+
C->>S: Ack Finish Configuration
113+
end
114+
115+
rect rgb(60, 40, 40)
116+
Note over C,S: PLAY STATE
117+
S->>C: Login (Play)
118+
S->>C: Player Abilities
119+
S->>C: Synchronize Position
120+
C->>S: Confirm Teleportation
121+
S->>C: Chunk Data...
122+
Note over C,S: Gameplay begins
123+
end
124+
```
125+
126+
### Code Flow
127+
128+
| Step | Function | File |
129+
|------|----------|------|
130+
| 1. TCP Accept | `tcp_conn_acceptor()` | [`game_loop.rs`](../src/bin/src/game_loop.rs#L309) |
131+
| 2. Connection Handler | `handle_connection()` | [`connection.rs`](../src/lib/net/src/connection.rs#L253) |
132+
| 3. Handshake | `handle_handshake()` | [`conn_init/mod.rs`](../src/lib/net/src/conn_init/mod.rs#L60) |
133+
| 4. Login Sequence | `login()` | [`conn_init/login.rs`](../src/lib/net/src/conn_init/login.rs#L50) |
134+
| 5. ECS Registration | `accept_new_connections()` | [`new_connections.rs`](../src/bin/src/systems/new_connections.rs) |
135+
| 6. Packet Loop | `handle_connection()` recv loop | [`connection.rs`](../src/lib/net/src/connection.rs#L358) |
136+
137+
---
138+
139+
## Packet Format
140+
141+
All packets follow this format:
142+
143+
### Uncompressed
144+
```
145+
┌──────────────┬────────────┬──────────────────┐
146+
│ Length │ Packet ID │ Data │
147+
│ (VarInt) │ (VarInt) │ (varies) │
148+
└──────────────┴────────────┴──────────────────┘
149+
```
150+
151+
### Compressed (when data length > threshold)
152+
```
153+
┌──────────────┬────────────────┬────────────────────────┐
154+
│ Packet Len │ Data Length │ Compressed │
155+
│ (VarInt) │ (VarInt) │ (ID + Data) │
156+
└──────────────┴────────────────┴────────────────────────┘
157+
```
158+
159+
**Compression**: Handled by [`compress_packet()`](../src/lib/net/src/compression.rs)
160+
161+
---
162+
163+
## Play State Packet Handling
164+
165+
Once in Play state, packets flow through the ECS:
166+
167+
```mermaid
168+
flowchart LR
169+
TCP[TCP Stream] --> Reader[EncryptedReader]
170+
Reader --> Skeleton[PacketSkeleton]
171+
Skeleton --> Dispatch[handle_packet]
172+
Dispatch --> Channel[PacketSender Channel]
173+
Channel --> ECS[ECS Schedule]
174+
ECS --> Handler[Packet Handler System]
175+
```
176+
177+
### Key Components
178+
179+
| Component | Purpose | File |
180+
|-----------|---------|------|
181+
| `StreamWriter` | Async packet output | [`connection.rs`](../src/lib/net/src/connection.rs#L41) |
182+
| `EncryptedReader` | AES-encrypted input | `ferrumc_net_encryption` |
183+
| `PacketSkeleton` | Parsed packet frame | [`packet_skeleton.rs`](../src/lib/net/src/packets/incoming/packet_skeleton.rs) |
184+
| `PacketSender` | Channel to ECS | [`lib.rs`](../src/lib/net/src/lib.rs) |
185+
186+
### Packet Handler Registration
187+
188+
Packets are dispatched via the `setup_packet_handling!` macro:
189+
190+
```rust
191+
// src/lib/net/src/lib.rs
192+
setup_packet_handling!("\\src\\packets\\incoming");
193+
```
194+
195+
This generates a `handle_packet()` function that routes packets by ID to their handlers.
196+
197+
---
198+
199+
## Event System
200+
201+
Player actions trigger events that systems can listen to:
202+
203+
```mermaid
204+
flowchart TD
205+
Packet[Incoming Packet] --> Handler[Packet Handler]
206+
Handler --> Event[MessageWriter]
207+
Event --> Queue[Event Queue]
208+
Queue --> Listener1[Listener System 1]
209+
Queue --> Listener2[Listener System 2]
210+
Queue --> Listener3[Listener System N]
211+
```
212+
213+
**Example**: Player join triggers `PlayerJoined` event:
214+
- [`new_connections.rs`](../src/bin/src/systems/new_connections.rs) sends `PlayerJoined`
215+
- Listeners in [`register_gameplay_listeners()`](../src/bin/src/systems/listeners/mod.rs) react
216+
217+
---
218+
219+
## Threading Model
220+
221+
```
222+
┌─────────────────────────────────────────────────────────────┐
223+
│ MAIN THREAD │
224+
│ ┌─────────────────────────────────────────────────────┐ │
225+
│ │ Bevy ECS Scheduler │ │
226+
│ │ - Tick schedule (20 TPS) │ │
227+
│ │ - Keepalive schedule (1s) │ │
228+
│ │ - World sync schedule (15s) │ │
229+
│ └─────────────────────────────────────────────────────┘ │
230+
└─────────────────────────────────────────────────────────────┘
231+
232+
│ crossbeam channels (incoming)
233+
│ tokio mpsc channels (outgoing)
234+
235+
┌─────────────────────────────────────────────────────────────┐
236+
│ NETWORK THREAD (Tokio) │
237+
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
238+
│ │ TCP Acceptor │ │ Conn Handler 1 │ │ Conn Handler N │ │
239+
│ │ (listener) │ │ (per player) │ │ (per player) │ │
240+
│ └────────────────┘ └────────────────┘ └────────────────┘ │
241+
└─────────────────────────────────────────────────────────────┘
242+
```
243+
244+
See [`game_loop.rs`](../src/bin/src/game_loop.rs) for the threading setup.
245+
246+
---
247+
248+
## Quick Reference
249+
250+
### Protocol Version
251+
- **Minecraft**: 1.21.8
252+
- **Protocol**: 772
253+
- **Constant**: `PROTOCOL_VERSION_1_21_8` in [`conn_init/mod.rs`](../src/lib/net/src/conn_init/mod.rs#L31)
254+
255+
### External References
256+
- [Minecraft Protocol Wiki](https://minecraft.wiki/w/Java_Edition_protocol/Packets)
257+
- [Protocol Version Numbers](https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol_version_numbers)

0 commit comments

Comments
 (0)