Reupload after bitbucket wipe
This commit is contained in:
384
scripts/BASTARDrcon.pm
Normal file
384
scripts/BASTARDrcon.pm
Normal file
@ -0,0 +1,384 @@
|
||||
package BASTARDrcon;
|
||||
#
|
||||
# BASTARDrcon Perl Module - execute commands on a remote Half-Life 1 server using Rcon.
|
||||
# A merge of the KKrcon library into HLstatsX
|
||||
# Copyright (C) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
|
||||
# KKrcon Perl Module - execute commands on a remote Half-Life server using Rcon.
|
||||
# http://kkrcon.sourceforge.net
|
||||
#
|
||||
# TRcon Perl Module - execute commands on a remote Half-Life2 server using remote console.
|
||||
# http://www.hlstatsx.com
|
||||
#
|
||||
# Copyright (C) 2000, 2001 Rod May
|
||||
# Enhanced in 2005 by Tobi (Tobi@gameme.de)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use sigtrap;
|
||||
use Socket;
|
||||
use Sys::Hostname;
|
||||
use bytes;
|
||||
|
||||
##
|
||||
## Main
|
||||
##
|
||||
|
||||
#
|
||||
# Constructor
|
||||
#
|
||||
sub new
|
||||
{
|
||||
my ($class_name, $server_object) = @_;
|
||||
my ($self) = {};
|
||||
bless($self, $class_name);
|
||||
|
||||
# Initialise properties
|
||||
$self->{server_object} = $server_object;
|
||||
$self->{rcon_password} = $server_object->{rcon} or die("BASTARDrcon: a Password is required\n");
|
||||
$self->{server_host} = $server_object->{address};
|
||||
$self->{server_port} = int($server_object->{port}) or die("BASTARDrcon: invalid Port \"" . $server_object->{port} . "\"\n");
|
||||
|
||||
$self->{socket} = undef;
|
||||
$self->{error} = "";
|
||||
|
||||
# Set up socket parameters
|
||||
$self->{_ipaddr} = gethostbyname($self->{server_host}) or die("BASTARDrcon: could not resolve Host \"" . $self->{server_host} . "\"\n");
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
#
|
||||
# Execute an Rcon command and return the response
|
||||
#
|
||||
sub execute
|
||||
{
|
||||
my ($self, $command) = @_;
|
||||
my $msg;
|
||||
my $ans;
|
||||
|
||||
# version x.1.0.6+ HL1 server
|
||||
$msg = "\xFF\xFF\xFF\xFFchallenge rcon\n\0";
|
||||
$ans = $self->_sendrecv($msg);
|
||||
|
||||
if ($ans =~ /challenge +rcon +(\d+)/)
|
||||
{
|
||||
$msg = "\xFF\xFF\xFF\xFFrcon $1 \"" . $self->{"rcon_password"} . "\" $command\0";
|
||||
$ans = $self->_sendrecv($msg);
|
||||
}
|
||||
elsif (!$self->error())
|
||||
{
|
||||
$ans = "";
|
||||
$self->{"error"} = "No challenge response";
|
||||
}
|
||||
|
||||
if ($ans =~ /bad rcon_password/i)
|
||||
{
|
||||
$self->{"error"} = "Bad Password";
|
||||
}
|
||||
return $ans;
|
||||
}
|
||||
|
||||
sub _sendrecv
|
||||
{
|
||||
my ($self, $msg) = @_;
|
||||
my $host = $self->{"server_host"};
|
||||
my $port = $self->{"server_port"};
|
||||
my $ipaddr = $self->{"_ipaddr"};
|
||||
my $proto = $self->{"_proto"};
|
||||
|
||||
# Open socket
|
||||
socket($self->{"socket"}, PF_INET, SOCK_DGRAM, $proto) or die("BASTARDrcon(141): socket: $!\n");
|
||||
my $hispaddr = sockaddr_in($port, $ipaddr);
|
||||
|
||||
die("BASTARDrcon: send $ipaddr:$port : $!") unless(defined(send($self->{"socket"}, $msg, 0, $hispaddr)));
|
||||
|
||||
my $rin = "";
|
||||
vec($rin, fileno($self->{"socket"}), 1) = 1;
|
||||
my $ans = "TIMEOUT";
|
||||
if (select($rin, undef, undef, 0.5))
|
||||
{
|
||||
$ans = "";
|
||||
$hispaddr = recv($self->{"socket"}, $ans, 8192, 0);
|
||||
$ans =~ s/\x00+$//; # trailing crap
|
||||
$ans =~ s/^\xFF\xFF\xFF\xFFl//; # HL response
|
||||
$ans =~ s/^\xFF\xFF\xFF\xFFn//; # QW response
|
||||
$ans =~ s/^\xFF\xFF\xFF\xFF//; # Q2/Q3 response
|
||||
$ans =~ s/^\xFE\xFF\xFF\xFF.....//; # old HL bug/feature
|
||||
}
|
||||
# Close socket
|
||||
close($self->{"socket"});
|
||||
|
||||
if ($ans eq "TIMEOUT")
|
||||
{
|
||||
$ans = "";
|
||||
$self->{"error"} = "Rcon timeout";
|
||||
}
|
||||
return $ans;
|
||||
}
|
||||
|
||||
#
|
||||
# Send a package
|
||||
#
|
||||
sub send_rcon
|
||||
{
|
||||
my ($self, $id, $command, $string1, $string2) = @_;
|
||||
my $tmp = pack("VVZ*Z*",$id,$command,$string1,$string2);
|
||||
my $size = length($tmp);
|
||||
if($size > 4096)
|
||||
{
|
||||
$self->{error} = "Command too long to send!";
|
||||
return 1;
|
||||
}
|
||||
$tmp = pack("V", $size) .$tmp;
|
||||
|
||||
unless(defined(send($self->{"socket"},$tmp,0)))
|
||||
{
|
||||
die("BASTARDrcon: send $!");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#
|
||||
# Recieve a package
|
||||
#
|
||||
sub recieve_rcon
|
||||
{
|
||||
my $self = shift;
|
||||
my ($size, $id, $command, $msg);
|
||||
my $rin = "";
|
||||
my $tmp = "";
|
||||
|
||||
vec($rin, fileno($self->{"socket"}), 1) = 1;
|
||||
if(select($rin, undef, undef, 0.5))
|
||||
{
|
||||
while(length($size) < 4)
|
||||
{
|
||||
$tmp = "";
|
||||
recv($self->{"socket"}, $tmp, (4-length($size)), 0);
|
||||
$size .= $tmp;
|
||||
}
|
||||
$size = unpack("V", $size);
|
||||
if($size < 10 || $size > 8192)
|
||||
{
|
||||
close($self->{"socket"});
|
||||
$self->{error} = "illegal size $size ";
|
||||
return (-1, -1, -1);
|
||||
}
|
||||
|
||||
while(length($id)<4)
|
||||
{
|
||||
$tmp = "";
|
||||
recv($self->{"socket"}, $tmp, (4-length($id)), 0);
|
||||
$id .= $tmp;
|
||||
}
|
||||
$id = unpack("V", $id);
|
||||
$size = $size - 4;
|
||||
while(length($command)<4)
|
||||
{
|
||||
$tmp ="";
|
||||
recv($self->{"socket"}, $tmp, (4-length($command)),0);
|
||||
$command.=$tmp;
|
||||
}
|
||||
$command = unpack("V", $command);
|
||||
$size = $size - 4;
|
||||
my $msg = "";
|
||||
while($size >= 1)
|
||||
{
|
||||
$tmp = "";
|
||||
recv($self->{"socket"}, $tmp, $size, 0);
|
||||
$size -= length($tmp);
|
||||
$msg .= $tmp;
|
||||
}
|
||||
my ($string1,$string2) = unpack("Z*Z*",$msg);
|
||||
$msg = $string1.$string2;
|
||||
return ($id, $command, $msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (-1, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Get error message
|
||||
#
|
||||
sub error
|
||||
{
|
||||
my ($self) = @_;
|
||||
return $self->{"error"};
|
||||
}
|
||||
|
||||
#
|
||||
# Parse "status" command output into player information
|
||||
#
|
||||
sub getPlayers
|
||||
{
|
||||
my ($self) = @_;
|
||||
my $status = $self->execute("status");
|
||||
|
||||
my @lines = split(/[\r\n]+/, $status);
|
||||
|
||||
my %players;
|
||||
|
||||
# HL1
|
||||
# name userid uniqueid frag time ping loss adr
|
||||
# 1 "psychonic" 1 STEAM_0:1:4153990 0 00:33 13 0 192.168.5.115:27005
|
||||
|
||||
foreach my $line (@lines)
|
||||
{
|
||||
if ($line =~ /^\#\s*\d+\s+
|
||||
"(.+)"\s+ # name
|
||||
(\d+)\s+ # userid
|
||||
([^\s]+)\s+\d+\s+ # uniqueid
|
||||
([\d:]+)\s+ # time
|
||||
(\d+)\s+ # ping
|
||||
(\d+)\s+ # loss
|
||||
([^:]+): # addr
|
||||
(\S+) # port
|
||||
$/x)
|
||||
|
||||
{
|
||||
my $name = $1;
|
||||
my $userid = $2;
|
||||
my $uniqueid = $3;
|
||||
my $time = $4;
|
||||
my $ping = $5;
|
||||
my $loss = $6;
|
||||
my $state = "";
|
||||
my $address = $7;
|
||||
my $port = $8;
|
||||
|
||||
$uniqueid =~ s/^STEAM_[0-9]+?\://i;
|
||||
|
||||
# &::printEvent("DEBUG", "USERID: '$userid', NAME: '$name', UNIQUEID: '$uniqueid', TIME: '$time', PING: '$ping', LOSS: '$loss', ADDRESS:'$address', CLI_PORT: '$port'", 1);
|
||||
|
||||
if ($::g_mode eq "NameTrack") {
|
||||
$players{$name} = {
|
||||
"Name" => $name,
|
||||
"UserID" => $userid,
|
||||
"UniqueID" => $uniqueid,
|
||||
"Time" => $time,
|
||||
"Ping" => $ping,
|
||||
"Loss" => $loss,
|
||||
"State" => $state,
|
||||
"Address" => $address,
|
||||
"ClientPort" => $port
|
||||
};
|
||||
} elsif ($::g_mode eq "LAN") {
|
||||
$players{$address} = {
|
||||
"Name" => $name,
|
||||
"UserID" => $userid,
|
||||
"UniqueID" => $uniqueid,
|
||||
"Time" => $time,
|
||||
"Ping" => $ping,
|
||||
"Loss" => $loss,
|
||||
"State" => $state,
|
||||
"Address" => $address,
|
||||
"ClientPort" => $port
|
||||
};
|
||||
} else {
|
||||
$players{$uniqueid} = {
|
||||
"Name" => $name,
|
||||
"UserID" => $userid,
|
||||
"UniqueID" => $uniqueid,
|
||||
"Time" => $time,
|
||||
"Ping" => $ping,
|
||||
"Loss" => $loss,
|
||||
"State" => $state,
|
||||
"Address" => $address,
|
||||
"ClientPort" => $port
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return %players;
|
||||
}
|
||||
|
||||
sub getServerData
|
||||
{
|
||||
my ($self) = @_;
|
||||
my $status = $self->execute("status");
|
||||
|
||||
my @lines = split(/[\r\n]+/, $status);
|
||||
|
||||
my $servhostname = "";
|
||||
my $map = "";
|
||||
my $max_players = 0;
|
||||
foreach my $line (@lines)
|
||||
{
|
||||
if ($line =~ /^\s*hostname\s*:\s*([\S].*)$/x)
|
||||
{
|
||||
$servhostname = $1;
|
||||
}
|
||||
elsif ($line =~ /^\s*map\s*:\s*([\S]+).*$/x)
|
||||
{
|
||||
$map = $1;
|
||||
}
|
||||
elsif ($line =~ /^\s*players\s*:\s*\d+.+\((\d+)\smax.*$/)
|
||||
{
|
||||
$max_players = $1;
|
||||
}
|
||||
}
|
||||
return ($servhostname, $map, $max_players, 0);
|
||||
}
|
||||
|
||||
|
||||
sub getVisiblePlayers
|
||||
{
|
||||
my ($self) = @_;
|
||||
my $status = $self->execute("sv_visiblemaxplayers");
|
||||
|
||||
my @lines = split(/[\r\n]+/, $status);
|
||||
|
||||
|
||||
my $max_players = -1;
|
||||
foreach my $line (@lines)
|
||||
{
|
||||
# "sv_visiblemaxplayers" = "-1"
|
||||
# - Overrides the max players reported to prospective clients
|
||||
if ($line =~ /^\s*"sv_visiblemaxplayers"\s*=\s*"([-0-9]+)".*$/x)
|
||||
{
|
||||
$max_players = $1;
|
||||
}
|
||||
}
|
||||
return ($max_players);
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Get information about a player by userID
|
||||
#
|
||||
|
||||
sub getPlayer
|
||||
{
|
||||
my ($self, $uniqueid) = @_;
|
||||
my %players = $self->getPlayers();
|
||||
|
||||
if (defined($players{$uniqueid}))
|
||||
{
|
||||
return $players{$uniqueid};
|
||||
}
|
||||
else
|
||||
{
|
||||
$self->{"error"} = "No such player # $uniqueid";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
# end
|
247
scripts/ConfigReaderSimple.pm
Normal file
247
scripts/ConfigReaderSimple.pm
Normal file
@ -0,0 +1,247 @@
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
|
||||
package ConfigReaderSimple;
|
||||
#
|
||||
# Simple interface to a configuration file
|
||||
#
|
||||
# Originally developed by Ben Oberin.
|
||||
# Modified for HLstats by Simon Garner.
|
||||
# Modified for HLstatsX by Tobias Oetzel.
|
||||
#
|
||||
# ObLegalStuff:
|
||||
# Copyright (c) 2000 Bek Oberin. All rights reserved. This program is
|
||||
# free software; you can redistribute it and/or modify it under the
|
||||
# same terms as Perl itself.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
|
||||
|
||||
require Exporter;
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw();
|
||||
@EXPORT_OK = qw();
|
||||
|
||||
$VERSION = "1.0";
|
||||
|
||||
my $DEBUG = 0;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ConfigReader::Simple - Simple configuration file parser
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use ConfigReader::Simple;
|
||||
|
||||
$config = ConfigReader::Simple->new("configrc", [qw(Foo Bar Baz Quux)]);
|
||||
|
||||
$config->parse();
|
||||
|
||||
$config->get("Foo");
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
C<ConfigReader::Simple> reads and parses simple configuration files. It's
|
||||
designed to be smaller and simpler than the C<ConfigReader> module
|
||||
and is more suited to simple configuration files.
|
||||
|
||||
=cut
|
||||
|
||||
###################################################################
|
||||
# Functions under here are member functions #
|
||||
###################################################################
|
||||
|
||||
=head1 CONSTRUCTOR
|
||||
|
||||
=item new ( FILENAME, DIRECTIVES )
|
||||
|
||||
This is the constructor for a new ConfigReader::Simple object.
|
||||
|
||||
C<FILENAME> tells the instance where to look for the configuration
|
||||
file.
|
||||
|
||||
C<DIRECTIVES> is an optional argument and is a reference to an array.
|
||||
Each member of the array should contain one valid directive. A directive
|
||||
is the name of a key that must occur in the configuration file. If it
|
||||
is not found, the module will die. The directive list may contain all
|
||||
the keys in the configuration file, a sub set of keys or no keys at all.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $prototype = shift;
|
||||
my $filename = shift;
|
||||
my $keyref = shift;
|
||||
|
||||
my $class = ref($prototype) || $prototype;
|
||||
my $self = {};
|
||||
|
||||
$self->{"filename"} = $filename;
|
||||
$self->{"validkeys"} = $keyref;
|
||||
|
||||
bless($self, $class);
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# destructor
|
||||
#
|
||||
sub DESTROY {
|
||||
my $self = shift;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=pod
|
||||
=item parse ()
|
||||
|
||||
This does the actual work. No parameters needed.
|
||||
|
||||
=cut
|
||||
|
||||
sub parse {
|
||||
my $self = shift;
|
||||
|
||||
open(CONFIG, $self->{"filename"}) ||
|
||||
die "Config: Can't open config file " . $self->{"filename"} . ": $!";
|
||||
|
||||
my @array_buffer;
|
||||
my $ext_option = 0;
|
||||
my $parsed_line = 0;
|
||||
|
||||
while (<CONFIG>) {
|
||||
chomp;
|
||||
next if /^\s*$/; # blank
|
||||
next if /^\s*#/; # comment
|
||||
next if /^\s*.*\[[0-9]+\]\s*=\s*\(/; # old style server config start
|
||||
next if /^\s*.*\s*=>\s*\.*".*\",/; # old style server config option
|
||||
|
||||
$parsed_line = 0;
|
||||
my $input_text = $_;
|
||||
|
||||
if (($ext_option == 0) && ($parsed_line == 0)) {
|
||||
my ($key, $value) = &parse_line($input_text);
|
||||
warn "Key: '$key' Value: '$value'\n" if $DEBUG;
|
||||
$self->{"config_data"}{$key} = $value;
|
||||
}
|
||||
}
|
||||
close(CONFIG);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
=pod
|
||||
=item get ( DIRECTIVE )
|
||||
|
||||
Returns the parsed value for that directive.
|
||||
|
||||
=cut
|
||||
|
||||
sub get {
|
||||
my $self = shift;
|
||||
my $key = shift;
|
||||
|
||||
unless (ref $self->{"config_data"}{$key}) {
|
||||
return $self->{"config_data"}{$key};
|
||||
} else {
|
||||
return %{$self->{"config_data"}{$key}};
|
||||
}
|
||||
}
|
||||
|
||||
# Internal methods
|
||||
|
||||
sub parse_line {
|
||||
my $text = shift;
|
||||
|
||||
my ($key, $value);
|
||||
|
||||
if ($text =~ /^\s*(\w+)\s+(['"]?)(.*?)\2\s*$/) {
|
||||
$key = $1;
|
||||
$value = $3;
|
||||
} else {
|
||||
die "Config: Can't parse line: $text\n";
|
||||
}
|
||||
|
||||
return ($key, $value);
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 LIMITATIONS/BUGS
|
||||
|
||||
Directives are case-sensitive.
|
||||
|
||||
If a directive is repeated, the first instance will silently be
|
||||
ignored.
|
||||
|
||||
Always die()s on errors instead of reporting them.
|
||||
|
||||
C<get()> doesn't warn if used before C<parse()>.
|
||||
|
||||
C<get()> doesn't warn if you try to acces the value of an
|
||||
unknown directive not know (ie: one that wasn't passed via C<new()>).
|
||||
|
||||
All these will be addressed in future releases.
|
||||
|
||||
=head1 CREDITS
|
||||
|
||||
Kim Ryan <kimaryan@ozemail.com.au> adapted the module to make declaring
|
||||
keys optional. Thanks Kim.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Bek Oberin <gossamer@tertius.net.au>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (c) 2000 Bek Oberin. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself.
|
||||
|
||||
=cut
|
||||
|
||||
#
|
||||
# End code.
|
||||
#
|
||||
1;
|
86
scripts/GeoLiteCity/GeoLite_Import.sh
Normal file
86
scripts/GeoLiteCity/GeoLite_Import.sh
Normal file
@ -0,0 +1,86 @@
|
||||
#!/bin/sh
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
# Configure the variables below
|
||||
|
||||
# Set this value to 1 if you are running Gentoo linux, or any other linux distro where the "cal" command outputs not Sunday as the first day in every row!
|
||||
LINUX_OTHER="0"
|
||||
|
||||
# Login information for your MySQL server
|
||||
DBHOST="localhost"
|
||||
DBNAME=""
|
||||
DBUSER=""
|
||||
DBPASS=""
|
||||
|
||||
#
|
||||
# Nothing to change below here.
|
||||
#
|
||||
|
||||
|
||||
# database is updated every first tuesday of any month, so download it with that specific date and import it
|
||||
TODAY_MONTH=$( date +%m )
|
||||
TODAY_YEAR=$( date +%Y )
|
||||
if [ $LINUX_OTHER == "1" ]
|
||||
then CAL_COMMAND="cal -s"
|
||||
else CAL_COMMAND="cal"
|
||||
fi
|
||||
FIRST_TUESDAY_MONTH=$( $CAL_COMMAND $TODAY_MONTH $TODAY_YEAR |
|
||||
awk '
|
||||
NR == 1 { next }
|
||||
NR == 2 { next }
|
||||
NF <= 4 { next }
|
||||
NF == 5 { print $1 ; exit }
|
||||
NF == 6 { print $2 ; exit }
|
||||
NF == 7 { print $3 ; exit }
|
||||
' )
|
||||
|
||||
DATE=""$TODAY_YEAR""$TODAY_MONTH"0"$FIRST_TUESDAY_MONTH""
|
||||
DIR="GeoLiteCity_$DATE"
|
||||
FILE="GeoLiteCity_$DATE.zip"
|
||||
ls *.csv &>/dev/null && rm *.csv
|
||||
[ -f $FILE ] || wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity_CSV/$FILE || exit 1
|
||||
unzip -o $FILE || exit 1
|
||||
mv $DIR/GeoLiteCity-Blocks.csv geoLiteCity_Blocks.csv
|
||||
mv $DIR/GeoLiteCity-Location.csv geoLiteCity_Location.csv.temp
|
||||
iconv -f ISO-8859-1 -t UTF-8 geoLiteCity_Location.csv.temp > geoLiteCity_Location.csv
|
||||
mysqlimport -C -d --fields-terminated-by=, --fields-enclosed-by=\" --ignore-lines=2 --default-character-set=utf8 -L -i -h $DBHOST -u $DBUSER --password=$DBPASS $DBNAME geoLiteCity_Blocks.csv
|
||||
mysqlimport -C -d --fields-terminated-by=, --fields-enclosed-by=\" --ignore-lines=2 --default-character-set=utf8 -L -i -h $DBHOST -u $DBUSER --password=$DBPASS $DBNAME geoLiteCity_Location.csv
|
||||
|
||||
# Cleanup
|
||||
ls *.csv &>/dev/null && rm *.csv
|
||||
ls *.csv.temp &>/dev/null && rm *.csv.temp
|
||||
rm $FILE
|
||||
rmdir $DIR
|
17
scripts/GeoLiteCity/README
Normal file
17
scripts/GeoLiteCity/README
Normal file
@ -0,0 +1,17 @@
|
||||
Included in this folder are two scripts to import data from the MaxMind (http://www.maxmind.com) from the GeoLiteCity database into your HLX db.
|
||||
|
||||
For Linux:
|
||||
Edit the GeoLite_Import.sh file to insert your database settings in the top section and then execute.
|
||||
|
||||
For Windows:
|
||||
Download the HLstatsX CE GeoLiteCity Importer from http://code.google.com/p/hlstatsxcommunity
|
||||
|
||||
|
||||
--------------------------------------------------------------
|
||||
Alternative method by *XYZ*SaYnt:
|
||||
--------------------------------------------------------------
|
||||
* For Windows or Linux.
|
||||
* Requires python.
|
||||
* Generates INSERTs in case LOAD DATA command is disabled
|
||||
|
||||
Edit the geoip.py file to insert your database settings in the top section and then execute.
|
196
scripts/GeoLiteCity/geoip.py
Normal file
196
scripts/GeoLiteCity/geoip.py
Normal file
@ -0,0 +1,196 @@
|
||||
#!/usr/bin/env python
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
|
||||
import os,sys
|
||||
|
||||
# version 1.0 alpha contributed to hlstatsx community by *XYZ*SaYnt
|
||||
|
||||
DBHOST="localhost"
|
||||
DBNAME="your_hlstats_db"
|
||||
DBUSER="your_sql_username"
|
||||
DBPASS="your_sql_password"
|
||||
|
||||
|
||||
def system(cmd):
|
||||
"""
|
||||
executes a system call and returns the text as a string. Returns only the first line of output.
|
||||
"""
|
||||
print("EXECUTING: %s"%cmd)
|
||||
f = os.popen(cmd)
|
||||
output = f.readlines()
|
||||
f.close()
|
||||
if len(output) > 0:
|
||||
return output[0].replace("\n","")
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
def fetch_geodata():
|
||||
"""
|
||||
Obtains the geoLiteCity raw data, resulting in geoLiteCity_Location.csv and geoLiteCity_Blocks.csv
|
||||
"""
|
||||
# database is updated on 1st every month, so download the file from the 1st of current month
|
||||
DAT = system("date +%Y%m01")
|
||||
FIL = "GeoLiteCity_%s"%DAT
|
||||
FILE = FIL + ".zip"
|
||||
system("rm *.csv > /dev/null")
|
||||
if not os.path.exists(FILE):
|
||||
system("wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity_CSV/" + FILE)
|
||||
system("unzip -o " + FILE)
|
||||
|
||||
system("mv %s/GeoLiteCity-Blocks.csv geoLiteCity_Blocks.csv"%FIL)
|
||||
system("mv %s/GeoLiteCity-Location.csv geoLiteCity_Location.csv.temp"%FIL)
|
||||
system("rmdir " + FIL)
|
||||
system("iconv -f ISO-8859-1 -t UTF-8 geoLiteCity_Location.csv.temp > geoLiteCity_Location.csv")
|
||||
|
||||
return
|
||||
|
||||
|
||||
def dump_sql(fname):
|
||||
"""
|
||||
Dump the new sql data into our database
|
||||
"""
|
||||
system("mysql -u %s -p%s -h %s %s < %s"%(DBUSER,DBPASS,DBHOST,DBNAME,fname))
|
||||
|
||||
|
||||
def write_sql(fname):
|
||||
"""
|
||||
Write a file of sql commands so that our data can be imported into our database.
|
||||
"""
|
||||
try:
|
||||
fout = open(fname,"w")
|
||||
except:
|
||||
print("ERROR: unable to open "+fname)
|
||||
return 0
|
||||
|
||||
fout.write("""
|
||||
DROP TABLE IF EXISTS `geoLiteCity_Blocks`;
|
||||
DROP TABLE IF EXISTS `geolitecity_blocks`;
|
||||
DROP TABLE IF EXISTS `geolitecity_location`;
|
||||
DROP TABLE IF EXISTS `geoLiteCity_Location`;
|
||||
|
||||
CREATE TABLE `geoLiteCity_Blocks`
|
||||
(`startIpNum` bigint(11) unsigned NOT NULL default '0',
|
||||
`endIpNum` bigint(11) unsigned NOT NULL default '0',
|
||||
`locId` bigint(11) unsigned NOT NULL default '0'
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `geoLiteCity_Location` (
|
||||
`locId` bigint(11) unsigned NOT NULL default '0',
|
||||
`country` varchar(2) NOT NULL,
|
||||
`region` varchar(50) default NULL,
|
||||
`city` varchar(50) default NULL,
|
||||
`postalCode` varchar(10) default NULL,
|
||||
`latitude` decimal(14,4) default NULL,
|
||||
`longitude` decimal(14,4) default NULL,
|
||||
PRIMARY KEY (`locId`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
""")
|
||||
|
||||
# read in the raw data
|
||||
f = open("geoLiteCity_Blocks.csv")
|
||||
raw = f.readlines()
|
||||
f.close()
|
||||
del raw[0:2]
|
||||
|
||||
# chunk up the raw data
|
||||
chunksize = 1000
|
||||
gblocks = []
|
||||
chunks = len(raw)/chunksize + 1
|
||||
for i in xrange(0,chunks): gblocks.append(raw[i*chunksize:(i+1)*chunksize])
|
||||
print("SQL: %d data items, %d chunks"%(len(raw),chunks))
|
||||
del raw
|
||||
|
||||
for chunk in gblocks:
|
||||
if chunk:
|
||||
s = "insert into `geoLiteCity_Blocks`(`startIpNum`,`endIpNum`,`locId`) values"
|
||||
for l in chunk:
|
||||
vals = l.replace('"',"").replace('\n',"").split(',')
|
||||
s += "(%s,%s,%s),"%(vals[0],vals[1],vals[2])
|
||||
s = s[0:-1] # chop the last comma
|
||||
fout.write(s + ";\n");
|
||||
del gblocks
|
||||
|
||||
|
||||
|
||||
|
||||
f = open("geoLiteCity_Location.csv")
|
||||
raw = f.readlines()
|
||||
f.close()
|
||||
del raw[0:2]
|
||||
|
||||
# chunk up the raw data
|
||||
gblocks = []
|
||||
chunks = len(raw)/chunksize + 1
|
||||
for i in xrange(0,chunks): gblocks.append(raw[i*chunksize:(i+1)*chunksize])
|
||||
print("SQL: %d data items, %d chunks"%(len(raw),chunks))
|
||||
del raw
|
||||
|
||||
for chunk in gblocks:
|
||||
if chunk:
|
||||
s = "insert into `geoLiteCity_Location`(`locId`,`country`,`region`,`city`,`postalCode`,`latitude`,`longitude`) values"
|
||||
for l in chunk:
|
||||
vals = l.replace('"',"").replace('\n',"").split(',')
|
||||
for i,v in enumerate(vals): vals[i] = v.replace("'","\\'")
|
||||
s += "(%s,'%s','%s','%s','%s','%s','%s'),"%(vals[0],vals[1],vals[2],vals[3],vals[4],vals[5],vals[6])
|
||||
s = s[0:-1] # chop the last comma
|
||||
fout.write(s + ";\n");
|
||||
del gblocks
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
def main():
|
||||
sqlname = "geodata.sql"
|
||||
print("DOWNLOADING GEO DATA....")
|
||||
fetch_geodata()
|
||||
print("WRITING DATABASE FILE....")
|
||||
if write_sql(sqlname):
|
||||
print("IMPORTING DATABASE FILE....")
|
||||
dump_sql(sqlname)
|
||||
else:
|
||||
print("Fatal error; unable to finish.")
|
||||
|
||||
# clean up.
|
||||
system("rm "+sqlname)
|
||||
|
||||
print("DONE.")
|
||||
|
||||
|
||||
|
||||
main()
|
||||
|
54
scripts/GeoLiteCity/install_binary.sh
Normal file
54
scripts/GeoLiteCity/install_binary.sh
Normal file
@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
# *** You should not need to configure anything in this script. ***
|
||||
# URL is the location to download the GeoLiteCity.dat.gz file from.
|
||||
URL=http://geolite.maxmind.com/download/geoip/database/
|
||||
|
||||
# File is the file to download from the server above, as well as what to store it as locally.
|
||||
FILE=GeoLiteCity.dat.gz
|
||||
|
||||
# ***** NOTHING TO CONFIGURE BELOW HERE *****
|
||||
|
||||
# Change to directory where installer is
|
||||
cd `dirname $0`
|
||||
|
||||
echo Downloading a new copy of GeoLiteCity, if needed.
|
||||
wget -N -q $URL$FILE
|
||||
echo Uncompressing database
|
||||
gzip -dc < $FILE > $(basename $FILE .gz)
|
||||
chmod 777 *.dat
|
||||
echo Done
|
49
scripts/GeoLiteCity/ip2number.php
Normal file
49
scripts/GeoLiteCity/ip2number.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/*
|
||||
HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
http://www.hlxcommunity.com
|
||||
|
||||
HLstatsX Community Edition is a continuation of
|
||||
ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
http://ovrsized.neo-soft.org/
|
||||
|
||||
ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
http://www.hlstatsx.com/
|
||||
Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
|
||||
HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
http://sourceforge.net/projects/hlstats/
|
||||
Copyright (C) 2001 Simon Garner
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
For support and installation notes visit http://www.hlxcommunity.com
|
||||
*/
|
||||
|
||||
$ip = "62.77.230.10";
|
||||
|
||||
$ip = explode(".",$ip);
|
||||
$number = ($ip[0]*16777216) + ($ip[1]*65536) + ($ip[2]*256) + $ip[3];
|
||||
|
||||
echo $number;
|
||||
|
||||
// example SQL to determine location
|
||||
// SELECT geoLiteCity_Location.* FROM geoLiteCity_Blocks INNER JOIN geoLiteCity_Location ON (geoLiteCity_Blocks.locId=geoLiteCity_Location.locId) WHERE startIpNum<=$number AND endIpNum>=$number;
|
||||
|
||||
?>
|
31
scripts/HLStatsFTP/README
Normal file
31
scripts/HLStatsFTP/README
Normal file
@ -0,0 +1,31 @@
|
||||
hlstats-ftp.pl README
|
||||
|
||||
Utility written by Woody.
|
||||
|
||||
This utility can be used to grab log files from a remote game server through FTP and then use the HLStatsX Daemon to enter
|
||||
the data into the database. You must have perl installed to use this utility.
|
||||
|
||||
The script "remembers" the modification time (mtime) of the last log file that has been processed, and when run again,
|
||||
only processes files with a later mtime.
|
||||
|
||||
*** NOTE ***
|
||||
To use this utility you must copy it into the same folder your hlstats.pl (the daemon) is in.
|
||||
You probably want to configure this as a cronjob as well.
|
||||
|
||||
|
||||
Usage:
|
||||
hlstats-ftp.pl --help
|
||||
hlstats-ftp.pl --version
|
||||
hlstats-ftp.pl --gs-ip=GSIP --gs-port=GSPORT [--ftp-ip=FTPIP] --ftp-usr=FTPUSR --ftp-pwd=FTPPWD --ftp-dir=FTPDIR [--quiet]
|
||||
|
||||
Options:
|
||||
--help display this help and exit
|
||||
--version output version information and exit
|
||||
--gs-ip=IP game server IP address
|
||||
--gs-port=PORT game server port
|
||||
--ftp-ip=IP ftp log server IP address, if different from
|
||||
game server IP address (--gs-ip)
|
||||
--ftp-usr=USERNAME ftp log server user name
|
||||
--ftp-pwd=PASSWORD ftp log server password
|
||||
--ftp-dir=DIRECTORY ftp log server directory
|
||||
--quiet quiet operation, i.e. no output
|
235
scripts/HLStatsFTP/hlstats-ftp.pl
Normal file
235
scripts/HLStatsFTP/hlstats-ftp.pl
Normal file
@ -0,0 +1,235 @@
|
||||
#!/usr/bin/perl
|
||||
################################################################################################################
|
||||
# hlstats-ftp.pl
|
||||
################################################################################################################
|
||||
# Feed HLstatsX with log data via FTP
|
||||
# (w) 2009 by Woody (http://woodystree.net)
|
||||
################################################################################################################
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use Net::FTP;
|
||||
|
||||
use constant VERSION => "0.42";
|
||||
use constant USAGE => <<EOT
|
||||
|
||||
Feed HLstatsX with log data via FTP.
|
||||
|
||||
Usage:
|
||||
hlstats-ftp.pl --help
|
||||
hlstats-ftp.pl --version
|
||||
hlstats-ftp.pl --gs-ip=<IP> --gs-port=<PORT> [--ftp-ip=<IP>] --ftp-usr=<USR> --ftp-pwd=<PWD> --ftp-dir=<DIR> [--quiet]
|
||||
|
||||
Options:
|
||||
--help display this help and exit
|
||||
--version output version information and exit
|
||||
--gs-ip=IP game server IP address
|
||||
--gs-port=PORT game server port
|
||||
--ftp-ip=IP ftp log server IP address, if different from
|
||||
game server IP address (--gs-ip)
|
||||
--ftp-usr=USR ftp log server user name
|
||||
--ftp-pwd=PWD ftp log server password
|
||||
--ftp-dir=DIR ftp log server directory
|
||||
--quiet quiet operation, i.e. no output
|
||||
|
||||
(w)2009 by Woody (http://woodystree.net)
|
||||
|
||||
|
||||
EOT
|
||||
;
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# define output subroutine
|
||||
################################################################################################################
|
||||
sub output {
|
||||
if (!(our $opt_quiet)) {
|
||||
my $text = shift;
|
||||
print $text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# get & parse command line options
|
||||
################################################################################################################
|
||||
my $opt_help; my $opt_version; my $gs_ip; my $gs_port; my $ftp_ip; my $ftp_usr; my $ftp_pwd; my $ftp_dir; our $opt_quiet;
|
||||
GetOptions(
|
||||
"help" => \$opt_help,
|
||||
"version" => \$opt_version,
|
||||
"gs-ip=s" => \$gs_ip,
|
||||
"gs-port=i" => \$gs_port,
|
||||
"ftp-ip=s" => \$ftp_ip,
|
||||
"ftp-usr=s" => \$ftp_usr,
|
||||
"ftp-pwd=s" => \$ftp_pwd,
|
||||
"ftp-dir=s" => \$ftp_dir,
|
||||
"quiet" => \$opt_quiet
|
||||
) or die(USAGE);
|
||||
|
||||
if ($opt_help) {
|
||||
print USAGE;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($opt_version) {
|
||||
print "\nhlstats-ftp.pl - Version " . VERSION . "\n";
|
||||
print "Feed HLstatsX with log data via FTP.\n";
|
||||
print "(w)2009 by Woody (http://woodystree.net)\n\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!(defined $gs_ip) && !(defined $gs_port) && !(defined $ftp_usr) && !(defined $ftp_pwd) && !(defined $ftp_dir)) {
|
||||
die(USAGE);
|
||||
}
|
||||
|
||||
if (!(defined $ftp_ip)) {
|
||||
$ftp_ip = $gs_ip;
|
||||
}
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# OK, lets go...
|
||||
################################################################################################################
|
||||
output("\nStarting hlstats-ftp.pl for IP $gs_ip, Port $gs_port...\n\n");
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# create tmp directory
|
||||
################################################################################################################
|
||||
output(" - creating tmp directory... ");
|
||||
|
||||
my $tmp_dir = "hlstats-ftp-$gs_ip-$gs_port.tmp";
|
||||
|
||||
if (-e $tmp_dir) {
|
||||
if (!(-w $tmp_dir)) {
|
||||
die "Writing to tmp directory is not possible.";
|
||||
}
|
||||
} else {
|
||||
mkdir($tmp_dir, 0775) || die "Make tmp directory \"$tmp_dir\" failed: $!";
|
||||
}
|
||||
|
||||
output("OK.\n");
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# get last mtime info, if any
|
||||
################################################################################################################
|
||||
output(" - getting last mtime info... ");
|
||||
|
||||
my $last_mtime_filename = "hlstats-ftp-$gs_ip-$gs_port.last";
|
||||
my $last_mtime = 0;
|
||||
|
||||
if (-e $last_mtime_filename) {
|
||||
open(LASTMTIME, "<$last_mtime_filename") || die "Open file \"$last_mtime_filename\" failed: $!";
|
||||
$last_mtime = <LASTMTIME>;
|
||||
close(LASTMTIME);
|
||||
output("OK: last mtime $last_mtime.\n");
|
||||
} else {
|
||||
output("none: using default 0.\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# establish ftp connection
|
||||
################################################################################################################
|
||||
output(" - establishing FTP connection... ");
|
||||
|
||||
my $ftp = Net::FTP->new($ftp_ip) || die "FTP connect to \"$ftp_ip\" failed: $!";
|
||||
$ftp->login($ftp_usr,$ftp_pwd) || die "FTP login for user \"$ftp_usr\" failed: $!";
|
||||
$ftp->binary() || die "FTP binary mode failed: $!";
|
||||
$ftp->cwd($ftp_dir) || die "FTP chdir to \"$ftp_dir\" failed: $!";
|
||||
|
||||
output("OK.\n");
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# get complete list of log files
|
||||
################################################################################################################
|
||||
output(" - getting complete list of log files... ");
|
||||
|
||||
my @files = $ftp->ls("-t *.log"); # get list of log files sorted by mtime
|
||||
$#files = $#files - 1; # skip last file, i.e. the latest file, which is possibly still in use by the game server
|
||||
|
||||
output("OK.\n");
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# transfer log files to tmp directory, if todo
|
||||
################################################################################################################
|
||||
output(" + transfering log files, if todo:\n");
|
||||
|
||||
my @todo_files = ();
|
||||
my @todo_mtimes = ();
|
||||
|
||||
foreach my $file (@files) {
|
||||
output(" - \"$file\" ");
|
||||
my $mtime = $ftp->mdtm($file) || die "FTP mtdm failed: $!";
|
||||
output("(mtime $mtime): ");
|
||||
if ($mtime > $last_mtime) {
|
||||
output("transferring... ");
|
||||
$ftp->get($file, "$tmp_dir/$file") || die "FTP get with \"$file\" failed: $!";
|
||||
push(@todo_files, $file);
|
||||
push(@todo_mtimes, $mtime);
|
||||
output("OK.\n");
|
||||
} else {
|
||||
output("skipping.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# close ftp connection
|
||||
################################################################################################################
|
||||
output(" - closing FTP connection... ");
|
||||
|
||||
$ftp->close() || die "FTP close failed: $!";
|
||||
|
||||
output("OK.\n");
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# process log files in tmp directory
|
||||
################################################################################################################
|
||||
output(" + parsing log files:\n");
|
||||
|
||||
for (my $i = 0; $i <= $#todo_files; $i++) {
|
||||
my $progress = "(" . ($i+1) . "/" . ($#todo_files+1) . ")";
|
||||
output(" - \"" . $todo_files[$i] . "\" " . $progress . ": parsing... ");
|
||||
system("./hlstats.pl --stdin --server-ip $gs_ip --server-port $gs_port < $tmp_dir/" . $todo_files[$i] . " > /dev/null");
|
||||
output("updating last mtime...");
|
||||
open(LASTMTIME, ">$last_mtime_filename") || die "Open file \"$last_mtime_filename\" failed: $!";
|
||||
print LASTMTIME $todo_mtimes[$i];
|
||||
close(LASTMTIME);
|
||||
output("OK.\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# delete tmp log files and directory
|
||||
################################################################################################################
|
||||
output(" - delete tmp log files and directory... ");
|
||||
|
||||
foreach my $file (<$tmp_dir/*>) {
|
||||
unlink($file) || die "Delete tmp log files failed: $!";
|
||||
}
|
||||
rmdir($tmp_dir) || die "Delete tmp directory failed: $!";
|
||||
|
||||
output("OK.\n");
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
# the end
|
||||
################################################################################################################
|
||||
output("\nSo Long, and Thanks for all the Fish.\n\n");
|
455
scripts/HLstats.plib
Normal file
455
scripts/HLstats.plib
Normal file
@ -0,0 +1,455 @@
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
|
||||
# HLstatsX CE release version number
|
||||
|
||||
$g_version = "<Unable to Detect>";
|
||||
my %db_stmt_cache = ();
|
||||
|
||||
%g_eventTables = (
|
||||
"TeamBonuses",
|
||||
["playerId", "actionId", "bonus"],
|
||||
"ChangeRole",
|
||||
["playerId", "role"],
|
||||
"ChangeName",
|
||||
["playerId", "oldName", "newName"],
|
||||
"ChangeTeam",
|
||||
["playerId", "team"],
|
||||
"Connects",
|
||||
["playerId", "ipAddress", "hostname", "hostgroup"],
|
||||
"Disconnects",
|
||||
["playerId"],
|
||||
"Entries",
|
||||
["playerId"],
|
||||
"Frags",
|
||||
["killerId", "victimId", "weapon", "headshot", "killerRole", "victimRole", "pos_x","pos_y","pos_z", "pos_victim_x","pos_victim_y","pos_victim_z"],
|
||||
"PlayerActions",
|
||||
["playerId", "actionId", "bonus", "pos_x","pos_y","pos_z"],
|
||||
"PlayerPlayerActions",
|
||||
["playerId", "victimId", "actionId", "bonus", "pos_x","pos_y","pos_z", "pos_victim_x","pos_victim_y","pos_victim_z"],
|
||||
"Suicides",
|
||||
["playerId", "weapon", "pos_x","pos_y","pos_z"],
|
||||
"Teamkills",
|
||||
["killerId", "victimId", "weapon", "pos_x","pos_y","pos_z", "pos_victim_x","pos_victim_y","pos_victim_z"],
|
||||
"Rcon",
|
||||
["type", "remoteIp", "password", "command"],
|
||||
"Admin",
|
||||
["type", "message", "playerName"],
|
||||
"Statsme",
|
||||
["playerId", "weapon", "shots", "hits", "headshots", "damage", "kills", "deaths"],
|
||||
"Statsme2",
|
||||
["playerId", "weapon", "head", "chest", "stomach", "leftarm", "rightarm", "leftleg", "rightleg"],
|
||||
"StatsmeLatency",
|
||||
["playerId", "ping"],
|
||||
"StatsmeTime",
|
||||
["playerId", "time"],
|
||||
"Latency",
|
||||
["playerId", "ping"],
|
||||
"Chat",
|
||||
["playerId", "message_mode", "message"]
|
||||
);
|
||||
|
||||
|
||||
##
|
||||
## Common Functions
|
||||
##
|
||||
|
||||
sub number_format {
|
||||
local $_ = shift;
|
||||
1 while s/^(-?\d+)(\d{3})/$1,$2/;
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub date_format {
|
||||
my $timestamp = shift;
|
||||
return sprintf('%dd %02d:%02d:%02dh',
|
||||
$timestamp / 86400,
|
||||
$timestamp / 3600 % 24,
|
||||
$timestamp / 60 % 60,
|
||||
$timestamp % 60
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#
|
||||
# void error (string errormsg)
|
||||
#
|
||||
# Dies, and optionally mails error messages to $g_mailto.
|
||||
#
|
||||
|
||||
sub error
|
||||
{
|
||||
my $errormsg = $_[0];
|
||||
|
||||
if ($g_mailto && $g_mailpath)
|
||||
{
|
||||
system("echo \"$errormsg\" | $g_mailpath -s \"HLstatsX:CE crashed `date`\" $g_mailto");
|
||||
}
|
||||
|
||||
die("$errormsg\n");
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# string quoteSQL (string varQuote)
|
||||
#
|
||||
# Escapes all quote characters in a variable, making it suitable for use in an
|
||||
# SQL query. Returns the escaped version.
|
||||
#
|
||||
|
||||
sub quoteSQL
|
||||
{
|
||||
my $varQuote = $_[0];
|
||||
|
||||
$varQuote =~ s/\\/\\\\/g; # replace \ with \\
|
||||
$varQuote =~ s/'/\\'/g; # replace ' with \'
|
||||
|
||||
return $varQuote;
|
||||
}
|
||||
|
||||
#
|
||||
# void doConnect
|
||||
#
|
||||
# Connects to the HLstatsX database
|
||||
#
|
||||
|
||||
sub doConnect
|
||||
{
|
||||
$db_conn = DBI->connect(
|
||||
"DBI:mysql:$db_name:$db_host",
|
||||
$db_user, $db_pass, { mysql_enable_utf8 => 1 }
|
||||
);
|
||||
while(!$db_conn) {
|
||||
&printEvent("MYSQL", "\nCan't connect to MySQL database '$db_name' on '$db_host'\n" .
|
||||
"Server error: $DBI::errstr\n");
|
||||
sleep(5);
|
||||
$db_conn = DBI->connect(
|
||||
"DBI:mysql:$db_name:$db_host",
|
||||
$db_user, $db_pass, { mysql_enable_utf8 => 1 }
|
||||
);
|
||||
}
|
||||
$db_conn->do("SET NAMES 'utf8'");
|
||||
&printEvent("MYSQL", "Connecting to MySQL database '$db_name' on '$db_host' as user '$db_user' ... connected ok", 1);
|
||||
%db_stmt_cache = ();
|
||||
}
|
||||
|
||||
#
|
||||
# result doQuery (string query)
|
||||
#
|
||||
# Executes the SQL query 'query' and returns the result identifier.
|
||||
#
|
||||
|
||||
sub doQuery
|
||||
{
|
||||
my ($query, $callref) = @_;
|
||||
if(!$db_conn->ping()) {
|
||||
&printEvent("HLSTATSX", "Lost database connection. Trying to reconnect...", 1);
|
||||
&doConnect();
|
||||
}
|
||||
|
||||
my $result = $db_conn->prepare($query) or die("Unable to prepare query:\n$query\n$DBI::errstr\n$callref");
|
||||
$result->execute or die("Unable to execute query:\n$query\n$DBI::errstr\n$callref");
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
sub execNonQuery
|
||||
{
|
||||
my ($query) = @_;
|
||||
if(!$db_conn->ping()) {
|
||||
&printEvent("HLSTATSX", "Lost database connection. Trying to reconnect...", 1);
|
||||
&doConnect();
|
||||
}
|
||||
#&printEvent("DEBUG","execNonQuery:\n".$query);
|
||||
$db_conn->do($query);
|
||||
}
|
||||
|
||||
sub execCached {
|
||||
my ($query_id,$query, @bind_args) = @_;
|
||||
|
||||
if(!$db_conn->ping()) {
|
||||
&printEvent("HLSTATSX", "Lost database connection. Trying to reconnect...", 1);
|
||||
&doConnect();
|
||||
}
|
||||
|
||||
if(!$db_stmt_cache{$query_id}) {
|
||||
$db_stmt_cache{$query_id} = $db_conn->prepare($query) or die("Unable to prepare query ($query_id):\n$query\n$DBI::errstr");
|
||||
#&printEvent("HLSTATSX", "Prepared a statement ($query_id) for the first time.", 1);
|
||||
}
|
||||
$db_stmt_cache{$query_id}->execute(@bind_args) or die ("Unable to execute query ($query_id):\n$query\n$DBI::errstr");
|
||||
return $db_stmt_cache{$query_id};
|
||||
}
|
||||
|
||||
#
|
||||
# string resolveIp (string ip, boolean quiet)
|
||||
#
|
||||
# Do a DNS reverse-lookup on an IP address and return the hostname, or empty
|
||||
# string on error.
|
||||
#
|
||||
|
||||
sub resolveIp
|
||||
{
|
||||
my ($ip, $quiet) = @_;
|
||||
my ($host) = "";
|
||||
|
||||
unless ($g_dns_resolveip)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
eval
|
||||
{
|
||||
$SIG{ALRM} = sub { die "DNS Timeout\n" };
|
||||
alarm $g_dns_timeout; # timeout after $g_dns_timeout sec
|
||||
$host = gethostbyaddr(inet_aton($ip), AF_INET);
|
||||
alarm 0;
|
||||
};
|
||||
|
||||
if ($@)
|
||||
{
|
||||
my $error = $@;
|
||||
chomp($error);
|
||||
printEvent("DNS", "Resolving hostname (timeout $g_dns_timeout sec) for IP \"$ip\" - $error ", 1);
|
||||
$host = ""; # some error occurred
|
||||
}
|
||||
elsif (!defined($host))
|
||||
{
|
||||
printEvent("DNS", "Resolving hostname (timeout $g_dns_timeout sec) for IP \"$ip\" - No Host ", 1);
|
||||
$host = ""; # ip did not resolve to any host
|
||||
} else {
|
||||
$host = lc($host); # lowercase
|
||||
printEvent("DNS", "Resolving hostname (timeout $g_dns_timeout sec) for IP \"$ip\" - $host ", 1);
|
||||
}
|
||||
chomp($host);
|
||||
return $host;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# object queryHostGroups ()
|
||||
#
|
||||
# Returns result identifier.
|
||||
#
|
||||
|
||||
sub queryHostGroups
|
||||
{
|
||||
return &doQuery("
|
||||
SELECT
|
||||
pattern,
|
||||
name,
|
||||
LENGTH(pattern) AS patternlength
|
||||
FROM
|
||||
hlstats_HostGroups
|
||||
ORDER BY
|
||||
patternlength DESC,
|
||||
pattern ASC
|
||||
");
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# string getHostGroup (string hostname[, object result])
|
||||
#
|
||||
# Return host group name if any match, or last 2 or 3 parts of hostname.
|
||||
#
|
||||
|
||||
sub getHostGroup
|
||||
{
|
||||
my ($hostname, $result) = @_;
|
||||
my $hostgroup = "";
|
||||
|
||||
# User can define special named hostgroups in hlstats_HostGroups, i.e.
|
||||
# '.adsl.someisp.net' => 'SomeISP ADSL'
|
||||
|
||||
$result = &queryHostGroups() unless ($result);
|
||||
$result->execute();
|
||||
|
||||
while (my($pattern, $name) = $result->fetchrow_array())
|
||||
{
|
||||
$pattern = quotemeta($pattern);
|
||||
$pattern =~ s/\\\*/[^.]*/g; # allow basic shell-style globbing in pattern
|
||||
if ($hostname =~ /$pattern$/)
|
||||
{
|
||||
$hostgroup = $name;
|
||||
last;
|
||||
}
|
||||
}
|
||||
$result->finish;
|
||||
|
||||
if (!$hostgroup)
|
||||
{
|
||||
#
|
||||
# Group by last 2 or 3 parts of hostname, i.e. 'max1.xyz.someisp.net' as
|
||||
# 'someisp.net', and 'max1.xyz.someisp.net.nz' as 'someisp.net.nz'.
|
||||
# Unfortunately some countries do not have categorical SLDs, so this
|
||||
# becomes more complicated. The dom_nosld array below contains a list of
|
||||
# known country codes that do not use categorical second level domains.
|
||||
# If a country uses SLDs and is not listed below, then it will be
|
||||
# incorrectly grouped, i.e. 'max1.xyz.someisp.yz' will become
|
||||
# 'xyz.someisp.yz', instead of just 'someisp.yz'.
|
||||
#
|
||||
# Please mail sgarner@hlstats.org with any additions.
|
||||
#
|
||||
|
||||
my @dom_nosld = (
|
||||
"ca", # Canada
|
||||
"ch", # Switzerland
|
||||
"be", # Belgium
|
||||
"de", # Germany
|
||||
"ee", # Estonia
|
||||
"es", # Spain
|
||||
"fi", # Finland
|
||||
"fr", # France
|
||||
"ie", # Ireland
|
||||
"nl", # Netherlands
|
||||
"no", # Norway
|
||||
"ru", # Russia
|
||||
"se", # Sweden
|
||||
);
|
||||
|
||||
my $dom_nosld = join("|", @dom_nosld);
|
||||
|
||||
if ($hostname =~ /([\w-]+\.(?:$dom_nosld|\w\w\w))$/)
|
||||
{
|
||||
$hostgroup = $1;
|
||||
}
|
||||
elsif ($hostname =~ /([\w-]+\.[\w-]+\.\w\w)$/)
|
||||
{
|
||||
$hostgroup = $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$hostgroup = $hostname;
|
||||
}
|
||||
}
|
||||
|
||||
return $hostgroup;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# void doConf (object conf, hash directives)
|
||||
#
|
||||
# Walk through configuration directives, setting values of global variables.
|
||||
#
|
||||
|
||||
sub doConf
|
||||
{
|
||||
my ($conf, %directives) = @_;
|
||||
|
||||
while (($directive, $variable) = each(%directives))
|
||||
{
|
||||
if ($directive eq "Servers") {
|
||||
%$variable = $conf->get($directive);
|
||||
} else {
|
||||
$$variable = $conf->get($directive);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# void setOptionsConf (hash optionsconf)
|
||||
#
|
||||
# Walk through configuration directives, setting values of global variables.
|
||||
#
|
||||
|
||||
sub setOptionsConf
|
||||
{
|
||||
my (%optionsconf) = @_;
|
||||
|
||||
while (($thekey, $theval) = each(%optionsconf))
|
||||
{
|
||||
if($theval)
|
||||
{
|
||||
$$thekey = $theval;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# string abbreviate (string thestring[, int maxlength)
|
||||
#
|
||||
# Returns thestring abbreviated to maxlength-3 characters plus "...", unless
|
||||
# thestring is shorter than maxlength.
|
||||
#
|
||||
|
||||
sub abbreviate
|
||||
{
|
||||
my ($thestring, $maxlength) = @_;
|
||||
|
||||
$maxlength = 12 unless ($maxlength);
|
||||
|
||||
if (length($thestring) > $maxlength)
|
||||
{
|
||||
$thestring = substr($thestring, 0, $maxlength - 3);
|
||||
return "$thestring...";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $thestring;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# void printEvent (int code, string description)
|
||||
#
|
||||
# Logs event information to stdout.
|
||||
#
|
||||
|
||||
sub printEvent
|
||||
{
|
||||
my ($code, $description, $update_timestamp, $force_output) = @_;
|
||||
if ( (($g_debug > 0) && ($g_stdin == 0))|| (($g_stdin == 1) && ($force_output == 1)) ) {
|
||||
my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time());
|
||||
my $timestamp = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
|
||||
if ($update_timestamp == 0) {
|
||||
$timestamp = $ev_timestamp;
|
||||
}
|
||||
if (is_number($code)) {
|
||||
printf("%s: %21s - E%03d: %s\n", $timestamp, $s_addr, $code, $description);
|
||||
} else {
|
||||
printf("%s: %21s - %s: %s\n", $timestamp, $s_addr, $code, $description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
3096
scripts/HLstats_EventHandlers.plib
Normal file
3096
scripts/HLstats_EventHandlers.plib
Normal file
File diff suppressed because it is too large
Load Diff
104
scripts/HLstats_Game.pm
Normal file
104
scripts/HLstats_Game.pm
Normal file
@ -0,0 +1,104 @@
|
||||
package HLstats_Game;
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
#
|
||||
# Constructor
|
||||
#
|
||||
|
||||
sub new
|
||||
{
|
||||
my $class_name = shift;
|
||||
my $game = shift;
|
||||
|
||||
my $self = {};
|
||||
bless($self, $class_name);
|
||||
|
||||
# Initialise Properties
|
||||
$self->{game} = $game;
|
||||
$self->{weapons} = ();
|
||||
$self->{actions} = ();
|
||||
|
||||
# Set Property Values
|
||||
|
||||
die("HLstats_Game->new(): must specify game's game code\n") if ($game eq "");
|
||||
#&::printEvent("DEBUG","game is $game");
|
||||
my $weaponlist = &::doQuery("SELECT code, name, modifier FROM hlstats_Weapons WHERE game='".&::quoteSQL($game)."'");
|
||||
while ( my($code,$name,$modifier) = $weaponlist->fetchrow_array) {
|
||||
$self->{weapons}{$code}{name} = $name;
|
||||
$self->{weapons}{$code}{modifier} = $modifier;
|
||||
#&::printEvent("DEBUG","Weapon: name is \"$name\"; modifier is $modifier");
|
||||
}
|
||||
|
||||
my $actionlist = &::doQuery("SELECT id, code, reward_player, reward_team, team, description, for_PlayerActions, for_PlayerPlayerActions, for_TeamActions, for_WorldActions FROM hlstats_Actions WHERE game='".&::quoteSQL($game)."'");
|
||||
while ( my($id, $code, $reward_player,$reward_team,$team, $descr, $paction, $ppaction, $taction, $waction) = $actionlist->fetchrow_array) {
|
||||
$self->{actions}{$code}{id} = $id;
|
||||
$self->{actions}{$code}{descr} = $descr;
|
||||
$self->{actions}{$code}{reward_player} = $reward_player;
|
||||
$self->{actions}{$code}{reward_team} = $reward_team;
|
||||
$self->{actions}{$code}{team} = $team;
|
||||
$self->{actions}{$code}{paction} = $paction;
|
||||
$self->{actions}{$code}{ppaction} = $ppaction;
|
||||
$self->{actions}{$code}{taction} = $taction;
|
||||
$self->{actions}{$code}{waction} = $waction;
|
||||
}
|
||||
$actionlist->finish;
|
||||
|
||||
&::printNotice("Created new game object " . $game);
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub getTotalPlayers
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
my $query = "
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
hlstats_Players
|
||||
WHERE
|
||||
game=?
|
||||
AND hideranking = 0
|
||||
AND kills >= 1
|
||||
";
|
||||
my $resultTotalPlayers = &::execCached("get_game_total_players", $query, &::quoteSQL($self->{game}));
|
||||
my ($totalplayers) = $resultTotalPlayers->fetchrow_array;
|
||||
$resultTotalPlayers->finish;
|
||||
|
||||
return $totalplayers;
|
||||
}
|
||||
|
||||
1;
|
56
scripts/HLstats_GameConstants.plib
Normal file
56
scripts/HLstats_GameConstants.plib
Normal file
@ -0,0 +1,56 @@
|
||||
use constant {
|
||||
UNKNOWN => -1,
|
||||
CSS => 0,
|
||||
HL2MP => 1,
|
||||
TF => 2,
|
||||
DODS => 3,
|
||||
INSMOD => 4,
|
||||
FF => 5,
|
||||
HIDDEN => 6,
|
||||
ZPS => 7,
|
||||
AOC => 8,
|
||||
CSTRIKE => 9,
|
||||
TFC => 10,
|
||||
DOD => 11,
|
||||
NS => 12,
|
||||
L4D => 13,
|
||||
FOF => 14,
|
||||
GES => 15,
|
||||
BG2 => 16,
|
||||
SGTLS => 17,
|
||||
DYSTOPIA => 18,
|
||||
NTS => 19,
|
||||
PVKII => 20,
|
||||
CSP => 21,
|
||||
VALVE => 22,
|
||||
NUCLEARDAWN => 23,
|
||||
DDD => 24,
|
||||
};
|
||||
|
||||
%gamecode_to_game = (
|
||||
'css' => CSS(),
|
||||
'hl2mp' => HL2MP(),
|
||||
'tf' => TF(),
|
||||
'dods' => DODS(),
|
||||
'insmod' => INSMOD(),
|
||||
'ff' => FF(),
|
||||
'hidden' => HIDDEN(),
|
||||
'zps' => ZPS(),
|
||||
'aoc' => AOC(),
|
||||
'cstrike' => CSTRIKE(),
|
||||
'tfc' => TFC(),
|
||||
'dod' => DOD(),
|
||||
'ns' => NS(),
|
||||
'l4d' => L4D(),
|
||||
'fof' => FOF(),
|
||||
'ges' => GES(),
|
||||
'bg2' => BG2(),
|
||||
'sgtls' => SGTLS(),
|
||||
'dystopia' => DYSTOPIA(),
|
||||
'nts' => NTS(),
|
||||
'pvkii' => PVKII(),
|
||||
'csp' => CSP(),
|
||||
'valve' => VALVE(),
|
||||
'nucleardawn' => NUCLEARDAWN(),
|
||||
'dinodday' => DDD()
|
||||
);
|
1124
scripts/HLstats_Player.pm
Normal file
1124
scripts/HLstats_Player.pm
Normal file
File diff suppressed because it is too large
Load Diff
1414
scripts/HLstats_Server.pm
Normal file
1414
scripts/HLstats_Server.pm
Normal file
File diff suppressed because it is too large
Load Diff
55
scripts/ImportBans/README
Normal file
55
scripts/ImportBans/README
Normal file
@ -0,0 +1,55 @@
|
||||
HLStatsX:CE Import Ban Options
|
||||
----------------------
|
||||
Description:
|
||||
HLStatsX:CE has two different scripts to use to import bans from your banning system:
|
||||
|
||||
1) ImportBans
|
||||
ImportBans.pl is a perl script and is the original importing script.
|
||||
It only imports bans and does not unban a player if they're unbanned from your ban system.
|
||||
This script supports SourceBans, AMXBans, BeetleMod, and GlobalBan.
|
||||
You must have perl installed to use this script.
|
||||
|
||||
2) hlstatsxbans
|
||||
Hlstatsxbans is written by Peace-Maker and is written in PHP.
|
||||
This script will ban AND UNBAN players as they are banned from your banning system.
|
||||
Forum URL: http://forums.interwavestudios.com/topic/167-import-mysql-bans-to-hlxce-bancheater-page/
|
||||
This script suports SourceBans, AMXBans, BeetleMod, and GlobalBan.
|
||||
You must have PHP installed to use this script.
|
||||
|
||||
Configuration:
|
||||
Select which ban system you want to use, either ImportBans or HLStatsXBans. You must then edit the corresponding file.
|
||||
|
||||
*run_importbans
|
||||
** Open run_importbans in a text editor
|
||||
** Configure "BANSYSTEM" for which script you would like to use.
|
||||
|
||||
*ImportBans
|
||||
** Open ImportBans.pl in a text editor.
|
||||
** Fill in the HLX DB INFO section (should be same as that found in hlstats.conf in the Perl directory)
|
||||
** Fill in at least one of the other databases (Sourcebans, AMXBans, BeetlesMod) that you want to import from.
|
||||
|
||||
NOTE: You can use any of these databases simultaneously -- fill in the ones you want
|
||||
to pull from and those databases will be queried.
|
||||
|
||||
*HLStatsXBans
|
||||
** Open HLStatsXBans.cfg in a text editor.
|
||||
** Fill in the database info for HLX.
|
||||
** Fill in at least one of the other databases that you want to import from.
|
||||
|
||||
Running:
|
||||
You should run the script manually one time to make sure everything is working.
|
||||
To run ImportBans, run:
|
||||
|
||||
./importbans.pl
|
||||
|
||||
To run HLStatsXBans, run:
|
||||
|
||||
php hlstatsxbans.php
|
||||
|
||||
If everything works, you can either schedule the exact same command you just executed to run at a configured interval or time,
|
||||
or use the run_importbans wrapper to get logging (great for console use).
|
||||
To use run_importbans, make sure you have edited the file for which script you want to use, and then simply execute:
|
||||
|
||||
./run_importbans.
|
||||
|
||||
Note: you will not get any output from this script. Everything is written into your logs/ directory.
|
105
scripts/ImportBans/hlstatsxban.cfg
Normal file
105
scripts/ImportBans/hlstatsxban.cfg
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/***************
|
||||
** Deactivate HLstatsX ranking for banned players
|
||||
** and reactivate them if unbanned
|
||||
** Supports SourceBans, AMXBans, Beetlesmod, Globalban, MySQL Banning*
|
||||
** by Jannik 'Peace-Maker' Hartung
|
||||
** http://www.sourcebans.net/, http://www.wcfan.de/
|
||||
|
||||
** This program is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU General Public License
|
||||
** as published by the Free Software Foundation; either version 2
|
||||
** of the License, or (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
**
|
||||
**
|
||||
** Version 1.3: Added MySQL Banning support
|
||||
** Version 1.2: Added more error handling
|
||||
** Version 1.1: Fixed banned players not marked as banned, if a previous ban was unbanned
|
||||
** Version 1.0: Initial Release
|
||||
|
||||
|
||||
** YOU MUST ADJUST THIS FILE TO MEET YOUR NEEDS!
|
||||
** Please fill in AT LEAST one bans database AND
|
||||
** the HLStatsX Database section! Don't forget the names
|
||||
** of the HLStatsX Databases near the end of this file!
|
||||
**************/
|
||||
|
||||
//** SOURCEBANS MYSQL INFO ----------------------------
|
||||
// http://www.sourcebans.net/
|
||||
define('SB_HOST', 'localhost'); // MySQL host
|
||||
define('SB_PORT', 3306); // MySQL port (Default 3306)
|
||||
define('SB_USER', ''); // MySQL user
|
||||
define('SB_PASS', ''); // MySQL password
|
||||
define('SB_NAME', ''); // MySQL database name
|
||||
define('SB_PREFIX', 'sb'); // MySQL table prefix
|
||||
//** END SOURCEBANS MYSQL INFO ------------------------
|
||||
|
||||
//** AMXBANS MYSQL INFO -------------------------------
|
||||
// http://www.amxbans.net/
|
||||
define('AMX_HOST', 'localhost'); // MySQL host
|
||||
define('AMX_PORT', 3306); // MySQL port (Default 3306)
|
||||
define('AMX_USER', ''); // MySQL user
|
||||
define('AMX_PASS', ''); // MySQL password
|
||||
define('AMX_NAME', ''); // MySQL database name
|
||||
define('AMX_PREFIX', 'amx'); // MySQL table prefix
|
||||
//** END AMXBANS MYSQL INFO ---------------------------
|
||||
|
||||
//** BEETLESMOD MYSQL INFO ----------------------------
|
||||
// http://www.beetlesmod.com/
|
||||
define('BM_HOST', 'localhost'); // MySQL host
|
||||
define('BM_PORT', 3306); // MySQL port (Default 3306)
|
||||
define('BM_USER', ''); // MySQL user
|
||||
define('BM_PASS', ''); // MySQL password
|
||||
define('BM_NAME', ''); // MySQL database name
|
||||
define('BM_PREFIX', 'bm'); // MySQL table prefix
|
||||
//** END BEETLESMOD MYSQL INFO ------------------------
|
||||
|
||||
//** GLOBALBAN MYSQL INFO -----------------------------
|
||||
// http://addons.eventscripts.com/addons/view/GlobalBan
|
||||
// http://forums.eventscripts.com/viewtopic.php?t=14384
|
||||
define('GB_HOST', 'localhost'); // MySQL host
|
||||
define('GB_PORT', 3306); // MySQL port (Default 3306)
|
||||
define('GB_USER', ''); // MySQL user
|
||||
define('GB_PASS', ''); // MySQL password
|
||||
define('GB_NAME', 'global_ban'); // MySQL database name
|
||||
define('GB_PREFIX', 'gban'); // MySQL table prefix
|
||||
//** END GLOBALBAN MYSQL INFO -------------------------
|
||||
|
||||
//** MySQL Banning - MYSQL INFO -----------------------
|
||||
// http://forums.alliedmods.net/showthread.php?t=65822
|
||||
define('MB_HOST', 'localhost'); // MySQL host
|
||||
define('MB_PORT', 3306); // MySQL port (Default 3306)
|
||||
define('MB_USER', ''); // MySQL user
|
||||
define('MB_PASS', ''); // MySQL password
|
||||
define('MB_NAME', ''); // MySQL database name
|
||||
define('MB_PREFIX', 'mysql'); // MySQL table prefix
|
||||
//** END MySQL Banning - MYSQL INFO -------------------
|
||||
|
||||
//** HLSTATSX MYSQL INFO ------------------------------
|
||||
// http://www.hlxcommunity.com/
|
||||
define('HLX_HOST', 'localhost'); // MySQL host
|
||||
define('HLX_PORT', 3306); // MySQL port (Default 3306)
|
||||
define('HLX_USER', ''); // MySQL user
|
||||
define('HLX_PASS', ''); // MySQL password
|
||||
define('HLX_PREFIX', 'hlstats'); // MySQL table prefix
|
||||
|
||||
/*************************************************
|
||||
/* We're using different databases for each of our server to isolate each ranking
|
||||
/* Type the HLstatsX database name here like
|
||||
/* $hlxdbs[] = "databasename";
|
||||
/* It's fine to just type one database.
|
||||
**************************************************/
|
||||
$hlxdbs = array();
|
||||
$hlxdbs[] = "hlstatsx";
|
||||
//** END HLSTATSX MYSQL INFO --------------------------
|
||||
|
||||
?>
|
362
scripts/ImportBans/hlstatsxban.php
Normal file
362
scripts/ImportBans/hlstatsxban.php
Normal file
@ -0,0 +1,362 @@
|
||||
<?php
|
||||
/***************
|
||||
** Deactivate HLstatsX ranking for banned players
|
||||
** and reactivate them if unbanned
|
||||
** Supports SourceBans, AMXBans, Beetlesmod, Globalban, MySQL Banning*
|
||||
** by Jannik 'Peace-Maker' Hartung
|
||||
** http://www.sourcebans.net/, http://www.wcfan.de/
|
||||
|
||||
** This program is free software; you can redistribute it and/or
|
||||
** modify it under the terms of the GNU General Public License
|
||||
** as published by the Free Software Foundation; either version 2
|
||||
** of the License, or (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
**
|
||||
**
|
||||
** Version 1.3: Added MySQL Banning support
|
||||
** Version 1.2: Added more error handling
|
||||
** Version 1.1: Fixed banned players not marked as banned, if a previous ban was unbanned
|
||||
** Version 1.0: Initial Release
|
||||
***************/
|
||||
|
||||
/*****************************
|
||||
/***MAKE YOUR CONFIGURATION***
|
||||
/********SETTINGS IN**********
|
||||
/******hlstatsxban.cfg********
|
||||
/***** DON'T EDIT BELOW ******
|
||||
/*****************************/
|
||||
|
||||
require("hlstatsxban.cfg");
|
||||
|
||||
if (!extension_loaded('mysqli')) {
|
||||
die("This script requires the MySQLi extension to be enabled. Consult your administrator, or edit your php.ini file, to enable this extension.");
|
||||
}
|
||||
|
||||
$usesb = (SB_HOST == ""||SB_PORT == ""||SB_USER == ""||SB_PASS == ""||SB_NAME == ""||SB_PREFIX == ""?false:true);
|
||||
$useamx = (AMX_HOST == ""||AMX_PORT == ""||AMX_USER == ""||AMX_PASS == ""||AMX_NAME == ""||AMX_PREFIX == ""?false:true);
|
||||
$usebm = (BM_HOST == ""||BM_PORT == ""||BM_USER == ""||BM_PASS == ""||BM_NAME == ""||BM_PREFIX == ""?false:true);
|
||||
$usegb = (GB_HOST == ""||GB_PORT == ""||GB_USER == ""||GB_PASS == ""||GB_NAME == ""||GB_PREFIX == ""?false:true);
|
||||
$usemb = (MB_HOST == ""||MB_PORT == ""||MB_USER == ""||MB_PASS == ""||MB_NAME == ""||MB_PREFIX == ""?false:true);
|
||||
$hlxready = (HLX_HOST == ""||HLX_PORT == ""||HLX_USER == ""||HLX_PASS == ""||empty($hlxdbs)||HLX_PREFIX == ""?false:true);
|
||||
|
||||
if (!$hlxready || (!$usesb && !$useamx && !$usebm && !$usegb && !$usemb))
|
||||
die('[-] Please type your database information for HLstatsX and at least for one other ban database.');
|
||||
|
||||
$bannedplayers = array();
|
||||
$unbannedplayers = array();
|
||||
|
||||
//------------------------------
|
||||
// SourceBans Part
|
||||
//------------------------------
|
||||
if ($usesb)
|
||||
{
|
||||
// Connect to the SourceBans database.
|
||||
$con = new mysqli(SB_HOST, SB_USER, SB_PASS, SB_NAME, SB_PORT);
|
||||
if (mysqli_connect_error()) die('[-] Can\'t connect to SourceBans Database (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
|
||||
|
||||
print("[+] Successfully connected to SourceBans database. Retrieving bans now.\n");
|
||||
|
||||
// Get permanent banned players
|
||||
$bcnt = 0;
|
||||
if ($bans = $con->query("SELECT `authid` FROM `".SB_PREFIX."_bans` WHERE `RemoveType` IS NULL AND `length` = 0")) {
|
||||
while ($banned = $bans->fetch_array(MYSQL_ASSOC)) {
|
||||
if(!in_array($banned["authid"], $bannedplayers)) {
|
||||
$bannedplayers[] = $banned["authid"];
|
||||
++$bcnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
die('[-] Error retrieving banned players: ' . $con->error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Read unbanned players
|
||||
$ubcnt = 0;
|
||||
if ($unbans = $con->query("SELECT `authid` FROM `".SB_PREFIX."_bans` WHERE `RemoveType` IS NOT NULL AND `RemovedOn` IS NOT NULL")) {
|
||||
while ($unbanned = $unbans->fetch_array(MYSQL_ASSOC)) {
|
||||
if(!in_array($unbanned["authid"], $bannedplayers) && !in_array($unbanned["authid"], $unbannedplayers)) {
|
||||
$unbannedplayers[] = $unbanned["authid"];
|
||||
++$ubcnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
die('[-] Error retrieving unbanned players: ' . $con->error);
|
||||
}
|
||||
|
||||
$con->close();
|
||||
print("[+] Retrieved ".$bcnt." banned and ".$ubcnt." unbanned players from SourceBans.\n");
|
||||
}
|
||||
|
||||
//------------------------------
|
||||
// AMXBans Part
|
||||
//------------------------------
|
||||
if ($useamx)
|
||||
{
|
||||
// Connect to the AMXBans database.
|
||||
$con = new mysqli(AMX_HOST, AMX_USER, AMX_PASS, AMX_NAME, AMX_PORT);
|
||||
if (mysqli_connect_error()) die('[-] Can\'t connect to AMXBans Database (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
|
||||
|
||||
print("[+] Successfully connected to AMXBans database. Retrieving bans now.\n");
|
||||
|
||||
// Get permanent banned players
|
||||
$bcnt = 0;
|
||||
if ($bans = $con->query("SELECT `player_id` FROM `".AMX_PREFIX."_bans` WHERE `ban_length` = 0")) {
|
||||
while ($banned = $bans->fetch_array(MYSQL_ASSOC)) {
|
||||
if(!in_array($banned["player_id"], $bannedplayers))
|
||||
{
|
||||
$bannedplayers[] = $banned["player_id"];
|
||||
++$bcnt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('[-] Error retrieving banned players: ' . $con->error);
|
||||
}
|
||||
|
||||
|
||||
// Read unbanned players
|
||||
$ubcnt = 0;
|
||||
// Handles (apparently) pre-6.0 version DB or lower
|
||||
if ($unbans = $con->query("SELECT `player_id` FROM `".AMX_PREFIX."_banhistory` WHERE `ban_length` = 0")) {
|
||||
while ($unbanned = $unbans->fetch_array(MYSQL_ASSOC)) {
|
||||
if(!in_array($unbanned["player_id"], $bannedplayers) && !in_array($unbanned["player_id"], $unbannedplayers))
|
||||
{
|
||||
$unbannedplayers[] = $unbanned["player_id"];
|
||||
++$ubcnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handles (apparently) 6.0 version DB or higher
|
||||
else if ($unbans = $con->query("SELECT `player_id` FROM `".AMX_PREFIX."_bans` WHERE `expired` = 1")) {
|
||||
while ($unbanned = $unbans->fetch_array(MYSQL_ASSOC)) {
|
||||
if(!in_array($unbanned["player_id"], $bannedplayers) && !in_array($unbanned["player_id"], $unbannedplayers))
|
||||
{
|
||||
$unbannedplayers[] = $unbanned["player_id"];
|
||||
++$ubcnt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('[-] Error retrieving unbanned players: ' . $con->error);
|
||||
}
|
||||
|
||||
|
||||
$con->close();
|
||||
print("[+] Retrieved ".$bcnt." banned and ".$ubcnt." unbanned players from AMXBans.\n");
|
||||
}
|
||||
|
||||
//------------------------------
|
||||
// Beetlesmod Part
|
||||
//------------------------------
|
||||
if ($usebm)
|
||||
{
|
||||
// Connect to the Beetlesmod database.
|
||||
$con = new mysqli(BM_HOST, BM_USER, BM_PASS, BM_NAME, BM_PORT);
|
||||
if (mysqli_connect_error()) die('[-] Can\'t connect to Beetlesmod Database (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
|
||||
|
||||
print("[+] Successfully connected to Beetlesmod database. Retrieving bans now.\n");
|
||||
|
||||
// Get permanent banned players
|
||||
$bcnt = 0;
|
||||
if ($bans = $con->query("SELECT `steamid` FROM `".BM_PREFIX."_bans` WHERE `Until` IS NULL")) {
|
||||
while ($banned = $bans->fetch_array(MYSQL_ASSOC)) {
|
||||
if(!in_array($banned["steamid"], $bannedplayers))
|
||||
{
|
||||
$bannedplayers[] = $banned["steamid"];
|
||||
++$bcnt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('[-] Error retrieving banned players: ' . $con->error);
|
||||
}
|
||||
|
||||
|
||||
// Read unbanned players
|
||||
$ubcnt = 0;
|
||||
if ($unbans = $con->query("SELECT `steamid` FROM `".BM_PREFIX."_bans` WHERE `Until` IS NULL AND `Remove` = 0")) {
|
||||
while ($unbanned = $unbans->fetch_array(MYSQL_ASSOC)) {
|
||||
if(!in_array($unbanned["steamid"], $bannedplayers) && !in_array($unbanned["steamid"], $unbannedplayers))
|
||||
{
|
||||
$unbannedplayers[] = $unbanned["steamid"];
|
||||
++$ubcnt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('[-] Error retrieving unbanned players: ' . $con->error);
|
||||
}
|
||||
|
||||
|
||||
$con->close();
|
||||
print("[+] Retrieved ".$bcnt." banned and ".$ubcnt." unbanned players from Beetlesmod.\n");
|
||||
}
|
||||
|
||||
//------------------------------
|
||||
// Globalban Part
|
||||
//------------------------------
|
||||
if ($usegb)
|
||||
{
|
||||
// Connect to the Globalban database.
|
||||
$con = new mysqli(GB_HOST, GB_USER, GB_PASS, GB_NAME, GB_PORT);
|
||||
if (mysqli_connect_error()) die('[-] Can\'t connect to Globalban Database (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
|
||||
|
||||
print("[+] Successfully connected to Globalban database. Retrieving bans now.\n");
|
||||
|
||||
// Get permanent banned players
|
||||
$bcnt = 0;
|
||||
if ($bans = $con->query("SELECT `steam_id` FROM `".GB_PREFIX."_ban` WHERE `active` = 1 AND `pending` = 0 AND `length` = 0")) {
|
||||
while ($banned = $bans->fetch_array(MYSQL_ASSOC)) {
|
||||
if(!in_array($banned["steam_id"], $bannedplayers))
|
||||
{
|
||||
$bannedplayers[] = $banned["steam_id"];
|
||||
++$bcnt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('[-] Error retrieving banned players: ' . $con->error);
|
||||
}
|
||||
|
||||
|
||||
// Read unbanned players
|
||||
$ubcnt = 0;
|
||||
if ($unbans = $con->query("SELECT `steam_id` FROM `".GB_PREFIX."_ban` WHERE `active` = 0 AND `pending` = 0 AND `length` = 0")) {
|
||||
while ($unbanned = $unbans->fetch_array(MYSQL_ASSOC)) {
|
||||
if(!in_array($unbanned["steam_id"], $bannedplayers) && !in_array($unbanned["steam_id"], $unbannedplayers))
|
||||
{
|
||||
$unbannedplayers[] = $unbanned["steam_id"];
|
||||
++$ubcnt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('[-] Error retrieving unbanned players: ' . $con->error);
|
||||
}
|
||||
|
||||
|
||||
$con->close();
|
||||
print("[+] Retrieved ".$bcnt." banned and ".$ubcnt." unbanned players from Globalban.\n");
|
||||
}
|
||||
|
||||
//------------------------------
|
||||
// MySQL Banning Part
|
||||
//------------------------------
|
||||
if ($usemb)
|
||||
{
|
||||
// Connect to the MySQL Banning database.
|
||||
$con = new mysqli(MB_HOST, MB_USER, MB_PASS, MB_NAME, MB_PORT);
|
||||
if (mysqli_connect_error()) die('[-] Can\'t connect to MySQL Banning Database (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
|
||||
|
||||
print("[+] Successfully connected to MySQL Banning database. Retrieving bans now.\n");
|
||||
|
||||
// Get permanent banned players
|
||||
$bcnt = 0;
|
||||
if ($bans = $con->query("SELECT `steam_id` FROM `".MB_PREFIX."_bans` WHERE `ban_length` = 0")) {
|
||||
while ($banned = $bans->fetch_array(MYSQL_ASSOC)) {
|
||||
if(!in_array($banned["steam_id"], $bannedplayers))
|
||||
{
|
||||
$bannedplayers[] = $banned["steam_id"];
|
||||
++$bcnt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('[-] Error retrieving banned players: ' . $con->error);
|
||||
}
|
||||
|
||||
|
||||
/****** SM MySQL Banning doesn't provide a ban history AFAIK ******/
|
||||
|
||||
// Read unbanned players
|
||||
// $ubcnt = 0;
|
||||
// if ($unbans = $con->query("SELECT `steam_id` FROM `".MB_PREFIX."_bans` WHERE `ban_length` = 0")) {
|
||||
// while ($unbanned = $unbans->fetch_array(MYSQL_ASSOC)) {
|
||||
// if(!in_array($unbanned["steam_id"], $bannedplayers) && !in_array($unbanned["steam_id"], $unbannedplayers))
|
||||
// {
|
||||
// $unbannedplayers[] = $unbanned["steam_id"];
|
||||
// ++$ubcnt;
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// die('[-] Error retrieving unbanned players: ' . $con->error);
|
||||
//}
|
||||
|
||||
$con->close();
|
||||
//print("[+] Retrieved ".$bcnt." banned and ".$ubcnt." unbanned players from MySQL Banning.\n");
|
||||
print("[+] Retrieved ".$bcnt." banned players from MySQL Banning.\n");
|
||||
}
|
||||
|
||||
//------------------------------
|
||||
// HLstatsX Part
|
||||
//------------------------------
|
||||
|
||||
if(empty($bannedplayers) && empty($unbannedplayers))
|
||||
die('[-] Nothing to change. Exiting.');
|
||||
|
||||
$bannedsteamids="''";
|
||||
$unbannedsteamids="''";
|
||||
|
||||
if(!empty($bannedplayers))
|
||||
{
|
||||
$bannedsteamids = "'";
|
||||
foreach ($bannedplayers as $steamid)
|
||||
{
|
||||
$steamid = preg_replace('/^STEAM_[0-9]+?\:/i','',$steamid);
|
||||
$bannedsteamids .= $steamid."','";
|
||||
}
|
||||
$bannedsteamids .= preg_replace('/\,\'$/','',$steamid);
|
||||
$bannedsteamids .= "'";
|
||||
}
|
||||
|
||||
if(!empty($unbannedplayers))
|
||||
{
|
||||
$unbannedsteamids = "'";
|
||||
foreach ($unbannedplayers as $steamid)
|
||||
{
|
||||
$steamid = preg_replace('/^STEAM_[0-9]+?\:/i','',$steamid);
|
||||
$unbannedsteamids .= $steamid."','";
|
||||
}
|
||||
$unbannedsteamids .= preg_replace('/\,\'$/','',$steamid);
|
||||
$unbannedsteamids .= "'";
|
||||
}
|
||||
|
||||
// Connection to DB
|
||||
$hlxcon = new mysqli(HLX_HOST, HLX_USER, HLX_PASS, '', HLX_PORT);
|
||||
if (mysqli_connect_error()) die('[-] Can\'t connect to HLstatsX Database (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
|
||||
|
||||
print("[+] Successfully connected to HLstatsX database server. Updating players...\n");
|
||||
// Loop through all hlstatsx databases
|
||||
foreach ($hlxdbs as $hlxdb)
|
||||
{
|
||||
$unbancnt = $bancnt = 0;
|
||||
$hlxcon->select_db($hlxdb);
|
||||
// Hide all banned players
|
||||
if ($hlxban = $hlxcon->query("UPDATE `".HLX_PREFIX."_Players` SET `hideranking` = 2 WHERE `hideranking` < 2 AND `playerId` IN (SELECT `playerId` FROM `".HLX_PREFIX."_PlayerUniqueIds` WHERE `uniqueId` IN (".$bannedsteamids."));")) {
|
||||
$bancnt = ($hlxcon->affected_rows?$hlxcon->affected_rows:0);
|
||||
}
|
||||
else {
|
||||
die('[-] Error hiding banned players: ' . $hlxcon->error);
|
||||
}
|
||||
|
||||
// Show all unbanned players
|
||||
if ($hlxunban = $hlxcon->query("UPDATE `".HLX_PREFIX."_Players` SET `hideranking` = 0 WHERE `hideranking` = 2 AND `playerId` IN (SELECT `playerId` FROM `".HLX_PREFIX."_PlayerUniqueIds` WHERE `uniqueId` IN (".$unbannedsteamids."));")) {
|
||||
$unbancnt = ($hlxcon->affected_rows?$hlxcon->affected_rows:0);
|
||||
|
||||
if ($bancnt>0||$unbancnt>0) {
|
||||
print("[+] ".$hlxdb.": ".$bancnt." players were marked as banned, ".$unbancnt." players were reenabled again.\n");
|
||||
}
|
||||
else {
|
||||
print("[-] ".$hlxdb.": No player changed.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
die('[-] Error showing unbanned players: ' . $hlxcon->error);
|
||||
}
|
||||
}
|
||||
$hlxcon->close();
|
||||
?>
|
194
scripts/ImportBans/importbans.pl
Normal file
194
scripts/ImportBans/importbans.pl
Normal file
@ -0,0 +1,194 @@
|
||||
#!/usr/bin/perl
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
####
|
||||
# Script to mark banned users in HLstatsX Community Edition from a Sourcebans, AMXBans, Beetlesmod, or ES GlobalBan database (or multiple at once!)
|
||||
# Last Revised: 2009-07-22 13:35 GMT
|
||||
# BeetlesMod and GlobalBan support added by Bo Tribun (R3M)
|
||||
|
||||
#######################################################################################
|
||||
# You must fill info out for the HLX DB and at least one of the Bans databases
|
||||
#######################################################################################
|
||||
# Sourcebans DB Info
|
||||
$sb_dbhost = "localhost";
|
||||
$sb_dbport = 3306;
|
||||
$sb_dbuser = "";
|
||||
$sb_dbpass = "";
|
||||
$sb_dbname = "";
|
||||
$sb_prefix = "sb_"; # be sure to include the underscore (_)
|
||||
|
||||
# AMXBans DB Info
|
||||
$amxb_dbhost = "localhost";
|
||||
$amxb_dbport = 3306;
|
||||
$amxb_dbuser = "";
|
||||
$amxb_dbpass = "";
|
||||
$amxb_dbname = "";
|
||||
|
||||
# BeetlesMod DB Info
|
||||
$bm_dbhost = "localhost";
|
||||
$bm_dbport = 3306;
|
||||
$bm_dbuser = "";
|
||||
$bm_dbpass = "";
|
||||
$bm_dbname = "";
|
||||
|
||||
# ES GlobalBan DB Info
|
||||
$gb_dbhost = "localhost";
|
||||
$gb_dbport = 3306;
|
||||
$gb_dbuser = "";
|
||||
$gb_dbpass = "";
|
||||
$gb_dbname = "";
|
||||
|
||||
# HLX DB Info
|
||||
$hlx_dbhost = "localhost";
|
||||
$hlx_dbport = 3306;
|
||||
$hlx_dbuser = "";
|
||||
$hlx_dbpass = "";
|
||||
$hlx_dbname = "";
|
||||
|
||||
|
||||
##
|
||||
##
|
||||
################################################################################
|
||||
## No need to edit below this line
|
||||
##
|
||||
|
||||
use DBI;
|
||||
|
||||
$havesbinfo = ($sb_dbhost eq "" || $sb_dbuser eq "" || $sb_dbpass eq "" || $sb_dbname eq "")?0:1;
|
||||
$haveamxbinfo = ($amxb_dbhost eq "" || $amxb_dbuser eq "" || $amxb_dbpass eq "" || $amxb_dbname eq "")?0:1;
|
||||
$havebminfo = ($bm_dbhost eq "" || $bm_dbuser eq "" || $bm_dbpass eq "" || $bm_dbname eq "")?0:1;
|
||||
$havegbinfo = ($gb_dbhost eq "" || $gb_dbuser eq "" || $gb_dbpass eq "" || $gb_dbname eq "")?0:1;
|
||||
$havehlxinfo = ($hlx_dbhost eq "" || $hlx_dbuser eq "" || $hlx_dbpass eq "" || $hlx_dbname eq "")?0:1;
|
||||
|
||||
die("DB login info incomplete. Exiting\n") if ($havehlxinfo == 0 || ($havesbinfo == 0 && $haveamxbinfo == 0 && $havebminfo == 0 && $havegbinfo == 0));
|
||||
|
||||
@steamids = ();
|
||||
|
||||
if ($havesbinfo) {
|
||||
print "Connecting to Sourcebans database...\n";
|
||||
my $sb_dbconn = DBI->connect(
|
||||
"DBI:mysql:database=$sb_dbname;host=$sb_dbhost;port=$sb_dbport",
|
||||
$sb_dbuser, $sb_dbpass) or die ("\nCan't connect to Sourcebans database '$sb_dbname' on '$sb_dbhost'\n" .
|
||||
"Server error: $DBI::errstr\n");
|
||||
|
||||
print "Successfully connected to Sourcebans database. Retrieving banned Steam IDs now...\n";
|
||||
|
||||
my $result = &doQuery($sb_dbconn, "SELECT `authid` FROM ".$sb_prefix."bans WHERE `length` = 0 AND `RemovedBy` IS NULL");
|
||||
while ( my($steamid) = $result->fetchrow_array) {
|
||||
push(@steamids, $steamid);
|
||||
}
|
||||
my $rows = $result->rows;
|
||||
if ($rows) {
|
||||
print $rows." banned users retrieved from Sourcebans.\n";
|
||||
}
|
||||
$sb_dbconn->disconnect;
|
||||
}
|
||||
|
||||
if ($haveamxbinfo) {
|
||||
print "Connecting to AMXBans database...\n";
|
||||
my $amxb_dbconn = DBI->connect(
|
||||
"DBI:mysql:database=$amxb_dbname;host=$amxb_dbhost;port=$amxb_dbport",
|
||||
$amxb_dbuser, $amxb_dbpass) or die ("\nCan't connect to AMXBans database '$amxb_dbname' on '$amxb_dbhost'\n" .
|
||||
"Server error: $DBI::errstr\n");
|
||||
|
||||
print "Successfully connected to AMXBans database. Retrieving banned Steam IDs now...\n";
|
||||
|
||||
my $result = &doQuery($amxb_dbconn, "SELECT `player_id` FROM amx_bans WHERE `ban_length` = 0");
|
||||
while ( my($steamid) = $result->fetchrow_array) {
|
||||
push(@steamids, $steamid);
|
||||
}
|
||||
my $rows = $result->rows;
|
||||
if ($rows) {
|
||||
print $rows." banned users retrieved from AMXBans.\n";
|
||||
}
|
||||
$amxb_dbconn->disconnect;
|
||||
}
|
||||
|
||||
if ($havebminfo) {
|
||||
print "Connecting to BeetlesMod database...\n";
|
||||
my $bm_dbconn = DBI->connect(
|
||||
"DBI:mysql:database=$bm_dbname;host=$bm_dbhost;port=$bm_dbport",
|
||||
$bm_dbuser, $bm_dbpass) or die ("\nCan't connect to BeetlesMod database '$bm_dbname' on '$bm_dbhost'\n" .
|
||||
"Server error: $DBI::errstr\n");
|
||||
|
||||
print "Successfully connected to BeetlesMod database. Retrieving banned Steam IDs now...\n";
|
||||
|
||||
my $result = &doQuery($bm_dbconn, "SELECT `steamid` FROM `bm_bans` WHERE `Until` IS NULL");
|
||||
while ( my($steamid) = $result->fetchrow_array) {
|
||||
push(@steamids, $steamid);
|
||||
}
|
||||
my $rows = $result->rows;
|
||||
if ($rows) {
|
||||
print $rows." banned users retrieved from BeetlesMod.\n";
|
||||
}
|
||||
$bm_dbconn->disconnect;
|
||||
}
|
||||
|
||||
if ($havegbinfo) {
|
||||
print "Connecting to ES GlobalBan database...\n";
|
||||
my $gb_dbconn = DBI->connect(
|
||||
"DBI:mysql:database=$gb_dbname;host=$gb_dbhost;port=$gb_dbport",
|
||||
$gb_dbuser, $gb_dbpass) or die ("\nCan't connect to ES GlobalBan database '$gb_dbname' on '$gb_dbhost'\n" .
|
||||
"Server error: $DBI::errstr\n");
|
||||
|
||||
print "Successfully connected to ES GlobalBan database. Retrieving banned Steam IDs now...\n";
|
||||
|
||||
my $result = &doQuery($gb_dbconn, "SELECT `steam_id` FROM `gban_ban` WHERE `active` = 1 AND `pending` = 0 AND `length` = 0");
|
||||
while ( my($steamid) = $result->fetchrow_array) {
|
||||
push(@steamids, $steamid);
|
||||
}
|
||||
my $rows = $result->rows;
|
||||
if ($rows) {
|
||||
print $rows." banned users retrieved from ES GlobalBan.\n";
|
||||
}
|
||||
$gb_dbconn->disconnect;
|
||||
}
|
||||
|
||||
if (@steamids) {
|
||||
$steamidstring = "'";
|
||||
foreach $steamid (@steamids)
|
||||
{
|
||||
$steamid =~ s/^STEAM_[0-9]+?\://i;
|
||||
$steamidstring .= $steamid."','";
|
||||
}
|
||||
$steamidstring =~ s/\,\'$//;
|
||||
|
||||
print "Connecting to HLX:CE database...\n";
|
||||
$hlx_dbconn = DBI->connect(
|
||||
"DBI:mysql:database=$hlx_dbname;host=$hlx_dbhost;port=$hlx_dbport",
|
||||
$hlx_dbuser, $hlx_dbpass) or die ("\nCan't connect to HLX:CE database '$hlx_dbname' on '$hlx_dbhost'\n" .
|
||||
"Server error: $DBI::errstr\n");
|
||||
print "Updating HLX:CE banned players...\n";
|
||||
$result = &doQuery($hlx_dbconn, "UPDATE `hlstats_Players` SET `hideranking` = 2 WHERE `playerId` IN (SELECT `playerId` FROM hlstats_PlayerUniqueIds WHERE `uniqueId` IN ($steamidstring)) AND `hideranking` < 2");
|
||||
print $result->rows." users newly marked as banned.\n";
|
||||
$hlx_dbconn->disconnect;
|
||||
} else {
|
||||
die("No banned users found in database(s). Exiting\n");
|
||||
}
|
||||
|
||||
sub doQuery
|
||||
{
|
||||
my ($dbconn, $query, $callref) = @_;
|
||||
my $result = $dbconn->prepare($query) or die("Unable to prepare query:\n$query\n$DBI::errstr\n$callref");
|
||||
$result->execute or die("Unable to execute query:\n$query\n$DBI::errstr\n$callref");
|
||||
|
||||
return $result;
|
||||
}
|
79
scripts/ImportBans/run_importbans
Normal file
79
scripts/ImportBans/run_importbans
Normal file
@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
# HLStatsX:CE now has two import ban utilities:
|
||||
# 1) ImportBans.pl is the original importing script written in perl.
|
||||
#
|
||||
# 2) hlstatsxbans.php is written by Peace-Maker and is written in PHP.
|
||||
#
|
||||
# More information on these scripts can be found in README.
|
||||
|
||||
|
||||
# Please select your banning system below using the number that corresponds to the ban system above.
|
||||
BANSYSTEM=1
|
||||
|
||||
### Nothing needs to be modified below here ###
|
||||
|
||||
# verify that you have a logs directory
|
||||
if [ ! -d logs ];then
|
||||
mkdir logs
|
||||
fi
|
||||
|
||||
if [ ! -w logs ];then
|
||||
echo "you need write access to the logs folder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# print info to the log file and run importbans.pl
|
||||
echo Importing Bans -- `date +%c` >> logs/log`date +_%Y%m%d`
|
||||
|
||||
case $BANSYSTEM in
|
||||
1)
|
||||
echo Using importbans.pl >> logs/log`date +_%Y%m%d` 2>&1
|
||||
./importbans.pl >> logs/log`date +_%Y%m%d` 2>&1
|
||||
;;
|
||||
2)
|
||||
echo Using hlstatsxbans.php >> logs/log`date +_%Y%m%d` 2>&1
|
||||
/usr/bin/php `pwd`/hlstatsxban.php >> logs/log`date +_%Y%m%d` 2>&1
|
||||
;;
|
||||
*)
|
||||
echo Warning: BANSYSTEM is not correctly configured. Please check your configuration.
|
||||
;;
|
||||
esac
|
||||
echo >> logs/log`date +_%Y%m%d`
|
||||
|
||||
|
||||
exit 0
|
500
scripts/TRcon.pm
Normal file
500
scripts/TRcon.pm
Normal file
@ -0,0 +1,500 @@
|
||||
package TRcon;
|
||||
#
|
||||
# TRcon Perl Module - execute commands on a remote Half-Life2 server using remote console.
|
||||
#
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
use strict;
|
||||
no strict 'vars';
|
||||
|
||||
use Sys::Hostname;
|
||||
use IO::Socket;
|
||||
use IO::Select;
|
||||
use bytes;
|
||||
use Scalar::Util;
|
||||
|
||||
do "$::opt_libdir/HLstats_GameConstants.plib";
|
||||
|
||||
my $VERSION = "1.00";
|
||||
my $TIMEOUT = 1.0;
|
||||
|
||||
my $SERVERDATA_EXECCOMMAND = 2;
|
||||
my $SERVERDATA_AUTH = 3;
|
||||
my $SERVERDATA_RESPONSE_VALUE = 0;
|
||||
my $SERVERDATA_AUTH_RESPONSE = 2;
|
||||
my $REFRESH_SOCKET_COUNTER_LIMIT = 100;
|
||||
my $AUTH_PACKET_ID = 1;
|
||||
my $SPLIT_END_PACKET_ID = 2;
|
||||
|
||||
#
|
||||
# Constructor
|
||||
#
|
||||
|
||||
sub new
|
||||
{
|
||||
my ($class_name, $server_object) = @_;
|
||||
my ($self) = {};
|
||||
bless($self, $class_name);
|
||||
|
||||
$self->{"rcon_socket"} = 0;
|
||||
$self->{"server_object"} = $server_object;
|
||||
Scalar::Util::weaken($self->{"server_object"});
|
||||
$self->{"auth"} = 0;
|
||||
$self->{"refresh_socket_counter"} = 0;
|
||||
$self->{"packet_id"} = 10;
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub execute
|
||||
{
|
||||
my ($self, $command, $splitted_answer) = @_;
|
||||
if ($::g_stdin == 0) {
|
||||
my $answer = $self->sendrecv($command, $splitted_answer);
|
||||
if ($answer =~ /bad rcon_password/i) {
|
||||
&::printEvent("TRCON", "Bad Password");
|
||||
}
|
||||
return $answer;
|
||||
}
|
||||
}
|
||||
|
||||
sub get_auth_code
|
||||
{
|
||||
my ($self, $id) = @_;
|
||||
my $auth = 0;
|
||||
|
||||
if ($id == $AUTH_PACKET_ID) {
|
||||
&::printEvent("TRCON", "Rcon password accepted");
|
||||
$auth = 1;
|
||||
$self->{"auth"} = 1;
|
||||
} elsif( $id == -1) {
|
||||
&::printEvent("TRCON", "Rcon password refused");
|
||||
$self->{"auth"} = 0;
|
||||
$auth = 0;
|
||||
} else {
|
||||
&::printEvent("TRCON", "Bad password response id=$id");
|
||||
$self->{"auth"} = 0;
|
||||
$auth = 0;
|
||||
}
|
||||
return $auth;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub sendrecv
|
||||
{
|
||||
my ($self, $msg, $splitted_answer) = @_;
|
||||
|
||||
my $rs_counter = $self->{"refresh_socket_counter"};
|
||||
if ($rs_counter % $REFRESH_SOCKET_COUNTER_LIMIT == 0) {
|
||||
if ($self->{"rcon_socket"} > 0) {
|
||||
shutdown($self->{"rcon_socket"}, 2);
|
||||
$self->{"rcon_socket"} = 0;
|
||||
}
|
||||
my $server_object = $self->{"server_object"};
|
||||
$self->{"rcon_socket"} = IO::Socket::INET->new(
|
||||
Proto=>"tcp",
|
||||
PeerAddr=>$server_object->{address},
|
||||
PeerPort=>$server_object->{port},
|
||||
);
|
||||
if (!$self->{"rcon_socket"}) {
|
||||
&::printEvent("TRCON", "Cannot setup TCP socket on ".$server_object->{address}.":".$server_object->{port}.": $!");
|
||||
}
|
||||
$self->{"refresh_socket_counter"} = 0;
|
||||
$self->{"auth"} = 0;
|
||||
}
|
||||
|
||||
|
||||
my $r_socket = $self->{"rcon_socket"};
|
||||
my $server = $self->{"server_object"};
|
||||
|
||||
my $auth = $self->{"auth"};
|
||||
my $response = "";
|
||||
my $packet_id = $self->{"packet_id"};
|
||||
|
||||
if (($r_socket) && ($r_socket->connected() )) {
|
||||
if ($auth == 0) {
|
||||
&::printEvent("TRCON", "Trying to get rcon access (auth)");
|
||||
if ($self->send_rcon($AUTH_PACKET_ID, $SERVERDATA_AUTH, $server->{rcon}, "")) {
|
||||
&::printEvent("TRCON", "Couldn't send password");
|
||||
return;
|
||||
}
|
||||
my ($id, $command, $response) = $self->recieve_rcon($AUTH_PACKET_ID);
|
||||
if($command == $SERVERDATA_AUTH_RESPONSE) {
|
||||
$auth = $self->get_auth_code($id);
|
||||
} elsif (($command == $SERVERDATA_RESPONSE_VALUE) && ($id == $AUTH_PACKET_ID)) {
|
||||
#Source servers sends one junk packet during the authentication step, before it responds
|
||||
# with the correct authentication response.
|
||||
&::printEvent("TRCON", "Junk packet from Source Engine");
|
||||
my ($id, $command, $response) = $self->recieve_rcon($AUTH_PACKET_ID);
|
||||
$auth = $self->get_auth_code($id);
|
||||
}
|
||||
}
|
||||
|
||||
if ($auth == 1) {
|
||||
$self->{"refresh_socket_counter"}++;
|
||||
$self->send_rcon($packet_id, $SERVERDATA_EXECCOMMAND, $msg);
|
||||
if ($splitted_answer > 0) {
|
||||
$self->send_rcon($SPLIT_END_PACKET_ID, $SERVERDATA_EXECCOMMAND, "");
|
||||
}
|
||||
my ($id, $command, $response) = $self->recieve_rcon($packet_id, $splitted_answer);
|
||||
$self->{"packet_id"}++;
|
||||
if ($self->{"packet_id"} > 32767) {
|
||||
$self->{"packet_id"} = 10;
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
} else {
|
||||
$self->{"refresh_socket_counter"} = 0;
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Send a package
|
||||
#
|
||||
sub send_rcon
|
||||
{
|
||||
my ($self, $id, $command, $string1, $string2) = @_;
|
||||
my $data = pack("VVZ*Z*", $id, $command, $string1, $string2);
|
||||
my $size = length($data);
|
||||
if($size > 4096) {
|
||||
&::printEvent("TRCON", "Command to long to send!");
|
||||
return 1;
|
||||
}
|
||||
$data = pack("V", $size).$data;
|
||||
|
||||
my $r_socket = $self->{"rcon_socket"};
|
||||
if ($r_socket && $r_socket->connected() && $r_socket->peeraddr()) {
|
||||
$r_socket->send($data, 0);
|
||||
return 0;
|
||||
} else {
|
||||
$self->{"refresh_socket_counter"} = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#
|
||||
# Recieve a package
|
||||
#
|
||||
sub recieve_rcon
|
||||
{
|
||||
my ($self, $packet_id, $splitted_answer) = @_;
|
||||
my ($size, $id, $command, $msg);
|
||||
my $tmp = "";
|
||||
|
||||
my $r_socket = $self->{"rcon_socket"};
|
||||
my $server = $self->{"server_object"};
|
||||
my $auth = $self->{"auth"};
|
||||
my $packet_id = $self->{"packet_id"};
|
||||
|
||||
if (($r_socket) && ($r_socket->connected() )) {
|
||||
if(IO::Select->new($r_socket)->can_read($TIMEOUT)) { # $TIMEOUT seconds timeout
|
||||
$r_socket->recv($tmp, 1500);
|
||||
$size = unpack("V", substr($tmp, 0, 4));
|
||||
if ($size == 0) {
|
||||
$self->{"refresh_socket_counter"} = 0;
|
||||
return (-1, -1, -1);
|
||||
}
|
||||
$id = unpack("V", substr($tmp, 4, 4));
|
||||
$command = unpack("V", substr($tmp, 8, 4));
|
||||
if ($id == $packet_id) {
|
||||
$tmp = substr($tmp, 12, length($tmp)-12);
|
||||
if ($splitted_answer > 0) {
|
||||
my $last_packet_id = $id;
|
||||
while ($last_packet_id != $SPLIT_END_PACKET_ID) {
|
||||
if(IO::Select->new($r_socket)->can_read($TIMEOUT)) {
|
||||
$r_socket->recv($split_data, 1500);
|
||||
my $split_size = unpack("V", substr($split_data, 0, 4));
|
||||
my $split_id = unpack("V", substr($split_data, 4, 4));
|
||||
my $split_command = unpack("V", substr($split_data, 8, 4));
|
||||
if ($split_id == $last_packet_id) {
|
||||
$split_data = substr($split_data, 12, length($split_data)-12);
|
||||
}
|
||||
if (!defined($split_id)){
|
||||
$last_packet_id = $SPLIT_END_PACKET_ID;
|
||||
} else {
|
||||
$last_packet_id = $split_id;
|
||||
}
|
||||
$tmp .= $split_data;
|
||||
} else {
|
||||
&::printNotice("TRCON", "Multiple packet error");
|
||||
$last_packet_id = $SPLIT_END_PACKET_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (length($tmp) > 0) {
|
||||
$tmp .= "\x00";
|
||||
my ($string1, $string2) = unpack("Z*Z*", $tmp);
|
||||
$msg = $string1.$string2;
|
||||
} else {
|
||||
$msg = "";
|
||||
}
|
||||
}
|
||||
return ($id, $command, $msg);
|
||||
} else {
|
||||
$self->{"refresh_socket_counter"} = 0;
|
||||
return (-1, -1, -1);
|
||||
}
|
||||
} else {
|
||||
$self->{"refresh_socket_counter"} = 0;
|
||||
return (-1, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Get error message
|
||||
#
|
||||
|
||||
sub error
|
||||
{
|
||||
my ($self) = @_;
|
||||
return $self->{"rcon_error"};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Parse "status" command output into player information
|
||||
#
|
||||
|
||||
sub getPlayers
|
||||
{
|
||||
my ($self) = @_;
|
||||
my $status = $self->execute("status", 1);
|
||||
if (!$status)
|
||||
{
|
||||
return ("", -1, "", 0);
|
||||
}
|
||||
|
||||
my @lines = split(/[\r\n]+/, $status);
|
||||
|
||||
my %players;
|
||||
|
||||
# HL2 standard
|
||||
# userid name uniqueid connected ping loss state adr
|
||||
# 187 ".:[SoV]:.Evil Shadow" STEAM_0:1:6200412 13:48 97 0 active 213.10.196.229:24085
|
||||
|
||||
# L4D
|
||||
# userid name uniqueid connected ping loss state rate adr
|
||||
# 2 1 "psychonic" STEAM_1:1:4153990 00:45 68 1 active 20000 192.168.5.115:27006
|
||||
|
||||
foreach my $line (@lines)
|
||||
{
|
||||
if ($line =~ /^\#\s*
|
||||
(\d+)\s+ # userid
|
||||
(?:\d+\s+|) # extra number in L4D, not sure what this is??
|
||||
"(.+)"\s+ # name
|
||||
(.+)\s+ # uniqueid
|
||||
([\d:]+)\s+ # time
|
||||
(\d+)\s+ # ping
|
||||
(\d+)\s+ # loss
|
||||
([A-Za-z]+)\s+ # state
|
||||
(?:\d+\s+|) # rate (L4D only)
|
||||
([^:]+): # addr
|
||||
(\S+) # port
|
||||
$/x)
|
||||
{
|
||||
my $userid = $1;
|
||||
my $name = $2;
|
||||
my $uniqueid = $3;
|
||||
my $time = $4;
|
||||
my $ping = $5;
|
||||
my $loss = $6;
|
||||
my $state = $7;
|
||||
my $address = $8;
|
||||
my $port = $9;
|
||||
|
||||
$uniqueid =~ s/^STEAM_[0-9]+?\://i;
|
||||
|
||||
# &::printEvent("DEBUG", "USERID: '$userid', NAME: '$name', UNIQUEID: '$uniqueid', TIME: '$time', PING: '$ping', LOSS: '$loss', STATE: '$state', ADDRESS:'$address', CLI_PORT: '$port'", 1);
|
||||
|
||||
if ($::g_mode eq "NameTrack") {
|
||||
$players{$name} = {
|
||||
"Name" => $name,
|
||||
"UserID" => $userid,
|
||||
"UniqueID" => $uniqueid,
|
||||
"Time" => $time,
|
||||
"Ping" => $ping,
|
||||
"Loss" => $loss,
|
||||
"State" => $state,
|
||||
"Address" => $address,
|
||||
"ClientPort" => $port
|
||||
};
|
||||
} elsif ($::g_mode eq "LAN") {
|
||||
$players{$address} = {
|
||||
"Name" => $name,
|
||||
"UserID" => $userid,
|
||||
"UniqueID" => $uniqueid,
|
||||
"Time" => $time,
|
||||
"Ping" => $ping,
|
||||
"Loss" => $loss,
|
||||
"State" => $state,
|
||||
"Address" => $address,
|
||||
"ClientPort" => $port
|
||||
};
|
||||
} else {
|
||||
$players{$uniqueid} = {
|
||||
"Name" => $name,
|
||||
"UserID" => $userid,
|
||||
"UniqueID" => $uniqueid,
|
||||
"Time" => $time,
|
||||
"Ping" => $ping,
|
||||
"Loss" => $loss,
|
||||
"State" => $state,
|
||||
"Address" => $address,
|
||||
"ClientPort" => $port
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return %players;
|
||||
}
|
||||
|
||||
sub getServerData
|
||||
{
|
||||
my ($self) = @_;
|
||||
my $status = $self->execute("status", 1);
|
||||
|
||||
my $server_object = $self->{server_object};
|
||||
my $game = $server_object->{play_game};
|
||||
|
||||
my @lines = split(/[\r\n]+/, $status);
|
||||
|
||||
my $servhostname = "";
|
||||
my $map = "";
|
||||
my $max_players = 0;
|
||||
my $difficulty = 0;
|
||||
|
||||
foreach my $line (@lines)
|
||||
{
|
||||
if ($line =~ /^\s*hostname\s*:\s*([\S].*)$/)
|
||||
{
|
||||
$servhostname = $1;
|
||||
}
|
||||
elsif ($line =~ /^\s*map\s*:\s*([\S]+).*$/)
|
||||
{
|
||||
$map = $1;
|
||||
}
|
||||
elsif ($line =~ /^\s*players\s*:\s*\d+.+\((\d+)\smax.*$/)
|
||||
{
|
||||
$max_players = $1;
|
||||
}
|
||||
}
|
||||
if ($game == L4D()) {
|
||||
$difficulty = $self->getDifficulty();
|
||||
}
|
||||
return ($servhostname, $map, $max_players, $difficulty);
|
||||
}
|
||||
|
||||
|
||||
sub getVisiblePlayers
|
||||
{
|
||||
my ($self) = @_;
|
||||
my $status = $self->execute("sv_visiblemaxplayers");
|
||||
|
||||
my @lines = split(/[\r\n]+/, $status);
|
||||
|
||||
|
||||
my $max_players = -1;
|
||||
foreach my $line (@lines)
|
||||
{
|
||||
# "sv_visiblemaxplayers" = "-1"
|
||||
# - Overrides the max players reported to prospective clients
|
||||
if ($line =~ /^\s*"sv_visiblemaxplayers"\s*=\s*"([-0-9]+)".*$/x)
|
||||
{
|
||||
$max_players = $1;
|
||||
}
|
||||
}
|
||||
return ($max_players);
|
||||
}
|
||||
|
||||
my %l4d_difficulties = (
|
||||
'Easy' => 1,
|
||||
'Normal' => 2,
|
||||
'Hard' => 3,
|
||||
'Impossible' => 4
|
||||
);
|
||||
|
||||
sub getDifficulty
|
||||
{
|
||||
#z_difficulty
|
||||
#"z_difficulty" = "Normal"
|
||||
# game replicated
|
||||
# - Difficulty of the current game (Easy, Normal, Hard, Impossible)
|
||||
|
||||
my ($self) = @_;
|
||||
my $zdifficulty = $self->execute("z_difficulty");
|
||||
|
||||
my @lines = split(/[\r\n]+/, $zdifficulty);
|
||||
|
||||
foreach my $line (@lines)
|
||||
{
|
||||
if ($line =~ /^\s*"z_difficulty"\s*=\s*"([A-Za-z]+)".*$/x)
|
||||
{
|
||||
if (exists($l4d_difficulties{$1}))
|
||||
{
|
||||
return $l4d_difficulties{$1};
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Get information about a player by userID
|
||||
#
|
||||
|
||||
sub getPlayer
|
||||
{
|
||||
my ($self, $uniqueid) = @_;
|
||||
my %players = $self->getPlayers();
|
||||
|
||||
if (defined($players{$uniqueid}))
|
||||
{
|
||||
return $players{$uniqueid};
|
||||
}
|
||||
else
|
||||
{
|
||||
$self->{"error"} = "No such player # $uniqueid";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
# end
|
1282
scripts/hlstats-awards.pl
Normal file
1282
scripts/hlstats-awards.pl
Normal file
File diff suppressed because it is too large
Load Diff
374
scripts/hlstats-resolve.pl
Normal file
374
scripts/hlstats-resolve.pl
Normal file
@ -0,0 +1,374 @@
|
||||
#!/usr/bin/perl
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
|
||||
##
|
||||
## Settings
|
||||
##
|
||||
|
||||
# $opt_configfile - Absolute path and filename of configuration file.
|
||||
$opt_configfile = "./hlstats.conf";
|
||||
|
||||
# $opt_libdir - Directory to look in for local required files
|
||||
# (our *.plib, *.pm files).
|
||||
$opt_libdir = "./";
|
||||
|
||||
|
||||
##
|
||||
##
|
||||
################################################################################
|
||||
## No need to edit below this line
|
||||
##
|
||||
|
||||
|
||||
use Getopt::Long;
|
||||
use IO::Socket;
|
||||
use DBI;
|
||||
|
||||
require "$opt_libdir/ConfigReaderSimple.pm";
|
||||
do "$opt_libdir/HLstats.plib";
|
||||
|
||||
$|=1;
|
||||
Getopt::Long::Configure ("bundling");
|
||||
|
||||
|
||||
##
|
||||
## Functions
|
||||
##
|
||||
|
||||
|
||||
sub is_number ($) { ( $_[0] ^ $_[0] ) eq '0' }
|
||||
|
||||
|
||||
#
|
||||
# void printEvent (int code, string description)
|
||||
#
|
||||
# Logs event information to stdout.
|
||||
#
|
||||
|
||||
sub printEvent
|
||||
{
|
||||
my ($code, $description, $update_timestamp) = @_;
|
||||
|
||||
if ($g_debug > 0)
|
||||
{
|
||||
if ($update_timestamp > 0)
|
||||
{
|
||||
my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time());
|
||||
my $timestamp = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
|
||||
} else {
|
||||
my $timestamp = $ev_timestamp;
|
||||
}
|
||||
print localtime(time) . "" unless ($timestamp);
|
||||
if (is_number($code))
|
||||
{
|
||||
printf("%s: %21s - E%03d: %s\n", $timestamp, $s_addr, $code, $description);
|
||||
} else {
|
||||
printf("%s: %21s - %s: %s\n", $timestamp, $s_addr, $code, $description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
##
|
||||
## MAIN
|
||||
##
|
||||
|
||||
# Options
|
||||
|
||||
$opt_help = 0;
|
||||
$opt_version = 0;
|
||||
$opt_regroup = 0;
|
||||
|
||||
$db_host = "localhost";
|
||||
$db_user = "";
|
||||
$db_pass = "";
|
||||
$db_name = "hlstats";
|
||||
|
||||
$g_dns_timeout = 5;
|
||||
$g_debug = 0;
|
||||
|
||||
# Usage message
|
||||
|
||||
$usage = <<EOT
|
||||
Usage: hlstats-resolve.pl [OPTION]...
|
||||
Resolve player IP addresses to hostnames.
|
||||
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
-d, --debug enable debugging output (-dd for more)
|
||||
-n, --nodebug disables above; reduces debug level
|
||||
--db-host=HOST database ip:port
|
||||
--db-name=DATABASE database name
|
||||
--db-password=PASSWORD database password (WARNING: specifying the
|
||||
password on the command line is insecure.
|
||||
Use the configuration file instead.)
|
||||
--db-username=USERNAME database username
|
||||
--dns-timeout=SEC timeout DNS queries after SEC seconds [$g_dns_timeout]
|
||||
-r, --regroup only re-group hostnames--don't resolve any IPs
|
||||
|
||||
Long options can be abbreviated, where such abbreviation is not ambiguous.
|
||||
|
||||
Most options can be specified in the configuration file:
|
||||
$opt_configfile
|
||||
Note: Options set on the command line take precedence over options set in the
|
||||
configuration file.
|
||||
|
||||
HLstats: http://www.hlstats.org
|
||||
EOT
|
||||
;
|
||||
|
||||
# Read Config File
|
||||
|
||||
if ($opt_configfile && -r $opt_configfile)
|
||||
{
|
||||
$conf = ConfigReaderSimple->new($opt_configfile);
|
||||
$conf->parse();
|
||||
|
||||
%directives = (
|
||||
"DBHost", "db_host",
|
||||
"DBUsername", "db_user",
|
||||
"DBPassword", "db_pass",
|
||||
"DBName", "db_name",
|
||||
"DNSTimeout", "g_dns_timeout",
|
||||
"DebugLevel", "g_debug"
|
||||
);
|
||||
|
||||
&doConf($conf, %directives);
|
||||
}
|
||||
else
|
||||
{
|
||||
print "-- Warning: unable to open configuration file '$opt_configfile'\n";
|
||||
}
|
||||
|
||||
# Read Command Line Arguments
|
||||
|
||||
GetOptions(
|
||||
"help|h" => \$opt_help,
|
||||
"version|v" => \$opt_version,
|
||||
"debug|d+" => \$g_debug,
|
||||
"nodebug|n+" => \$g_nodebug,
|
||||
"db-host=s" => \$db_host,
|
||||
"db-name=s" => \$db_name,
|
||||
"db-password=s" => \$db_pass,
|
||||
"db-username=s" => \$db_user,
|
||||
"dns-timeout=i" => \$g_dns_timeout,
|
||||
"regroup|r" => \$opt_regroup
|
||||
) or die($usage);
|
||||
|
||||
if ($opt_help)
|
||||
{
|
||||
print $usage;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($opt_version)
|
||||
{
|
||||
print "hlstats-resolve.pl (HLstats) $g_version\n"
|
||||
. "Real-time player and clan rankings and statistics for Half-Life\n\n"
|
||||
. "Copyright (C) 2001 Simon Garner\n"
|
||||
. "This is free software; see the source for copying conditions. There is NO\n"
|
||||
. "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$g_debug -= $g_nodebug;
|
||||
$g_debug = 0 if ($g_debug < 0);
|
||||
|
||||
if ($g_debug >= 2)
|
||||
{
|
||||
$opt_quiet = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$opt_quiet = 1; # quiet name resolution
|
||||
}
|
||||
|
||||
$g_dns_resolveip = 1;
|
||||
|
||||
|
||||
# Startup
|
||||
|
||||
print "++ HLstats Resolve $g_version starting...\n\n";
|
||||
|
||||
# Connect to the database
|
||||
|
||||
print "-- Connecting to MySQL database '$db_name' on '$db_host' as user '$db_user' ... ";
|
||||
|
||||
$db_conn = DBI->connect(
|
||||
"DBI:mysql:$db_name:$db_host",
|
||||
$db_user, $db_pass
|
||||
) or die ("Can't connect to MySQL database '$db_name' on '$db_host'\n" .
|
||||
"$DBI::errstr\n");
|
||||
|
||||
print "connected OK\n";
|
||||
|
||||
# Print configuration
|
||||
|
||||
print "-- DNS timeout is $g_dns_timeout seconds. Debug level is $g_debug.\n";
|
||||
|
||||
|
||||
# Main data routine
|
||||
|
||||
if ($opt_regroup)
|
||||
{
|
||||
my $result = &doQuery("
|
||||
SELECT
|
||||
id,
|
||||
hostname
|
||||
FROM
|
||||
hlstats_Events_Connects
|
||||
WHERE
|
||||
hostname != ''
|
||||
");
|
||||
|
||||
my $total = $result->rows;
|
||||
|
||||
if ($total > 0) {
|
||||
print "\n++ Re-grouping hosts (total $total hostnames) ... ";
|
||||
|
||||
my $resultHG = &queryHostGroups();
|
||||
|
||||
if ($g_debug > 0)
|
||||
{
|
||||
print "\n\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print " ";
|
||||
}
|
||||
|
||||
my $p = 1;
|
||||
while( my($id, $hostname) = $result->fetchrow_array )
|
||||
{
|
||||
my $percent = ($p / $total) * 100;
|
||||
|
||||
my $hostgroup = &getHostGroup($hostname, $resultHG);
|
||||
|
||||
&execNonQuery("
|
||||
UPDATE
|
||||
hlstats_Events_Connects
|
||||
SET
|
||||
hostgroup='" . "eSQL($hostgroup) . "'
|
||||
WHERE
|
||||
id=$id
|
||||
");
|
||||
|
||||
if ($g_debug > 0)
|
||||
{
|
||||
printf("-> (%3d%%) %50s = %s\n", $percent, $hostname, $hostgroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\b\b\b\b%3d%%", $percent);
|
||||
}
|
||||
|
||||
$p++;
|
||||
}
|
||||
|
||||
print "\n" unless ($g_debug > 0);
|
||||
} else {
|
||||
print "\n++ No Connects found!\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my $result = &doQuery("
|
||||
SELECT
|
||||
DISTINCT ipAddress,
|
||||
hostname
|
||||
FROM
|
||||
hlstats_Events_Connects
|
||||
");
|
||||
|
||||
my $total = $result->rows;
|
||||
if ($total > 0) {
|
||||
print "\n++ Resolving IPs and re-grouping hosts (total $total connects) ... ";
|
||||
|
||||
my $resultHG = &queryHostGroups();
|
||||
|
||||
if ($g_debug > 0)
|
||||
{
|
||||
print "\n\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print " ";
|
||||
}
|
||||
|
||||
my $p = 1;
|
||||
while( my($ipAddress, $hostname) = $result->fetchrow_array )
|
||||
{
|
||||
my $percent = ($p / $total) * 100;
|
||||
|
||||
if ($hostname eq "")
|
||||
{
|
||||
$hostname = &resolveIp($ipAddress, $opt_quiet);
|
||||
}
|
||||
|
||||
my $hostgroup = &getHostGroup($hostname, $resultHG);
|
||||
|
||||
&execNonQuery("
|
||||
UPDATE
|
||||
hlstats_Events_Connects
|
||||
SET
|
||||
hostname='$hostname',
|
||||
hostgroup='" . "eSQL($hostgroup) . "'
|
||||
WHERE
|
||||
ipAddress='$ipAddress'
|
||||
");
|
||||
|
||||
if ($g_debug > 0)
|
||||
{
|
||||
printf("-> (%3d%%) %15s = %50s = %s\n", $percent, $ipAddress, $hostname, $hostgroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\b\b\b\b%3d%%", $percent);
|
||||
}
|
||||
|
||||
$p++;
|
||||
}
|
||||
|
||||
print "\n" unless ($g_debug > 0);
|
||||
} else {
|
||||
print "\n++ No Connects found!\n";
|
||||
}
|
||||
}
|
||||
|
||||
print "\n++ Operation complete.\n";
|
||||
exit(0);
|
83
scripts/hlstats.conf
Normal file
83
scripts/hlstats.conf
Normal file
@ -0,0 +1,83 @@
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
|
||||
##
|
||||
## Database Settings
|
||||
##
|
||||
|
||||
# DBHost - Database server "address" or "address:port". Address can be an IP or
|
||||
# a hostname. The default MySQL port is 3306 (tcp).
|
||||
DBHost ""
|
||||
|
||||
# DBUsername - User to connect to the database as.
|
||||
DBUsername ""
|
||||
|
||||
# DBPassword - Password for the database user.
|
||||
DBPassword ""
|
||||
|
||||
# DBName - Name of the database to use.
|
||||
DBName ""
|
||||
|
||||
|
||||
##
|
||||
## UDP Socket Settings (should match "logaddress ip port" on the game servers)
|
||||
##
|
||||
|
||||
# BindIP - IP address to bind to (leave empty to use all interfaces).
|
||||
BindIP ""
|
||||
|
||||
# Port - Port to listen on for log data from the game servers. this is also valid for proxy-daemon.pl
|
||||
Port 27500
|
||||
|
||||
##
|
||||
## Cpanel hack
|
||||
##
|
||||
## Set this to 1 if you use cpanel and need to use a user-installed Perl module
|
||||
CpanelHack 0
|
||||
|
||||
##
|
||||
## Event Queue
|
||||
##
|
||||
## Number of each type of events to queue before inserting events of that type
|
||||
## (larger installs may try raising this for better performance
|
||||
EventQueueSize 10
|
||||
|
||||
# DebugLevel - Set this to 1 to have debugging information printed on stdout.
|
||||
# Set higher for even more debugging information. Set to 0 for
|
||||
# quiet operation. It is recommended that you set this to 1 when
|
||||
# first configuring HLstats, to help diagnose any problems.
|
||||
DebugLevel 1
|
||||
|
3626
scripts/hlstats.pl
Normal file
3626
scripts/hlstats.pl
Normal file
File diff suppressed because it is too large
Load Diff
456
scripts/proxy-daemon.pl
Normal file
456
scripts/proxy-daemon.pl
Normal file
@ -0,0 +1,456 @@
|
||||
#!/usr/bin/perl
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
use strict;
|
||||
use DBI;
|
||||
use IO::Socket;
|
||||
use IO::Select;
|
||||
use Getopt::Long;
|
||||
use Time::Local;
|
||||
|
||||
no strict 'vars';
|
||||
|
||||
##
|
||||
## Settings
|
||||
##
|
||||
|
||||
# $opt_configfile - Absolute path and filename of configuration file.
|
||||
$opt_configfile = "./hlstats.conf";
|
||||
|
||||
# $opt_libdir - Directory to look in for local required files
|
||||
# (our *.plib, *.pm files).
|
||||
$opt_libdir = "./";
|
||||
$heartbeat = 30;
|
||||
|
||||
##
|
||||
##
|
||||
################################################################################
|
||||
## No need to edit below this line
|
||||
##
|
||||
require "$opt_libdir/ConfigReaderSimple.pm";
|
||||
do "$opt_libdir/HLstats.plib";
|
||||
|
||||
$|=1;
|
||||
Getopt::Long::Configure ("bundling");
|
||||
|
||||
binmode STDIN, ":utf8";
|
||||
binmode STDOUT, ":utf8";
|
||||
|
||||
# Variables
|
||||
my %srv_list = ();
|
||||
my ($datagram,$flags);
|
||||
my $oldtime = (time + $heartbeat);
|
||||
|
||||
$usage = <<EOT
|
||||
Usage: hlstats.pl [OPTION]...
|
||||
Collect statistics from one or more Half-Life2 servers for distribution
|
||||
to sub-daemons (hlstats.pl).
|
||||
|
||||
-h, --help display this help and exit
|
||||
-d, --debug enable debugging output (-dd for more)
|
||||
-c, --configfile Specific configfile to use, settings in this file can't
|
||||
be overided with commandline settings.
|
||||
|
||||
HLstatsX: Community Edition http://www.hlxcommunity.com
|
||||
EOT
|
||||
;
|
||||
|
||||
# Read Config File
|
||||
|
||||
if ($opt_configfile && -r $opt_configfile) {
|
||||
$conf = ConfigReaderSimple->new($opt_configfile);
|
||||
$conf->parse();
|
||||
|
||||
%directives = (
|
||||
"DBHost", "db_host",
|
||||
"DBUsername", "db_user",
|
||||
"DBPassword", "db_pass",
|
||||
"DBName", "db_name",
|
||||
"BindIP", "s_ip",
|
||||
"Port", "proxy_port",
|
||||
"DebugLevel", "g_debug",
|
||||
);
|
||||
|
||||
&doConf($conf, %directives);
|
||||
} else {
|
||||
&printEvent("CONFIG", "-- Warning: unable to open configuration file '$opt_configfile'", 1);
|
||||
}
|
||||
|
||||
# Read Command Line Arguments
|
||||
GetOptions(
|
||||
"help|h" => \$opt_help,
|
||||
"configfile|c=s" => \$configfile,
|
||||
"debug|d+" => \$g_debug
|
||||
) or die($usage);
|
||||
|
||||
if ($opt_help) {
|
||||
print $usage;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($configfile && -r $configfile) {
|
||||
$conf = '';
|
||||
$conf = ConfigReaderSimple->new($configfile);
|
||||
$conf->parse();
|
||||
&doConf($conf, %directives);
|
||||
}
|
||||
|
||||
#
|
||||
# assignDaemon(string ipaddr, string ipport, hash daemon, hash srv_list)
|
||||
#
|
||||
# Round-Robin kind of way of spreading the load to different daemons.
|
||||
#
|
||||
sub assignDaemon
|
||||
{
|
||||
my ($ipaddr, $ipport, $daemon, $srv_list) = @_;
|
||||
my $next = "";
|
||||
|
||||
if (defined($$srv_list{'rr-next'})) {
|
||||
$next = $$srv_list{'rr-next'};
|
||||
} else {
|
||||
$next = 0;
|
||||
}
|
||||
|
||||
my $max = keys %$daemon;
|
||||
|
||||
if (!defined($$srv_list{$ipaddr}{$ipport})) {
|
||||
if ($next eq $max) {
|
||||
$next = 1;
|
||||
} else {
|
||||
$next++;
|
||||
}
|
||||
$$srv_list{'rr-next'} = $next;
|
||||
|
||||
$$srv_list{$ipaddr}{$ipport}{'dest_ip'} = $$daemon{$next}{'ip'};
|
||||
$$srv_list{$ipaddr}{$ipport}{'dest_port'} = $$daemon{$next}{'port'};
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#
|
||||
# checkHeartbeat (hash daemon, string proxy_key)
|
||||
#
|
||||
# Prints and update the state of the perl daemons, if they are up or not.
|
||||
#
|
||||
sub checkHeartbeat
|
||||
{
|
||||
my ($daemon, $proxy_key) = @_;
|
||||
|
||||
my $state = '';
|
||||
foreach my $key (keys(%$daemon)) {
|
||||
my $value = $$daemon{$key};
|
||||
my $socket = IO::Socket::INET->new( Proto=>"udp",
|
||||
PeerHost=>$$daemon{$key}{'ip'},
|
||||
PeerPort=>$$daemon{$key}{'port'}
|
||||
);
|
||||
$packet = "C;HEARTBEAT;";
|
||||
$socket->send("PROXY Key=$proxy_key PROXY $packet");
|
||||
|
||||
if(IO::Select->new($socket)->can_read(4)) { # 4 second timeout
|
||||
$socket->recv($msg,1024);
|
||||
if ($msg =~ /Heartbeat OK/) {
|
||||
$state = "up";
|
||||
} else {
|
||||
$state = "down";
|
||||
}
|
||||
}
|
||||
if ($$daemon{$key}{'curstate'} eq "") {
|
||||
$$daemon{$key}{'curstate'} = "n/a";
|
||||
}
|
||||
|
||||
$$daemon{$key}{'oldstate'} = $$daemon{$key}{'curstate'};
|
||||
$$daemon{$key}{'curstate'} = $state;
|
||||
|
||||
&printEvent("HEARTBEAT", "Sending HB to $$daemon{$key}{'ip'}:$$daemon{$key}{'port'}... state: $$daemon{$key}{'curstate'} (old: $$daemon{$key}{'oldstate'})", 1);
|
||||
$state = '';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#
|
||||
# string retunrServerList(hash srv_list)
|
||||
#
|
||||
# Return a list of servers to requestor (udp package C;SERVERLIST).
|
||||
#
|
||||
sub returnServerList
|
||||
{
|
||||
my ($srv_list) = @_;
|
||||
#$srv_list{$ipaddr}{$ipport}{'dest_ip'}
|
||||
|
||||
for my $ip (keys(%srv_list)) {
|
||||
for my $port (keys(%{$srv_list{$ip}})) {
|
||||
$msg = $msg . "$ip:$port -> $srv_list{$ip}{$port}{'dest_ip'}:$srv_list{$ip}{$port}{'dest_port'}\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
#
|
||||
# string theTime(int sec, int min, int hour, int mday, int year, int wday, int yday, int isdst)
|
||||
#
|
||||
# Makes a pretty timestampformat to output
|
||||
#
|
||||
sub theTime
|
||||
{
|
||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
||||
$year = $year + 1900;
|
||||
$mon = $mon + 1;
|
||||
|
||||
if ($mon <= 9) { $mon = "0$mon"; }
|
||||
if ($mday <= 9) { $mday = "0$mday"; }
|
||||
if ($hour <= 9) { $hour = "0$hour"; }
|
||||
if ($min <= 9) { $min = "0$min"; }
|
||||
if ($sec <= 9) { $sec = "0$sec"; }
|
||||
|
||||
my $time = "[$year-$mon-$mday $hour:$min:$sec] ";
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
#
|
||||
# string reloadDaemon(hash daemon, string proxy_key)
|
||||
#
|
||||
# Sends reload package to all daemons specified in hlstats.Options.Proxy_Daemons
|
||||
#
|
||||
sub reloadDaemon
|
||||
{
|
||||
my ($daemon, $proxy_key) = @_;
|
||||
my $fake_ip = "127.0.0.1";
|
||||
my $fake_port = "30000";
|
||||
my $msg = '';
|
||||
$packet = "C;RELOAD;";
|
||||
|
||||
foreach my $key (keys(%$daemon)) {
|
||||
if ($$daemon{$key}{'curstate'} eq "up") {
|
||||
&printEvent("CONTROL", "Sending RELOAD packet to $$daemon{$key}{'ip'}:$$daemon{$key}{'port'}", 1);
|
||||
$msg = $msg . &theTime() . "Sending RELOAD packet to $daemon{$key}{'ip'}:$daemon{$key}{'port'}\n";
|
||||
|
||||
# Sedning actual message to the daemon.
|
||||
my $cmd = IO::Socket::INET->new( Proto=>"udp",
|
||||
PeerHost=>$$daemon{$key}{'ip'},
|
||||
PeerPort=>$$daemon{$key}{'port'}
|
||||
);
|
||||
$cmd->send("PROXY Key=$proxy_key PROXY $packet");
|
||||
}
|
||||
}
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
#
|
||||
# string getProxyKey ()
|
||||
#
|
||||
# Get the value for Proxy_Key
|
||||
#
|
||||
sub getProxyKey
|
||||
{
|
||||
my $query = "SELECT `value` FROM hlstats_Options WHERE `keyname` = 'Proxy_Key'";
|
||||
my $result = &doQuery($query);
|
||||
my ($proxy_key) = $result->fetchrow_array;
|
||||
$result->finish;
|
||||
|
||||
return $proxy_key;
|
||||
}
|
||||
|
||||
sub is_number ($) { ( $_[0] ^ $_[0] ) eq '0' }
|
||||
|
||||
|
||||
############## Main program ##############
|
||||
$g_stdin = 0;
|
||||
|
||||
# Connect yo mysql DB to get required settings
|
||||
&doConnect();
|
||||
|
||||
my $proxy_key = &getProxyKey();
|
||||
|
||||
# Get the daemons you will use
|
||||
$query = "SELECT `value` FROM hlstats_Options WHERE `keyname` = 'Proxy_Daemons'";
|
||||
$result = &doQuery($query);
|
||||
|
||||
my ($daemonlist) = $result->fetchrow_array;
|
||||
$result->finish;
|
||||
my @proxy_daemons = split(/,/, $daemonlist);
|
||||
my $total_daemons = scalar(@proxy_daemons);
|
||||
|
||||
my %daemon = ();
|
||||
my $i = 1;
|
||||
|
||||
while ($i <= $total_daemons) {
|
||||
($daemon{$i}{'ip'}, $daemon{$i}{'port'}) = split(/:/, $proxy_daemons[$i-1]);
|
||||
$daemon{$i}{'oldstate'} = "";
|
||||
$daemon{$i}{'curstate'} = "";
|
||||
$i++;
|
||||
}
|
||||
|
||||
# Setting up the proxy port to listen on.
|
||||
my $server = IO::Socket::INET->new( LocalPort=>$proxy_port,
|
||||
Proto=>"udp"
|
||||
) or die "Can't create UDP server: $@";
|
||||
|
||||
# It went ok, lets start recive messages...
|
||||
&printEvent("DAEMON", "HlstatsX Proxy Daemon up and running on port: $proxy_port, key: $proxy_key", 1);
|
||||
|
||||
# Do initial heartbeat check.
|
||||
&checkHeartbeat(\%daemon, $proxy_key);
|
||||
|
||||
# Reload all child daemons config
|
||||
&reloadDaemon(\%daemon, $proxy_key);
|
||||
|
||||
while ($server->recv($datagram,1024,$flags)) {
|
||||
my $control = 0;
|
||||
# Checks the subdaemons every 30 sec if they are alive.
|
||||
# the interval can be changed by modify $heartbeat value in beginning of script.
|
||||
if (time > $oldtime) {
|
||||
&checkHeartbeat(\%daemon, $proxy_key);
|
||||
$oldtime = (time + $heartbeat);
|
||||
}
|
||||
|
||||
my $ipaddr = $server->peerhost;
|
||||
my $ipport = $server->peerport;
|
||||
|
||||
if ($ipaddr eq "127.0.0.1" && $datagram =~/C;HEARTBEAT;/) {
|
||||
$control = 1;
|
||||
$msg = '';
|
||||
$msg = "Heartbeat OK";
|
||||
&printEvent("CONTROL", "Sending Heartbeat to $ipaddr:$ipport", 1);
|
||||
} elsif ($ipaddr eq "127.0.0.1" && $datagram =~/C;SERVERLIST;/) {
|
||||
$control = 1;
|
||||
$msg = '';
|
||||
$msg = returnServerList($srv_list);
|
||||
$msg = "ServerList\n$msg";
|
||||
&printEvent("CONTROL", "Sending Serverlist to $ipaddr:$ipport", 1);
|
||||
} elsif ($ipaddr eq "127.0.0.1" && $datagram =~/C;RELOAD;/) {
|
||||
$control = 1;
|
||||
$msg = '';
|
||||
$msg = &reloadDaemon($daemon);
|
||||
}
|
||||
|
||||
if ($ipaddr eq "127.0.0.1" && $control == 1) {
|
||||
# Sending actual message to the daemon.
|
||||
my $dest = sockaddr_in($ipport, inet_aton($ipaddr));
|
||||
my $bytes = send($server, $msg, 0, $dest);
|
||||
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($datagram =~ /PROXY Key=(.+) (.*)PROXY (.+)/) {
|
||||
if ($proxy_key eq $1) {
|
||||
if ($3 =~ /C;HEARTBEAT;/) {
|
||||
$msg = '';
|
||||
$msg = "Heartbeat OK";
|
||||
&printEvent("CONTROL", "Sending Heartbeat to $ipaddr:$ipport", 1);
|
||||
} elsif ($3 =~ /C;SERVERLIST;/) {
|
||||
$msg = '';
|
||||
$msg = returnServerList($srv_list);
|
||||
$msg = "ServerList\n$msg";
|
||||
&printEvent("CONTROL", "Sending Serverlist to $ipaddr:$ipport", 1);
|
||||
&printEvent("CONTROL", $msg, 1);
|
||||
} elsif ($3 =~ /C;RELOAD;/) {
|
||||
$msg = '';
|
||||
$msg = &reloadDaemon($daemon);
|
||||
}
|
||||
} else {
|
||||
$msg = "FAILED PROXY REQUEST ($ipaddr:$ipport)\n";
|
||||
&printEvent("E403", "Sending FAILED PROXY REQUEST to $ipaddr:$ipport", 1);
|
||||
}
|
||||
|
||||
|
||||
# Sedning actual message to the daemon.
|
||||
my $dest = sockaddr_in($ipport, inet_aton($ipaddr));
|
||||
my $bytes = send($server, $msg, 0, $dest);
|
||||
|
||||
next;
|
||||
}
|
||||
|
||||
if (defined($srv_list{$ipaddr}{$ipport})) {
|
||||
# Check the oldstate, curstate of your logging daemon
|
||||
foreach my $key (keys %daemon) {
|
||||
if ($srv_list{$ipaddr}{$ipport}{'dest_ip'} eq $daemon{$key}{'ip'} && $srv_list{$ipaddr}{$ipport}{'dest_port'} eq $daemon{$key}{'port'}) {;
|
||||
if ($daemon{$key}{'curstate'} eq "up" && $daemon{$key}{'oldstate'} eq "down") {
|
||||
# Recovering, should do a reload of some kind here.
|
||||
%srv_list = ();
|
||||
|
||||
} elsif ($daemon{$key}{'curstate'} eq "down" && $daemon{$key}{'oldstate'} eq "up") {
|
||||
# Daemon died, assing a new daemon to server
|
||||
|
||||
delete $srv_list{$ipaddr}{$ipport};
|
||||
($daemon, $srv_list) = &assignDaemon($ipaddr, $ipport, $daemon, $srv_list);
|
||||
&printEvent("BALANCE", "down - up: Re-Assing daemon $srv_list{$ipaddr}{$ipport}{'dest_ip'}:$srv_list{$ipaddr}{$ipport}{'dest_port'} to $ipaddr:$ipport", 1);
|
||||
} elsif ($daemon{$key}{'curstate'} eq "down" && $daemon{$key}{'oldstate'} eq "down") {
|
||||
# DOWN, should already reassinged the daemon.
|
||||
|
||||
delete $srv_list{$ipaddr}{$ipport};
|
||||
($daemon, $srv_list) = &assignDaemon($ipaddr, $ipport, $daemon, $srv_list);
|
||||
&printEvent("BALANCE", "down-down: Re-Assing daemon $srv_list{$ipaddr}{$ipport}{'dest_ip'}:$srv_list{$ipaddr}{$ipport}{'dest_port'} to $ipaddr:$ipport", 1);
|
||||
} elsif ($daemon{$key}{'curstate'} eq "down" && $daemon{$key}{'oldstate'} eq "n/a") {
|
||||
# Daemon down when we started proxy, assing another daemon.
|
||||
|
||||
delete $srv_list{$ipaddr}{$ipport};
|
||||
($daemon, $srv_list) = &assignDaemon($ipaddr, $ipport, $daemon, $srv_list);
|
||||
&printEvent("BALANCE", "down - na: Assing daemon $srv_list{$ipaddr}{$ipport}{'dest_ip'}:$srv_list{$ipaddr}{$ipport}{'dest_port'} to $ipaddr:$ipport from down/na", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# Assign a logging daemon for your server:port
|
||||
delete $srv_list{$ipaddr}{$ipport};
|
||||
&assignDaemon($ipaddr, $ipport, \%daemon, \%srv_list);
|
||||
&printEvent("BALANCE", "Assing daemon $srv_list{$ipaddr}{$ipport}{'dest_ip'}:$srv_list{$ipaddr}{$ipport}{'dest_port'} to $ipaddr:$ipport", 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($datagram =~ /.*rcon from.*: command "status".*/ || $datagram =~ /.*rcon from.*: command "stats".*/ || $datagram =~ /.*rcon from.*: command "".*/) {
|
||||
# skip messages that looks like this, to ease the load on the sub daemons alittle
|
||||
&printEvent("NOTICE", "Skipping message...", 1) if ($g_debug > 1);
|
||||
} else {
|
||||
if (defined($srv_list{$ipaddr}{$ipport}{'dest_ip'}) && defined($srv_list{$ipaddr}{$ipport}{'dest_port'})) {
|
||||
$datagram =~ s/^.*RL /RL /g;
|
||||
|
||||
&printEvent("NOTICE", "Sending $datagram to daemon $srv_list{$ipaddr}{$ipport}{'dest_ip'}:$srv_list{$ipaddr}{$ipport}{'dest_port'}", 1) if ($g_debug > 1);
|
||||
# Sedning actual message to the daemon.
|
||||
my $forward = IO::Socket::INET->new( Proto=>"udp",
|
||||
PeerHost=>$srv_list{$ipaddr}{$ipport}{'dest_ip'},
|
||||
PeerPort=>$srv_list{$ipaddr}{$ipport}{'dest_port'}
|
||||
);
|
||||
$forward->send("PROXY Key=$proxy_key $ipaddr:".$ipport."PROXY $datagram");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
791
scripts/run_hlstats
Normal file
791
scripts/run_hlstats
Normal file
@ -0,0 +1,791 @@
|
||||
#!/bin/bash
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxce.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Usage
|
||||
# Information on how to use this script can be found on our wiki:
|
||||
# http://wiki.hlxce.com
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Script Configuration
|
||||
# These parameters allow you to adjust various functions of the daemon.
|
||||
# In general, they should not need to be modified.
|
||||
# Please visit our wiki for more information: http://wiki.hlxce.com
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# SCRIPTPATH:
|
||||
# File system path to daemon and supporting files
|
||||
# NOTE: This is only needed if the other scripts files will be in another directory.
|
||||
# In general, NO TOUCHY! :)
|
||||
SCRIPTPATH=.
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# CONFFILE:
|
||||
# Specifies the configuration file (relative to SCRIPTPATH) to use for the daemon
|
||||
CONFFILE=hlstats.conf
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# DAEMON:
|
||||
# Specifies the daemon Perl script to be used
|
||||
DAEMON=hlstats.pl
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# LOGDIR:
|
||||
# Specifies the location to store logs
|
||||
LOGDIR=${SCRIPTPATH}/logs
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# LOGDATE:
|
||||
# Specifies the date format to use in log file names
|
||||
LOGDATE_FORMAT=%Y-%m-%d_%H-%M-%S
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# PIDDIR:
|
||||
# Specifies location to store daemon PID files
|
||||
PIDDIR=${SCRIPTPATH}
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Nothing to modify below here
|
||||
WEBSITE=http://www.hlxce.com
|
||||
WIKI=http://wiki.hlxce.com
|
||||
|
||||
# Start output
|
||||
echo
|
||||
echo "HLstatsX:CE daemon control"
|
||||
echo "${WEBSITE}"
|
||||
echo "---------------------------"
|
||||
|
||||
# Change to directory of script
|
||||
cd `dirname ${0}`
|
||||
|
||||
# Perform some initial checks before we encounter later errors
|
||||
# Check if we can write to the SCRIPTPATH
|
||||
if [ ! -w ${SCRIPTPATH} ]; then
|
||||
echo "CRITICAL ERROR: Could not write to SCRIPTPATH: ${SCRIPTPATH}"
|
||||
echo "Verify you have write access to this directory."
|
||||
echo "Visit our wiki for more information: ${WIKI}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if the daemon perl script exists
|
||||
if [ ! -f ${SCRIPTPATH}/${DAEMON} ]; then
|
||||
echo "CRITICAL ERROR: Cannot access the daemon: ${DAEMON}"
|
||||
echo "Verify that the daemon, and corresponding files, exist in ${SCRIPTPATH}"
|
||||
echo "Visit our wiki for more information: ${WIKI}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify shebang line in daemon
|
||||
SHEBANG=`head -n1 ${SCRIPTPATH}/${DAEMON}`
|
||||
if [[ ${SHEBANG} =~ ^#! ]]; then
|
||||
SHEBANG_BINARY=`echo "${SHEBANG}" | sed 's/^#!//'`
|
||||
if [ ! -f ${SHEBANG_BINARY} ]; then
|
||||
echo "CRITICAL ERROR: The path to Perl is incorrect in ${DAEMON}."
|
||||
echo "Current Perl path in shebang: ${SHEBANG_BINARY}"
|
||||
echo "Visit our wiki for more information: ${WIKI}."
|
||||
echo
|
||||
echo "Potential paths for Perl: "
|
||||
echo `which perl`
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "CRITICAL ERROR: The shebang line is incorrectly configured. Please verify that your shebang line is correct in ${DAEMON}."
|
||||
echo "Current shebang line: ${SHEBANG}"
|
||||
echo "Visit our wiki for more information: ${WIKI}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create logdir if needed
|
||||
if [ ! -d ${LOGDIR} ]; then
|
||||
mkdir ${LOGDIR}
|
||||
fi
|
||||
|
||||
# Make sure we can write to logdir
|
||||
if [ ! -w ${LOGDIR} ]; then
|
||||
echo "CRITICAL ERROR: Could not write to the log folder: ${LOGDIR}"
|
||||
echo "Verify that you have write access to the log folder."
|
||||
echo "Visit our wiki for more information: ${WIKI}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Daemon control functions
|
||||
function start_daemon {
|
||||
# This function handles the creation of a new daemon process.
|
||||
# This function requires one parameter: PORT
|
||||
# Returns:
|
||||
# 0 - Daemon started
|
||||
# 1 - Daemon failed to start
|
||||
# 2 - Daemon already running
|
||||
|
||||
if [ ! $1 ]; then
|
||||
echo "CRITICAL ERROR: No port was received on function start_daemon"
|
||||
exit 1
|
||||
else
|
||||
local PORT=$1
|
||||
fi
|
||||
|
||||
local LOG=${LOGDIR}/hlstats_${PORT}_`date +${LOGDATE_FORMAT}`
|
||||
|
||||
local PID=`get_pid ${PORT}`
|
||||
# Check if a PID exists for this port number
|
||||
if [ "${PID}" != "" ]; then
|
||||
# PID exists -- check if the daemon is running.
|
||||
kill -0 ${PID} &> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# Daemon running -- nothing to do.
|
||||
return 2
|
||||
else
|
||||
# Daemon not running -- remove pid.
|
||||
remove_pidfile ${PORT}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start the daemon on requested port
|
||||
echo -ne "Attempting to start HLstatsX:CE daemon on port ${PORT}..."
|
||||
${SCRIPTPATH}/${DAEMON} --configfile=${CONFFILE} --port=${PORT} &> ${LOG} &
|
||||
# Store PID in memory until we verify Daemon has launched
|
||||
PID=$!
|
||||
|
||||
# Perform one quick check to see if PID is running
|
||||
kill -0 ${PID} &> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
create_pidfile ${PORT} ${PID}
|
||||
echo ""
|
||||
return 0
|
||||
else
|
||||
# PID not detected in time, keep checking for 10 more seconds.
|
||||
local i=1
|
||||
while [ $i -le 10 ]
|
||||
do
|
||||
echo -ne " ${i}"
|
||||
sleep 1
|
||||
# Perform a kill check against saved PID
|
||||
kill -0 ${PID} &> /dev/null
|
||||
# Check results of pid test
|
||||
if [ $? -eq 1 ]; then
|
||||
# Process does not exist
|
||||
let i++
|
||||
if [ $i -eq 10 ]; then
|
||||
# Daemon did not respond to start request within 10 seconds.
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
# Daemon started successfully -- commit PID to file
|
||||
create_pidfile ${PORT} ${PID}
|
||||
echo ""
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
function stop_daemon {
|
||||
# This function handles shutting a daemon down.
|
||||
# This function requires one parameter: PORT.
|
||||
|
||||
# Returns:
|
||||
# 0 - Daemon gracefully stopped
|
||||
# 1 - Daemon forcefully stopped
|
||||
# 2 - Daemon could not be stopped
|
||||
# 3 - No daemon to stop or PID missing
|
||||
|
||||
if [ ! $1 ]; then
|
||||
echo "CRITICAL ERROR: No port was received on function stop_daemon"
|
||||
exit 1
|
||||
else
|
||||
local PORT=$1
|
||||
fi
|
||||
|
||||
local PID=`get_pid ${PORT}`
|
||||
|
||||
if [ ${PID} -eq 0 ]; then
|
||||
return 3
|
||||
fi
|
||||
|
||||
# Attempt to stop the daemon
|
||||
echo -n "Attempting graceful shutdown of HLstatsX:CE daemon on port ${PORT} "
|
||||
kill -INT ${PID} &> /dev/null
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
# Daemon is not running, purge the PID.
|
||||
remove_pidfile ${PORT}
|
||||
echo ""
|
||||
return 3
|
||||
else
|
||||
# Found running PID -- perform a quick check before entering loop
|
||||
kill -0 ${PID} &> /dev/null
|
||||
if [ $? -eq 1 ]; then
|
||||
# Daemon stopped, remove PID
|
||||
remove_pidfile ${PORT}
|
||||
echo ""
|
||||
return 0
|
||||
else
|
||||
local i=1
|
||||
while [ $i -le 10 ]
|
||||
do
|
||||
echo -n " ${i}"
|
||||
sleep 1
|
||||
# Perform a kill check against saved PID
|
||||
kill -0 ${PID} &> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# Daemon still operating
|
||||
let i++
|
||||
else
|
||||
# Daemon stopped, remove PID
|
||||
remove_pidfile ${PORT}
|
||||
echo ""
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Daemon did not respond to shutdown, attempt a forced kill
|
||||
echo ""
|
||||
echo "WARNING: Daemon did not respond to a graceful shut down. Forcing a shut down on port ${PORT} "
|
||||
local i=1
|
||||
while [ $i -le 5 ]
|
||||
do
|
||||
kill -KILL ${PID} &> /dev/null
|
||||
echo -n " ${i}"
|
||||
sleep 1
|
||||
|
||||
# Check if PID is still present
|
||||
kill -0 ${PID} &> /dev/null
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
# Daemon still operating
|
||||
let i++
|
||||
else
|
||||
# Daemon stopped successfully.
|
||||
remove_pidfile ${PORT}
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
function reload_daemon {
|
||||
# This function handles reloading a daemon down.
|
||||
# This function requires one parameter: PORT.
|
||||
|
||||
# Returns:
|
||||
# 0 - Reload sent successfully
|
||||
# 1 - Daemon not running or pid file missing
|
||||
|
||||
# Sanity check on incoming required parameter
|
||||
if [ ! $1 ]; then
|
||||
echo "CRITICAL ERROR: No port was received on function reload_daemon"
|
||||
exit 1
|
||||
else
|
||||
local PORT=$1
|
||||
fi
|
||||
|
||||
|
||||
local PID=`get_pid ${PORT}`
|
||||
# Check to verify the daemon is operational
|
||||
if [ ${PID} -ne 0 ]; then
|
||||
kill -0 ${PID} &> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
kill -HUP ${PID} &> /dev/null
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function check_port {
|
||||
# This function verifies user input on the port number
|
||||
# One argument is required
|
||||
|
||||
# Returns:
|
||||
# 0 - Valid input
|
||||
# 1 - Invalid Input (non-digit or not in UDP port range)
|
||||
|
||||
if [ $1 ]; then
|
||||
# Perform regex test on input
|
||||
echo ${1} | grep -q '^[0-9]\{1,5\}$'
|
||||
# Check if within range and if grep test was successful.
|
||||
if [ $? -eq 0 ] && [ $1 -le 65535 ] && [ $1 -ge 1 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function get_status {
|
||||
# This function performs a lookup for the PID on specified port and checks status
|
||||
# Parameters:
|
||||
# 1 - port
|
||||
|
||||
# Returns:
|
||||
# 0 - PID is running
|
||||
# 1 - PID is not running
|
||||
# 2 - Invalid PID
|
||||
|
||||
if [ $1 ]; then
|
||||
local PID=`get_pid ${1}`
|
||||
if [ "${PID}" != "" ]; then
|
||||
kill -0 ${PID} &> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 2
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function create_pidfile {
|
||||
# This function will handle the creation of a PID file for a corresponding port
|
||||
# Parameters required:
|
||||
# 1 - port number
|
||||
# 2 - PID
|
||||
|
||||
# Returns:
|
||||
# 0 - PID saved
|
||||
# 1 - Unable to save PID
|
||||
|
||||
if [[ $1 && $2 ]]; then
|
||||
PIDFILE=${PIDDIR}/hlstats_${1}.pid
|
||||
echo ${2} > ${PIDFILE}
|
||||
|
||||
if [ "`cat ${PIDFILE}`" -eq "${2}" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function remove_pidfile {
|
||||
# This function will handle the deletion of a PID file for a corresponding port
|
||||
# Parameters required:
|
||||
# 1 - port number
|
||||
|
||||
# Returns:
|
||||
# 0 - PID removed
|
||||
# 1 - PID does not exist
|
||||
|
||||
if [ $1 ]; then
|
||||
PIDFILE=${PIDDIR}/hlstats_${1}.pid
|
||||
rm -f ${PIDFILE} &> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function get_pid {
|
||||
# This function will echo out the found pid and return 0, or return 1 if it finds nothing
|
||||
# Parameters required:
|
||||
# 1 - port number
|
||||
|
||||
# Output
|
||||
# Requested PID on return 0
|
||||
|
||||
# Returns:
|
||||
# 0 - PID number for corresponding process
|
||||
# 1 - No PID file for specified port
|
||||
|
||||
if [ $1 ]; then
|
||||
PIDFILE=${PIDDIR}/hlstats_${1}.pid
|
||||
PID=`cat ${PIDFILE} 2> /dev/null`
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ${PID}
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Cleanup old legacy run_hlstats stuff
|
||||
# Check if hlstats.pid exists (original pid from legacy run_hlstats)
|
||||
if [ -f ${PIDDIR}/hlstats.pid ]; then
|
||||
echo "WARNING: A old PID file has been detected. To prevent further troubles this daemon will be shut down."
|
||||
kill -KILL `cat ${PIDDIR}/hlstats.pid` &> /dev/null
|
||||
sleep 1
|
||||
# Check if PID is dead
|
||||
i=1
|
||||
while [ $i -le 5 ]
|
||||
do
|
||||
kill -0 `cat ${PIDDIR}/hlstats.pid` &> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# Daemon still operating
|
||||
let i++
|
||||
sleep 1
|
||||
else
|
||||
# Daemon stopped successfully.
|
||||
rm -f ${PIDDIR}/hlstats.pid
|
||||
echo ""
|
||||
echo "HLstatsX:CE daemon has been forcefully stopped."
|
||||
echo "Please re-run this script to control your daemon."
|
||||
exit
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Daemon control case switcher
|
||||
case "$1" in
|
||||
start)
|
||||
# Usage: run_hlstats start <# of daemons> <first port number> <port increment number>
|
||||
# All arguments are optional
|
||||
# Defaults: # of Daemons = 1; First port number = 27500; Port increment number = 1
|
||||
NUMDAEMONS=1
|
||||
STARTPORT=27500
|
||||
INCREMENT=1
|
||||
|
||||
# Get user-specified number of daemons
|
||||
if [ $2 ]; then
|
||||
NUMDAEMONS=$2
|
||||
fi
|
||||
|
||||
if [ $3 ]; then
|
||||
check_port $3
|
||||
if [ $? -eq 0 ]; then
|
||||
STARTPORT=$3
|
||||
else
|
||||
echo "CRITICAL ERROR: An invalid port number was specified."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $4 ]; then
|
||||
INCREMENT=$4
|
||||
fi
|
||||
|
||||
# Saving this for a future release -- right now this would prevent people from running run_hlstats every few minutes to make sure their daemon is operational.
|
||||
#else
|
||||
# # Lookup the highest currently used port number
|
||||
# LASTPORT=`ls ${PIDDIR} | egrep 'hlstats_[0-9]{1,5}.pid' | egrep -o '[0-9]{1,5}' | tail -1`
|
||||
# if [ "${LASTPORT}" != "" ]; then
|
||||
# # We have currently running daemons, to take the current highest port number and increment it
|
||||
# let STARTPORT=LASTPORT+INCREMENT
|
||||
# fi
|
||||
#
|
||||
#fi
|
||||
|
||||
i=0
|
||||
CURRENTPORT=${STARTPORT}
|
||||
while [ ${i} -lt ${NUMDAEMONS} ]
|
||||
do
|
||||
start_daemon ${CURRENTPORT}
|
||||
case $? in
|
||||
0)
|
||||
echo "Daemon successfully started on port ${CURRENTPORT}"
|
||||
let CURRENTPORT=CURRENTPORT+INCREMENT
|
||||
let i++
|
||||
;;
|
||||
1)
|
||||
echo "CRITICAL ERROR: Unable to start daemon on port ${CURRENTPORT}"
|
||||
exit 1
|
||||
;;
|
||||
2)
|
||||
echo "Daemon is already running on port ${CURRENTPORT}"
|
||||
let CURRENTPORT=CURRENTPORT+INCREMENT
|
||||
let i++
|
||||
;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
|
||||
stop)
|
||||
# Usage: run_hlstats stop <port>
|
||||
# All arguments are optional
|
||||
# Defaults: port = ALL
|
||||
|
||||
if [ $2 ]; then
|
||||
check_port $2
|
||||
if [ $? -eq 0 ]; then
|
||||
PORT=$2
|
||||
else
|
||||
echo "CRITICAL ERROR: An invalid port number was specified."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
PORT=0
|
||||
fi
|
||||
|
||||
# Stop a single daemon
|
||||
if [ ${PORT} -ne 0 ]; then
|
||||
stop_daemon ${PORT}
|
||||
case $? in
|
||||
0)
|
||||
echo "Daemon gracefully stopped on port ${PORT}"
|
||||
exit 0
|
||||
;;
|
||||
1)
|
||||
echo "Daemon forcefully stopped on port ${PORT}"
|
||||
exit 0
|
||||
;;
|
||||
2)
|
||||
echo "WARNING: Daemon could not be stopped on port ${PORT}"
|
||||
exit 1
|
||||
;;
|
||||
3)
|
||||
echo "No daemon running on port ${PORT} or PID file is missing."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Stop all daemons
|
||||
PORTS=`ls ${PIDDIR} | egrep 'hlstats_[0-9]{1,5}.pid' | egrep -o '[0-9]{1,5}'`
|
||||
if [ $? -eq 0 ]; then
|
||||
for port in ${PORTS} ; do
|
||||
stop_daemon ${port}
|
||||
case $? in
|
||||
0)
|
||||
echo "Daemon gracefully stopped on port ${port}"
|
||||
;;
|
||||
1)
|
||||
echo "Daemon forcefully stopped on port ${port}"
|
||||
;;
|
||||
2)
|
||||
echo "WARNING: Daemon could not be stopped on port ${port}"
|
||||
;;
|
||||
3)
|
||||
echo "No daemon running on port ${port} or PID file is missing."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
echo "No daemons found running, or PID files are missing."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
restart)
|
||||
# Usage: run_hlstats restart <port>
|
||||
# All arguments are optional
|
||||
# Defaults: port = ALL
|
||||
|
||||
if [ $2 ]; then
|
||||
check_port $2
|
||||
if [ $? -eq 0 ]; then
|
||||
PORT=$2
|
||||
else
|
||||
echo "CRITICAL ERROR: An invalid port number was specified."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
PORT=0
|
||||
fi
|
||||
|
||||
# Handle individual restart request
|
||||
if [ ${PORT} -ne 0 ]; then
|
||||
stop_daemon ${PORT}
|
||||
case $? in
|
||||
0 | 1 | 3)
|
||||
start_daemon ${PORT}
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Daemon successfully restarted on port ${PORT}"
|
||||
exit 0
|
||||
else
|
||||
echo "CRITICAL ERROR: Failed to restart daemon on port ${PORT}"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
echo "WARNING: Daemon could not be stopped on port ${port}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Restart all PIDs
|
||||
PORTS=`ls ${PIDDIR} | egrep 'hlstats_[0-9]{1,5}.pid' | egrep -o '[0-9]{1,5}'`
|
||||
if [ $? -eq 0 ]; then
|
||||
for port in ${PORTS} ; do
|
||||
stop_daemon ${port}
|
||||
case $? in
|
||||
0 | 1 | 3)
|
||||
start_daemon ${port}
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Daemon successfully restarted on port ${port}"
|
||||
else
|
||||
echo "WARNING: Failed to restart daemon on port ${port}"
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
echo "WARNING: Daemon could not be stopped on port ${port}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
echo "WARNING: No HLstatsX:CE daemons currently running."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
reload)
|
||||
# Usage: run_hlstats reload <port>
|
||||
# All arguments are optional
|
||||
# Defaults: port = ALL
|
||||
|
||||
if [ $2 ]; then
|
||||
check_port $2
|
||||
if [ $? -eq 0 ]; then
|
||||
PORT=$2
|
||||
else
|
||||
echo "CRITICAL ERROR: An invalid port number was specified."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
PORT=0
|
||||
fi
|
||||
|
||||
# Handle individual reload request
|
||||
if [ ${PORT} -ne 0 ]; then
|
||||
reload_daemon ${PORT}
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Successfully reloaded daemon running on port ${PORT}"
|
||||
exit 0
|
||||
else
|
||||
echo "WARNING: Unable to reload daemon on port ${PORT} (daemon might not be running)"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Reload all PIDs
|
||||
PORTS=`ls ${PIDDIR} | egrep 'hlstats_[0-9]{1,5}.pid' | egrep -o '[0-9]{1,5}'`
|
||||
if [ "${PORTS}" != "" ]; then
|
||||
for port in ${PORTS} ; do
|
||||
reload_daemon ${port}
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Successfully reloaded daemon running on port ${port}"
|
||||
else
|
||||
echo "WARNING: Unable to reload daemon on port ${port} (daemon might not be running)"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "WARNING: No HLstatsX:CE daemons currently running."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
status)
|
||||
# Usage: run_hlstats status <port>
|
||||
# All arguments are optional
|
||||
# Defaults: port = ALL
|
||||
|
||||
if [ $2 ]; then
|
||||
check_port $2
|
||||
if [ $? -eq 0 ]; then
|
||||
PORT=$2
|
||||
else
|
||||
echo "CRITICAL ERROR: An invalid port number was specified."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
PORT=0
|
||||
fi
|
||||
|
||||
# Handle individual status request
|
||||
if [ ${PORT} -ne 0 ]; then
|
||||
get_status ${PORT}
|
||||
case $? in
|
||||
0)
|
||||
echo "Daemon on port ${PORT} is currently running."
|
||||
exit 0
|
||||
;;
|
||||
1)
|
||||
echo "A stale process was found for daemon on port ${PORT}."
|
||||
exit 0
|
||||
;;
|
||||
2)
|
||||
echo "There is no daemon running on port ${PORT}."
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Reload all PIDs
|
||||
PORTS=`ls ${PIDDIR} | egrep 'hlstats_[0-9]{1,5}.pid' | egrep -o '[0-9]{1,5}'`
|
||||
if [ "${PORTS}" != "" ]; then
|
||||
for port in ${PORTS} ; do
|
||||
get_status ${port}
|
||||
case $? in
|
||||
0)
|
||||
echo "Daemon on port ${port} is currently running."
|
||||
;;
|
||||
1)
|
||||
echo "A stale process was found for daemon on port ${port}. It has been removed."
|
||||
;;
|
||||
2)
|
||||
echo "There is no daemon running on port ${port}."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
echo "WARNING: No HLstatsX:CE daemons currently running."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage"
|
||||
echo "All optional arguments are in <>. The default is in ()."
|
||||
echo ""
|
||||
echo -e "\trun_hlstats start <number of daemons (1)> <starting port number (27500)> <port increment (1)>"
|
||||
echo -e "\trun_hlstats stop <port # of daemon to stop (ALL)>"
|
||||
echo -e "\trun_hlstats status <port # of daemon to check status of (ALL)>"
|
||||
echo -e "\trun_hlstats restart <port # of daemon to restart (ALL)>"
|
||||
echo -e "\trun_hlstats reload <port # of daemon to reload (ALL)>"
|
||||
;;
|
||||
esac
|
||||
exit
|
||||
|
50
scripts/run_hlstats_multi
Normal file
50
scripts/run_hlstats_multi
Normal file
@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
# If you wish to run this script as a daemon script (in /etc/init.d, etc.)
|
||||
# you must configure the "confdir" variable below.
|
||||
# The other variables are optional and really should not be modified.
|
||||
|
||||
echo "
|
||||
WARNING: run_hlstats_multi is deprecated as of 1.6.11.
|
||||
If you need to start multiple daemons you should now use run_hlstats with the correct parameters.
|
||||
|
||||
For information run_hlstats, run:
|
||||
|
||||
./run_hlstats help
|
||||
|
||||
or visit http://wiki.hlxce.com/wiki/Controlling_the_HLXCE_daemon"
|
||||
exit 0
|
151
scripts/run_proxy
Normal file
151
scripts/run_proxy
Normal file
@ -0,0 +1,151 @@
|
||||
#!/bin/bash
|
||||
# HLstatsX Community Edition - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
|
||||
# http://www.hlxcommunity.com
|
||||
#
|
||||
# HLstatsX Community Edition is a continuation of
|
||||
# ELstatsNEO - Real-time player and clan rankings and statistics
|
||||
# Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
|
||||
# http://ovrsized.neo-soft.org/
|
||||
#
|
||||
# ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
|
||||
# HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
|
||||
# http://www.hlstatsx.com/
|
||||
# Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
|
||||
#
|
||||
# HLstatsX is an enhanced version of HLstats made by Simon Garner
|
||||
# HLstats - Real-time player and clan rankings and statistics for Half-Life
|
||||
# http://sourceforge.net/projects/hlstats/
|
||||
# Copyright (C) 2001 Simon Garner
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# For support and installation notes visit http://www.hlxcommunity.com
|
||||
|
||||
# If you wish to run this script as a daemon script (in /etc/init.d, etc.)
|
||||
# you must configure the "confdir" variable below.
|
||||
# The other variables are optional and really should not be modified.
|
||||
|
||||
# Set the path to the scripts folder (you should not need to modify this.)
|
||||
confdir=.
|
||||
|
||||
# Set the configuration file for the daemon (you should not need to modify this.)
|
||||
conffile=hlstats.conf
|
||||
# Set the filename of the daemon to use (you should not need to modify this.)
|
||||
daemonfile=proxy-daemon.pl
|
||||
# Set where you want to log to. This is a directory inside of the confdir setting.
|
||||
# (You should not need to modify this.)
|
||||
logdir=logs
|
||||
# Set the format of the log file
|
||||
logfile=proxy`date +_%Y%m%d_%H-%M-%S`
|
||||
# Set where to store PID files
|
||||
piddir=${confdir}
|
||||
|
||||
# verify that we can see the daemon file
|
||||
if [ ! -f ${confdir}/${daemonfile} ]; then
|
||||
echo "Can't see the daemon. (${daemonfile})"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# verify that you have write access to the directories
|
||||
if [ ! -w ${confdir} ]; then
|
||||
echo "you need write access to ${confdir}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# verify that you have a logs directory
|
||||
if [ ! -d ${confdir}/${logdir} ];then
|
||||
mkdir ${confdir}/${logdir}
|
||||
fi
|
||||
|
||||
if [ ! -w ${confdir}/${logdir} ];then
|
||||
echo "you need write access to ${confdir}/${logdir}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Grab out original directory so we can return after
|
||||
origdir=`pwd`
|
||||
|
||||
# Move into configured directory
|
||||
cd ${confdir}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
# verify that we have a .conf file
|
||||
if [ ! -f ${conffile} ]; then
|
||||
echo "You're missing your configuration file. (${conffile})"
|
||||
exit 1
|
||||
fi
|
||||
echo "Starting HLstatsX:CE...";
|
||||
if [ -f ${piddir}/proxy-daemon.pid ]; then
|
||||
kill -0 `cat ${piddir}/proxy-daemon.pid` >/dev/null 2>&1
|
||||
if [ "$?" == "0" ]; then
|
||||
echo "HLstatsX:CE already running!"
|
||||
else
|
||||
rm -rf ${piddir}/proxy-daemon.pid
|
||||
./${daemonfile} --configfile=${conffile} > ${logdir}/${logfile} 2>&1 &
|
||||
echo $! >${piddir}/proxy-daemon.pid
|
||||
echo "PID file created"
|
||||
echo "Started successfully"
|
||||
fi
|
||||
else
|
||||
./${daemonfile} --configfile=${conffile} > ${logdir}/${logfile} 2>&1 &
|
||||
echo $! >${piddir}/proxy-daemon.pid
|
||||
echo "PID file created"
|
||||
echo "Started successfully"
|
||||
fi
|
||||
;;
|
||||
|
||||
stop)
|
||||
echo "Stopping HLstatsX:CE..."
|
||||
kill -9 `cat ${piddir}/proxy-daemon.pid` >/dev/null 2>&1
|
||||
if [ "$?" == "0" ]; then
|
||||
rm -rf ${piddir}/proxy-daemon.pid
|
||||
echo "Stopped successfully"
|
||||
else
|
||||
echo "No HLstatsX:CE running!"
|
||||
fi
|
||||
;;
|
||||
|
||||
restart)
|
||||
echo "Restarting HLstatsX:CE..."
|
||||
kill -9 `cat ${piddir}/proxy-daemon.pid` >/dev/null 2>&1
|
||||
if [ "$?" == "0" ]; then
|
||||
rm -rf ${piddir}/proxy-daemon.pid
|
||||
./${daemonfile} --configfile=${conffile} > ${logdir}/${logfile} 2>&1 &
|
||||
echo $! >${piddir}/proxy-daemon.pid
|
||||
echo "PID file created"
|
||||
echo "Restarted successfully"
|
||||
else
|
||||
echo "HLstatsX:CE"
|
||||
if [ -f ${piddir}/proxy-daemon.pid ]; then
|
||||
rm -rf ${piddir}/proxy-daemon.pid
|
||||
fi
|
||||
./${daemonfile} --configfile=${conffile} > ${logdir}/${logfile} 2>&1 &
|
||||
echo $! >${piddir}/proxy-daemon.pid
|
||||
echo "PID file created"
|
||||
echo "Started successfully"
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: ./run_hlstats [ start | stop | restart ]"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Return to original directory
|
||||
cd ${origdir}
|
||||
|
||||
exit 0
|
Reference in New Issue
Block a user