Skip to content

Commit

Permalink
Improve error handling in GoldSourceRcon, SourceRcon, and SourceQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
leojonathanoh committed Oct 1, 2019
1 parent 2400cec commit 58b57b7
Show file tree
Hide file tree
Showing 3 changed files with 215 additions and 203 deletions.
122 changes: 64 additions & 58 deletions Modules/GoldSourceRcon/GoldSourceRcon.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -19,83 +19,89 @@ function GoldSourceRcon {
[string]$Command
)

Write-Verbose "Sending GoldSourceRcon to $Address`:$Port"
if (!$Address) { throw "Invalid address" }
try {
Write-Verbose "Sending GoldSourceRcon to $Address`:$Port"
if (!$Address) { throw "Invalid address" }

$enc = [system.Text.Encoding]::UTF8
$enc = [system.Text.Encoding]::UTF8

# Set up UDP Socket
$remoteEP = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Parse($Address), $Port)
$udpClient = New-Object System.Net.Sockets.UdpClient
$udpClient.Client.SendTimeout = 500
$udpClient.Client.ReceiveTimeout = 500
$udpClient.Connect($remoteEP)
# Set up UDP Socket
$remoteEP = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Parse($Address), $Port)
$udpClient = New-Object System.Net.Sockets.UdpClient
$udpClient.Client.SendTimeout = 500
$udpClient.Client.ReceiveTimeout = 500
$udpClient.Connect($remoteEP)


function BuildPacket ([string]$Command) {
$pack = @(255,255,255,255) + $enc.GetBytes($Command) + 0
$pack
}
function SendPacket ([byte[]]$pack) {
Debug-Packet $MyInvocation.MyCommand.Name $pack
$udpClient.Send($pack, $pack.Length) > $null
}
function ReceivePacket {
$pack = $udpClient.Receive([ref]$remoteEP)
Debug-Packet $MyInvocation.MyCommand.Name $pack
$pack
}
function GetResponse ([byte[]]$pack) {
$response = $enc.GetString( $pack[5..($pack.Length - 1)] )
$response
}
function Init {
# 1 - Client sends: \xFF\xFF\xFF\xFFchallenge rcon\n\0
$pack = BuildPacket "challenge rcon`n"
# 2 - Server replies with challenge id
$response = SendReceive $pack
if ($response -match '(\d+)') {
$challengeID = $matches[1]
Write-Verbose "Got challengeID: $challengeID"
$challengeID
function BuildPacket ([string]$Command) {
$pack = @(255,255,255,255) + $enc.GetBytes($Command) + 0
$pack
}
function SendPacket ([byte[]]$pack) {
Debug-Packet $MyInvocation.MyCommand.Name $pack
$udpClient.Send($pack, $pack.Length) > $null
}
function ReceivePacket {
$pack = $udpClient.Receive([ref]$remoteEP)
Debug-Packet $MyInvocation.MyCommand.Name $pack
$pack
}
function GetResponse ([byte[]]$pack) {
$response = $enc.GetString( $pack[5..($pack.Length - 1)] )
$response
}
function Init {
# 1 - Client sends: \xFF\xFF\xFF\xFFchallenge rcon\n\0
$pack = BuildPacket "challenge rcon`n"
# 2 - Server replies with challenge id
$response = SendReceive $pack
if ($response -match '(\d+)') {
$challengeID = $matches[1]
Write-Verbose "Got challengeID: $challengeID"
$challengeID
}
}
function SendReceive ([byte[]]$pack) {
SendPacket $pack
$rPack = ReceivePacket
$response = GetResponse $rPack
$response
}
}
function SendReceive ([byte[]]$pack) {
SendPacket $pack
$rPack = ReceivePacket
$response = GetResponse $rPack
$response
}

function Debug-Packet ($label, $pack) {
if ($pack) {
Write-Verbose "[$label]"
#Write-Verbose "pack: $pack"
Write-Verbose "pack: $( $pack | % { $_.ToString('X2').PadLeft(2) } )"
Write-Verbose "pack: "
Write-Verbose "$( $pack | % { if ($_ -eq 0x00) { "\".PadLeft(2) } else { [System.Text.Encoding]::Utf8.GetString($_).Trim().PadLeft(2) } } )"
Write-Verbose "length: $($pack.Length)"
Write-Verbose ""
function Debug-Packet ($label, $pack) {
if ($pack) {
Write-Verbose "[$label]"
#Write-Verbose "pack: $pack"
Write-Verbose "pack: $( $pack | % { $_.ToString('X2').PadLeft(2) } )"
Write-Verbose "pack: "
Write-Verbose "$( $pack | % { if ($_ -eq 0x00) { "\".PadLeft(2) } else { [System.Text.Encoding]::Utf8.GetString($_).Trim().PadLeft(2) } } )"
Write-Verbose "length: $($pack.Length)"
Write-Verbose ""
}
}
}

# Rcon
try {
# Rcon
$challengeID = Init
if (!$challengeID) {
throw "Bad rcon password."
throw "No challengeID."
}else {
# 3 - Client sends: \xFF\xFF\xFF\xFFrcon CHALLENGEID RCONPASSWORD COMMAND
$pack = BuildPacket "rcon $challengeID $Password $Command"
# 4 - Server replies with plain text
$response = SendReceive $pack
$udpClient.Dispose()
if ($response -match 'Bad rcon_password') {
throw $response
}
$response
}
}catch {
Write-Error "GoldSourceRcon Failed"
throw
if ($ErrorActionPreference -eq 'Stop') {
throw
}else {
Write-Error -ErrorRecord $_
}
}
}

Export-ModuleMember -Function GoldSourceRcon
Export-ModuleMember -Function GoldSourceRcon
9 changes: 6 additions & 3 deletions Modules/SourceQuery/SourceQuery.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,12 @@ function SourceQuery {
$udpClient.Dispose()
$answer
}catch {
Write-Error "SourceQuery Failed"
throw
if ($ErrorActionPreference -eq 'Stop') {
throw
}else {
Write-Error -ErrorRecord $_
}
}
}

Export-ModuleMember -Function SourceQuery
Export-ModuleMember -Function SourceQuery
Loading

0 comments on commit 58b57b7

Please sign in to comment.