PHP Code:
; HL server query snippet by Saturn
;
; 16-04-2009: update to protocol version 48 by NaNg
; 29-01-2011: update to fix UTF8 problem in mIRC 7.* and fixed name problems if last char is space by NaNg
;
; usage:
; /hlinfo <ip> <port>
; or: /hlinfo <ip>:<port>
; /hlplay <ip> <port>
; or: /hlplay <ip>:<port>
; the alias that opens a new socket if you want to get general information about a running CS-server
alias hlinfo {
if (!$2) tokenize 58 $1
; using a dynamic socket name so we can use multiple instances at once
var %sock = $+(hlinfo-,$ticks)
; construct the query to send to the server
bset &t 1 255 255 255 255
bset -t &t 5 TSource Engine Query
bset &t 25 0
; actually open the socket, and send the query
sockudp -k %sock $1-2 &t
; closing the socket after 60seconds if there is no response (else it will be closed by another event (see below))
.timer $+ %sock 1 60 sockclose %sock
}
; this event will get all data sent back from the server
on *:UDPREAD:hlinfo-*:{
; save it in a binary variable
sockread -f &reply
; set some local variables that we will use below
var %offset, %name, %map, %game, %num, %max, %ip, %dir
; following the protocol, this "m" shows us that we queried a Half-Life 1 server
if ($chr($bvar(&reply,5)) == m) {
; Half-Life 1 info reply
%offset = 6
; save the ip
%ip = $bvar(&reply,%offset,128).text
inc %offset $calc($len($bvar(&reply,%offset,128).text) + 1)
; the same
%name = $bvar(&reply,%offset,128).text
inc %offset $calc($len($bvar(&reply,%offset,128).text) + 1)
; the current map
%map = $bvar(&reply,%offset,128).text
inc %offset $calc($len($bvar(&reply,%offset,128).text) + 1)
; the game directory
%dir = $bvar(&reply,%offset,128).text
inc %offset $calc($len($bvar(&reply,%offset,128).text) + 1)
; the name of the game
%game = $bvar(&reply,%offset,128).text
inc %offset $calc($len($bvar(&reply,%offset,128).text) + 1)
; current and maximum players
%num = $bvar(&reply,%offset)
%max = $bvar(&reply,$calc(%offset + 1))
}
; else we get data for a CS:Source game
else {
; Source info reply
; we do the same as above
%offset = 7
%name = $bvar(&reply,%offset,128).text
inc %offset $calc($len($bvar(&reply,%offset,128).text) + 1)
%map = $bvar(&reply,%offset,128).text
inc %offset $calc($len($bvar(&reply,%offset,128).text) + 1)
%dir = $bvar(&reply,%offset,128).text
inc %offset $calc($len($bvar(&reply,%offset,128).text) + 1)
%game = $bvar(&reply,%offset,128).text
inc %offset $calc($len($bvar(&reply,%offset,128).text) + 1)
%num = $bvar(&reply,$calc(%offset + 2))
%max = $bvar(&reply,$calc(%offset + 3))
}
; now we echo all stored details to the active window
echo -a Info for $sock($sockname).saddr $+ : $+ $sock($sockname).sport
echo -a Name: %name
echo -a Map: %map
echo -a Game: %game
echo -a Players: %num $+ / $+ %max
; and turn off the timer closing the socket
.timer $+ $sockname off
; as we can close it now manually
sockclose $sockname
}
; this is the alias that will be called from hlplay to open the socket
alias hlchal {
; $1 = ip, $2 = port, $3- = what to call when received
; use dynamic socket name as above
var %sock = $+(hlchal-,$ticks)
; construct the query to send to the server
bset &t 1 255 255 255 255 85 255 255 255 255
; open the socket, and ask for a player challenge number
sockudp -k %sock $1-2 &t
; mark it with the ip and port (and the query we want to call when we've received something from the server)
sockmark %sock $3- $1-2
; and make a new timer to close it after 60 seconds
.timer $+ %sock 1 60 sockclose %sock
}
; read everything that comes back from the hlchal-* query
on *:UDPREAD:hlchal-*:{
; and save it in the binary variable called &reply
sockread -f &reply
; actually call the alias saved in the sockmark (hlplay_query)
$sock($sockname).mark $bvar(&reply,6,4)
; and turn the timer off because we can close it manually
.timer $+ $sockname off
sockclose $sockname
}
; the alias we can call to make everything easier
; it will call other aliases to open sockets etc.
alias hlplay {
if (!$2) tokenize 58 $1
hlchal $1-2 hlplay_query
}
; the alias that opens the _real_ socket to receive data (everything before was just to challenge the server (read the website mentioned above))
alias hlplay_query {
; set a binary variable
bset &query 1 255 255 255 255 85 $3-
; use dynamic socket names again
var %sock = $+(hlplay-,$ticks)
; open the socket
sockudp -k %sock $1-2 &query
; and turn on the timer closing the socket after 60seconds
.timer $+ %sock 1 60 sockclose %sock
}
; this event will receive all data from the server as response to our query
on *:UDPREAD:hlplay-*:{
; we save it in &reply
sockread -f &reply
; set some local variables we will use later
var %i = 1, %num = $bvar(&reply,6), %offset = 7
var %count = 0, %name, %kills
; and echo the number of players
echo -a Players on $sock($sockname).saddr $+ : $+ $sock($sockname).sport
; now we can loop through all player and save some details about them
while (%i <= %num) {
inc %offset
; the name
%name = $bvar(&reply,%offset,128).text
inc %offset $calc($len($bvar(&reply,%offset,128).text) + 1)
; the kills
%kills = $bvar(&reply,%offset).long
if ($isbit(%kills,32)) dec %kills $calc(2^32)
inc %offset 8
; and if there was a player
if (%name != $null) {
; increase the variable that shows us the number of the player
inc %count
; and echo it to the active window with the kills saved above
echo -a %count $+ . %name - %kills
}
; increase %i so we go on with the next player
inc %i
}
; if there are no players online, echo it aswell
if (%count == 0) echo -a No players found!
; turn off the timer
.timer $+ $sockname off
; and close the socket manually
sockclose $sockname
}