XRcon.pm


package XSTAB::Voice::XRcon;
# This package talks to the RCon server without waiting
# a reply.
# $Id: XRcon.pm,v 1.12 2003/03/25 05:12:28 dranok Exp $
# This module is released under the GPL
# Author: DranoK
# Email: dranok@users.sourceforge.net
# Documentation: http://xstab.sourceforge.net
########################################################


NAME

XSTAB::Voice::XRcon


DESCRIPTION

This module will issue commands from the @Voice_queue to a RCon UDP socket, specifically Quake3-like games.


INITIALIZATION

use IO::Socket;
use IO::Select;
use XSTAB::XData;
use Time::HiRes qw( time );
use strict;

my $VERSION = 0.9;


PUBLIC METHODS

create ()
Constructor which will return the blessed object. Before returning this object, it stores the socket information for the RCon server as $self->{data_sock}
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;
}

do_log (string Message, int Priority)
This is the overloaded do_log function. Purpose is to identify which module is logging the message
sub do_log
{
  my $string = shift;
  my $prio = shift;
  XSTAB::XData::do_log("Voice::XRcon: $string", $prio);
}

act ()
This method will send one command from the @Voice_queue to the RCon server. This will only occur once every second, with $self->{start_time} used in the exact same manner as the XUdp sensor. This method does not wait for a response, so it has no idea if the command was executed successfully or not.

The priority system is basic enough. Every element in the @Voice_queue array is in the format of

        Priority$Global{sp}Command (Priority:x:Command)

The command with the highest priority is popped from the array and issued via the _issue_command private method. The @Voice_queue is then traversed to increase the priority of all other elements.

sub act
{
  my $self = shift;

  if (!(scalar(@Voice_queue))) {
    return -1;
  }
 
  my $end_time = time;
  if ($end_time - $self->{start_time} < 0.6) {
    return -1;
  }
  $self->{start_time} = $end_time;
 
  # Debug line format:
  #   priority$Global{sp}text
  @Voice_queue = sort {$a <=> $b} @Voice_queue; 
  
  my ($prio, $action) = split($Global{sp}, pop(@Voice_queue));
  do_log("Highest priority in voice queue: $prio", 5);
  $self->_issue_command($action);

  my @tmpar;
  foreach my $event (@Voice_queue) {
    my ($prio, $action) = split($Global{sp}, $event);
    $prio++;
    push(@tmpar, "$prio$Global{sp}$action");
  }
  @Voice_queue = @tmpar;
}


PRIVATE METHODS

_issue_command (string Command)
This method will print Command to the RCon socket. It does not wait for a response, and has no clue if it succeeded or not.
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;

  $command =~ s/:NEWLINE:/\\n/g;
  my $RCONString = $self->{Magic} . "rcon " . $Global{Rcon_passwd} . " $command";
  print {$self->{data_sock}} $RCONString;
  do_log("Issued '$RCONString' to RCON socket", 5);
}

1;


AUTHOR

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