arit93
9th November, 2002, 03:52 AM
Just playing around with perl and server query. all that is required to run this is perl. If you on windows I would suggest ActiveSate's perl. Not sure if this will be useful to anyone let me know if it is.
arit93
[code:1:b07a92a943]
#!/usr/bin/perl
###################################################################
# Author: Arit93
# Date: 11-8-2002
# Title: queryshell.pl
# Description: This will open a socket to the Unreal Tournament
# server. you can then query away for information. This script
# needs the IP of hostname of the server running an Ureal Tournament
# server and the port that the gamespy network is listening on.
####################################################################
use strict;
use IO::Socket;
#Global socket object
my $sock;
#opensocket($host, $port) will open a por and start listening
sub opensocket($$){
my($host,$port) = @<hidden>;
$sock = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => $port,
Proto => 'udp',
);
die "Could not open socket: $!\n" unless $sock;
}
#sendquery(Query string) sends the query to the server
sub sendquery($){
#send the query wrapped in backslashes
$sock->send("\\@<hidden>\\");
#receive the response
$sock->recv(my $line,15000)or die"$!";
#parse the results into a hash the will
#contain the data element and the value
my @<hidden> = split /\\/,$line;
my %info;
my $i;
#eliminate the leading space that is placed there
#on the split. This is because the string returned by
#the server starts with a \
shift(@<hidden>);
#load the hash
for($i=0;$i<@<hidden>;$i+=2){
if($messages[$i] ne 'final'){
$info{$messages[$i]}=$messages[$i+1];
}
}
#Display to the user
foreach my $message(sort keys %info){
print "$message - $info{$message}\n";
}
}
#closesock will close down the socket
sub closesock(){
close($sock);
}
#prints the help dialog
sub helpmess(){
print <<END_OF_HELP;
exit - Leave the queryshell
help - print this message
queries
basic - basic game information:
Game Name
Game Version
Location
info - Full information
Hostname
Host port
Host ip
Map Name
Game Type
Number of Players
Max Players
Game Mode
rules - rules of the current game
Time Limit
Frag Limit
Multiplayer Bots
Change Levels
Admin Name
Admin Email
players - list of players
Name
Score
Team
Skin
Mesh
Ping
Response
status - Combines basic + info + rules + players
echo\\echo_string - parrots the echo_string back at ya
secure\\challenge_string used by gamespy to ensure its a
valid UT server
Please address any additional questions to the nearest
brick wall
END_OF_HELP
}
###########################################
# begin mainline execution#
my $b=1; #boolean to control execution
my $comm; #query command to server
my $host = $ARGV[0]; #host to connect to
my $port = $ARGV[1]; #prot to connect to
#make sure we have a host and port
if($host eq '' || $port eq ''){
print " usage\: queryshell.pl server port\n";
$b=0;
}
#connect to the host
&opensocket($host,$port);
#start the shell
while($b){
#give the user a prompt
print "\$";
#take the input
chomp($comm = <STDIN>);
#check to see if we are shutting down
if($comm eq 'exit'){
$b=0;
}elsif($comm eq 'help'){ #does the user need help?
&helpmess;
}else{ #send the query
eval{
#catch $SIG{ALRM} This is important because if
#we send the server an unknown command we will get
#no return and that will lock us up. Thats a bad thing
local $SIG{ALRM}= sub{print "request timed out\n"};
#set the alarm to fire in 5 seconds
alarm 5;
#send the query
sendquery($comm);
#clear the alarm
alarm 0;
};
#according to the book this will avoid the race condition
alarm 0;
}
}
#clean up and go home
&closesock;
[/code:1:b07a92a943]
arit93
[code:1:b07a92a943]
#!/usr/bin/perl
###################################################################
# Author: Arit93
# Date: 11-8-2002
# Title: queryshell.pl
# Description: This will open a socket to the Unreal Tournament
# server. you can then query away for information. This script
# needs the IP of hostname of the server running an Ureal Tournament
# server and the port that the gamespy network is listening on.
####################################################################
use strict;
use IO::Socket;
#Global socket object
my $sock;
#opensocket($host, $port) will open a por and start listening
sub opensocket($$){
my($host,$port) = @<hidden>;
$sock = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => $port,
Proto => 'udp',
);
die "Could not open socket: $!\n" unless $sock;
}
#sendquery(Query string) sends the query to the server
sub sendquery($){
#send the query wrapped in backslashes
$sock->send("\\@<hidden>\\");
#receive the response
$sock->recv(my $line,15000)or die"$!";
#parse the results into a hash the will
#contain the data element and the value
my @<hidden> = split /\\/,$line;
my %info;
my $i;
#eliminate the leading space that is placed there
#on the split. This is because the string returned by
#the server starts with a \
shift(@<hidden>);
#load the hash
for($i=0;$i<@<hidden>;$i+=2){
if($messages[$i] ne 'final'){
$info{$messages[$i]}=$messages[$i+1];
}
}
#Display to the user
foreach my $message(sort keys %info){
print "$message - $info{$message}\n";
}
}
#closesock will close down the socket
sub closesock(){
close($sock);
}
#prints the help dialog
sub helpmess(){
print <<END_OF_HELP;
exit - Leave the queryshell
help - print this message
queries
basic - basic game information:
Game Name
Game Version
Location
info - Full information
Hostname
Host port
Host ip
Map Name
Game Type
Number of Players
Max Players
Game Mode
rules - rules of the current game
Time Limit
Frag Limit
Multiplayer Bots
Change Levels
Admin Name
Admin Email
players - list of players
Name
Score
Team
Skin
Mesh
Ping
Response
status - Combines basic + info + rules + players
echo\\echo_string - parrots the echo_string back at ya
secure\\challenge_string used by gamespy to ensure its a
valid UT server
Please address any additional questions to the nearest
brick wall
END_OF_HELP
}
###########################################
# begin mainline execution#
my $b=1; #boolean to control execution
my $comm; #query command to server
my $host = $ARGV[0]; #host to connect to
my $port = $ARGV[1]; #prot to connect to
#make sure we have a host and port
if($host eq '' || $port eq ''){
print " usage\: queryshell.pl server port\n";
$b=0;
}
#connect to the host
&opensocket($host,$port);
#start the shell
while($b){
#give the user a prompt
print "\$";
#take the input
chomp($comm = <STDIN>);
#check to see if we are shutting down
if($comm eq 'exit'){
$b=0;
}elsif($comm eq 'help'){ #does the user need help?
&helpmess;
}else{ #send the query
eval{
#catch $SIG{ALRM} This is important because if
#we send the server an unknown command we will get
#no return and that will lock us up. Thats a bad thing
local $SIG{ALRM}= sub{print "request timed out\n"};
#set the alarm to fire in 5 seconds
alarm 5;
#send the query
sendquery($comm);
#clear the alarm
alarm 0;
};
#according to the book this will avoid the race condition
alarm 0;
}
}
#clean up and go home
&closesock;
[/code:1:b07a92a943]