package XSTAB::Sensor::XUdp; # This is a sensor designed for UDP rcon # protocols. This sensor will return data # (as specified by the game module) from # the UDP socket # NOTE: The timeout on getting an answer is .5 # seconds. This time is busy-wait, and CPU # load will jump momentarily while the daemon # sits waiting for a reply. # # $Id: XUdp.pm,v 1.6 2003/03/24 04:11:54 dranok Exp $ # # This module distributed under the GPL # Author: DranoK # Email: dranok@users.sourceforge.net # Documentation: xstab.sourceforge.net ############################################
XSTAB::Sensor::XUdp - UDP RCon Sensor Module
This sensor is designed to work with UDP RCon protocols, such as is used in Quake3, RTCW, etc.
use IO::Socket; use IO::Select; use XSTAB::XData; use strict; my $VERSION = 0.9;
$self->{start_time}
sub create { my $class = shift; my $self = { }; $self->{Magic} = "\377\377\377\377"; $self->{start_time} = time; if (defined($self->{data_sock} = IO::Socket::INET->new("PeerAddr" => $Global{Udp_ip}, "PeerPort" => $Global{Udp_port}, "Proto" => 'udp', "Timeout" => '300'))) { $self->{data_sock}->timeout(300); } else { return -2; } bless($self, $class); return $self; }
sub do_log { my $string = shift; my $prio = shift; XSTAB::XData::do_log("Sensor::XUdp: $string", $prio); }
sub whoami { return "XUdp"; }
$Global{sp}
) one at a time by sending the individual command to issue_command.
The scalar $results (which should be treated as a string) has the returned string
from issue_command appended to it for each command listed. This final string is
then returned.
Although this method is called every loop by xstab, it will only run once every 10
seconds. This is done by checking if the current time minus $self->{start_time
is less than 10, and if so returning before doing anything further. If the propper
ammount of time has passed, $self->{start_time}
will be reset to the current
time.
sub gather_data { my $self = shift; my $command_list = shift; my $end_time = time; # RCon sucks my fucking ass if (scalar(@Voice_queue)) { return; } if ($end_time - $self->{start_time} < 10) { return; } $self->{start_time} = $end_time; my @commands = split($Global{sp}, $command_list); my $results; foreach my $command (@commands) { $results .= $self->issue_command($command); } return $results; }
$self->{start_time}
.
This has the affect of decreasing the time before the next probe to 5 seconds
instead of 10 seconds.
NOTE: RCon has some drain bramage to say the least. If someone knows why RCon behaves as it does, I would love to know. RCon cannot handle multiple requests coming in at (or close to) the same time, so not getting a response every time is to be expected.
sub issue_command { my $self = shift; my $command = shift; my $tmpbuf = ""; my $pattern = "^$self->{Magic}" . "print\n"; my $tcr = 0; my $tmpbufc; my $chars_read; my $RCONString = $self->{Magic} . "rcon " . $Global{Rcon_passwd} . " $command"; print {$self->{data_sock}} $RCONString; do_log("Waiting for answer from UDP server.", 5); my $select = IO::Select->new($self->{data_sock}); while (my @sockets = $select->can_read(0.5)) { foreach my $socket (@sockets) { if (defined($chars_read = $socket->sysread($tmpbuf, 65507))) { $tcr += $chars_read; $tmpbuf =~ s/$pattern//; $tmpbufc .= "$command$Global{sp}$tmpbuf$Global{sp2}"; } } } if (!$tcr) { # OK, reset to 5 seconds instead of 10 $self->{start_time} -= 4; return -1; } return $tmpbufc; } 1; __END__
This module was coded by DranoK and is part of the core XStab modules. You may directly contact DranoK at dranok@users.sourceforge.net, or by posting to the forums at:
http://www.oltl.net/forums/forumdisplay.php?s=&forumid=25