mirror of
https://github.com/SK8-ENGINE/skate-3-rust-engine.git
synced 2026-10-26 19:47:44 +00:00
45 lines
3.4 KiB
PowerShell
45 lines
3.4 KiB
PowerShell
param([string]$AssetRoot = $env:SKATE3_ASSETS, [switch]$MenuOnly, [string]$MapPath = '', [switch]$TwoControllers, [ValidateRange(2,10)][int]$Players = 2, [string]$BuildDirectory = 'bin/multiplayer')
|
|
$ErrorActionPreference = 'Stop'
|
|
$instanceCount = if ($MenuOnly) { 1 } else { $Players }
|
|
$workspace = Split-Path -Parent $PSScriptRoot
|
|
$binary = Join-Path (Join-Path $workspace $BuildDirectory) 'skate3-multiplayer.exe'
|
|
if (-not $AssetRoot) { $AssetRoot = Join-Path $workspace 'assets' }
|
|
$assets = (Resolve-Path -LiteralPath $AssetRoot).Path
|
|
$installation = Split-Path -Parent $assets
|
|
if (-not (Test-Path -LiteralPath $binary)) { throw 'Build missing. Run scripts/build-multiplayer-test.ps1 first.' }
|
|
if (-not (Test-Path -LiteralPath (Join-Path $assets 'private/game.json'))) { throw 'Prepared game assets are missing. No installer or conversion will be started.' }
|
|
if (-not $MapPath) { $MapPath = Join-Path $installation 'maps/University.skate' }
|
|
$MapPath = (Resolve-Path -LiteralPath $MapPath).Path
|
|
if ([IO.Path]::GetExtension($MapPath) -ne '.skate') { throw 'Expected an existing .skate map.' }
|
|
$logs = Join-Path $workspace ('logs/multiplayer/' + (Get-Date -Format 'yyyyMMdd-HHmmss') + '-' + [Guid]::NewGuid().ToString('N').Substring(0,8))
|
|
New-Item -ItemType Directory -Path $logs -Force | Out-Null
|
|
# Reserve distinct ports, then release immediately before the games start.
|
|
$reservations = @(1..$instanceCount | ForEach-Object { [Net.Sockets.UdpClient]::new([Net.IPEndPoint]::new([Net.IPAddress]::Loopback,0)) })
|
|
$ports = @($reservations | ForEach-Object { $_.Client.LocalEndPoint.Port })
|
|
$session = Get-Random -Minimum 1 -Maximum ([long]::MaxValue)
|
|
$reservations | ForEach-Object { $_.Dispose() }
|
|
$common = '--assets "' + $assets + '" --map "' + $MapPath + '" --net-session ' + $session
|
|
for ($index = 0; $index -lt $instanceCount; $index++) {
|
|
$label = [string][char](65 + $index)
|
|
$playerArgs = $common
|
|
if ($MenuOnly) {
|
|
# Start offline; Steam initializes only through the multiplayer menu.
|
|
$playerArgs += ' --start-paused'
|
|
} elseif ($index -eq 0) {
|
|
$playerArgs += ' --net-host 127.0.0.1:' + $ports[0]
|
|
} else {
|
|
$playerArgs += ' --net-local 127.0.0.1:' + $ports[$index] + ' 127.0.0.1:' + $ports[0]
|
|
# Guests advertise an unavailable outfit to exercise default fallback.
|
|
$playerArgs += ' --spawn-offset ' + ($index * 2).ToString([Globalization.CultureInfo]::InvariantCulture) + ' --appearance test-uninstalled-outfit'
|
|
}
|
|
$playerArgs += ' --player-title "Multiplayer ' + $label + ' - ' + $Players + ' player test"'
|
|
if ($TwoControllers -and $index -lt 2) { $playerArgs += ' --controller ' + $index }
|
|
$process = Start-Process -FilePath $binary -ArgumentList $playerArgs -WorkingDirectory $workspace -WindowStyle Normal -RedirectStandardOutput (Join-Path $logs ('player-' + $label.ToLower() + '.out.log')) -RedirectStandardError (Join-Path $logs ('player-' + $label.ToLower() + '.err.log')) -PassThru
|
|
Write-Host "Started player $label ($($process.Id))"
|
|
}
|
|
if ($MenuOnly) { Write-Host "Press Esc, then Multiplayer to host or browse Steam lobbies." }
|
|
else { Write-Host "$Players players connect automatically on University; A hosts the lobby." }
|
|
Write-Host 'Steam is not required. Click a game window to control that player with your controller.'
|
|
Write-Host 'For two pads, use -TwoControllers (XInput slots 0 and 1). Use -Players 10 for the full lobby.'
|
|
Write-Host "Logs: $logs"
|