Вход без пароля, права админа и F3+B

Аутентификация переделана по схеме пользователя: лаунчер — единственный
источник токена, сервер проверяет его сам и лаунчера не спрашивает.

- rsx-auth/GameToken: токен это base64url(payload) + "." + base64url(HMAC-SHA256),
  payload {uuid, nick, aud, exp, jti, typ}, typ = session или reload.
- Сессия живёт час, reload-токен полтора часа и только внутри игры. Пакет
  SessionReload продлевает сессию и выдаёт новый reload-токен.
- Сервер проверяет подпись, аудиенс, срок и совпадение uuid. HTTP-запрос к
  лаунчеру из сервера убран.
- Клиент: окно пароля убрано совсем, ник берётся из токена, клиент сам
  продлевает сессию за 5 минут до конца.
- Для локальной разработки сервер с --dev-token пишет свой токен в
  world/dev-token.txt, клиент берёт токен оттуда.
- Права админа: свой список world/admins.txt, перечитывается раз в 5 секунд,
  поэтому право снимается на лету. Пакет AdminState.
- Ванильные блоки мира ломает только админ, режим игры прав не даёт.
- F3+B только для админов: без прав показываем отказ, с правом включаются и
  ванильные хитбоксы, и наш отладочный рендер. Права сняли посреди просмотра —
  гаснут сразу.
- run-game.ps1 умеет -Token.

Проверено на живом сервере: own session ok, player in, rights of Player given.
Тесты: протокол 34, сервер 88, форк собирается чисто.
This commit is contained in:
sasheg dev
2026-10-22 08:50:57 +03:00
parent cf90f71e58
commit d2a0a7a93b
21 changed files with 1478 additions and 543 deletions
@@ -36,6 +36,14 @@ public final class RsxBootstrap {
private static boolean frameFailed;
private static boolean tickFailed;
/**
* How long before the session runs out the client makes it longer.
*
* Five minutes is enough to reach the server even when the connection is
* not very good.
*/
private static final long RELOAD_MARGIN_MILLIS = 5L * 60L * 1000L;
private RsxBootstrap() {
}
@@ -182,9 +190,20 @@ public final class RsxBootstrap {
public static synchronized void clientTick() {
// the connection is pumped from here, not from the screen that started
// it. A handshake that only runs while a screen is up is a handshake
// that the player can break by moving the window.
// the player can break by moving the window.
net.rustnotmc.client.net.RsxNetworkManager.pump();
// the session runs out after an hour, so it is made longer before that
net.rustnotmc.client.net.RsxNetworkManager manager =
net.rustnotmc.client.net.RsxNetworkManager.active();
if (manager != null) {
long left = manager.sessionLeft();
if (left > 0L && left < RELOAD_MARGIN_MILLIS) {
manager.reloadSession();
}
}
if (loader == null || broken || tickFailed) {
return;
}