README: серверная часть, наш протокол и вход через лаунчер

This commit is contained in:
sasheg dev
2026-10-19 20:11:19 +03:00
parent 450bdecc34
commit 60130d8d17
+84 -2
View File
@@ -8,10 +8,10 @@ with its own server, its own protocol and its own accounts.
| Repository | License | What lives there |
|---|---|---|
| `rsx-client` | MIT | Loader, mod API, client hooks, deobfuscation tools |
| `rsx-protocol` | MIT | Wire format, packet schemas, shared simulation library |
| `rsx-protocol` | MIT | Wire format, packet schemas, shared vocabulary |
| `rsx-plugin-api` | MIT | Interfaces for server-side content |
| `rsx-server-core` | proprietary | Tick loop, world, entities, scaling |
| `rsx-auth` | proprietary | Accounts, tokens, revocation |
| `rsx-auth` | proprietary | The server's own accounts, used when there is no launcher |
## Target
@@ -56,6 +56,71 @@ both came out of this class of bug.
The fork holds Mojang-derived code and is **not published**. What ships in the
open repository is the loader, the mod API and the build tools.
## The server
The server owns the world. The client draws it and believes nothing.
### The wire
The protocol is ours, not the vanilla one. A vanilla 1.12.2 client and our
server cannot talk to each other at all, and that is the point: the game is
ours, so the wire is ours, and every packet in it is one we wrote down.
The client's own game code is not rewritten. The client reads our packets and
translates them into the game's, and the game does what it already knows how to
do: build a world, spawn entities, draw them. The transport is ours; the
renderer is the game's. The other direction is the same: the game says "the
player moved" and "the player broke a block", and those two become our packets.
### The world
A chunk is sixteen by sixteen columns, two hundred and fifty six high, one byte
per block. Generation is a pure function of the seed and the coordinates: no
shared state, no `java.util.Random` carried between calls, no dependence on the
order chunks are asked for. A chunk may be generated months after its
neighbour, on another machine, and has to agree with it exactly, because a save
file can only record what changed and not the terrain underneath it.
Chunks are written one file per chunk, to a temporary name and moved into
place, with a version and a checksum. A chunk that is half written when the
power goes is a chunk the server refuses to load, rather than one that loads
with half a world in it.
### Who gets in
The launcher is where accounts live: it has the passwords, the roles, the bans
and the friends. The game server has none of that and does not want a second
copy, so it asks the launcher whether a player is one of ours, and gets the ban
list in the same answer.
This is the part Yggdrasil does in vanilla, done with our own launcher. The
launcher already logs the player in and already hands the game a name, a uuid
and a token; the game hands that token to the server, and the server asks the
launcher about it. The token is used once and dropped.
The server's own accounts exist for a server of our own and for development.
When a launcher is configured they are shut, because a server with two doors
has no doors.
```
client game server launcher
| Hello | |
|------------------------->| |
| HelloAck | |
|<-------------------------| |
| LauncherAuth | |
|------------------------->|--- POST /auth/validate ->|
| |<-- {valid, reason} -----|
| AuthAck | |
|<-------------------------| |
| Login / LoginAck | |
|==========================>| |
| JoinWorld / WorldJoin | |
|<==========================| |
| ChunkData ... | |
|<==========================| |
```
## Modding
Mods are jars with a descriptor at `META-INF/rsxmod.properties`:
@@ -114,10 +179,27 @@ rsx-client\scripts\test.ps1 # self test, 128 checks
game-fork\scripts\prepare-game.ps1 # rebuild the fork from the vanilla jar
game-fork\scripts\compile-game.ps1 # compile only, fast iteration
rsx-client\scripts\run-game.ps1 # launch the client
rsx-protocol\scripts\build.ps1 # dist\rsx-protocol.jar
rsx-protocol\scripts\test.ps1 # 22 checks
rsx-server-core\scripts\build.ps1 # dist\rsx-server-core.jar
rsx-server-core\scripts\test.ps1 # 49 checks
rsx-server-core\scripts\run-server.ps1
```
Only a JDK is required. No Gradle, no network once the mappings are cached.
### Running the server
```
run-server.ps1 --port 25565 --world world --seed 0
run-server.ps1 --launcher-api https://launcher.example/api
```
`--launcher-api` points the server at the launcher's API. With it, the
launcher decides who gets in and the server's own accounts are shut.
`--allow-local-accounts` opens them again on purpose.
### Assets
The client will not run without a real asset tree, and the launcher on this