#!/usr/bin/perl -w

use strict;
use warnings;
use Digest::MD5  qw(md5_hex);
use RPC::XML;
use RPC::XML::Client;
use Nagios::Plugin;
use vars qw($PROGNAME $VERSION);

$PROGNAME = "check_crysis.pl";
$VERSION = '1.0';

my $np = Nagios::Plugin->new(
  usage => "Usage: %s -H [address] -p [port] -P [password]\n",
  version => $VERSION,
  plugin  => $PROGNAME,
  shortname => uc($PROGNAME),
  blurb => 'Check server for running Crysis game.',
  timeout => 10,
);
$np->add_arg(
  spec => 'host|H=s',
  help => "-H, --host=HOST\n"
    . "   Host to connect to",
  required => 1,
);
$np->add_arg(
  spec => 'port|p=s',
  help => "-p, --port=PORT\n"
    . "   Port to connect to",
  required => 1,
);
$np->add_arg(
  spec => 'password|P=s',
  help => "-P, --password=PASSWORD\n"
    . "   Password",
  required => 1,
);
$np->getopts;

my $verbose = $np->opts->verbose;


# Bail once timeout expires
alarm $np->opts->timeout;

# Try to connect to server, Server Down if not able
my $cli = RPC::XML::Client->new('http://' . $np->opts->host . ':' . $np->opts->port . '/RPC2', useragent=>[ keep_alive=>1 ], error_handler => sub { $np->nagios_exit('CRITICAL', "Server down") });

# Challenge and authentication
my $req = RPC::XML::request->new('challenge', 'perl');
my $resp = $cli->send_request($req);
my $value = $resp->value;
warn("Challenge response : $value\n") if ($verbose);
my $md5_hash = md5_hex( "$value:" . $np->opts->password );
$req = RPC::XML::request->new("authenticate $md5_hash");
$resp = $cli->send_request($req);
$value = $resp->value;

# Did we authenticate
if ($value !~ m/.*authorized.*/) {
	warn("Authentication failed\n") if ($verbose);
	$np->nagios_exit('CRITICAL', "Could not authenticate");
}

# Send the status request
$req = RPC::XML::request->new("status");
$resp = $cli->send_request($req);
$value = $resp->value;

my @lines;

# Parse the stats: players = up, status = no map loaded
if ($value =~ m/players/) {
	warn("Server up\n") if ($verbose);
	@lines = split(/\n/, $value);
} elsif ($value =~ m/status/) {
	$np->nagios_exit('WARNING', "Server up but no map");
}

foreach (@lines) {
	warn($_ . "\n") if ($verbose);
	if ($_ =~ m/.*players.*(\d+)\/(\d+)/) {
		$np->add_perfdata(
			label => 'players',
			value => $1,
			uom => ''
		);
		# All done, we can exit
		$np->nagios_exit('OK', "Server up with $1 players");
	}
}

$np->nagios_exit('UNKNOWN', "Server not up");
