Arma 3: Add headless client functionality (#356)

This commit is contained in:
Greelan 2023-05-08 14:31:54 +10:00 committed by GitHub
parent bfbaeaf70d
commit 02dca1597b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 116 additions and 7 deletions

View File

@ -59,7 +59,7 @@ App.RCONHeartbeatMinutes=0.5
App.RCONHeartbeatCommand=ping
App.TelnetLoginFormat={0}
App.UpdateSources=@IncludeJson[arma3updates.json]
App.PreStartStages=[{"UpdateStageName":"Delete Active File","UpdateSourcePlatform":"Linux","UpdateSource":"Executable","UpdateSourceData":"/bin/bash","UpdateSourceArgs":"-c 'rm -f {{$FullBaseDir}}battleye/beserver_x64_active_*.cfg'"},{"UpdateStageName":"Delete Active File","UpdateSourcePlatform":"Windows","UpdateSource":"Executable","UpdateSourceData":"cmd.exe","UpdateSourceArgs":"/C del /Q /F {{$FullBaseDir}}battleye\\beserver_x64_active_*.cfg"}]
App.PreStartStages=[{"UpdateStageName":"Delete Active File","UpdateSourcePlatform":"Linux","UpdateSource":"Executable","UpdateSourceData":"/bin/bash","UpdateSourceArgs":"-c 'rm -f {{$FullBaseDir}}battleye/beserver_x64_active_*.cfg'"},{"UpdateStageName":"Delete Active File","UpdateSourcePlatform":"Windows","UpdateSource":"Executable","UpdateSourceData":"cmd.exe","UpdateSourceArgs":"/C del /Q /F {{$FullBaseDir}}battleye\\beserver_x64_active_*.cfg"},{"UpdateStageName":"Headless Client Script Download","UpdateSourcePlatform":"Linux","UpdateSource":"FetchURL","UpdateSourceData":"https://github.com/CubeCoders/AMPTemplates/raw/main/arma3runhc.sh","UpdateSourceArgs":"runhc.sh","UpdateSourceTarget":"{{$FullInstanceDir}}","OverwriteExistingFiles":true},{"UpdateStageName":"Headless Client Script Download","UpdateSourcePlatform":"Windows","UpdateSource":"FetchURL","UpdateSourceData":"https://github.com/CubeCoders/AMPTemplates/raw/main/arma3runhc.ps1","UpdateSourceArgs":"runhc.ps1","UpdateSourceTarget":"{{$FullInstanceDir}}","OverwriteExistingFiles":true},{"UpdateStageName":"Start Headless Clients","UpdateSourcePlatform":"Linux","UpdateSource":"Executable","UpdateSourceData":"/bin/bash","UpdateSourceArgs":"-c 'chmod +x ./runhc.sh; ./runhc.sh {{HeadlessClientsNum}} {{$ApplicationIPBinding}} {{$GamePort}} \"{{password}}\" \"{{mod}}\" &'"},{"UpdateStageName":"Start Headless Clients","UpdateSourcePlatform":"Windows","UpdateSource":"Executable","UpdateSourceData":"cmd.exe","UpdateSourceArgs":"/C start powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File \"runhc.ps1\" {{HeadlessClientsNum}} {{$ApplicationIPBinding}} {{$GamePort}} \"{{password}}\" \"{{mod}}\""}]
App.Compatibility=None
App.SteamUpdateAnonymousLogin=False
App.SteamForceLoginPrompt=True
@ -75,8 +75,8 @@ Console.FilterMatchRegex=
Console.FilterMatchReplacement=
Console.ThrowawayMessageRegex=^((WARNING|ERROR): Shader.+|Unknown command)$
Console.AppReadyRegex=^RCon admin #\d+ \([\d\.:]+\) logged in$
Console.UserJoinRegex=^[\d:]+ BattlEye Server: Player #(?<sessionid>.+?) (?<username>.+( \(\d+\))?) \((?<endpoint>.+?):(?:\d+)\) connected$
Console.UserLeaveRegex=^[\d:]+ BattlEye Server: Player #(?<sessionid>.+?) (?<username>.+( \(\d+\))?) disconnected$
Console.UserJoinRegex=^([\d:]+ BattlEye Server: )?Player #(?<sessionid>.+?) (?<username>.+( \(\d+\))?) \((?<endpoint>.+?):(?:\d+)\) connected$
Console.UserLeaveRegex=^([\d:]+ BattlEye Server: )?Player #(?<sessionid>.+?) (?<username>.+( \(\d+\))?) disconnected$
Console.UserChatRegex=^$
Console.UpdateAvailableRegex=
Console.MetricsRegex=
@ -88,4 +88,4 @@ Limits.SleepOnStart=False
Limits.SleepDelayMinutes=5
Limits.DozeDelay=2
Limits.AutoRetryCount=5
Limits.SleepStartThresholdSeconds=25
Limits.SleepStartThresholdSeconds=25

View File

@ -254,10 +254,26 @@
"True":"true"
}
},
{
"DisplayName":"Headless Clients To Launch",
"Category":"Arma Server Settings",
"Description":"Sets the number of headless clients to launch when the server starts. Further information on configuration is [here](https://discourse.cubecoders.com/t/arma-3-generic-guide/3475#h-6-headless-clients-9)",
"Keywords":"headless,client",
"FieldName":"HeadlessClientsNum",
"InputType":"number",
"MinValue":"0",
"MaxValue":"5",
"IsFlagArgument":false,
"ParamFieldName":"HeadlessClientsNum",
"IncludeInCommandLine":false,
"DefaultValue":"0",
"Placeholder":"0",
"EnumValues":{}
},
{
"DisplayName":"Headless Client IPs",
"Category":"Arma Server Settings",
"Description":"Sets the IPs of [headless clients](https://community.bistudio.com/wiki/Arma_3:_Headless_Client) able to connect to the server. Multiples connections and IPs are allowed. Format is \"IP1\",\"IP2\"",
"Description":"Sets the IPs of headless clients able to connect to the server. Multiples connections and IPs are allowed. Format is \"IP1\",\"IP2\"",
"Keywords":"headless,client,ip,headlessclients",
"FieldName":"headlessClients",
"InputType":"text",
@ -265,7 +281,7 @@
"ParamFieldName":"headlessClients",
"IncludeInCommandLine":false,
"DefaultValue":"",
"Placeholder":"\"123.456.789.12\",\"210.987.654.321\"",
"Placeholder":"\"127.0.0.1\",\"210.187.254.121\"",
"EnumValues":{}
},
{

43
arma3runhc.ps1 Normal file
View File

@ -0,0 +1,43 @@
# Arguments: [number_clients] [server_binding] [server_port] "<server_password>" "<mod_list>"
# Check if any headless clients are to be run
# If none, immediately exit
if ($args[0] -eq "0") { exit }
# Check if server starts successfully within 3 minutes
# If not, exit
$serverStarted = $false
for ($i = 1; $i -le 180; $i++) {
if (Get-NetUDPEndpoint -LocalPort $args[2] -ErrorAction SilentlyContinue) {
$serverStarted = $true
break
}
Start-Sleep -Seconds 1
}
if (-not $serverStarted) { exit 1 }
# Start the headless clients
$clients = @()
$basePort = [int]$args[2] + 498
cd "$PSScriptRoot\arma3\233780"
for ($i = 1; $i -le [int]$args[0]; $i++) {
if ($args[1] -eq "0.0.0.0") {
$connect = "127.0.0.1"
} else {
$connect = $args[1]
}
$hcProcess = Start-Process -FilePath "ArmA3Server_x64.exe" -ArgumentList "-client", "-nosound", "-connect=${connect}:$($args[2])", "-port=$basePort", "-password=`"$($args[3])`"", "`"-mod=$($args[4])`"" -WindowStyle Hidden -PassThru
$clients += $hcProcess.Id
}
# Monitor server process and terminate headless clients
# when server terminates
while ($true) {
if (-not (Get-NetUDPEndpoint -LocalPort $args[2] -ErrorAction SilentlyContinue)) {
foreach ($processId in $clients) {
Stop-Process -Id $processId -Force
}
exit 0
}
Start-Sleep -Seconds 1
}

50
arma3runhc.sh Normal file
View File

@ -0,0 +1,50 @@
#!/bin/bash
# Arguments: [number_clients] [server_binding] [server_port] "<server_password>" "<mod_list>"
netcommand="$(command -v "ss" >/dev/null 2>&1 && echo "ss" || echo "netstat")"
# Check if any headless clients are to be run
# If none, immediately exit
[[ $1 -eq 0 ]] && exit 0
# Check if server starts successfully within 3 minutes
# If not, exit
server_started=false
for i in $(seq 1 180); do
if $netcommand -uln | grep -q ":$3 "; then
server_started=true
break
fi
sleep 1
done
if ! $server_started; then
exit 1
fi
# Start the headless clients
baseport=$(($3 + 498))
export LD_LIBRARY_PATH=$(dirname "$0")/linux64:$LD_LIBRARY_PATH
cd ./arma3/233780
for i in $(seq 1 "$1"); do
if [[ "$2" == "0.0.0.0" ]]; then
connect="127.0.0.1"
else
connect="$2"
fi
./arma3server_x64 -client -nosound -connect=$connect:$3 -port=$baseport -password="$4" "-mod=$5" >/dev/null 2>&1 &
clients+=($!)
done
# Monitor server process and terminate headless clients
# when server terminates
trap 'kill "${clients[@]}" >/dev/null 2>&1' SIGTERM
while true; do
if ! $netcommand -uln | grep -q ":$3 "; then
for client in "${clients[@]}"; do
kill "$client" >/dev/null 2>&1
done
exit 0
fi
sleep 1
done

View File

@ -55,4 +55,4 @@
"UpdateSourceData":"cmd.exe",
"UpdateSourceArgs":"/C cd .\\arma3\\233780 && for /D %G in (.\\steamapps\\workshop\\content\\107410\\*) do mklink /J %~nxG %G"
}
]
]