Files
RustNotMC/rsx-server-core/scripts/run-server.ps1
T
sasheg dev 620f136361 Серверная база со своим логином
Теперь можно зарегистрировать аккаунт, поднять сервер и зайти в него.

Пароль не ходит по сети и не хранится на сервере в обратимом виде. Клиент
называет аккаунт, сервер отдаёт его соль и одноразовый вызов для этого
соединения, клиент тянет из пароля ключ через PBKDF2-HMAC-SHA256 и
подписывает им вызов вместе с именем. Пароль пересекает сокет ноль раз, а
запись обрезать нельзя: сервер не знает исходного пароля.

Отсюда важное следствие, которое сразу отозвало одну ошибку в протоколе:
соль обязана прийти раньше, чем клиент что-то доказывает, поэтому аккаунт
называется в Hello, а не в Auth. Иначе клиент получает соль не того
аккаунта и не может вывести ключ.

Учётная запись хранится как PBKDF2 соль, счётчик раундов и хеш. Раунды
лежат рядом с записью, а не в исходниках: число, существующее только в
коде, однажды становится причиной того, что аккаунт невозможно проверить.

Имена уникальны независимо от регистра: Player и player — это один
аккаунт. Иначе игрок получает двух персонажей и не понимает, какой его.

Троттлинг двумя ведрами, по аккаунту и по адресу: одно не мешает
подбирать одно имя, другое не мешает перебирать много имён с разных
адресов. Ответ на несуществующий аккаунт выполняет ту же работу, что и на
неверный пароль, и занимает то же время.

Токены живут только в памяти. Записанный на диск токен пережил бы процесс,
который его выдал, а украденный каталог сервера стал бы набором живых
сессий.

Сессии различаются номером, а не адресом. Ключ по адресу вытеснял всех, кто
зашёл с одного IP, то есть всех игроков за одним NAT.

Тик-цикл: 20 раз в секунду, с ограничением догоняющих тиков. Мир, который
тикает по кадрам, тикает в зависимости от видеокарты — ровно то, от чего
мы уходим, перенося симуляцию на свой сервер.

Регистрация — команда оператора, а не функция у клиента. Открытая
саморегистрация превращает хранилище аккаунтов в спам-цель и в очередь
поддержки.

Проверено 12 сценариев, и главный из них — не юнит-тест, а настоящий
сокет: регистрация, вход, доказательство пароля, токен, его погашение и
появление игроком. Отдельно проверено, что неверный пароль отвергается, а
старое доказательство не принимается против нового вызова. Тик-цикл
замеряется числом тиков за секунду, а не наличием потока.

Всё одним JDK, без Gradle и без сети, как и весь проект.
2026-10-19 01:45:56 +03:00

56 lines
1.9 KiB
PowerShell

# Starts the server. Needs rsx-protocol and rsx-auth built first.
#
# ASCII only, for the same reason as the other scripts.
#
# run-server.ps1 [-Port 25565] [-Accounts path] [-Capacity 200]
param(
[int]$Port = 25565,
[string]$Accounts = '',
[int]$Capacity = 200,
[string]$Name = 'RustNotMC',
[string]$Motd = 'a survival game',
[string]$Register = '',
[string]$Password = ''
)
$ErrorActionPreference = 'Stop'
$Repo = Split-Path -Parent $PSScriptRoot
if (-not $Repo) { $Repo = $PSCommandPath | Split-Path -Parent | Split-Path -Parent }
$Workspace = Split-Path -Parent $Repo
$Protocol = Join-Path $Workspace 'rsx-protocol\build\classes'
$Auth = Join-Path $Workspace 'rsx-auth\build\classes'
$Server = Join-Path $Repo 'build\classes'
foreach ($dep in @($Protocol, $Auth, $Server)) {
if (-not (Test-Path $dep)) {
Write-Host " Missing: $dep" -ForegroundColor Red
Write-Host ' Build rsx-protocol, rsx-auth and rsx-server-core first.' -ForegroundColor Red
exit 1
}
}
if (-not $Accounts) { $Accounts = Join-Path $Repo 'accounts.txt' }
if ($Register) {
& java -cp "$Protocol;$Auth;$Server" net.rustnotmc.server.ServerMain `
--accounts $Accounts --register $Register --password $Password
exit $LASTEXITCODE
}
Write-Host ' rsx-protocol ' -NoNewline
Write-Host (Split-Path -Leaf $Protocol) -ForegroundColor DarkGray
Write-Host ' rsx-auth ' -NoNewline
Write-Host (Split-Path -Leaf $Auth) -ForegroundColor DarkGray
Write-Host ' rsx-server-core ' -NoNewline
Write-Host (Split-Path -Leaf $Server) -ForegroundColor DarkGray
Write-Host ''
Write-Host " accounts : $Accounts"
Write-Host " port : $Port"
Write-Host " capacity : $Capacity"
Write-Host ''
& java -cp "$Protocol;$Auth;$Server" net.rustnotmc.server.ServerMain `
--port $Port --accounts $Accounts --capacity $Capacity --name $Name --motd $Motd
exit $LASTEXITCODE