How to RCON an HL1 engine based server
From Scriptwiki
Revision as of 20:18, 11 June 2011 by NaNg (talk | contribs) (moved How to RCON a HL1 engine based server to How to RCON an HL1 engine based server: Corrected title.)
; HL1 RCON control snippet by NaNg ; Date: 11-06-2011 ; Tested on mIRC 7.19 ; ; Remote control window for HL1 engine based games (e.g. HL, CS, TF etc.), ; based on the HL1 Rcon Protocol (no source). ; ; Usage: ; * /hlrcon <ip> <port> <pass> ; Define a prefix for sockent names. alias -l hlrcon.prefix { return HLRcon } ; Validates arguments and challenges the game server. alias hlrcon { ; Validate arguments (simple, no need for full validation). if ((!$longip($1)) || ($2 !isnum 1-65536) || (!$3)) { echo -ag Invalid parameters. return } ; Save the server's address. var %server.addr = $+($1, :, $2) ; Check that the user has not opened a Rcon window for the same server already. ; This makes sure that the user won't have a Rcon step over another Rcon for the same server. if ($window(%server.addr)) { echo -ag Rcon window for $1 is already open! close it before trying. return } ; Open the Rcon window whilst activating it, with an editbox, hide the @ prefix and maximize it. window -aek0x @ $+ %server.addr aline 12 @ $+ %server.addr HL Rcon window. Type a command\cvar to send to the server, responses will be displayed here. aline 12 @ $+ %server.addr Warning! commands like exit or quit will close the server! avoid using them! ; Set the socket name we'll use. var %sockname = $+($hlrcon.prefix, %server.addr) ; Save the Rcon password. set $+(%, $hlrcon.prefix, .rconpw., %sockname) $3 ; Challenge the Rcon. hlrcon.challengercon %sockname $1 $2 } alias -l hlrcon.challengercon { ; Construct the challenge request query. bset &hlrcon.challenge 1 255 255 255 255 bset -t &hlrcon.challenge 5 challenge rcon ; Open the socket and challenge the game server. sockudp -k $$1-3 &hlrcon.challenge } ; Read data from the game server. on *:UDPREAD:$($+($hlrcon.prefix, *)): { ; Get the window name for the current game server. var %hlrcon.window = $+(@, $remove($sockname, $hlrcon.prefix)) ; If there were errors, $sockerr will tell us so. ; Write the error message to the window and clear the connection. if ($sockerr) { aline 04 %hlrcon.window * Error: Reading from socket: $sock($sockname).wsmsg sockclose $sockname return } ; Read the data packet type. sockread 4 &hlrcon.pckt.type ; Since we are not using it (and we are disregarding longer packets), drop the packet type. bunset &hlrcon.pckt.type ; Read the rest of the data. sockread 1400 &hlrcon.pckt.data var %hlrcon.data = $bvar(&hlrcon.pckt.data, 1, $bvar(&hlrcon.pckt.data, 0)).text ; If Rcon challenge is received, set it. if (challenge rcon* iswm %hlrcon.data) { ; Tokenize the received data to rows. tokenize $asc($lf) %hlrcon.data ; Tokenize the first row to get the challenge. tokenize 32 $1 ; Save the challenge. set $+(%, $hlrcon.prefix, .challenge., $sockname) $3 } else { ; Ignore the first byte (for non-log responses, the response contains this extra non-sense byte). var %hlrcon.data = $bvar(&hlrcon.pckt.data, 2, $bvar(&hlrcon.pckt.data, 0)).text } ; Tokenize the received data to rows. tokenize $asc($lf) %hlrcon.data ; Dispose the bvar. bunset &hlrcon.pckt.data ; Print the given data. aline %hlrcon.window $* ; If an error occured, display a friendly message. if (bad challenge* iswm $1) { hlrcon.challengercon $sockname $sock($sockname).addr $sock($sockname).port aline 04 %hlrcon.window Bad challenge, requesting a new one. Please try again. } elseif (bad rcon_password* iswm $1) { aline 04 %hlrcon.window Bad Rcon password. Please try again. } } ; Sends user input to the server as is. ; NOTE: Commands like exit or quit will close the server! on *:INPUT:@: { ; Get the socket name. var %hlrcon.socket = $+($hlrcon.prefix, $remove($target, @)) ; If the input is not for the HL Rcon window, ignore it. if ($($+(%, $hlrcon.prefix, .rconpw., %hlrcon.socket), 2) == $null) { return } ; Check if the socket is still alive. if (!$sock(%hlrcon.socket)) { aline 04 $target * Error: Socket is dead. Close the window and try again. return } ; Build the command packet and send it to the server. bset &hlrcon.cmd 1 255 255 255 255 bset -t &hlrcon.cmd 5 rcon $($+(%, $hlrcon.prefix, .challenge., %hlrcon.socket), 2) $+(", $($+(%, $hlrcon.prefix, .rconpw., %hlrcon.socket), 2), ") $1- aline $target -> $1- ; Send the command request. sockudp -k %hlrcon.socket $sock(%hlrcon.socket).saddr $sock(%hlrcon.socket).sport &hlrcon.cmd } ; If the user has closed the HL Rcon window, clear the socket. on *:CLOSE:@: { ; Construct the sock name. var %hlrcon.socket = $+($hlrcon.prefix, $remove($target, @)) ; If the input is not for the HL Rcon window, ignore it. if ($($+(%, $hlrcon.prefix, .rconpw., %hlrcon.socket), 2) == $null) { return } ; If there's a socket named accordingly, close it. if ($sock(%hlrcon.socket)) { sockclose %hlrcon.socket } ; Clear any variables set for this socket. unset $($+(%, $hlrcon.prefix, .*., %hlrcon.socket)) }