Code:
package cPGS::q2;
use strict;
use IPC::Open2;
use cPGS::Shared;
our $VERSION="1.0";
my $short = 'q2';
my $long = 'Quake 2';
sub new {
my $class = shift;
return bless {}, $class;
}
sub register_self {
return(1,__PACKAGE__,$short,"$VERSION",$long);
}
sub showsimpleconfig {
my($self,$s,$srvargs_hashref,$home,$servdir,$user,$game,$srvn,$portdata,$ipdata,$ports_list,$ips_list) = @_;
my %srvargs = %{$srvargs_hashref};
my $map_list;
open(CONF,'<'."$home/.gameservers/$servdir\_$srvn/baseq2/server.cfg") or print $s "Could not open config file ($home/.gameservers/$servdir\_$srvn/baseq2/server.cfg) : $!\n";
while(<CONF>) {
s/(\r|\n|\")//g;
next if /^\/\//;
if(/^(?:seta|set)\s+(.*?)\s+(.*)/) {
if(defined($srvargs{$1})) { next; }
$srvargs{$1}=$2;
$srvargs{$1} =~ s/(\s+)?\/\/.*$//;
} else {
next;
}
}
close(CONF);
return(\%srvargs,$map_list,$ports_list,$ips_list);
}
sub configsave {
my($self,$s,$form_hashref,$home,$servdir,$user,$game,$srvn,$maxc) = @_;
my %form = %{$form_hashref};
my $chg_cnt = 0;
my $cfg_file = delete $form{'cfg_file'};
if( $cfg_file eq 'advconfig') {
my @realform = split(/\n/,$form{'conf'});
if(open(CONF,'>',"$home/.gameservers/$servdir\_$srvn/baseq2/server.cfg")) {
foreach my $line(@realform) {
$line =~ s/(\r|\n)//g;
if($line =~ m/seta\s+sv_maxclients\s+\"(\d+)\"/) {
my $usermax=$1;
if($usermax > $maxc) { $usermax = $maxc; }
print CONF "seta sv_maxclients $usermax\n";
} else {
print CONF "$line\n";
}
}
close(CONF);
return("Config file saved.");
} else {
return("Can not open config file: $!");
}
}
return("Unknown config, can not save.");
}
sub formsave {
my($self,$s,$form_hashref,$home,$servdir,$user,$game,$srvn,$maxc) = @_;
my %form = %{$form_hashref};
my $chg_cnt = 0;
open(CONF,'<',"$home/.gameservers/$servdir\_$srvn/.launchrc");
my @existconf=(<CONF>);
close(CONF);
open(CONFRE,'>',"$home/.gameservers/$servdir\_$srvn/.launchrc");
foreach my $line(@existconf) {
$line =~ s/(\n|\r)//g;
next if $line =~ /^\/\//;
if($line =~ /^(.*?)\s+(.*)/) {
my $var = $1;
my $val = $2;
if(defined($form{$var})) {
print CONFRE "$var $form{$var}\n";
if($val ne $form{$var}) {
$chg_cnt++;
print $s "<tr><td>$var</td><td>$val</td><td>$form{$var}</td></tr>\n";
}
} else {
print CONFRE "$line\n";
}
}
}
close(CONFRE);
open(CONF,'<',"$home/.gameservers/$servdir\_$srvn/baseq2/server.cfg");
my @existconf=(<CONF>);
close(CONF);
open(CONFRED,'>',"$home/.gameservers/$servdir\_$srvn/baseq2/server.cfg");
foreach my $line(@existconf) {
$line =~ s/(\n|\r|\")//g;
if($line =~ /^\/\//) {
print CONFRED "$line\n";
} elsif($line =~ /^(set|seta)\s+(.*?)\s+(.*)/) {
my $set = $1;
my $var = $2;
my $val = $3;
if(defined($form{$var})) {
if($var eq 'sv_maxclients' && $form{$var} > $maxc) { $form{$var} = $maxc; }
print CONFRED "$set $var \"". $form{$var} ."\"\n";
if($val ne $form{$var}) {
$chg_cnt++;
print $s "<tr><td>$var</td><td>$val</td><td>$form{$var}</td></tr>\n";
}
} else {
print CONFRED "$line\n";
}
} else {
print CONFRED "$line\n";
}
}
close(CONFRED);
return($chg_cnt);
}
sub showconfig {
my($self,$s,$query,$home,$servdir,$user,$game,$srvn) = @_;
if( $query eq 'servercfg' ) {
open(CONF,'<',"$home/.gameservers/$servdir\_$srvn/baseq2/server.cfg") or print $s "Could not open config file $home/.gameservers/$servdir\_$srvn/baseq2/server.cfg : $!\n";
my @confi=(<CONF>);
close(CONF);
foreach my $line(@confi) {
print $s "OK: $line";
}
}
}
sub get_servdir {
return($short);
}
sub isinstalledql {
my($self,$s,$user,$game,$srvn,$home,$servdir) = @_;
if(-x "$home/.gameservers/$servdir\_$srvn/quake2") { return 0; }
else { return 1; }
}
# gather game specific data to send to startserver code in cpgsd
sub loadlaunchrc {
my($self,$user,$game,$srvn,$home)= @_;
my(%launchrc);
my $gd = &get_servdir;
open(my $launch_fh,'<',"$home/.gameservers/$gd\_$srvn/.launchrc");
my @launch=(<$launch_fh>);
close($launch_fh);
foreach my $args(@launch) {
$args =~ s/(\r|\n)//g;
if($args =~ /^net_port(=|\s+)(.*)/i) { $launchrc{'port'}=$2; }
elsif($args =~ /^net_ip(=|\s+)(.*)/i) { $launchrc{'ip'}=$2; }
elsif($args =~ /^maxplayers(=|\s+)(.*)/i) { $launchrc{'maxplayers'}=$2; }
}
$launchrc{'extracli'} = ' +set sv_punkbuster 0';
open(my $serverset,'<',"$home/.gameservers/$gd\_$srvn/baseq2/server.cfg") or main::msglog("Could not open config file ($home/.gameservers/$gd\_$srvn/baseq2/server.cfg) : $!");
my @srvargs = (<$serverset>);
close($serverset);
foreach my $args(@srvargs) {
$args =~ s/\n//g;
$args =~ s/\"//g;
if($args =~ /^seta\s+sv_punkbuster\s+(.*)/i) { $launchrc{'extracli'} = ' +set sv_punkbuster 1'; }
}
$launchrc{'ld_library_path'} = "$home/.gameservers/$gd\_$srvn/libs\:/var/cpanel/gameserv_libs";
$launchrc{'pbname'} = 'q2a';
$launchrc{'fullname'} = $long;
$launchrc{'cpgs-divider'} = ' ';
return(\%launchrc);
}
sub set_default_configs {
my($self,$s,$user,$game,$srvn,$dir,$maxc,$lowport,$defip) = @_;
my $pcnt = my @ports = split(/\_/,$lowport);
if($pcnt > 1) {
$lowport = shift(@ports);
}
# create default config
if( open(DEF,'<','/var/cpanel/cpgs/games/q2/custom_default_server.cfg') || open(DEF,'<','/var/cpanel/cpgs/games/q2/default_server.cfg')) {
if(open(DEFC,'>',"$dir/baseq2/server.cfg")) {
while(<DEF>) {
if(m/^set\s+sv_maxclients/) {
print DEFC "set sv_maxclients $maxc\n";
} else {
print DEFC;
}
}
close(DEFC);
} else {
main::msglog("Couldn't write to $dir/baseq2/server.cfg : $!");
return("Could not open config file $dir/baseq2/server.cfg : $!");
}
close(DEF);
} else {
main::msglog("Couldn't open /var/cpanel/cpgs/games/q2/default_server.cfg : $!");
return("Could not open default config template: $!");
}
if(open(LAUNCHRC,'>',"$dir/.launchrc")) {
print LAUNCHRC "net_port $lowport\n";
print LAUNCHRC "net_ip $defip\n";
print LAUNCHRC "maxplayers $maxc\n";
close(LAUNCHRC);
}
return(0);
}
sub getserverip {
my($self,$s,$user,$game,$srvn,$home,$servdir) = @_;
open(ARGSF,"<$home/.gameservers/q2\_$srvn/.launchrc") or print $s "Could not open config file ($home/.gameservers/q2\_$srvn/.launchrc) : $! <br>\n";
my @srvargs = (<ARGSF>);
close(ARGSF);
foreach my $args(@srvargs) {
$args =~ s/(\r|\n)//g;
if($args =~ /^net_ip\s+(.*)/i) { return($1); }
}
return(1);
}
sub getStats {
my($self,$user,$game,$srvn,$pubip,$verbose,@targets) = @_;
my($sip,$players,$map,$gtype,$sname,@reply,$target,%seen,$matched1,%retteam,$pname,$time,$score);
my($pkg,$calling_file,$calling_line)=caller;
my($sip,$players,$map,$gtype,$sname,@reply,$target,%seen,$matched1,%retteam,$pname,$time,$score);
foreach $target(@targets) {
if($target =~ /(\d{0,3}\.\d{0,3}\.\d{0,3}\.\d{0,3})\:(\d+)\s+\((.*)\)/) {
my $ip=$1;
my $port=$2;
if($ip eq '0.0.0.0') { $ip=$pubip; }
$target = "$ip\:$port";
}
if($seen{$target} eq $target) { next; }
$seen{$target}=$target;
@reply="";
if($verbose == 0) {
my @arg = ("-q2s",$target,"-nh","-timeout",$cPGS::Shared::to);
my $pid = open2(\*READ,\*WRITE,$cPGS::Shared::qstatpath,@arg); close(WRITE); while(<READ>) { push(@reply,$_); } close(READ);
foreach my $ln(@reply) {
if($ln =~ m/^(\d{0,3}\.\d{0,3}\.\d{0,3}\.\d{0,3}.*)\s+(\d+\/\d+)\s+\d+\/\d+\s+([\w\s]+)\s+(\d+)\s+\/\s+\d+\s+(.*)/) {
$sip=$1;
$players=$2;
$map=$3;
$gtype=$4;
$sname=$5;
$matched1=1;
}
}
} else {
my @arg = ("-q2s",$target,"-nh","-P","-timeout",$cPGS::Shared::to);
my $pid = open2(\*READ,\*WRITE,$cPGS::Shared::qstatpath,@arg); close(WRITE); while(<READ>) { push(@reply,$_); } close(READ);
foreach my $ln(@reply) {
if($ln =~ m/^(\d{0,3}\.\d{0,3}\.\d{0,3}\.\d{0,3}.*)\s+(\d+\/\d+)\s+\d+\/\d+\s+([\w\s]+)\s+(\d+)\s+\/\s+\d+\s+(.*)/) {
$sip=$1;
$players=$2;
$map=$3;
$gtype=$4;
$sname=$5;
$matched1=1;
}
elsif($ln =~ /^\s+(\d+)\s+frags\s+(\d+.*ms)\s+(.+)/) {
$score=$1;
$time=$2;
$pname=$3;
$pname = $pkg->filter($pname);
$retteam{$pname}{'score'}=$score;
$retteam{$pname}{'time'}=$time;
$retteam{$pname}{'pname'}=$pname;
}
}
}
if($matched1 == 1) {
last;
}
}
return($matched1,$sip,$players,$map,$gtype,$sname,undef,%retteam);
}
sub showPlayerStats {
my($self,$game,$retteam)=@_;
print "<table border=0 cellpadding=0 cellspacing=0 width=100\%><tr><th>Player Name</th><th>Score</th><th>Ping</th></tr>";
foreach my $key(keys %{$retteam}) { print "<tr><td>$$retteam{$key}{'pname'}</td><td>$$retteam{$key}{'score'}</td><td>$$retteam{$key}{'time'}</td></tr>\n"; }
print "</div></table></div>\n";
}
1;