Title    : fragstats
Filename : fs106b_NT.zip, fs106b_linux.tar.gz, fs106b_solaris.tar.gz
Version  : 1.06b
Date     : 12th October 1998
Author   : Chris Scarvell
Email    : chriss@pcug.org.au
WWW      : http://quake.tip.net.au/fragstats.html
Credits  : id software and the QuakeWorld team. Thanks to Nigel Haynes (Fanatic) 
           & Rohan McElwee (BigFoot) for help with the Linux port. Also thanks to:
           Hofkens Dale (ZZip) for help with the Quake extended character mapping.
           Marco Berri for the new Duel statistic.
           RooS for the alternative Skill statistic.
           Danny Whitesel (VaReBeL) for beta testing & suggestions.
           And thanks to the growing Fragstats user base out there for the constructive
           feedback!

Type of Mod
===========
Quake C    : No
Sound      : no
MDL        : no
C code     : Yes
HTML       : Yes
QuakeWorld : Yes
Quake 2    : Yes
O/S        : Win32, Linux 2.0.x, Solaris 2.51
Compiler   : MSVC++ 5.0 sp3 (Win32), GCC 2.7.2.1 (UNIX)

Package
=======
fragstats.exe (fragstats)  Win32 (UNIX) Fragstats program
qplayer.exe (qplayer)      Win32 (UNIX) Query Player cgi program
scores.html                Sample scores page
fs.bat                     Sample batch file for automatic execution
fragstats.cfg              Sample config file
fragstats.txt              This file
fs106.txt                  Upgrade instructions
FAQ.txt                    Frequently asked questions
template.txt               The whys and wherefores of HTML templates
maintemp.html              Sample HTML template
top20temp.html             Sample HTML template
cgitemp.html               Sample HTML template for Qplayer
cgierrtemp.html            Sample HTML Error template for Qplayer
ctf_templates              Directory
   ctf_cgitemp.html           Sample CTF HTML template for Qplayer
   ctf_maintemp.html          Sample CTF HTML template
   ctf_top20temp.html         Sample CTF HTML template
qwlog_templates            Directory
   cgitemp.html            Sample HTML template for Qplayer
   maintemp.html           Sample HTML template
   top20temp.html          Sample HTML template

Whats new in 1.06
=================
. User Defined Tags (UDT's) for use in templates. See the templates.txt and fragstats.cfg
  files for details.

. Support for Quake 2 mods such as CTF, HeadHunters, etc via UDT's. User defined tags
  let you specify what special bonus scores are recorded and logged. The user defined
  tags can be used in all template files. Some sample CTF templates have been included
  in the distribution.

. Team statistics for GS log users. Fragstats can generate a complete list of teams and
  total scores for the Overall Stats and each map, Qplayer can display the Players team
  name and total score.

. Map based statistics for GS log users with the option to switch them off if you want.
  As before, HTML pages for 'Overall Stats' will be generated in the 'htmldir' directory.
  If map stats are enabled (the default if using GS style logs), a subdirectory will
  be created for each map under the directory specified by 'htmldir'. A complete set
  of HTML pages as specified by the 'htmlout' commands will be generated in each
  subdirectory. You can also use 'htmlout' and the new tags (see below) to help generate
  a custom scores.html for each map. check out the sample fragstats.cfg and scores.html
  files for details.

. Weapon based statistics for GS log users. These are only visible for indiviuals via
  Qplayer.

. Added 'Duelthresh' option to provide fairer Duel sorting.

. Specify the GS log name via the 'gslogname' option. Previously, Fragstats forced you
  rename the GS log to "stdlog.log". Now you can just set the name in the config file.

. Added comparative frag count to victim lists in Qplayer. This makes it easier to compare
  frag counts with your buddy/enemy, especially if you have lots of frags.

. Added optional Error template for Qplayer. You can alter this template to the look & feel
  of your site. Errors that are caused by bad user input (eg. lookup by name of someone
  who doesn't exist) will use this template to display an error message.

. Fixed bug with last line processing of cfg file.

. Tighter log parsing code; malformed frag log entries are now always rejected.

. Added new template tags for support of team, weapon & map statistics:
  <!--team_name-->        team name
  <!--team_name_pad-->    team name padded to 32 chars
  <!--total_team_score--> total score for team
  <!--total_team_score_pad-->  total score for team padded to 8 chars
  <!--map_name-->         map name
  <!--map_numplayers-->   number of players recorded for that map (Fragstats only)
  <!--map_numfrags-->     number of frags recorded for that map (Fragstats only)
  <!--map_path-->         subdirectory containing the stats for
                          that map
  <!--map_name_url-->     Encoded link to Qplayer with map name and player name (Qplayer
                          only)
  <!--page_name-->        name of the HTML page being written (Fragstats only)
  <!--weap_name-->        weapon name (Qplayer only)
  <!--weap_kills-->       kills by that weapon (Qplayer only)
  <!--weap_deaths-->      deaths by that weapon (Qplayer only)

  There are also new embed tags, <!--embed_teams--> for Fragstats, <!--embed_maps-->
  for Fragstat and Qplayer, and <!--embed_weaps--> for Qplayer.

. New sample template files which show the usage of the new tags.

Whats's new in v1.05
====================
. GS log support. Note that initially I'm only using info from the
  stdlog.log which is compatible with the 1.04b of Fragstats, ie. Kills
  and Suicides. No other score types or general log information is used
  at this time.
. Bug fixes (mainly with the smart name conversion). If after stripping
  clan designations, etc. the player name is shorter than 3 characters, the
  name is left as-is.
. Changed Deaths so it doesn't include Suicides.
. Alias option. This allows the admin to define aliases for players that
  have changed names, so their scores get combined into one.
. Duel statistic. This shows a count of how many players you outfrag and
  how many outfrag you to. Draws are not shown. This statistic is limited
  to those players you have frags against or have been fragged by.
. Alternative Skill statistic. A modified skill calculation. Enabled using
  the 'Skilltype' option (see below).

  Currently, the skill calculation formula taken from QW Master Servers
  doesn't take the killer's Skill into consideration. This means that a
  master player gains exactly the same number of points for fragging
  "John_Rambo", as a newbie would.

  The new skill calcuation works like this:

  Killers skill = Killers skill + ((Killees skill / Killers skill) * 10)

  and correspondingly:

  Killees skill = Killees skill - ((Killees skill / Killers skill) * 10)

  The alternative skill calculation is added Killer's skill, and subtracted
  from the from the Killee's skill.

  Some examples: 
  1)
  Killer: a very good player with skill 3500
  Killee: a good player with skill 2500

  Killer = Killer + 2500/3500 * 10
  Killee = Killee - 2500/3500 * 10

  Killer has now 3507 points, Killee 2493

  2)
  Killer: a very good player with skill 3500
  Killee: a newbie with skill 1200

  Killer = Killer + 1200/3500 * 10
  Killee = Killee - 1200/3500 * 10

  Killer has now 3503 points, Killee 1197

  3)
  Killer: a newbie with skill 1200
  Killee: a good player with skill 2500

  Killer = Killer + 2500/1200 * 10
  Killee = killee - 2500/1200 * 10

  Killer has now 1220 points, Killee 2480
  Note the integer rounding in this case.

  If a player suicides, the player gets their alternative skill adjusted
  like so:

  Killer = Killer - (Killer skill / 1000)

  This is a significant penalty to those who like to keep their skill high
  by topping themselves when in a bad position.

  Note that is a an alternative statistic; it replaces the old skill when used.

What you need to have
=====================
. Administrative access to a system running the QuakeWorld/Quake2 server

. Access to a Web Server running on this machine, or having network
  drive access to at least the qw directory belonging to the QuakeWorld
  server. You will need to be able to write to a Web Server document
  directory and a Web Server CGI directory.

. I've tested fragstats sucessfully with Netscape FastTrack 2.01,
  Enterprise 2.01/3.51, MS Internet Information Server, MS Win95 personal
  webserver and Apache. This list is by no means exhaustive - fragstats
  should work happily with virtually any Web Server. This being said,
  there is a known problem with Website and the qplayer program on NT.

Description
===========
Fragstats replaces the much missed scoring system from the original
QuakeWorld 1.2x. The QuakeWorld team decided that centralised frag
logging was just too much and instead implemented local server frag
logging. This document assumes you are familiar with the deployment of
a Web Server.

Current versions of the server record frags in the frag_*.log
files under the qw directory. These logs contain all the information,
but need processing to read anything meaningful from them. This is
where fragstats comes in!

Fragstats parses the frag logs, collating scores for each player.
From this data, fragstats generates html pages suitable for display
on any table capable browser and creates a database which can be
queried later by the cgi program qplayer.

For safety, fragstats does not alter the frag logs in any way.

Features
========
. To provide the scoring functionality of the original QuakeWorld Master.
  That's got to be the starting point, hasn't it? Fragstats records Frags,
  Deaths, Rank, Efficiency and Skill PLUS compiles lists of victims and
  deaths for each player.

. Maximum performance 
  The actual processing of the log files is quite intensive, and increases
  exponentially as the number of logs and players increases. Fragstats and
  the qplayer CGI program are optimised C code for just this reason.
  Optimised sorting and searching algorithms such as quick sorts, hash
  indexes and binary searches are used extensively. Fragstats has NO LIMIT
  to the number of players it can process (actually, the limit is MAXINT or
  2^31 - 1. Now if I had a 64 bit compiler... :)

. Access to generated stats via a web browser. 
  Almost a given these days. Fragstats can generates player lists sorted by
  Frags, Deaths, Rank, Efficiency, Suicides, Skill and Duel.

. To provide a player lookup feature accessible via a web browser, rather
  than just a huge static list of players. At the time of writing we have
  over 3000 registered players on our QuakeWorld server. There are other
  sites with over 6000 players. Finding an individual in this list is pretty
  hard. Fragstats supports (via the qplayer CGI program) lookup of additional
  player details such as victim and death lists. You can also lookup players
  by name.

Using Fragstats with Quake 2
============================
You will need to obtain a Quake 2 mod that generates logs files - Quake 2 out
of the box will *not* do this. Suggestions are:

. ServerConfig Mod by GutSpiller (pstepp@hotmail.com), available for win32 and
  Linux. It generates both QW and GS style logs. Obtain from:
  http://quake2.com/sconfig

. Lithium Mod by WhiteFang (matt@lithium.com), available for win32, Linux & Solaris.
  It generates GS style logs. Obtain from:
  http://www.planetquake.com/lithium/

. GS log mod by Mark "Grey" Davies, available for most platforms. It *only* generates
  GS style logs. Obtain from:
  http://www.planetquake.com/gslogmod

Mods like Capture the Flag and Rocket Arena can generate GS style logs as standard. 

Installation
============
To install:

1. Unzip the package.
2. Copy fragstats to your qw directory or some other directory in
   your path.
3. Copy qplayer to a cgi directory.
4. Inspect the scores.html file, changing the "action=/cgi-bin/qplayer.exe" to
   the approprate URL mapped path for qplayer. Also check the "method=POST" and
   change to "method=GET" if your web server doesn't support POST. Copy the
   modified scores.html to a web server document directory.
5. Check the options set in the sample fragstats.cfg file, modify as required.
6. If using QuakeWorld, enable frag logging in your QuakeWorld server by toggling
   'fraglogfile' at the server console. From the QuakeWorld Server Console Commands
   document (Version: 1.1 Author: JakFrost
   <jakfrost@ultinet.net>):

   fraglogfile (T)

    Syntax: fraglogfile
    Default: off

    Toggles logging of kills to a file and reporting to external frag 
    polling programs.  The file name is frag_*.log.

   If you are using Quake 2 with a mod that provides logging, refer to the mod
   documentation for information on how to enable logging.

How to run
==========

Fragstats
---------
Fragstats requires the following arguments (they can be specified in the config file):

  logdir=<directory where the frag logs are found>
  htmldir=<directory to put the html pages - same as scores.html>
  cgidir=<explicit path to cgi directory>
  cgiurl=<URL mapped path to cgi directory>

If the CGI interface is disabled (see below), cgidir & cgiurl are not required.

Eg.
For UNIX:
  fragstats server=Megadeath logdir=/quake/qw htmldir=/webserver/docs cgidir=/webserver/cgi-bin cgiurl=/cgi-bin
For Win32:
  fragstats server=Megadeath logdir=c:\quake\qw htmldir=c:\InetPub\webroot cgidir=c:\Inetpub\scripts cgiurl=/scripts

If these options are not set on the command line, fragstats will attempt
to find them in the config file. By default fragstats will look for
fragstats.cfg in the current directory. By using the 'config' option,
you can specify another location and name for the config file. Other
options you can specify are:

  server=<server name>
  config=<path to the config file>
  cgiqplayer=<name the qplayer program will be invoked as>
  text=<HTML text colour>
  bgcolor=<HTML background colour>
  link=<HTML link colour>
  vlink=<HTML visited link colour>
  alink=<HTML active link colour>
  lastscanned=<last scanned data file name>
  effthresh=<number of frags before a efficiency rating is given>
  duelthresh=<number of Wins required to sort higher>
  background=<HTML background image>
  mapchar=<character mapping>
  htmlout=<output directive>
  cgitemplate=<CGI template file>
  rawoutput=<raw output file> [extended|mapped]
  disablecgi=<yes or no>
  nameconvert=<yes or no>
  disablemapstats=<yes or no>
  logstyle=<QW or GS>
  alias=<alias definition>
  skilltype=<Original or Alternate>

New in v1.06 are the following settings:
  gslogname=<GS log filename>
  cgierr=<error template used by qplayer>

'Htmlout' specifies HTML output. I've provided several sample templates which will
generate default output. I've also included some derivations of the defaults for CTF
support and others if you are using QW style logs. You can find these, respectively,
in the ctf_templates and qwlog_template directories.

Templates are described in detail in the template.txt file. If no 'htmlout' commands
are specified, Fragstats will generate default outputs of all players and the top 20
sorted by Frags, Deaths, Rank, Suicides, Efficiency and Skill. I would recommend using
templates where possible; they are much more flexible.

'Cgitemplate' specifies a template file for qplayer to use. See the template.txt
file for details.

'Cgierr' specifies an error template file for qplayer to use when it encounters some
errors. For example, it will get used when someone tries to look up a name that doesn't
exist. A sample error template 'cgierrtemp.html' has been provided.

'Rawoutput' specifies a file to which Fragstats will write the players database
contents in CSV format. You might find this useful for later anaylsis via a
spreadsheet or input to another program. You can optionally specify to output player
names using the Quake extended character set ('extended' option) or with character
mappings as per the 'mapchar' command ('mapped' option). If neither is specified, the
default is 'mapped'.

'Disablecgi' simply toggles the links to qplayer in the HTML output generated
by Fragstats.

'Nameconvert' toggles whether Fragstats will do a smart name conversion of
player's names. If this is switched off, 'Primevil [DLS]' WILL NOT be the same
as 'Primevil'. IMPORTANT NOTE: If you change this setting, you should delete the
last scanned data file (see the lastscanned option) and reprocess your
logs from scratch. This will ensure that all records in the logs are processed
with the same name conventions.

'Logstyle' allows you to specify Fragstats to parse QuakeWorld style logs (QW) or
GS log standard style logs (GS).

'Alias' allows you to define a list of aliases that a player is known by. This is
most useful when a player has changed names and would like to combine their old
scores under their new name.

'Skilltype' allows you to specify the type of skill calculation done. The default
calculation is the same as the one used by the original QuakeWorld Master server.
See above for deatils on how the alternate calculation works.

'Duelthresh' specifies the number of Wins you need to have to sort higher. For example,
if set to 10 , this would prevent someone with a Win/Loss ratio of 9/0 getting rated
higher than someone with 50/1.

'Disablemapstats' allows you to specify if you want to include map scoring as well
as overall scoring. Calculating map stats about doubles the work and hence memory
and CPU consumption of Fragstats. You also chew up more disk space. I've added this
option in case you don't want to crunch map stats. Of course, this option is
meaningless for QW style frag logs - there is no map data anyway.

'Gslogname' allows you to specify a specific filename that contains your GS logs.
If not specified, Fragstats will default to 'stdlog.log'. This option is of no use
whatsoever if you are using QW style logs.

All of these (except for config) can be specified in the config file.
Options are specified in the config file without the '=', eg.

server	Megadeath
htmldir	/webserver/docs
rawoutput /tmp/stats.csv extended

Check out the included fragstats.cfg file for details.

What it does
------------
Fragstats will parse all the frag logs starting from frag_0.log going
to frag_N.log sequentially. If you are parsing GS style logs, Fragstats will
look in the log directory for the 'stdlog.log' file.

Fragstats tries to be a little smart about how it processes player
names. For comparison purposes, player names are case insensitive,
spaces are removed and clan designations enclosed in [], (), {}, <> and
-- are ignored. For example, 'PrimEvil [DLS]' is considered to be the
same player as 'primevil'. If the 'nameconvert' option is set to 'no',
this smart name comparison will not occur, and players will have to have
identical names to be considered the same.

For complete name changes, you can define the old name(s) as aliases of the
new name.

The Quake extended character set is fully supported via the 'mapchar'
command'. All those funky names you see in QuakeWorld are translated
automatically into displayable ASCII characters!

Once the logs are scanned, fragstats will generate web pages as instructed
via the 'htmlout' commands (or if no 'htmlout' commands are specified, via
internal defaults), and the player database and the victims database.

The player and victims database end up in the cgidir along with qplayer.

The default HTML pages contain complete and top 20 lists of players, sorted by
rank, frags, deaths, suicides, efficiency and skill. The players and victims
databases are accessed by the cgi executable, qplayer.

Fragstats saves the last log number and file pointer position in the
last scanned data file. The next time you run fragstats, it will reload
the database and start scanning from this position. This can save a lot
of time for subsequent runs. If you want to rescan the logs from
scratch, delete the last scanned data file or change the contents to "0 0 0".

Did it work?
------------
Fragstats will generate some output which you should check to verify
a successful run. If you see an 'Error parsing' message, don't worry.
It indicates that an incomplete frag record was found in a frag log.

The 'Error parsing' message indicates that an incomplete frag record
was found. When fragstats encounters an incomplete record, it ignores
it and gets the next record. In my experience, incomplete records can
occur in two situations:

1. The server has crashed, and so hasn't flushed the last record(s) to
   the frag log.
2. The server is still writing that particular frag log (this doesn't
   seem to happen much, but is possible).

In case 1, frags that hadn't been flushed to the logs will be lost.
Sorry.

In case 2, the frags will be flushed eventually, so the data is OK,
just temporarily unavailable.

Fragstats can produce other error messages. For example, you haven't
provided the required command arguments, specified an invalid directory,
you've run out of disk space, etc.

Running fragstats automatically
-------------------------------
Fragstats was designed to be run as a batch job maybe once or twice a
day. A good reason for this is that it is fairly CPU intensive. Running
this at the same time as a full on frag fest is likely to result in a
few seconds of poor performance. Also, the frag logs are flushed fairly
infrequently by the server. Fragstats is not a real time reporting
tool!

With this in mind, it is quite easy to set up a job via the NT
scheduler or UNIX cron command to execute fragstats periodically.

With NT, enable the Scheduler service and run fragstats with the 'at'
command. For example:

   at 3:00 /every:monday,tuesday,wednesday,thursday,friday,saturday,sunday c:\quake\qw\fs.bat

The fs.bat file simply invokes fragstats and redirects standard output
to a text file for later perusal.

With UNIX (Linux, Solaris) run fragstats via cron. I won't go into a
discussion on the usage of cron - the man pages should cover this.

Aliases
-------
Fragstats allows you to set up alias definitions for mapping of old
names to new ones. Use this when a player has used more than one name
and would like to combine the scores.

The format is:
  alias name with aliasname ...

Example:
  alias "Stoo [GE]" with Stoo Stoo.[GE] Stoo.{ge} stoo "Stoo [DLS]"

will combine the scores of Stoo, Stoo.[GE], Stoo.{ge}, stoo and
Stoo [DLS] into one player called Stoo [GE]. note I've used double
quotes to ensure Stoo [DLS] and Stoo [GE] are considered to be
single player names.

Alias names are case sensitive.

If you add or change alias definitions, delete the last.dat file to force
Fragstats to reparse the logs. Otherwise, data stored in the databases
will not be updated.

Extended character support
--------------------------
Fragstats will automatically convert extended Quake characters to
standard ASCII characters suitable for display. Mapping of characters
is done via the 'mapchar' option.

The format is:
  mapchar c to n n n n n ...

Example:
  mapchar ! to 61

Would cause every instance of = (ASCII 61) to be replaced with a !
You can specify numbers as well as characters.

Example:
  mapchar 34 to + # 64

Would cause every instance of +, # or @ (ASCII 64) to be changed to
double quotes. Single digit numbers are assumed to be a character.

Example:
  mapchar 1 to 147

is the same as:
  mapchar 49 to 147

while:
  mapchar 01 to 147

is the same as:
  mapchar 001 to 147

Lastly, you don't need to map a character to it's valid ASCII position.

If this sounds all a bit too hard, don't worry - the sample fragstats.cfg
file has all the mappings required for the Quake extended character set.
Feel free to have modify these mappings. I deliberately went to the effort
to make these mappings customisable so you're not just stuck with my
interpretation of "best fit".

If you find a problem or figure out a better mapping, let me know.

IMPORTANT NOTE: If you change the mappings, you should delete the
last scanned data file (see the lastscanned option) and reprocess your
logs from scratch. This will ensure that all players in the database
are processed with the same mappings.

Qplayer
-------
Qplayer gets invoked when you click on a player in the generated
pages. It will query the databases and returns stats for that player.
You will have to set up the web server to recognise the cgidir as a
cgi directory if you haven't already. The stats returned include the
frags, deaths, rank, efficiency and skill of that player, along with a
list of that players victims and a list of who has killed that player.

Qplayer support both HTML GET and POST methods. So if name lookup in
scores.html isn't invoking qplayer correctly, try changing the method.

To Test
=======
. Setup your web server cgi directory and mapping if you haven't
  already.

. Make sure fragstats is in your path.

. Make sure scores.html has been copied to the html directory you will
  provide as an argument to fragstats.

. Make sure you've enabled fraglogfile as described above and ensure
  there are some frag logs written.

. Run fragstats via the command line, providing the log directory,
  html directory, cgi directory and cgi URL mapping as arguments.
  Alternately, set the options in the fragstats.cfg file and run
  fragstats without any command line options.

. Check to see that some html pages have been created in the html
  directory you specified to fragstats (these are the default pages
  produced if you don't specify any htmlout commands):
  Rank.html
  Frags.html
  Deaths.html
  Efficiency.html
  Skill.html
  Suicides.html
  Rank-top20.html
  Frags-top20.html
  Deaths-top20.html
  Efficiency-top20.html
  Skill-top20.html
  Suicides-top20.html

. Check to see that the players.db and victims.db have been created in
  the cgi directory you specified to fragstats.

. Send your browser to scores.html and see if it worked! You can compare
  your output with that found at http://quake.tip.net.au/scores.html

If something is not working right, check out out the FAQ.txt file.

Disclaimer
==========
This software is "Freeware" as defined by the GNU public licence, with
the exception that source code is not provided. No warranty of any kind
is offered or given with this software. The software is provided on an
"as is" basis. No liability is offered or accepted by the use or misuse
of this software. 
