Skip to content

Instantly share code, notes, and snippets.

@VIRUXE
Last active May 16, 2024 23:08
Show Gist options
  • Save VIRUXE/002e493f15fd3f42615267734765c8c1 to your computer and use it in GitHub Desktop.
Save VIRUXE/002e493f15fd3f42615267734765c8c1 to your computer and use it in GitHub Desktop.
Displays a list of Scavenge and Survive servers, curated from scavengesurvive.com/servers and api.open.mp/servers
function Ping-SampServer {
param(
[string]$Address,
[int]$Port
)
$udpClient = $null
try {
$udpClient = New-Object System.Net.Sockets.UdpClient
$udpClient.Connect($Address, $Port)
# Build the packet byte by byte to get the protocol right
$packet = [byte[]]::new(11)
[System.Text.Encoding]::ASCII.GetBytes("SAMP").CopyTo($packet, 0)
$ipBytes = $Address.Split('.') | ForEach-Object { [byte]$_ }
for ($i = 0; $i -lt $ipBytes.Length; $i++) { $packet[$i + 4] = $ipBytes[$i] }
# * Finding how to do this shit in powershell took too long
$packet[8] = $Port -band 0xFF # Low byte of port
$packet[9] = ($Port -shr 8) -band 0xFF # High byte of port
$packet[10] = 105 # ASCII code for 'i'. Which requests server info data, that we don't actually need, but something needs to be requested, because we only want to measure ping
$startTime = [DateTime]::UtcNow
$udpClient.Send($packet, $packet.Length) | Out-Null
$endPoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Any, 0)
$udpClient.Receive([ref]$endPoint) | Out-Null
$endTime = [DateTime]::UtcNow
return [int]($endTime - $startTime).TotalMilliseconds
} catch {
return
} finally {
if ($udpClient) { $udpClient.Close() }
}
return
}
try {
$GetScavengeSurviveServers = Invoke-WebRequest "https://gist.githubusercontent.com/VIRUXE/737752c90d2f066d96806e2ff50a81d4/raw/d45919d1009fa43f48785072931e6dd4ae5041fd/GetScavengeSurviveServers.psm1"
Invoke-Expression $GetScavengeSurviveServers.Content
$servers = @()
[array] $openMp = Get-OpenMpServers
if($openMp) {
$servers += $openMp
Write-Host "Retrieved $($openMp.Count) open.mp server(s)."
}
[array] $scavengeSurviveCom = Get-ScavengeSurviveComServers
if ($scavengeSurviveCom) {
Write-Host "Retrieved $($scavengeSurviveCom.Count) scavengesurvive.com server(s)."
foreach ($server in $scavengeSurviveCom) {
$isDuplicate = $false
foreach ($existingServer in $servers) {
if ($existingServer.Address -eq $server.Address -and $existingServer.Port -eq $server.Port) {
$isDuplicate = $true
break
}
}
if (-not $isDuplicate) { $servers += $server }
}
}
Write-Host
if ($servers) {
Write-Host "Compiled $($servers.Count) server(s) from the $($openMp.Count + $scavengeSurviveCom.Count) retrieved." -ForegroundColor Yellow
# Ping each server to see which are available
$servers | ForEach-Object {
$ping = Ping-SampServer -Address $_.Address -Port $_.Port
# Create a custom object with Ping as the first property
[PSCustomObject]@{
Ping = if ($ping) { "${ping}ms" } else { "Offline" }
"Name" = $_.Name
"Address" = $_.Address + ":" + $_.Port
}
} | Format-Table -AutoSize
} else { Write-Host "No servers available." -ForegroundColor Red}
} catch { Write-Error "An error occurred: $($_.Exception.Message)" }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment