Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # 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"]
- );
- %g_eventTables2 = (
- "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;
Add Comment
Please, Sign In to add comment