Bend Source is the Best place in Oregon for weekly updates. : tribes1ms4

HomePage :: Categories :: PageIndex :: RecentChanges :: RecentlyCommented :: Login/Register
This is an example that I found for a master server for a different game.
I was going to try and reverse engineer it to see what I could make it do with Tribes

#!/usr/local/bin/perl

#
# Torque Master Server Prototype
# ------------------------------
#
# Free for all for any use
# This is only useful for proof of concept or a starting point to ode your own
# I would advice against using this in production
#
# Author: Thomas Lund, thomas@trylleskoven.dk, www.c3command.com
#
# Mildly upgraded by: Ian Hardingham, ian@mode7games.com, www.mode7games.com
#

my $MAXLEN = 1024;
my $PORT = 28000;

$sock = IO::Socket::INET->new(LocalPort => $PORT, Proto => 'udp') or die "socket: $@";

my %gameServers;

print "Listening for game servers on port $PORT\n";

while ( $sock->recv(my $newmsg, $MAXLEN) ) {
    my($port, $ipaddr) = sockaddr_in($sock->peername);
    my $gameserverIP = join(".", unpack("C4", $ipaddr));

    # Retrieve the command type from the request
    my ($cmd_type) = unpack("C1",$newmsg);

    # Heartbeat from game servers = 22
    # Add the server to the gameServers hash array
    if ($cmd_type eq "22") {
    print "Heartbeat recieved from $gameserverIP port $port\n";
    $gameServers{join("£", $ipaddr, $port)} = time();


    } elsif ($cmd_type eq "16") {
    print "Heartbeat recieved from Tribes 1 server IP:$gameserverIP:$port\n";
    $gameServers{join("£", $ipaddr, $port)} = time();


    # Game Server list request = 6
    # The request contains tons of flags to filter the response list created
    # Here I just dump it all on the console and return a complete list of servers
    } elsif ($cmd_type eq "6") {
    print "Server list request from $gameserverIP\n";
    my ($cmd_type, $query_flags, $key, $dummy, $gametype_size) = unpack("C1 C1 i1 C1 C1", $newmsg);
    print "  Qflags: $query_flags\n";
    print "  Key: $key\n";
    print "  Gametype_size: $gametype_size\n";
    my $gametype = substr($newmsg,8,$gametype_size);
    print "  Gametype: '$gametype'\n";
    my $misstype_size = unpack("C1", substr($newmsg,8+$gametype_size,1));
    print "  Missiontype_size: $misstype_size\n";
    my $misstype = substr($newmsg, 8+$gametype_size+1, $misstype_size);
    print "  Missiontype: $misstype\n";
    my ($min_players, $max_players, $reg_mask, $version, $filterflag, $maxbot, $mincpu, $buddycount) = unpack("C1 C1 I1 I1 C1 C1 S1 C1", substr($newmsg, 8+$gametype_size+1+$misstype_size));
    print "  Min play: $min_players\n";
    print "  Max play: $max_players\n";
    print "  Region mask: $reg_mask\n";
    print "  Version: $version\n";
    print "  Filter flag: $filterflag\n";
    print "  Max bots: $maxbot\n";
    print "  Min CPU: $mincpu\n";
    print "  Buddy Count: $buddycount\n";
    sendServerList($key);


    # Unknown request = everything else
    } else {
      print "Unknown request type $cmd_type\n";
    }
}
die "recv: $!";

#
# Takes a request key as parameter and returns complete list of all game servers
#
sub sendServerList {
  my ($packetkey) = @_;

  # Game server list response = type 8
  my $packettype = 8;
  my $flag = 0;
  my $key = $packetkey;

  # Check number of servers
  my $packetindex = 0;
  my $servercount = scalar keys(%gameServers);

  # If there are servers, then populate list and send it back
  if ($servercount != 0) {
    my $packettotal = $servercount;

    # Loop over all servers
    foreach my $ipAndPort (keys %gameServers) {
      my ($ip, $portey) = split(/£/, $ipAndPort);
      my ($ip1, $ip2, $ip3, $ip4) = unpack("C4",$ip);
      my $lastPing = $gameServers{$ipAndPort};
      
      if (180 < time() - $lastPing)
        { next; }
        
      # Create single server info packet
      my $serverResponse = pack("C1 C1 I1 C1 C1 S1 C1 C1 C1 C1 S1",
                $packettype,
                $flag,
                $key,
                $packetindex,
                $packettotal,
                $servercount,
                $ip1, $ip2, $ip3, $ip4,
                $portey);
      print "Sending serverlist part $packetindex of $packettotal\n";
      $sock->send($serverResponse) or die "send: $!";     
      $packetindex++;
    }

  # Empty server list
  } else {     
    my $packettotal = 1;
      my $emptyServerResponse = pack("C1 C1 I1 C1 C1 S1 C1 C1 C1 C1 S1",
                     $packettype,
                     $flag,
                     $key,
                     $packetindex,
                     $packettotal,
                     $servercount,
                     0, 0, 0, 0,
                     0);
      print "Sending empty server list\n";
      $sock->send($emptyServerResponse) or die "send: $!";
    }
}

There are no comments on this page. [Add comment]

Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by Wikka Wakka Wiki 1.1.6.2
Page was generated in 0.5607 seconds