620f136361
Теперь можно зарегистрировать аккаунт, поднять сервер и зайти в него. Пароль не ходит по сети и не хранится на сервере в обратимом виде. Клиент называет аккаунт, сервер отдаёт его соль и одноразовый вызов для этого соединения, клиент тянет из пароля ключ через PBKDF2-HMAC-SHA256 и подписывает им вызов вместе с именем. Пароль пересекает сокет ноль раз, а запись обрезать нельзя: сервер не знает исходного пароля. Отсюда важное следствие, которое сразу отозвало одну ошибку в протоколе: соль обязана прийти раньше, чем клиент что-то доказывает, поэтому аккаунт называется в Hello, а не в Auth. Иначе клиент получает соль не того аккаунта и не может вывести ключ. Учётная запись хранится как PBKDF2 соль, счётчик раундов и хеш. Раунды лежат рядом с записью, а не в исходниках: число, существующее только в коде, однажды становится причиной того, что аккаунт невозможно проверить. Имена уникальны независимо от регистра: Player и player — это один аккаунт. Иначе игрок получает двух персонажей и не понимает, какой его. Троттлинг двумя ведрами, по аккаунту и по адресу: одно не мешает подбирать одно имя, другое не мешает перебирать много имён с разных адресов. Ответ на несуществующий аккаунт выполняет ту же работу, что и на неверный пароль, и занимает то же время. Токены живут только в памяти. Записанный на диск токен пережил бы процесс, который его выдал, а украденный каталог сервера стал бы набором живых сессий. Сессии различаются номером, а не адресом. Ключ по адресу вытеснял всех, кто зашёл с одного IP, то есть всех игроков за одним NAT. Тик-цикл: 20 раз в секунду, с ограничением догоняющих тиков. Мир, который тикает по кадрам, тикает в зависимости от видеокарты — ровно то, от чего мы уходим, перенося симуляцию на свой сервер. Регистрация — команда оператора, а не функция у клиента. Открытая саморегистрация превращает хранилище аккаунтов в спам-цель и в очередь поддержки. Проверено 12 сценариев, и главный из них — не юнит-тест, а настоящий сокет: регистрация, вход, доказательство пароля, токен, его погашение и появление игроком. Отдельно проверено, что неверный пароль отвергается, а старое доказательство не принимается против нового вызова. Тик-цикл замеряется числом тиков за секунду, а не наличием потока. Всё одним JDK, без Gradle и без сети, как и весь проект.
56 lines
1.9 KiB
PowerShell
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 |