home *** CD-ROM | disk | FTP | other *** search
- /* q3log - A quark III Arena log parser/analyzer
- "What's the point of playing if you don't keep score?"
- Feedback to: dante@island.net
- Current version is 1.0 */
-
- ========
- Contents
- ========
- Introduction
- Quick Start
- Installation
- Running q3log
- Notes
- Technical Notes
-
- ============
- Introduction
- ============
- Hi Mom!
-
- With that out of the way, let's talk logs. If you're thinking of something
- sexual or scatological at this point - ha ha, let's move on now. We're
- talking about quark3 logs, and what this program will do with them.
-
- q3log will read logs written by quark III Arena and tally all kills and
- suicides by each player. These stats will be stored in a database for future
- viewing and analysis. These stats will be displayed within 3 graphs:
- Lifetime totals/Current totals/Game stats. What precisely is displayed and what
- it means will be discussed in the "Running q3log" section.
-
- In summary, if you want to keep track of who you killed, who killed you, and
- what weapon was used, this program will do so nicely.
-
- By the way, this is freeware, so please don't hassle me about features that it
- absolutely must have. Ask nicely, and I'll see what I can do.
-
-
- ===========
- Quick Start
- ===========
- Run q3log.
- Enter your name and where your logs will be located.
- Select parse log.
- View your stats.
-
- The basic operation is pretty much that simple. Honest.
-
-
- ============
- Installation
- ============
- I didn't include an installer or anything, because I really don't think it's
- necessary. If there's a big demand, I might do something about that later, but
- it'll probably just amount to a self-extracting zipfile. But I digress.
-
- Personally, I keep the program in its own directory. It doesn't matter where
- it is, because you're going to tell it where to find the logs, and it writes all
- its own files in the directory that it's in. So, just create a directory, copy
- the q3log.exe file into it, and you're set. If you want a shortcut to it, that's
- entirely up to you. Make sure the shortcut's properties include the program's
- directory, or the program might have a problem finding its configuration and
- database files.
-
-
- =============
- Running q3log
- =============
- First off, you need to produce some logs. Q3 will do this quite happily, and
- all you need to do is run it with the following extra parameters.
- +set logfile 2
- If you understand what I mean by this and you know how to do it, you can move
- to the next thing. If you just use the "Play quark III Arena" shortcut, you need
- to alter it a little. In the "Target" box of the shortcut Properties, just add
- +set logfile 2 to the end of what's already there. If you use GameSpy, go to
- "Games and Filters". Scroll down until you find the settings for quark3. Change
- the command line from "quark3.exe" to "quark3.exe +set logfile 1".
- When all that's done, Q3 should write a log of all its activity, and that's
- what we're after.
-
- The first time you run q3log, the setup dialog will open. You need to show q3log
- where your log files will be. If you know where that is, move on. They are
- written in a sub-directory of your quark III Arena directory called "baseq3".
- Browse to this directory. In the file list box, you should see (among other
- things) pak3.pk3. If that file is there, you're in the right spot.
-
- After that, you simply need to enter the name you use in Q3 - and this has to
- be exact, or the individual stats will simply all read zero. A good way to find
- the exact text of your name is to look in your q3config.cfg file. This will also
- be in the directory I mentioned in the last paragraph. You're looking for an
- entry that looks like this:
- seta name "Dante"
- Yours won't say "Dante" of course, but you get the idea.
-
- Once those two things are done, you're pretty much ready to go. Select
- "Parse Log" from the menu. If your machine is relatively fast (and it should be
- if you're playing Q3) the parsing will be finished before you realize it's
- started. If you've been keeping a log for weeks and it's 100MB or something,
- it'll take a little longer. At any rate, it'll be pretty quick.
-
- When it's done, assuming there was at least one frag in the log, you will see
- the numbers at the bottom of the screen change from "0/0" to well, something
- else. These numbers tell you:
- which game in the database is currently selected/total games in the database
- You can browse through the database will the arrow buttons.
- Now, if you did any fragging yourself, the totals will have changed as well.
- The top grids show your lifetime stats - basically the total of all stats for
- you in the database, and the bottom grids show your stats for the currently
- selected game.
-
- You can click on the "Game Stats" tab to get to the nitty-gritty of the currently
- selected game. The top grid will show everybody who played in that particular
- game, and their totals for that game. The bottom grid shows who fragged who.
- Here's how this grid works: The names in the left column are who did the fragging
- and the names along the top row are whom they fragged. So if you want to know just
- how many times you nailed any particular person, find your name in the left
- column and highlight that row. Now just line up the totals with the names. If
- you want to scroll around, no problem - the names will remain visible.
-
- Keeping score is "A Good Thing", as Martha would say.
-
-
- =====
- Notes
- =====
- First off, if your desktop resolution is any lower than 800x600, I'm sorry, but
- you're going to be doing A LOT of scrolling around to see everything. Mine's
- 1024x768, but I did basically design the interface for 800x600. You'll see what
- I mean.
-
- q3log will rename your logfiles. I did that so that people wouldn't be
- accidentally parsing the same file a whole bunch of times. The logfiles will be
- renamed qconsole000.log, qconsole001.log, qconsole002.log, and so on up to
- qconsole999.log, at which point it will simply stop renaming them. If you want
- to keep more than 1000 logs, you need to get out more. Seriously though, I was
- originally going to just delete them, but folks might have another program that
- they want to run the logs through, or just want to keep them for a while for
- whatever reason. I also didn't really want to see people's hard drives filling up
- with files, so this seemed to be somewhere in the middle. If you want to ditch
- the old logs, by all means, ditch them. Future feedback will likely decide if
- this "feature" changes.
-
- If you're interested, q3log creates three files:
- q3log.ini - this just stores your name and the location of your logs
- totals.dat - stores your lifetime totals, and is updated whenever you
- parse new logs
- games.dat - stores all game stats, and is updated whenever you parse new logs
- (obviously)
-
- Don't ask me why I used separate files for the game stats and lifetime totals,
- I must have been half-asleep when I wrote that code. I might fix it one day.
-
- I don't really know (I don't even have a good guess) how well the program will
- scale up as your database grows. During testing I had about 175 games in the
- database and it didn't really get noticeably slower - the size of the games.dat
- file was just under 500K. However, I realize that folks will likely have thousands
- of games in there after a while, and I can't make any promises. The database is
- pretty much as compact as it can be, and the only way to make it smaller would be
- to get rid of the individual game stats. I don't really want to do that, but it
- might be necessary if the database file grows to 5 Gigs and it takes 20 minutes
- to browse to the last entry. For those who have a little programming knowledge and
- may have some ideas as to how I might make this scale better, I'm all ears. You
- can read the technical notes at the end of this file and I'll explain how the
- database is set up - assuming I still understand it myself.
-
- I'm considering adding a function to remove older games from the database, and
- while it would be very easy to write the actual code, I'm fairly sure it would be
- a VERY SLOW process with large database files. Another angle might be to have a
- maximum number of games per file and simply use multiple database files. That might
- get a little hairy after a while, especially if people play a lot of games. However,
- if a thousand games in a file isn't too slow, I think it might be the best answer.
- We'll see.
-
- I'm a CTF guy - that's why capture totals are seen here. However, please don't
- write to me asking for your favorite mod to be represented - it's not gonna
- happen. There's just too much to track, and the data portion of the program would
- quickly get out of hand and exceedingly difficult to manage. Only out-of-the-box
- DM/CTF. That's it. Don't ask. Writing the extra code doesn't bother me, but
- each individual frag string has to be included to get an accurate total, and I've
- seen mods that have 10 or more different strings for each weapon. While some think
- that's real nice and keeps everything fresh, it's a nightmare when you're the one
- who has to make sure that they have every single one of them exactly right. It's
- not hard when you have the source code, but mod authors tend not to release that to
- other programmers. So, let me say this once more, just so we're clear. No mods,
- no way. Not now, not ever.
-
-
- ===============
- Technical Notes
- ===============
- If you understand C++ and you're interested in (basically) how the program
- works, here it is. I'm not going to explain how each individual function works,
- but hopefully by the time I'm done, you'll have the general idea of what I did
- here.
-
- The way the frags are initially identified is not particularly magic. The program
- searches for strings that are common to each particular type of frag. The way that
- Q3 does its logging makes this very easy - once the client's graphics, sound, etc
- are set up, game events make up the lion's share of the remaining file.
-
- When a line in the log is identified as a frag/capture/suicide or whatever, the text
- is parsed to identify attacker, target, and weapon used. Once those things have been
- established, this information is added to a binary tree. Each node of the tree
- contains the player's name, a couple of structures representing total frags of each
- type, and another binary tree containing all the other's players names and how many
- times that player has fragged each of them.
-
- The math is pretty simple here. The main tree contains X squared objects, X being
- the total number of people in the game. While I admit that this would not scale up
- very well, the average number of players in any given game is somewhere between
- six and twelve, so we're only dealing with about 144 objects max on average. I wrote
- a similar program for quark2 and ran it on my 486DX2/66 and it ate through 100
- game log files in less than a minute and wrote html files for every game. Now that
- we're in Pentium3 country, there's really no problem.
-
- The actual mechanics of how all that is done is pretty lightweight stuff, and I'm
- going to leave it up to the user to figure out how they would do it. A first year
- computer science student could manage it - and in fact one did. Yes, that would be
- me. I wrote the previously mentioned program for Q2 during my first year, and once
- you have a working knowledge of linked lists and binary trees, it shouldn't be too
- difficult to figure out what I did.
-
- Ok, let's move on. The program has reached the end of the level, and it's time to
- do something useful with this tree we've built. We kick it over to a function that
- opens up our database. The first thing in the file is the number of records (games)
- contained in the file. We read that, add one, and then write that number back to
- the file. We then simply go to the end of the file, and we're ready to write the
- stats for this game.
-
- Each record is written like so:
- We write the number of players in this particular record.
- We do an inorder traversal of our player tree, and write the stats for each player
- along the way. Player's name, the contents of the kill/suicide structures, then an
- individual total for each other player in the tree (we don't need their names here,
- because everything is sorted, and their names will come up when we reach their node).
-
- Once that's done, we go back up to the top of the file. We then have to go through
- each record, searching for our designated player name so that we can update his/her
- lifetime stats. All that we need is the kill/suicide structures, and once the player's
- name is found within the record, the structure is read and the program moves to the
- next record. My hunch is that this will probably be the most time-consuming task when
- the file starts to get really large, but I haven't done any real analysis (and if the
- truth were known, I probably won't).
-
- So when it's time to display a particular game in the grids, the function that
- retrieves the stats is fed the record number of the game that the user wants to see.
- The program just searches through the file until it finds the desired record. It then
- re-builds the tree and that tree is used to fill in the grids. I know, I know. I should
- have just used a linked list here, since the records are already sorted. I didn't feel
- like going back and changing it by the time I'd reached that stage of the program. With
- the tests I've done to this point, it actually reads the records pretty quickly. I'm
- hoping that people's systems will be able to keep up with the growing databases to
- a certain point. What I'm actually hoping is that the databases will grow too large
- for people's hard drives before that happens...
-
- I do have a fairly workable idea to make navigation faster, and if it looks like it's
- going to bog down fairly quickly, I will implement it. Tallying the lifetime totals
- will not get any faster without sacrificing the program's ability to calculate totals
- for any named player. Life's a trade-off.
-
-
- That's it. Hope it's everything you need.
- -Dante
-