Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

css: Counter Strike Scanner

by skyknight (Hermit)
on Aug 10, 2003 at 03:09 UTC ( [id://282548]=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Scripts
Author/Contact Info
Description: I enjoy a good game of Counter Strike just as much as the next nerd, but I hate the interfaces for getting into a game. There are a small number of servers on which I like to play, and if there isn't a good game on any of them, I'd rather not waste my time at all. As such, I want a quick way to know if there are some good games available Half-Life itself is too heavy weight in its startup. GameSpy is also slow to start up, and furthermore extrememly annoying as you are forced to watch all kinds of crappy advertising. What I wanted was a simple command line script that quickly apprises me of what's up on my favorite servers, and so I wrote this. You can simply specify a server address and port on the command line, or use a -f switch and a name for a file that contains a bunch of lines, on each of which is a server address and port, separated by one or more spaces. Thus usage is very straightforward. The output is nicely formatted as well. As one minor tweak, server names have spaces translated to underscores, so as to allow for distinct space separated fields for passing off to other command line scripts for further processing, say, if you wanted to sort based on ping time. Enjoy! Oh yeah... Half-Life doesn't use a nice text based protocol. You get to wrangle with messy pack and unpack statements. Yum.
#!/usr/bin/perl -w

use strict;
use IO::Socket;
use Time::HiRes qw(tv_interval gettimeofday);

my $DEF_PORT = 27015;

my ($host, $name, $map, $active, $max, $ping, $port);

format SERVER =
@<<<<<<<<<<<<<<<<<<<<<  @<<<<<<<<<<<<<<<<<<<<  @<<<<<<<<<<<<  @<<<<<< 
+ @<<<
$host,     $name,       $map,        $active . '/' . $max, $ping
.

$~ = "SERVER";

my @servers;

die "invalid usage" unless $ARGV[0];

if ($ARGV[0] eq '-f') {
    open(CONFIG, "<$ARGV[1]") or die "can't open $ARGV[1]: $!";

    while (<CONFIG>) {
        chomp;
        ($host, $port) = split;
        push(@servers, [$host, ($port or $DEF_PORT)]);
    }

    close(CONFIG);
}
elsif ($ARGV[0]) {
    push(@servers, [$ARGV[0], ($ARGV[1] or $DEF_PORT)]);
}

foreach my $server (@servers) {
    my $sock = IO::Socket::INET->new(PeerAddr  => $server->[0],
                                     PeerPort  => $server->[1],
                                     Proto     => 'udp');
    unless ($sock) {
        warn("could not connect to ",
             join(':', $server->[0], $server->[1]), " ($!)");
        next;
    }

    output_info($sock);
    $sock->close();
}

sub hl_send {
    my $sock = shift();
    my $cmd = shift();
    print $sock pack("NZ*C", -1, $cmd, 0);
}

sub hl_recv {
    my $sock = shift();
    my $recv = undef;
    recv($sock, $recv, 1024, 0);
    return $recv;
}

sub output_info {
    my $sock = shift();

    my $t0 = [gettimeofday()];

    hl_send($sock, "info");
    my $recv = hl_recv($sock);

    unless (length($recv)) {
        warn "problem fetching data from remote host";
        return;
    }

    $ping = tv_interval($t0);
    $ping = sprintf("%.0d", 1000 * $ping);

    my @junk;
    (@junk[0..4], $host, $name, $map, @junk[5..6], $active, $max, $jun
+k[7]) =
        unpack("C5Z*Z*Z*Z*Z*CCC", $recv);

    $name =~ s/ /_/;

    write();
}
Replies are listed 'Best First'.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://282548]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2024-04-23 20:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found