Compare commits

..

No commits in common. "main" and "v0.1.0" have entirely different histories.
main ... v0.1.0

7 changed files with 55 additions and 144 deletions

View File

@ -35,19 +35,3 @@ finally {
Disconnect-Rcon -rcon $rcon
}
```
## Rcon Class
#### `Send($cmd) | Send($cmd, $timeout)`
```powershell
$rcon.Send("mapname")
$rcon.Send("g_gametype dm")
$rcon.Send("map_rotate", 2000)
```
If the command returns a response it will be printed to the console.
Pass an optional timeout (ms) for commands that return responses in fragments. (status, map_rotate etc...)

View File

@ -14,15 +14,12 @@ Function Read-HostUntilEmpty {
if ($line -in @("fast_restart", "map_rotate", "map_restart")) {
$cmd = $line -replace '(?:^|_)(\p{L})', { $_.Groups[1].Value.ToUpper() }
$rcon.$cmd()
}
elseif ($line.StartsWith("map mp_")) {
$mapname = $line.Split()[1]
$rcon.SetMap($mapname)
$resp = $rcon.$cmd()
}
else {
$rcon.Send($line)
$resp = $rcon.Send($line)
}
$resp | Write-Host
}
}

View File

@ -17,7 +17,7 @@ try {
"Rotating the map..."
$rcon.MapRotate()
Start-Sleep -Seconds 3 # wait for map to rotate
Start-Sleep -Milliseconds 3000 # wait for map to rotate
$rcon.Map()
}

View File

@ -10,9 +10,8 @@ $OKB = New-Object System.Windows.Forms.Button
$OTB = New-Object System.Windows.Forms.TextBox
$CAB = New-Object System.Windows.Forms.Button
$Lbl = New-Object System.Windows.Forms.Label
$RLbl = New-Object System.Windows.Forms.Label
Function New-Form {
Function InitForm {
$form = New-Object System.Windows.Forms.Form
$form.Text = "Q3Rcon Client"
$form.Size = New-Object System.Drawing.Size(275, 200)
@ -20,17 +19,17 @@ Function New-Form {
return $form
}
Function Add-OkButton {
Function AddOkButton {
param($form, $rcon)
$OKB.Location = New-Object System.Drawing.Size(65, 100)
$OKB.Size = New-Object System.Drawing.Size(65, 23)
$OKB.Text = "Send"
$OKB.Add_Click({ Send-RconCommand -rcon $rcon })
$OKB.Add_Click({ SendRconCommand -rcon $rcon })
$form.Controls.Add($OKB)
}
Function Add-CloseButton($form) {
Function AddCloseButton($form) {
$CAB.Location = New-Object System.Drawing.Size(140, 100)
$CAB.Size = New-Object System.Drawing.Size(65, 23)
$CAB.Text = "Close"
@ -38,61 +37,35 @@ Function Add-CloseButton($form) {
$form.Controls.Add($CAB)
}
Function Add-Label($form) {
Function AddLabel($form) {
$Lbl.Location = New-Object System.Drawing.Size(10, 20)
$Lbl.Size = New-Object System.Drawing.Size(260, 20)
$Lbl.Text = "Input Rcon Command:"
$form.Controls.Add($Lbl)
}
Function Add-TextBox {
Function AddTextBox {
param($form, $rcon)
$OTB.Location = New-Object System.Drawing.Size(10, 50)
$OTB.Size = New-Object System.Drawing.Size(240, 20)
$OTB.Add_KeyDown({
if ($_.KeyCode -eq [System.Windows.Forms.Keys]::Enter) {
Send-RconCommand -rcon $rcon
SendRconCommand -rcon $rcon
}
})
$form.Controls.Add($OTB)
}
Function Add-ResponseLabel($form) {
$RLbl.Location = New-Object System.Drawing.Size(10, 75)
$RLbl.Size = New-Object System.Drawing.Size(260, 20)
$RLbl.Text = ""
$form.Controls.Add($RLbl)
}
Function Start-Form($form) {
Function FinalizeForm($form) {
$form.Topmost = $true
$form.Add_Shown({ $form.Activate() })
[void] $form.ShowDialog()
$form.Add_Shown({ $form.Activate() })
}
Function Send-RconCommand() {
Function SendRconCommand() {
param($rcon)
$line = $OTB.Text
$line | Write-Debug
if ($line -in @("fast_restart", "map_rotate", "map_restart")) {
$RLbl.Text = ""
$cmd = $line -replace '(?:^|_)(\p{L})', { $_.Groups[1].Value.ToUpper() }
$rcon.$cmd()
}
elseif ($line.StartsWith("map mp_")) {
$RLbl.Text = ""
$mapname = $line.Split()[1]
$rcon.SetMap($mapname)
}
else {
$resp = $rcon.Send($line)
}
if ($resp -match '^["](?<name>[a-z_]+)["]\sis[:]\s["](?<value>.*?)\^7["]\s') {
$RLbl.Text = $Matches.name + ": " + $Matches.value
}
$rcon.Send($OTB.Text)
$OTB.Text = ""
}
@ -103,22 +76,21 @@ Function Get-ConnFromPSD1 {
}
Function Main {
BEGIN {
try {
$conn = Get-ConnFromPSD1
$rcon = Connect-Rcon -hostname $conn.host -port $conn.port -passwd $conn.passwd
Write-Host $rcon.base.ToString() -ForegroundColor Green
$form = New-Form
Add-OkButton -form $form -rcon $rcon
Add-CloseButton($form)
Add-Label($form)
Add-ResponseLabel($form)
Add-TextBox -form $form -rcon $rcon
$form = InitForm
AddOkButton -form $form -rcon $rcon
AddCloseButton($form)
AddLabel($form)
AddTextBox -form $form -rcon $rcon
FinalizeForm($form)
[void] $form.ShowDialog()
}
PROCESS {
Start-Form($form)
}
END {
finally {
Disconnect-Rcon -rcon $rcon
}
}

View File

@ -1,38 +0,0 @@
[cmdletbinding()]
param()
Import-Module ../lib/Q3Rcon.psm1
Function Get-ConnFromPSD1 {
$configpath = Join-Path $PSScriptRoot "config.psd1"
return Import-PowerShellDataFile -Path $configpath
}
Function Get-DadJoke {
Invoke-WebRequest -Uri "https://icanhazdadjoke.com" -Headers @{accept = "application/json" } | Select-Object -ExpandProperty Content | ConvertFrom-Json | Select-Object -ExpandProperty Joke
}
Function Send-Message {
param($rcon)
$msg = Get-DadJoke
$msg | Write-Debug
$rcon.Say($msg)
}
try {
$conn = Get-ConnFromPSD1
$rcon = Connect-Rcon -hostname $conn.host -port $conn.port -passwd $conn.passwd
$stopWatch = [system.diagnostics.stopwatch]::StartNew()
$timeSpan = New-TimeSpan -Seconds 30
do {
Send-Message -rcon $rcon
Start-Sleep -Seconds 10
} until ($stopWatch.Elapsed -ge $timeSpan)
$stopWatch.Stop()
}
finally {
Disconnect-Rcon -rcon $rcon
}

View File

@ -1,10 +1,5 @@
try {
. (Join-Path $PSScriptRoot packet.ps1)
. (Join-Path $PSScriptRoot base.ps1)
}
catch {
throw "unable to dot source module files"
}
. $PSScriptRoot\packet.ps1
. $PSScriptRoot\base.ps1
class Rcon {
@ -14,8 +9,8 @@ class Rcon {
$this.base = New-Base -hostname $hostname -port $port -passwd $passwd
}
[Rcon] _login() {
$resp = $this.Send("login")
[Rcon] Login() {
$resp = $this.base._send("login")
if ($resp -in @("Bad rcon", "Bad rconpassword.", "Invalid password.")) {
throw "invalid rcon password"
}
@ -23,59 +18,55 @@ class Rcon {
return $this
}
[string] Send([string]$msg) {
[string] Send($msg) {
return $this.base._send($msg)
}
[string] Send([string]$msg, [int]$timeout) {
return $this.base._send($msg, $timeout)
}
[void] Say($msg) {
$this.Send("say $msg")
$this.base._send($msg)
}
[void] FastRestart() {
$this.Send("fast_restart", 2000)
$this.base._send("fast_restart", 2000)
}
[void] MapRotate() {
$this.Send("map_rotate", 2000)
$this.base._send("map_rotate", 2000)
}
[void] MapRestart() {
$this.Send("map_restart", 2000)
$this.base._send("map_restart", 2000)
}
[string] Map() {
return $this.Send("mapname")
return $this.base._send("mapname")
}
[void] SetMap($mapname) {
$this.Send("map mp_" + $mapname.TrimStart("mp_"), 2000)
$this.base._send("map mp_$mapname")
}
[string] Gametype() {
return $this.Send("g_gametype")
return $this.base._send("g_gametype")
}
[void] SetGametype($gametype) {
$this.Send("g_gametype $gametype")
$this.base._send("g_gametype $gametype")
}
[string] HostName() {
return $this.Send("sv_hostname")
return $this.base._send("sv_hostname")
}
[void] SetHostName($hostname) {
$this.Send("sv_hostname $hostname")
$this.base._send("sv_hostname $hostname")
}
}
Function Connect-Rcon {
param([string]$hostname, [int]$port, [string]$passwd)
[Rcon]::new($hostname, $port, $passwd)._login()
[Rcon]::new($hostname, $port, $passwd).Login()
}
Function Disconnect-Rcon {

View File

@ -38,16 +38,22 @@ class Base {
[string] _send([string]$msg) {
$this._socket.Send($this.request.Payload($msg))
$buf = New-Object System.Byte[] 4096
try {
$this._socket.Receive($buf)
}
catch [System.Net.Sockets.SocketException] {
if ( $_.Exception.SocketErrorCode -eq 'TimedOut' ) {
"finished waiting for fragment" | Write-Debug
[string[]]$data = @()
$sw = [Diagnostics.Stopwatch]::StartNew()
While ($sw.ElapsedMilliseconds -lt 50) {
try {
$buf = New-Object System.Byte[] 4096
$this._socket.Receive($buf)
$data += [System.Text.Encoding]::ASCII.GetString($($buf | Select-Object -Skip $($this.response.Header().Length - 1)))
}
catch [System.Net.Sockets.SocketException] {
if ( $_.Exception.SocketErrorCode -eq 'TimedOut' ) {
"finished waiting for fragment" | Write-Debug
}
}
}
return [System.Text.Encoding]::ASCII.GetString($($buf | Select-Object -Skip $($this.response.Header().Length - 1)))
$sw.Stop()
return [string]::Join("", $data)
}
[string] _send([string]$msg, [int]$timeout) {
@ -67,7 +73,6 @@ class Base {
}
}
}
$sw.Stop()
return [string]::Join("", $data)
}